comparison m-toolbox/classes/@ssm/append.m @ 0:f0afece42f48

Import.
author Daniele Nicolodi <nicolodi@science.unitn.it>
date Wed, 23 Nov 2011 19:22:13 +0100
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:f0afece42f48
1 % appends embedded subsytems, with exogenous inputs
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 %
4 % DESCRIPTION: append appends embedded subsytems, does not close any loop
5 %
6 % CALL: sys = ltpda_ss_append(sys_array)
7 %
8 % INPUTS: sys_array - array or list of systems to append
9 %
10 % OUTPUTS: sys - appendd system
11 %
12 % <a href="matlab:utils.helper.displayMethodInfo('ssm', 'append')">Parameters Description</a>
13 %
14 % VERSION: $Id: append.m,v 1.8 2011/04/08 08:56:23 hewitson Exp $
15 %
16 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
17
18 function varargout = append( varargin )
19
20 %% Check if this is a call for parameters
21 if utils.helper.isinfocall(varargin{:})
22 varargout{1} = getInfo(varargin{3});
23 return
24 end
25
26 %% send starting message
27 import utils.const.*
28 utils.helper.msg(msg.PROC3, 'running %s/%s', mfilename('class'), mfilename);
29
30 %% collecting input
31 in_names = cell(size(varargin));
32 for ii = 1:nargin,in_names{ii} = inputname(ii);end
33
34 % Collect all SSMs and plists
35 [sys, ssm_invars] = utils.helper.collect_objects(varargin(:), 'ssm', in_names);
36
37 Nsys = numel(sys);
38
39 if Nsys < 2
40 error('### Two or more systems are needed to append.');
41 end
42
43 % We want to force a copy - this is not a modify method
44 if nargout ~= 1
45 error('### append cannot be used as a modifier. Please give exactly one output variable.');
46 end
47
48 %% Decide on a deep copy or a modify, depending on the output
49 sys_array = copy(sys, true);
50
51 %% begin function body
52 sys_out = ssm;
53
54 %% checking there is not problem with the timesteps
55
56 for i=2:Nsys
57 if ~(sys_array(i-1).timestep == sys_array(i).timestep)
58 error(['At least two ssm have incompatible timestep fields : ' ...
59 num2str(sys_array(i-1).timestep) ' for ''' sys_array(i-1).name ''' and '...
60 num2str(sys_array(i).timestep) ' for ''' sys_array(i).name '''' ]);
61 end
62 end
63
64 %% merging ss data : ss* output* *input
65 names = cell(1,0);
66 inputs = ssmblock.initObjectWithSize(1,0);
67 outputs = ssmblock.initObjectWithSize(1,0);
68 states = ssmblock.initObjectWithSize(1,0);
69 params = plist;
70 numparams = plist;
71
72 sssizes = zeros(1,0);
73 ssposition = zeros(1,0);
74 outputsizes = zeros(1,0);
75 outputposition = zeros(1,0);
76 inputsizes = zeros(1,0);
77 inputposition = zeros(1,0);
78
79 for i=1:Nsys
80 params.combine(sys_array(i).params);
81 numparams.combine(sys_array(i).numparams);
82 inputs = inputs.combine(sys_array(i).inputs, false) ;
83 outputs = [outputs, sys_array(i).outputs] ;
84 states = [states, sys_array(i).states] ;
85
86 names = [names sys_array(i).name ]; %#ok<*AGROW>
87 sssizes = [sssizes sys_array(i).sssizes ];
88 ssposition = [ssposition i*ones(1,sys_array(i).Nss) ];
89 outputsizes = [outputsizes sys_array(i).outputsizes ];
90 outputposition = [outputposition i*ones(1,sys_array(i).Noutputs) ];
91 inputsizes = [inputsizes sys_array(i).inputsizes ];
92 inputposition = [inputposition i*ones(1,sys_array(i).Ninputs) ];
93 end
94
95 %% data already good to store
96 sys_out.params = params;
97 sys_out.numparams = numparams;
98 sys_out.outputs = outputs;
99 sys_out.states = states;
100
101 %% non redundancy checks : not necessary anymore on the I/O fields
102 % to be added on subfields ??
103
104 %% building A and C matrices
105 amats = {};
106 cmats = {};
107 for i=1:Nsys
108 Namats = size(amats,2);
109 amats = ...
110 [amats cell(Namats, sys_array(i).Nss) ; ...
111 cell(sys_array(i).Nss, Namats) sys_array(i).amats ] ;
112 cmats = ...
113 [cmats cell(size(cmats,1), sys_array(i).Nss) ; ...
114 cell(sys_array(i).Noutputs, size(cmats,2)) sys_array(i).cmats ] ;
115 end
116
117 %% construction of B_xx and D_xx matrices
118 inputs_ext = ssmblock.initObjectWithSize(1,0);
119
120 B_in = cell( numel(sssizes), numel(outputsizes) );
121 D_in = cell( numel(outputsizes), numel(outputsizes) );
122 B_ext = cell( numel(sssizes), 0 );
123 D_ext = cell( numel(outputsizes), 0 );
124 inputsizes = [];
125 Ninputs = 0;
126 for i_sys=1:Nsys
127 for i_input = 1:numel(sys(i_sys).inputs)
128 % current input of a subsystem
129 input_name = sys_array(i_sys).inputs(i_input).name;
130 % does the input match a local output ?
131 [pos_output, sum_output] = findBlockWithNames(outputs, input_name, false);
132 % check it is not already in the external input list
133 [pos_input, sum_input] = findBlockWithNames(inputs_ext, input_name, false);
134 if sum_output>0
135 %% if it is an internal input
136 % put at the correct place in the B_in and D_in matrices
137 B_in(ssposition==i_sys, pos_output) = sys_array(i_sys).bmats(:,i_input);
138 D_in(outputposition==i_sys, pos_output) = sys_array(i_sys).dmats(:,i_input);
139 % checking sizes match
140 for i_out = pos_output
141 Nin = sys_array(i_sys).inputs(i_input).Nports;
142 if ~( Nin == outputs(i_out).Nports)
143 error(['I/O sizes not matching between input "' sys_array(i_sys).inputs(i_input).name , ...
144 '" of system "' sys_array(i_sys).name ' of size ' num2str(Nin) ...
145 '" and the output of size ' num2str(outputs(i_out).Nports) ...
146 ' of the system "' sys_array(outputposition(pos_output)).name '"'] )
147 end
148 end
149 else
150 %% if it is external
151 % if it is not there, add to the input plist
152 if sum_input == 0
153 % extend the size of the input fields
154 inputs_ext = [inputs_ext sys_array(i_sys).inputs(i_input)];
155 inputsizes = [inputsizes sys_array(i_sys).inputsizes(i_input)];
156 B_ext = [B_ext cell(size(B_ext,1),1)];
157 D_ext = [D_ext cell(size(D_ext,1),1)];
158 Ninputs = Ninputs +1;
159
160 pos_input = numel(inputs_ext);
161 end
162 % put at the correct place in the B_ext and D_ext matrices
163 B_ext(ssposition==i_sys, pos_input) = sys_array(i_sys).bmats(:,i_input);
164 D_ext(outputposition==i_sys, pos_input) = sys_array(i_sys).dmats(:,i_input);
165 end
166 end
167 end
168 sys_out.inputs = [outputs inputs_ext];
169
170 B_ext = ssm.blockMatFillDiag(B_ext, sssizes, inputsizes);
171 D_ext = ssm.blockMatFillDiag(D_ext, outputsizes, inputsizes);
172 B_in = ssm.blockMatFillDiag(B_in, sssizes, outputsizes);
173 D_in = ssm.blockMatFillDiag(D_in, outputsizes, outputsizes);
174 cmats = ssm.blockMatFillDiag(cmats, outputsizes, sssizes);
175
176 sys_out.amats = amats;
177 sys_out.bmats = [B_in B_ext];
178 sys_out.cmats = cmats;
179 sys_out.dmats = [D_in, D_ext];
180
181 %% building new name and strings
182 name = 'append( ';
183 for i = 1:Nsys
184 if i==1
185 name = [name, sys_array(i).name ]; %#ok<AGROW>
186 elseif i<=Nsys
187 name = [name,' + ', sys_array(i).name]; %#ok<AGROW>
188 end
189 end
190 name = [name ' )'];
191 sys_out.name = name;
192
193 %% getting timestep and checking consitency
194 for i=1:Nsys
195 if i == 1
196 sys_out.timestep = sys_array(i).timestep;
197 elseif ~ sys_out.timestep == sys_array(i).timestep
198 error(['error because systems 1 and ',num2str(i),...
199 ' named ',sys_array(i).name,' and ',sys_array(i).name,...
200 ' have different timesteps :',...
201 num2str(sys_array(i).timestep),' and ',num2str(sys_array(i).timestep) ]);
202 end
203 end
204
205 %% setting history
206
207 sys_out.addHistory(ssm.getInfo(mfilename), plist , ssm_invars(:), [sys_array(:).hist] );
208
209 %% parsing output
210 validate(sys_out);
211 varargout = {sys_out};
212 end
213
214
215
216
217
218 %--------------------------------------------------------------------------
219 % Get Info Object
220 %--------------------------------------------------------------------------
221 function ii = getInfo(varargin)
222
223 if nargin == 1 && strcmpi(varargin{1}, 'None')
224 sets = {};
225 pl = [];
226 else
227 sets = {'Default'};
228 pl = getDefaultPlist;
229 end
230 % Build info object
231 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);
232 ii.setModifier(false);
233 ii.setArgsmin(2);
234 end
235
236 %--------------------------------------------------------------------------
237 % Get Default Plist
238 %--------------------------------------------------------------------------
239 function pl = getDefaultPlist()
240 pl = plist();
241 end
242