line source
+ − % appends embedded subsytems, with exogenous inputs
+ − %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ − %
+ − % DESCRIPTION: append appends embedded subsytems, does not close any loop
+ − %
+ − % CALL: sys = ltpda_ss_append(sys_array)
+ − %
+ − % INPUTS: sys_array - array or list of systems to append
+ − %
+ − % OUTPUTS: sys - appendd system
+ − %
+ − % <a href="matlab:utils.helper.displayMethodInfo('ssm', 'append')">Parameters Description</a>
+ − %
+ − % VERSION: $Id: append.m,v 1.8 2011/04/08 08:56:23 hewitson Exp $
+ − %
+ − %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ −
+ − function varargout = append( varargin )
+ −
+ − %% Check if this is a call for parameters
+ − if utils.helper.isinfocall(varargin{:})
+ − varargout{1} = getInfo(varargin{3});
+ − return
+ − end
+ −
+ − %% send starting message
+ − import utils.const.*
+ − utils.helper.msg(msg.PROC3, 'running %s/%s', mfilename('class'), mfilename);
+ −
+ − %% collecting input
+ − in_names = cell(size(varargin));
+ − for ii = 1:nargin,in_names{ii} = inputname(ii);end
+ −
+ − % Collect all SSMs and plists
+ − [sys, ssm_invars] = utils.helper.collect_objects(varargin(:), 'ssm', in_names);
+ −
+ − Nsys = numel(sys);
+ −
+ − if Nsys < 2
+ − error('### Two or more systems are needed to append.');
+ − end
+ −
+ − % We want to force a copy - this is not a modify method
+ − if nargout ~= 1
+ − error('### append cannot be used as a modifier. Please give exactly one output variable.');
+ − end
+ −
+ − %% Decide on a deep copy or a modify, depending on the output
+ − sys_array = copy(sys, true);
+ −
+ − %% begin function body
+ − sys_out = ssm;
+ −
+ − %% checking there is not problem with the timesteps
+ −
+ − for i=2:Nsys
+ − if ~(sys_array(i-1).timestep == sys_array(i).timestep)
+ − error(['At least two ssm have incompatible timestep fields : ' ...
+ − num2str(sys_array(i-1).timestep) ' for ''' sys_array(i-1).name ''' and '...
+ − num2str(sys_array(i).timestep) ' for ''' sys_array(i).name '''' ]);
+ − end
+ − end
+ −
+ − %% merging ss data : ss* output* *input
+ − names = cell(1,0);
+ − inputs = ssmblock.initObjectWithSize(1,0);
+ − outputs = ssmblock.initObjectWithSize(1,0);
+ − states = ssmblock.initObjectWithSize(1,0);
+ − params = plist;
+ − numparams = plist;
+ −
+ − sssizes = zeros(1,0);
+ − ssposition = zeros(1,0);
+ − outputsizes = zeros(1,0);
+ − outputposition = zeros(1,0);
+ − inputsizes = zeros(1,0);
+ − inputposition = zeros(1,0);
+ −
+ − for i=1:Nsys
+ − params.combine(sys_array(i).params);
+ − numparams.combine(sys_array(i).numparams);
+ − inputs = inputs.combine(sys_array(i).inputs, false) ;
+ − outputs = [outputs, sys_array(i).outputs] ;
+ − states = [states, sys_array(i).states] ;
+ −
+ − names = [names sys_array(i).name ]; %#ok<*AGROW>
+ − sssizes = [sssizes sys_array(i).sssizes ];
+ − ssposition = [ssposition i*ones(1,sys_array(i).Nss) ];
+ − outputsizes = [outputsizes sys_array(i).outputsizes ];
+ − outputposition = [outputposition i*ones(1,sys_array(i).Noutputs) ];
+ − inputsizes = [inputsizes sys_array(i).inputsizes ];
+ − inputposition = [inputposition i*ones(1,sys_array(i).Ninputs) ];
+ − end
+ −
+ − %% data already good to store
+ − sys_out.params = params;
+ − sys_out.numparams = numparams;
+ − sys_out.outputs = outputs;
+ − sys_out.states = states;
+ −
+ − %% non redundancy checks : not necessary anymore on the I/O fields
+ − % to be added on subfields ??
+ −
+ − %% building A and C matrices
+ − amats = {};
+ − cmats = {};
+ − for i=1:Nsys
+ − Namats = size(amats,2);
+ − amats = ...
+ − [amats cell(Namats, sys_array(i).Nss) ; ...
+ − cell(sys_array(i).Nss, Namats) sys_array(i).amats ] ;
+ − cmats = ...
+ − [cmats cell(size(cmats,1), sys_array(i).Nss) ; ...
+ − cell(sys_array(i).Noutputs, size(cmats,2)) sys_array(i).cmats ] ;
+ − end
+ −
+ − %% construction of B_xx and D_xx matrices
+ − inputs_ext = ssmblock.initObjectWithSize(1,0);
+ −
+ − B_in = cell( numel(sssizes), numel(outputsizes) );
+ − D_in = cell( numel(outputsizes), numel(outputsizes) );
+ − B_ext = cell( numel(sssizes), 0 );
+ − D_ext = cell( numel(outputsizes), 0 );
+ − inputsizes = [];
+ − Ninputs = 0;
+ − for i_sys=1:Nsys
+ − for i_input = 1:numel(sys(i_sys).inputs)
+ − % current input of a subsystem
+ − input_name = sys_array(i_sys).inputs(i_input).name;
+ − % does the input match a local output ?
+ − [pos_output, sum_output] = findBlockWithNames(outputs, input_name, false);
+ − % check it is not already in the external input list
+ − [pos_input, sum_input] = findBlockWithNames(inputs_ext, input_name, false);
+ − if sum_output>0
+ − %% if it is an internal input
+ − % put at the correct place in the B_in and D_in matrices
+ − B_in(ssposition==i_sys, pos_output) = sys_array(i_sys).bmats(:,i_input);
+ − D_in(outputposition==i_sys, pos_output) = sys_array(i_sys).dmats(:,i_input);
+ − % checking sizes match
+ − for i_out = pos_output
+ − Nin = sys_array(i_sys).inputs(i_input).Nports;
+ − if ~( Nin == outputs(i_out).Nports)
+ − error(['I/O sizes not matching between input "' sys_array(i_sys).inputs(i_input).name , ...
+ − '" of system "' sys_array(i_sys).name ' of size ' num2str(Nin) ...
+ − '" and the output of size ' num2str(outputs(i_out).Nports) ...
+ − ' of the system "' sys_array(outputposition(pos_output)).name '"'] )
+ − end
+ − end
+ − else
+ − %% if it is external
+ − % if it is not there, add to the input plist
+ − if sum_input == 0
+ − % extend the size of the input fields
+ − inputs_ext = [inputs_ext sys_array(i_sys).inputs(i_input)];
+ − inputsizes = [inputsizes sys_array(i_sys).inputsizes(i_input)];
+ − B_ext = [B_ext cell(size(B_ext,1),1)];
+ − D_ext = [D_ext cell(size(D_ext,1),1)];
+ − Ninputs = Ninputs +1;
+ −
+ − pos_input = numel(inputs_ext);
+ − end
+ − % put at the correct place in the B_ext and D_ext matrices
+ − B_ext(ssposition==i_sys, pos_input) = sys_array(i_sys).bmats(:,i_input);
+ − D_ext(outputposition==i_sys, pos_input) = sys_array(i_sys).dmats(:,i_input);
+ − end
+ − end
+ − end
+ − sys_out.inputs = [outputs inputs_ext];
+ −
+ − B_ext = ssm.blockMatFillDiag(B_ext, sssizes, inputsizes);
+ − D_ext = ssm.blockMatFillDiag(D_ext, outputsizes, inputsizes);
+ − B_in = ssm.blockMatFillDiag(B_in, sssizes, outputsizes);
+ − D_in = ssm.blockMatFillDiag(D_in, outputsizes, outputsizes);
+ − cmats = ssm.blockMatFillDiag(cmats, outputsizes, sssizes);
+ −
+ − sys_out.amats = amats;
+ − sys_out.bmats = [B_in B_ext];
+ − sys_out.cmats = cmats;
+ − sys_out.dmats = [D_in, D_ext];
+ −
+ − %% building new name and strings
+ − name = 'append( ';
+ − for i = 1:Nsys
+ − if i==1
+ − name = [name, sys_array(i).name ]; %#ok<AGROW>
+ − elseif i<=Nsys
+ − name = [name,' + ', sys_array(i).name]; %#ok<AGROW>
+ − end
+ − end
+ − name = [name ' )'];
+ − sys_out.name = name;
+ −
+ − %% getting timestep and checking consitency
+ − for i=1:Nsys
+ − if i == 1
+ − sys_out.timestep = sys_array(i).timestep;
+ − elseif ~ sys_out.timestep == sys_array(i).timestep
+ − error(['error because systems 1 and ',num2str(i),...
+ − ' named ',sys_array(i).name,' and ',sys_array(i).name,...
+ − ' have different timesteps :',...
+ − num2str(sys_array(i).timestep),' and ',num2str(sys_array(i).timestep) ]);
+ − end
+ − end
+ −
+ − %% setting history
+ −
+ − sys_out.addHistory(ssm.getInfo(mfilename), plist , ssm_invars(:), [sys_array(:).hist] );
+ −
+ − %% parsing output
+ − validate(sys_out);
+ − varargout = {sys_out};
+ − end
+ −
+ −
+ −
+ −
+ −
+ − %--------------------------------------------------------------------------
+ − % Get Info Object
+ − %--------------------------------------------------------------------------
+ − function ii = getInfo(varargin)
+ −
+ − if nargin == 1 && strcmpi(varargin{1}, 'None')
+ − sets = {};
+ − pl = [];
+ − else
+ − sets = {'Default'};
+ − pl = getDefaultPlist;
+ − end
+ − % Build info object
+ − ii = minfo(mfilename, 'ssm', 'ltpda', utils.const.categories.op, '$Id: append.m,v 1.8 2011/04/08 08:56:23 hewitson Exp $', sets, pl);
+ − ii.setModifier(false);
+ − ii.setArgsmin(2);
+ − end
+ −
+ − %--------------------------------------------------------------------------
+ − % Get Default Plist
+ − %--------------------------------------------------------------------------
+ − function pl = getDefaultPlist()
+ − pl = plist();
+ − end
+ −