Home > classes > @ssm > assemble.m

assemble

PURPOSE ^

assembles embedded subsytems, with exogenous inputs

SYNOPSIS ^

function varargout = assemble( varargin )

DESCRIPTION ^

 assembles embedded subsytems, with exogenous inputs
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

 DESCRIPTION: assemble assembles embedded subsytems, with exogenous inputs

 CALL: [sys] = ltpda_ss_assemble(sys_array)

 INPUTS: sys_array - array of systems to assemble

 OUTPUTS: sys - assembled system

 ***** There are no parameters *****

 VERSION: '$Id: ltpda_ss_assemble.m,v 1.2 2008/02/20 09:20:07 adrien Exp$'

 M-FILE INFO: Get information about this methods by calling
              >> ssm.getInfo('assemble')

              Get information about a specified set-plist by calling:
              >> ssm.getInfo('assemble', 'Default')

 HISTORY:
 09-07-2008 A Grynagier
 29-05-2008 A Grynagier
 17-04-2008 A Grynagier
 23-01-2008 A Grynagier
 29-01-2008 A Grynagier

 TO DO : 
 needs work on D inversion.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SUBFUNCTIONS ^

SOURCE CODE ^

0001 % assembles embedded subsytems, with exogenous inputs
0002 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
0003 %
0004 % DESCRIPTION: assemble assembles embedded subsytems, with exogenous inputs
0005 %
0006 % CALL: [sys] = ltpda_ss_assemble(sys_array)
0007 %
0008 % INPUTS: sys_array - array of systems to assemble
0009 %
0010 % OUTPUTS: sys - assembled system
0011 %
0012 % ***** There are no parameters *****
0013 %
0014 % VERSION: '$Id: ltpda_ss_assemble.m,v 1.2 2008/02/20 09:20:07 adrien Exp$'
0015 %
0016 % M-FILE INFO: Get information about this methods by calling
0017 %              >> ssm.getInfo('assemble')
0018 %
0019 %              Get information about a specified set-plist by calling:
0020 %              >> ssm.getInfo('assemble', 'Default')
0021 %
0022 % HISTORY:
0023 % 09-07-2008 A Grynagier
0024 % 29-05-2008 A Grynagier
0025 % 17-04-2008 A Grynagier
0026 % 23-01-2008 A Grynagier
0027 % 29-01-2008 A Grynagier
0028 %
0029 % TO DO :
0030 % needs work on D inversion.
0031 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
0032 
0033 function   varargout = assemble( varargin )
0034 
0035   %% starting initial checks
0036   utils.helper.msg(utils.const.msg.MNAME, ['running ', mfilename]);
0037   
0038   % Check if this is a call for parameters
0039   if utils.helper.isinfocall(varargin{:})
0040     varargout{1} = getInfo(varargin{3});
0041     return
0042   end
0043   
0044   % Collect input variable names
0045   in_names = cell(size(varargin));
0046   for ii = 1:nargin,in_names{ii} = inputname(ii);end
0047 
0048   % Collect all SSMs and plists
0049   [sys, ssm_invars] = utils.helper.collect_objects(varargin(:), 'ssm', in_names);
0050   
0051   Nsys = numel(sys);  
0052   
0053   if Nsys < 2
0054     error('### Two or more systems are needed to assemble.');
0055   end
0056   
0057   % We want to force a copy - this is not a modify method
0058   if nargout < 1
0059     error('### assemble cannot be used as a modifier. Please give an output variable.');
0060   end
0061   
0062   % Decide on a deep copy or a modify, depending on the output
0063   sys_array = copy(sys, nargout);
0064   
0065   %% begin function body
0066   sys_out = ssm;
0067 
0068   %%  Putting toghether parameter fields
0069   for i=1:Nsys
0070     sys_out.paramnames  = [sys_out.paramnames  sys_array(i).paramnames ];  %#ok<AGROW>
0071     sys_out.paramvalues = [sys_out.paramvalues sys_array(i).paramvalues];  %#ok<AGROW>
0072     sys_out.paramsigmas = [sys_out.paramsigmas sys_array(i).paramsigmas];  %#ok<AGROW>
0073   end
0074   sys_out.isnumerical = true;
0075   for i=1:Nsys
0076     sys_out.isnumerical = sys_out.isnumerical*sys_array(i).isnumerical;
0077   end
0078 
0079   %% merging ss data : ss* output* *input
0080 
0081   names       = cell(1,0);
0082   ssnames       = cell(1,0);
0083   ssvarnames    = cell(1,0);
0084   sssizes       = zeros(1,0);
0085   ssposition    = zeros(2,0);
0086   outputnames    = cell(1,0);
0087   outputvarnames = cell(1,0);
0088   outputsizes    = zeros(1,0);
0089   outputposition = zeros(2,0);
0090   inputnames    = cell(1,0);
0091   inputvarnames = cell(1,0);
0092   inputsizes    = zeros(1,0);
0093   inputposition = zeros(2,0);
0094   for i=1:Nsys
0095     names          = [names          sys_array(i).name           ];
0096     ssnames        = [ssnames        sys_array(i).ssnames        ];
0097     ssvarnames     = [ssvarnames     sys_array(i).ssvarnames     ];
0098     sssizes        = [sssizes        sys_array(i).sssizes        ];
0099     ssposition     = [ssposition     [i*ones(1,sys_array(i).Nss)      ; 1:sys_array(i).Nss]       ];
0100     outputnames    = [outputnames    sys_array(i).outputnames    ];
0101     outputvarnames = [outputvarnames sys_array(i).outputvarnames ];
0102     outputsizes    = [outputsizes    sys_array(i).outputsizes    ];
0103     outputposition = [outputposition [i*ones(1,sys_array(i).Noutputs) ; 1:sys_array(i).Noutputs]  ];
0104     inputvarnames  = [inputvarnames  sys_array(i).inputvarnames  ];
0105     inputnames     = [inputnames     sys_array(i).inputnames     ];
0106     inputsizes     = [inputsizes     sys_array(i).inputsizes     ];
0107     inputposition  = [inputposition  [i*ones(1,sys_array(i).Ninputs)  ; 1:sys_array(i).Ninputs ]  ];
0108   end
0109   %% data already good to store
0110   sys_out.ssnames           = ssnames;
0111   sys_out.ssvarnames        = ssvarnames;
0112   sys_out.outputnames       = outputnames;
0113   sys_out.outputvarnames    = outputvarnames;
0114 
0115   %% non redundancy checks
0116   for i=1:length(names)
0117     [pos_in, sum_in] = ssm.cellstrfind(names, names{i},'all');
0118     if sum_in>1
0119       error([num2str(sum_in),' systems are named ', names{i}])
0120     end
0121   end
0122   for i=1:length(ssnames)
0123     [pos_in, sum_in] = ssm.cellstrfind(ssnames, ssnames{i},'all');
0124     if sum_in>1
0125       error([num2str(sum_in),' states are named ', ssnames{i}])
0126     end
0127   end
0128   for i=1:length(outputnames)
0129     [pos_in, sum_in] = ssm.cellstrfind(outputnames, outputnames{i},'all');
0130     if sum_in>1
0131       error([num2str(sum_in),' outputs are named ', outputnames{i}])
0132     end
0133   end
0134 
0135   %% fields for outer inputs
0136   inputisouter = false(1,length(outputnames));
0137   for i=1:length(inputnames)
0138     [pos_in, sum_in] = ssm.cellstrfind(outputnames, inputnames(i),'all');
0139     if sum_in==0
0140       inputisouter(i)=true;
0141     end
0142   end
0143 
0144   %% building A, M and C matrices
0145   amats = {};
0146   mmats = {};
0147   cmats = {};
0148   for i=1:Nsys
0149     amats = ...
0150       [amats                      cell(size(amats,1),size(sys_array(i).amats,2))    ; ...
0151       cell(size(sys_array(i).amats,1),size(amats,2))            sys_array(i).amats ] ;
0152     mmats = ...
0153       [mmats                      cell(size(mmats,1),size(sys_array(i).mmats,2))    ; ...
0154       cell(size(sys_array(i).mmats,1),size(mmats,2))            sys_array(i).mmats ] ;
0155     cmats = ...
0156       [cmats                      cell(size(cmats,1),size(sys_array(i).cmats,2))    ; ...
0157       cell(size(sys_array(i).cmats,1),size(cmats,2))            sys_array(i).cmats ] ;
0158   end
0159   sys_out.mmats = mmats;
0160   
0161   %% building B_in and D_in matrices
0162   B_in = cell( length(ssnames),     length(outputnames) );
0163   D_in = cell( length(outputnames), length(outputnames) );
0164   for i=1:length(outputnames)
0165       [pos_in, sum_in] = ssm.cellstrfind(inputnames, outputnames{i},'all');
0166       if sum_in>0
0167         for pos = pos_in
0168           systemNumber = inputposition(1,pos);
0169           inputNumber  = inputposition(2,pos);
0170             B_in(ssposition(1,:)==systemNumber, i)     = sys_array(systemNumber).bmats(:,inputNumber);
0171             D_in(outputposition(1,:)==systemNumber, i) = sys_array(systemNumber).dmats(:,inputNumber);
0172         end
0173       end
0174   end
0175 
0176   %% building B_ext and D_ext matrices
0177   B_ext = cell( length(ssnames),     length(inputnames) );
0178   D_ext = cell( length(outputnames), length(inputnames) );
0179   pos_keep = false(1, length(inputnames));
0180   for i=1:length(inputnames)
0181       [pos_in, sum_in] = ssm.cellstrfind(outputnames, inputnames(i),'all');
0182       if sum_in==0
0183         [pos_in, sum_in] = ssm.cellstrfind(inputnames, inputnames(i),'all');
0184         for pos = pos_in;
0185           systemNumber  = inputposition(1,pos);
0186           inputNumber   = inputposition(2,pos);
0187           B_ext( ssposition(1,:)==systemNumber , pos_in(1) )    = sys_array(systemNumber).bmats(:,inputNumber);
0188           D_ext( outputposition(1,:)==systemNumber, pos_in(1) ) = sys_array(systemNumber).dmats(:,inputNumber);
0189           pos_keep(pos_in(1)) = true;
0190         end
0191       end
0192   end
0193 
0194   %% getting amats, bmats, cmats, dmats
0195   B_ext                 = B_ext(:,pos_keep);
0196   D_ext                 = D_ext(:,pos_keep);
0197   sys_out.inputnames    = inputnames(pos_keep);
0198   sys_out.inputvarnames = inputvarnames(pos_keep);
0199 
0200   %% flattening and getting constant feedthrough
0201   D_in_f = ssm.cell_fusion(D_in, outputsizes,outputsizes);
0202   id_D_inv = (eye(size(D_in_f)) - D_in_f)^-1;
0203   id_D_inv = ssm.cell_recut(id_D_inv, outputsizes, outputsizes);
0204   sys_out.amats = ssm.cell_add(amats, ssm.cell_mult(B_in, ssm.cell_mult(id_D_inv, cmats)));
0205   sys_out.bmats = ssm.cell_add(B_ext, ssm.cell_mult(B_in, ssm.cell_mult(id_D_inv, D_ext)));
0206   sys_out.cmats = ssm.cell_mult(id_D_inv, cmats);
0207   sys_out.dmats = ssm.cell_mult(id_D_inv, D_ext);
0208 
0209   %% building new name and strings
0210   name = 'assembled( ';
0211   for i = 1:Nsys
0212     if i==1
0213       name = [name, sys_array(i).name ];                        %#ok<AGROW>
0214     elseif i<Nsys
0215       name = [name,' + ', sys_array(i).name];                   %#ok<AGROW>
0216     else
0217       name = [name,' + ', sys_array(i).name,')'];               %#ok<AGROW>
0218     end
0219   end
0220   name = [name ')'];
0221   sys_out.name = name;
0222 
0223   %% getting timestep and checking consitency
0224   for i=1:Nsys
0225     if i == 1
0226       sys_out.timestep = sys_array(i).timestep;
0227     elseif ~ sys_out.timestep == sys_array(i).timestep
0228       error(['error because systems 1 and ',num2str(i),...
0229         ' named ',sys_array(i).name,' and ',sys_array(i).name,...
0230         ' have different timesteps :',...
0231         num2str(sys_array(i).timestep),' and ',num2str(sys_array(i).timestep) ]);
0232     end
0233   end
0234 
0235   %% setting history
0236   h = history();
0237   for i=1:Nsys
0238     h(i) = sys_array(i).hist;
0239   end
0240   sys_out.addHistory(ssm.getInfo(mfilename), plist , {''}, h );
0241   %% parsing output
0242   validate(sys_out);
0243   varargout = {sys_out};
0244 end
0245 
0246 
0247 %--------------------------------------------------------------------------
0248 % Get Info Object
0249 %--------------------------------------------------------------------------
0250 function ii = getInfo(varargin)
0251   if nargin == 1 && strcmpi(varargin{1}, 'None')
0252     sets = {};
0253     pls   = [];
0254   elseif nargin == 1 && ~isempty(varargin{1}) && ischar(varargin{1})
0255     sets{1} = varargin{1};
0256     pls = getDefaultPlist(sets{1});
0257   else
0258     sets = {'Default'};
0259     pls = [];
0260     for kk=1:numel(sets)
0261       pls = [pls getDefaultPlist(sets{kk})];
0262     end
0263   end
0264   % Build info object
0265   ii = minfo(mfilename, 'ssm', '', utils.const.categories.statespace, '$Id: resp.m,v 1.17 2008/07/22 10:22:38 ingo Exp $', sets, pls);
0266 end
0267 
0268 %--------------------------------------------------------------------------
0269 % Get Default Plist
0270 %--------------------------------------------------------------------------
0271 function out = getDefaultPlist(set)
0272   switch set
0273     case 'Default'
0274       out = plist;
0275     otherwise
0276       error('### Unknown set [%s] to get the default plist.', set);
0277   end
0278 end

Generated on Mon 08-Sep-2008 13:18:47 by m2html © 2003