## -*-octave-*-
function [bonds,components,n_vector_bonds] = \
ibg2abg(name,bonds,infofile,errorfile)
## write useful quantity of data to log
struct_levels_to_print = 6;
################################
## create component structure ##
################################
## loop over each bond in ibg.m file
for [bond, bond_name] = bonds
## get the bond number
i = str2num(split(bond_name, "bond")(2,:));
## populate "head" and "tail" structures
## then copy the contents to an overall structure
## track (signed) vector bond number within each component
head.index = +i;
tail.index = -i;
## extract type of component at each end
head_type = deblank(split(bond.head.component, ":")(1,:));
tail_type = deblank(split(bond.tail.component, ":")(1,:));
## extract name of component at each end
head_name = deblank(split(bond.head.component, ":")(2,:));
tail_name = deblank(split(bond.tail.component, ":")(2,:));
## extract port label data
head.label = bond.head.ports;
tail.label = bond.tail.ports;
## determine whether internal port or subsystem
## and fix names of ports
if (strcmp(head_type, "SS") & (index(head_name, "[") == 1))
head_comp_or_port = "port";
head_name = mtt_strip_name(head_name);
else
head_comp_or_port = "comp";
endif
if (strcmp(tail_type, "SS") & (index(tail_name, "[") == 1))
tail_comp_or_port = "port";
tail_name = mtt_strip_name(tail_name);
else
tail_comp_or_port = "comp";
endif
## copy data to object structure (objects)
eval(sprintf("objects.%s.%s.type = '%s';",
head_comp_or_port, head_name, head_type));
eval(sprintf("objects.%s.%s.type = '%s';",
tail_comp_or_port, tail_name, tail_type));
eval(sprintf("objects.%s.%s.bond%i = head;",
head_comp_or_port, head_name, i));
eval(sprintf("objects.%s.%s.bond%i = tail;",
tail_comp_or_port, tail_name, i));
endfor
disp("--finished extracting data from ibg.m --")
objects
## object structure:
##
## objects
## comp
## %s (name)
## type
## bond%i
## label
## port
## %s (name)
## type
## bond%i
## label
##
## "comp" contains components, subsystems and external SS
## "port" contains internal SS:[...]
####################################################
## count number of vector bonds on each component ##
####################################################
if (struct_contains(objects, "comp"))
for [comp, comp_name] = objects.comp
n = size(struct_elements(comp))(1) - 1;
eval(sprintf("objects.comp.%s.n_bonds = %i;",
comp_name, n));
endfor
endif
if (struct_contains(objects, "port"))
for [port, port_name] = objects.port
n = size(struct_elements(port))(1) - 1;
eval(sprintf("objects.port.%s.n_bonds = %i;",
port_name, n));
endfor
endif
disp("-- finished counting number of bonds on components --")
objects
## objects
## comp
## %s (name)
## type
## n_bonds
## bond%i
## label
## port
## %s (name)
## type
## n_bonds
## bond%i
## label
########################################################
## ensure labels exist on all ports of each component ##
########################################################
if (struct_contains(objects, "comp"))
for [comp, comp_name] = objects.comp
if (strcmp(comp.type, "0") | strcmp(comp.type, "1"))
## convert type
if (strcmp(comp.type, "0"))
comp.type = "zero";
elseif (strcmp(comp.type, "1"))
comp.type = "one";
endif
## component is a junction
n_named_ports = 0;
## get labelled ports
for [bond, bond_name] = comp
if (index(bond_name, "bond") == 1)
if (! exist("bond.label"))
bond.label = "[]";
endif
if (! strcmp(bond.label, "[]"))
n_named_ports += 1;
port_label = bond.label;
endif
endif
eval(sprintf("comp.%s = bond;", bond_name));
endfor
## attach labels to unlabelled ports
if (n_named_ports == 0)
for [bond, bond_name] = comp
if (index(bond_name, "bond") == 1)
bond.label = "in";
endif
eval(sprintf("comp.%s = bond;", bond_name));
endfor
elseif (n_named_ports == 1)
mtt_info(sprintf("Defaulting all ports on junction %s to %s", \
comp_name, port_label), infofile);
for [bond, bond_name] = comp
if (index(bond_name, "bond") == 1)
bond.label = port_label;
endif
eval(sprintf("comp.%s = bond;", bond_name));
endfor
elseif (n_named_ports != bond.n_bonds)
mtt_error(sprintf("Junction must have 0,1 or %i port labels", \
n_bonds), errorfile);
endif
else
## component is not a junction
for [bond, bond_name] = comp
if (index(bond_name, "bond") == 1)
if (strcmp(bond.label, "[]"))
if (bond.index > 0)
bond.label = "in";
else
bond.label = "out";
endif
else
bond.label = mtt_strip_name(bond.label);
endif
endif
eval(sprintf("comp.%s = bond;", bond_name));
endfor
endif
eval(sprintf("objects.comp.%s = comp;", comp_name));
endfor
endif
####################
## expand aliases ##
####################
if (struct_contains(objects, "comp"))
for [comp, comp_name] = objects.comp
if ((! strcmp(comp.type, "zero")) & (! strcmp(comp.type, "one")))
alias = eval(sprintf("%s_alias", comp.type));
if (is_struct(alias))
for [bond, bond_name] = comp;
if (isstruct(bond))
if (struct_contains(alias, bond.label))
old_name = bond.label;
new_name = eval(sprintf("alias.%s", old_name));
bond.label = new_name;
mtt_info(sprintf("Aliasing [%s] on %s (%s) to [%s]",
old_name, comp_name, comp.type, new_name),
infofile);
endif
endif
eval(sprintf("comp.%s = bond;", bond_name));
endfor
endif
eval(sprintf("objects.comp.%s = comp;", comp_name));
endif
endfor
endif
disp("-- finished expanding aliases --")
objects
## objects
## comp
## %s (name)
## type
## n_bonds
## bond%i
## label
## port
## %s (name)
## type
## n_bonds
## bond%i
## label
##########################################
## create sub-bonds according to labels ##
##########################################
if (struct_contains(objects, "comp"))
for [comp, comp_name] = objects.comp
for [bond, bond_name] = comp
if (index(bond_name, "bond") == 1)
[sub_bonds, n_sub_bonds] = split_port(bond.label);
for i = 1:n_sub_bonds
eval(sprintf("bond.subbond%i.label = '%s';",
i, deblank(sub_bonds(i,:))))
endfor
endif
eval(sprintf("comp.%s = bond;", bond_name));
endfor
eval(sprintf("objects.comp.%s = comp;", comp_name));
endfor
endif
if (struct_contains(objects, "port"))
for [port, port_name] = objects.port
for [bond, bond_name] = port
if (index(bond_name, "bond") == 1)
[sub_bonds, n_sub_bonds] = split_port(bond.label);
for i = 1:n_sub_bonds
eval(sprintf("bond.subbond%i.label = '%s';",
i, deblank(sub_bonds(i,:))));
endfor
endif
eval(sprintf("port.%s = bond;", bond_name));
endfor
eval(sprintf("objects.port.%s = port;", port_name));
endfor
endif
disp("-- finished creating sub-bonds --")
objects
## objects
## comp
## %s (name)
## type
## n_bonds
## bond%i
## label
## subbond%i
## port
## %s (name)
## type
## n_bonds
## bond%i
## label
## subbond%i
#########################################
## assign a unique number to each bond ##
#########################################
unique_bond_number = 0;
for [bond, bond_name] = bonds
i = str2num(split(bond_name, "bond")(2,:));
## extract type of component at each end
head.type = deblank(split(bond.head.component, ":")(1,:));
tail.type = deblank(split(bond.tail.component, ":")(1,:));
## extract name of component at each end
head_name = deblank(split(bond.head.component, ":")(2,:));
tail_name = deblank(split(bond.tail.component, ":")(2,:));
## determine whether internal port or subsystem
## and fix names of ports
if (strcmp(head.type, "SS") & (index(head_name, "[") == 1))
head_comp_or_port = "port";
head_name = mtt_strip_name(head_name);
else
head_comp_or_port = "comp";
endif
if (strcmp(tail.type, "SS") & (index(tail_name, "[") == 1))
tail_comp_or_port = "port";
tail_name = mtt_strip_name(tail_name);
else
tail_comp_or_port = "comp";
endif
## create strings to reference each component
head_str = sprintf("objects.%s.%s.bond%i",
head_comp_or_port, head_name, i)
tail_str = sprintf("objects.%s.%s.bond%i",
tail_comp_or_port, tail_name, i)
head_bond = eval(head_str);
tail_bond = eval(tail_str);
## check compatible sizes
head.n_subs = size(struct_elements(head_bond))(1) - 2;
tail.n_subs = size(struct_elements(tail_bond))(1) - 2;
if (head.n_subs != tail.n_subs)
mtt_error(sprintf("Vector ports %s and %s are not compatible",
head_bond.label, tail_bond.label), errorfile);
elseif (head.n_subs > 1)
mtt_info(sprintf("Vector port %s matches %s",
head_bond.label, tail_bond.label), infofile);
endif
## write type at other end
eval(sprintf("%s.other_end_type = '%s';",
head_str, tail.type));
eval(sprintf("%s.other_end_type = '%s';",
tail_str, head.type));
## assign bond number
for i = 1:head.n_subs
++unique_bond_number;
eval(sprintf("%s.subbond%i.index = +%i;",
head_str, i, unique_bond_number));
eval(sprintf("%s.subbond%i.index = -%i;",
tail_str, i, unique_bond_number));
## write causality for bond
if (strcmp(bond.causality.effort, "head"))
eval(sprintf("causality(%i,1) = +1;", unique_bond_number));
elseif (strcmp(bond.causality.effort, "tail"))
eval(sprintf("causality(%i,1) = -1;", unique_bond_number));
else
eval(sprintf("causality(%i,1) = 0;", unique_bond_number));
endif
if (strcmp(bond.causality.flow, "head"))
eval(sprintf("causality(%i,2) = -1;", unique_bond_number));
elseif (strcmp(bond.causality.flow, "tail"))
eval(sprintf("causality(%i,2) = +1;", unique_bond_number));
else
eval(sprintf("causality(%i,2) = 0;", unique_bond_number));
endif
endfor
endfor
disp("-- finished assigning unique numbers to bonds --")
objects
## objects
## comp
## %s (name)
## type
## n_bonds
## bond%i
## label
## subbond%i
## index
## port
## %s (name)
## type
## n_bonds
## bond%i
## label
## subbond%i
## index
## causality matrix is called "bonds"
bonds = causality
disp("-- finished writing bonds matrix --")
#################################
## map component data to cmp.m ##
#################################
## count number of components
if (struct_contains(objects, "comp"))
n_comps = size(struct_elements(objects.comp), 1)
else
n_comps = 0;
endif
## count number of internal ports
if (struct_contains(objects, "port"))
n_ports = size(struct_elements(objects.port), 1)
else
n_ports = 0;
endif
## read data from _cmp.m
for cmp = 1:(n_comps + n_ports)
[this_type, this_name] = eval(sprintf("%s_cmp(%i)", name, cmp));
## determine if internal port (and fix name) or subsystem
if (strcmp(this_type, "SS") & (index(this_name, "[") == 1))
comp_or_port = "port";
this_name = mtt_strip_name(this_name)
else
comp_or_port = "comp";
endif
eval(sprintf("objects.%s.%s.index = cmp;", comp_or_port, this_name));
endfor
disp("-- finished getting component indices from cmp.m --")
objects
## objects
## comp
## %s (name)
## type
## n_bonds
## bond%i
## label
## subbond%i
## index
## index
## port
## %s (name)
## type
## n_bonds
## bond%i
## label
## subbond%i
## index
## index
##########################
## write n_vector_bonds ##
##########################
if (struct_contains(objects, "comp"))
for [comp, comp_name] = objects.comp
n_vector_bonds(comp.index,1) = comp.n_bonds;
endfor
endif
disp("-- finished writing n_vector_bonds --")
n_vector_bonds
###########################################
## Write connections matrix (components) ##
###########################################
if (struct_contains(objects, "comp"))
n_comps = size(struct_elements(objects.comp))(1);
else
n_comps = 0;
endif
components = zeros(n_comps+n_ports, max(n_vector_bonds));
if (struct_contains(objects, "comp"))
for [comp, comp_name] = objects.comp
## get portlist for component
if exist([comp.type, '_cause']) == 0
eval(sprintf("ABG = %s_abg;", comp.type));
if struct_contains(ABG, "portlist")
port_list = ABG.portlist;
else
error(sprintf("Component %s has no ports", comp.type));
endif
else
## must be a simple component:
## lib/comp/simple/comp_ports.m assigns port numbers
port_list = comp_ports(comp.type, comp.n_bonds)
endif
## but do what with it?
counter = 0;
n_ports = size(port_list,1)
if ((n_ports == 1) | ...
(strcmp(comp.type, "zero")) | (strcmp(comp.type, "one")))
## no ordering necessary
for [bond, bond_name] = comp
if (index(bond_name, "bond") == 1)
for [sub_bond, sub_bond_name] = bond
if (index(sub_bond_name, "subbond") == 1)
components(comp.index, ++counter) = sub_bond.index
endif
endfor
endif
endfor
else
## multiple ports, need to order them
for port = 1 : n_ports
component_type = comp.type
the_port_list = port_list
the_port = port
label = port_list(port,:)
if (index (label, "[") == 1)
label = mtt_strip_name(label)
endif
label = deblank(label)
for [bond, bond_name] = comp
if (index(bond_name, "bond") == 1)
for [sub_bond, sub_bond_name] = bond
if (index(sub_bond_name, "subbond") == 1)
sub_bond_label = sub_bond.label
if (index (sub_bond_label, "[") == 1)
sub_bond_label = mtt_strip_name(sub_bond_label)
endif
sub_bond_label = deblank(sub_bond_label)
## unalias sub_bond label
if exist([comp.type, '_alias'])
eval(sprintf("alias = %s_alias", comp.type))
if isstruct(alias)
while_counter = 0;
while isfield(alias, sub_bond_label)
old_sub_bond_label = sub_bond_label;
sub_bond_label = eval(sprintf("alias.%s", sub_bond_label))
if strcmp(old_sub_bond_label, sub_bond_label)
break;
endif
endwhile
endif
endif
if (strcmp(sub_bond_label, label))
components(comp.index, ++counter) = sub_bond.index
endif
endif
endfor
endif
endfor
endfor
endif
endfor
endif
disp("-- finished getting port_list --")
port_list
# if (struct_contains(objects, "comp"))
# for [comp, comp_name] = objects.comp
# counter = 0;
# for [bond, bond_name] = comp
# if (index(bond_name, "bond") == 1)
# # if (strcmp(bond.other_end_type, "SS"))
# for [sub_bond, sub_bond_name] = bond
# if (index(sub_bond_name, "subbond") == 1)
# components(comp.index, ++counter) = sub_bond.index
# endif
# endfor
# # endif
# endif
# endfor
# # for [bond, bond_name] = comp
# # if (index(bond_name, "bond") == 1)
# # if (!strcmp(bond.other_end_type, "SS"))
# # for [sub_bond, sub_bond_name] = bond
# # if (index(sub_bond_name, "subbond") == 1)
# # components(comp.index, ++counter) = sub_bond.index
# # endif
# # endfor
# # endif
# # endif
# # endfor
# endfor
# endif
if (struct_contains(objects, "port"))
for [port, port_name] = objects.port
counter = 0;
for [bond, bond_name] = port
if (index(bond_name, "bond") == 1)
for [sub_bond, sub_bond_name] = bond
if (index(sub_bond_name, "subbond") == 1)
components(port.index, ++counter) = sub_bond.index;
endif
endfor
endif
endfor
endfor
endif
disp("-- finished writing components matrix --")
components
endfunction