Mercurial > hg > ltpda
comparison m-toolbox/classes/@ssm/ssm.m @ 0:f0afece42f48
Import.
author | Daniele Nicolodi <nicolodi@science.unitn.it> |
---|---|
date | Wed, 23 Nov 2011 19:22:13 +0100 |
parents | |
children | a71a40911c27 bc767aaa99a8 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:f0afece42f48 |
---|---|
1 % SSM statespace model class constructor. | |
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
3 % | |
4 % DESCRIPTION: SSM statespace model class constructor. | |
5 % | |
6 % CONSTRUCTORS: | |
7 % | |
8 % s = ssm() - creates an empty statespace model | |
9 % s = ssm('a1.xml') - creates a new statespace model by loading the | |
10 % object from disk. | |
11 % s = ssm('a1.mat') - creates a new statespace model by loading the | |
12 % object from disk. | |
13 % a = ssm(plist) - creates a statespace model from the description | |
14 % given in the parameter list | |
15 % a = ssm(struct) - creates a statespace model from the | |
16 % structure returned by struct(ssm). | |
17 % | |
18 % | |
19 % EXAMPLES: | |
20 % | |
21 % 1) Construct an SSM object by description: | |
22 % | |
23 % name = 'sys'; | |
24 % statenames = {'ss1' 'ss2' 'ss3'}; | |
25 % inputnames = {'input1' 'input2' 'input3'}; | |
26 % outputnames = {'output1' 'output2' 'output3'}; | |
27 % timestep = 0; | |
28 % params = plist({'omega', 'system frequency'}, 2); | |
29 % amats = cell(3,3); | |
30 % bmats = cell(3,3); | |
31 % cmats = cell(3,3); | |
32 % dmats = cell(3,3); | |
33 % amats{1,1} = -(sym('omega')); | |
34 % amats{2,2} = -2; | |
35 % amats{3,3} = -3*eye(2); | |
36 % amats{3,1} = [-1;-3]; | |
37 % bmats{1,1} = 1; | |
38 % bmats{2,2} = 2; | |
39 % bmats{3,3} = 3*eye(2); | |
40 % cmats{1,1} = 1; | |
41 % cmats{2,2} = 1; | |
42 % cmats{3,3} = eye(2); | |
43 % dmats{1,3} = [6 6]; | |
44 % dmats{2,1} = 6; | |
45 % dmats{3,2} = [6;6]; | |
46 % sys = ssm(plist( ... | |
47 % 'amats',amats, 'bmats',bmats, 'cmats',cmats, 'dmats',dmats, ... | |
48 % 'timestep',timestep, 'name',name, 'params',params, ... | |
49 % 'statenames',statenames, 'inputnames',inputnames, 'outputnames',outputnames )); | |
50 % | |
51 % | |
52 % A shortcut (incomplete) syntax is : | |
53 % sys = ssm( amats, bmats, cmats, dmats, timestep, name, params, ... | |
54 % statenames, inputnames, outputnames ) | |
55 % Also : | |
56 % sys = ssm(miirObject); | |
57 % sys = ssm(rationalObject); | |
58 % sys = ssm(parfracObject); | |
59 % | |
60 % More complete call | |
61 % % here computation of the system's matrices, declaration | |
62 % % of parameters, some symbolic may be stored in the user | |
63 % % plist | |
64 % sys = struct | |
65 % SMD_W= 0.2; SMD_C=0.5; SMD_S1=0; SMD_S2=0; SMD_B=1; SMD_D1=0; | |
66 % sys.params = plist; | |
67 % | |
68 % | |
69 % sys.amats = {[0 1 ; -SMD_W*SMD_W -2*SMD_C*SMD_W]}; | |
70 % sys.cmats = {[1+SMD_S1 SMD_S2]}; | |
71 % sys.bmats = {[0;SMD_B] [0 0; 1 0]}; | |
72 % sys.dmats = {SMD_D1 [0 1]}; | |
73 % | |
74 % sys.timestep = 0; | |
75 % | |
76 % sys.name = 'SRPINGMASSDAMPER'; | |
77 % sys.description = 'standard spring-mass-damper test system'; | |
78 % | |
79 % inputnames = {'CMD' 'DIST_SMD'}; | |
80 % inputdescription = {'force noise' 'observation noise'}; | |
81 % inputvarnames = {{'F'} {'F' 'S'}}; | |
82 % inputvarunits = {unit('kg m s^-2') [unit('kg m s^-2') unit('m')]}; | |
83 % inputvardescription = []; | |
84 % | |
85 % ssnames = {'SMD'}; | |
86 % ssdescription = {'TM position and speed'}; | |
87 % ssvarnames = {{'x' 'xdot'}}; | |
88 % ssvarunits={[unit('m') unit('m s^-1')]}; | |
89 % ssvardescription = []; | |
90 % | |
91 % outputnames = {'SMD'}; | |
92 % outputdescription = {'observed position'}; | |
93 % outputvarnames ={{'OBS'}}; | |
94 % outputvarunits={unit('m')}; | |
95 % outputvardescription = []; | |
96 % | |
97 % %% Build ssmblocks | |
98 % sys.inputs = ssmblock.makeBlocksWithData(inputnames, inputdescription, inputvarnames, inputvarunits, inputvardescription); | |
99 % sys.outputs = ssmblock.makeBlocksWithData(outputnames, outputdescription, outputvarnames, outputvarunits, outputvardescription); | |
100 % sys.states = ssmblock.makeBlocksWithData(ssnames, ssdescription, ssvarnames, ssvarunits, ssvardescription); | |
101 % %% plist constructors | |
102 % sys = ssm(plist( ... | |
103 % 'amats',sys.amats, 'bmats',sys.bmats, 'cmats',sys.cmats, 'dmats',sys.dmats, ... | |
104 % 'timestep',0, 'name','sys.name', 'inputs',sys.inputs, ... | |
105 % 'states', sys.states, 'outputs', sys.outputs)); | |
106 % | |
107 % | |
108 % <a href="matlab:utils.helper.displayMethodInfo('ssm', 'ssm')">Parameters Description</a> | |
109 % | |
110 % VERSION: $Id: ssm.m,v 1.199 2011/05/13 15:14:39 ingo Exp $ | |
111 % | |
112 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
113 | |
114 classdef ssm < ltpda_uoh | |
115 | |
116 %% -------- Public (read/write) Properties ------- | |
117 properties | |
118 end % End (read/write) Properties | |
119 | |
120 %% -------- Private read-only Properties -------- | |
121 properties (SetAccess = protected) | |
122 amats = {}; % A matrix representing a difference/differential term in the state equation, block stored in a cell array | |
123 bmats = {}; % B matrix representing an input coefficient matrix in the state equation, block stored in a cell array | |
124 cmats = {}; % C matrix representing the state projection in the observation equation, block stored in a cell array | |
125 dmats = {}; % D matrix representing the direct feed through term in the observation equation, block stored in a cell array | |
126 timestep = 0; % Timestep of the difference equation. Zero means the representation is time continuous and A defines a differential equation. | |
127 inputs = ssmblock.initObjectWithSize(1,0); % ssmblock for input blocks | |
128 states = ssmblock.initObjectWithSize(1,0); % ssmblock describing state blocks | |
129 outputs = ssmblock.initObjectWithSize(1,0); % ssmblock describing the output blocks | |
130 numparams = plist.initObjectWithSize(1,1); % nested plist describing the numeric (substituted) parameters | |
131 params = plist.initObjectWithSize(1,1); % nested plist describing the symbolic parameters | |
132 end % End read only properties | |
133 | |
134 %% -------- Dependant Properties --------- | |
135 properties (Dependent) | |
136 Ninputs % Number of input-blocks, it is a double | |
137 inputsizes % Size corresponding to each input-block in the B/D matrices. It is a double vector | |
138 Noutputs % Number of output-blocks, it is a double | |
139 outputsizes % Size corresponding to each output-block in the C/D matrices. It is a double vector | |
140 Nstates % Number of state-blocks, it is a double | |
141 statesizes % Size corresponding to each state-block in the A/B/C matrices. It is a double vector | |
142 Nnumparams % number of parameters, a double; | |
143 Nparams % number of parameters, a double; | |
144 isnumerical % This binary tells whether the system has numerical content only, or symbolic as well | |
145 end | |
146 | |
147 %% -------- Dependant Properties --------- | |
148 properties (Dependent, Hidden) | |
149 Nss % Number of state-blocks, it is a double | |
150 sssizes % Size corresponding to each state-block in the A/B/C matrices. It is a double vector | |
151 inputnames % Cell array with input blocks names | |
152 inputvarnames % Embedded cell array with input ports names | |
153 ssnames % Cell array with states blocks names | |
154 ssvarnames % Embedded cell array with states ports names | |
155 statenames % Cell array with states blocks names | |
156 statevarnames % Embedded cell array with states ports names | |
157 outputnames % Cell array with output blocks names | |
158 outputvarnames % Embedded cell array with output ports names | |
159 paramnames % Cell array with input parameter names | |
160 paramvalues % Double array with input parameter values - may not work with new paramvalue class | |
161 numparamnames % Cell array with input parameter names | |
162 numparamvalues % Double array with input parameter values - may not work with new paramvalue class | |
163 end %-------- Protected Properties --------- | |
164 | |
165 %% -------- Dependant Properties Methods ------ | |
166 methods | |
167 | |
168 function value = get.Ninputs(obj) | |
169 value = size(obj.bmats,2); | |
170 end | |
171 | |
172 function value = get.inputsizes(obj) | |
173 Ninputs = obj.Ninputs; | |
174 Nstates = obj.Nstates; | |
175 Noutputs = obj.Noutputs; | |
176 if Nstates==0 && Ninputs~=0 && Noutputs==0 | |
177 error('This ssm has matrix sizes that make it impossible to determine the property inputsizes (0 states, 1+ inputs and 0 output)') | |
178 end | |
179 value = zeros(1, Ninputs); | |
180 for k=1:Ninputs | |
181 % b matrix vertically | |
182 for p=1:Nstates | |
183 value(k) = size(obj.bmats{p,k} ,2); | |
184 if value(k)>0 | |
185 break | |
186 end | |
187 end | |
188 % d matrix vertically | |
189 if value(k)==0 | |
190 for p=1:Noutputs | |
191 value(k) = size(obj.dmats{p,k} ,2); | |
192 if value(k)>0 | |
193 break | |
194 end | |
195 end | |
196 end | |
197 end | |
198 end | |
199 | |
200 function value = get.Noutputs(obj) | |
201 value = size(obj.cmats,1); | |
202 end | |
203 | |
204 function value = get.outputsizes(obj) | |
205 Ninputs = obj.Ninputs; | |
206 Nstates = obj.Nstates; | |
207 Noutputs = obj.Noutputs; | |
208 if Nstates==0 && Ninputs==0 && Noutputs~=0 | |
209 error('This ssm has matrix sizes that make it impossible to determine the property outputsizes (0 states, 0 input and 1+ outputs)') | |
210 end | |
211 value = zeros(1, Noutputs); | |
212 for k=1:Noutputs | |
213 % c matrix horizontally | |
214 for p=1:Nstates | |
215 value(k) = size(obj.cmats{k,p} ,1); | |
216 if value(k)>0 | |
217 break | |
218 end | |
219 end | |
220 % d matrix horizontally | |
221 if value(k)==0 | |
222 for p=1:Ninputs | |
223 value(k) = size(obj.dmats{k,p} ,1); | |
224 if value(k)>0 | |
225 break | |
226 end | |
227 end | |
228 end | |
229 end | |
230 end | |
231 | |
232 function value = get.Nstates(obj) | |
233 value = size(obj.amats,1); | |
234 end | |
235 | |
236 function value = get.statesizes(obj) | |
237 Ninputs = obj.Ninputs; | |
238 Nstates = obj.Nstates; | |
239 Noutputs = obj.Noutputs; | |
240 value = zeros(1, Nstates); | |
241 for k=1:Nstates | |
242 % b matrix horizontally | |
243 for p=1:Ninputs | |
244 value(k) = size(obj.bmats{k,p}, 1); | |
245 if value(k)>0 | |
246 break | |
247 end | |
248 end | |
249 % a matrix horizontally | |
250 if value(k)==0 | |
251 for p=1:Nstates | |
252 value(k) = size(obj.amats{k,p}, 1); | |
253 if value(k)>0 | |
254 break | |
255 end | |
256 end | |
257 end | |
258 % a matrix vertically | |
259 if value(k)==0 | |
260 for p=1:Nstates | |
261 value(k) = size(obj.amats{p,k}, 2); | |
262 if value(k)>0 | |
263 break | |
264 end | |
265 end | |
266 end | |
267 % c matrix vertically | |
268 if value(k)==0 | |
269 for p=1:Noutputs | |
270 value(k) = size(obj.cmats{p,k}, 2); | |
271 if value(k)>0 | |
272 break | |
273 end | |
274 end | |
275 end | |
276 end | |
277 end | |
278 | |
279 function value = get.Nss(obj) | |
280 value = obj.Nstates; | |
281 end | |
282 | |
283 function value = get.sssizes(obj) | |
284 value = obj.statesizes; | |
285 end | |
286 | |
287 function value = get.Nparams(obj) | |
288 value = obj.params.nparams; | |
289 end | |
290 | |
291 function value = get.Nnumparams(obj) | |
292 value = obj.numparams.nparams; | |
293 end | |
294 | |
295 | |
296 function value = get.isnumerical(obj) | |
297 value = true; | |
298 for i=1:numel(obj.amats) | |
299 if ~isa(obj.amats{i}, 'double'), | |
300 value = false; return; | |
301 end | |
302 end | |
303 for i=1:numel(obj.bmats) | |
304 if ~isa(obj.bmats{i}, 'double') | |
305 value = false; return; | |
306 end | |
307 end | |
308 for i=1:numel(obj.cmats) | |
309 if ~isa(obj.cmats{i}, 'double') | |
310 value = false; return; | |
311 end | |
312 end | |
313 for i=1:numel(obj.dmats) | |
314 if ~isa(obj.dmats{i}, 'double') | |
315 value = false; return; | |
316 end | |
317 end | |
318 end | |
319 | |
320 function names = get.inputnames(obj) | |
321 names = obj.inputs.blockNames; | |
322 end | |
323 | |
324 function names = get.inputvarnames(obj) | |
325 names = obj.inputs.portNames; | |
326 end | |
327 | |
328 function names = get.ssnames(obj) | |
329 names = obj.statenames; | |
330 end | |
331 | |
332 function names = get.ssvarnames(obj) | |
333 names = obj.statevarnames; | |
334 end | |
335 | |
336 function names = get.statenames(obj) | |
337 names = obj.states.blockNames; | |
338 end | |
339 | |
340 function names = get.statevarnames(obj) | |
341 names = obj.states.portNames; | |
342 end | |
343 | |
344 function names = get.outputnames(obj) | |
345 names = obj.outputs.blockNames; | |
346 end | |
347 | |
348 function names = get.outputvarnames(obj) | |
349 names = obj.outputs.portNames; | |
350 end | |
351 | |
352 function names = get.paramnames(obj) | |
353 Nparams = obj.params.nparams; | |
354 names = cell(1, Nparams); | |
355 for i=1:Nparams | |
356 names{i} = obj.params.params(i).key; | |
357 end | |
358 end | |
359 | |
360 function values = get.paramvalues(obj) | |
361 Nparams = obj.params.nparams; | |
362 values = zeros(1, Nparams); | |
363 for i=1:Nparams | |
364 values(i) = obj.params.params(i).getVal; | |
365 end | |
366 end | |
367 | |
368 function names = get.numparamnames(obj) | |
369 Nnumparams = obj.numparams.nparams; | |
370 names = cell(1, Nnumparams); | |
371 for i=1:Nnumparams | |
372 names{i} = obj.numparams.params(i).key; | |
373 end | |
374 end | |
375 | |
376 function values = get.numparamvalues(obj) | |
377 Nnumparams = obj.numparams.nparams; | |
378 values = zeros(1, Nnumparams); | |
379 for i=1:Nnumparams | |
380 values(i) = obj.numparams.params(i).getVal; | |
381 end | |
382 end | |
383 | |
384 function set.inputnames(obj, inputnames) | |
385 if ~obj.Ninputs == numel(inputnames) | |
386 error('### error : Input size is wrong') | |
387 end | |
388 if obj.Ninputs == numel(obj.inputs) | |
389 obj.inputs.setBlockNames(inputnames); | |
390 else | |
391 obj.inputs = ssmblock.makeBlocksWithSize(obj.inputsizes, inputnames); | |
392 end | |
393 % history to be added ? | |
394 end | |
395 | |
396 function set.statenames(obj, statenames) | |
397 if ~obj.Nstates == numel(statenames) | |
398 error('### error : Input size is wrong') | |
399 end | |
400 if (obj.Nstates == numel(obj.states)) | |
401 obj.states.setBlockNames(statenames); | |
402 else | |
403 obj.states = ssmblock.makeBlocksWithSize(obj.statesizes, statenames); | |
404 end | |
405 % history to be added ? | |
406 end | |
407 | |
408 function set.outputnames(obj, outputnames) | |
409 if ~obj.Noutputs == numel(outputnames) | |
410 error('### error : Input size is wrong') | |
411 end | |
412 if obj.Noutputs == numel(obj.outputs) | |
413 obj.outputs.setBlockNames(outputnames); | |
414 else | |
415 obj.outputs = ssmblock.makeBlocksWithSize(obj.outputsizes, outputnames); | |
416 end | |
417 % history to be added ? | |
418 end | |
419 | |
420 function set.ssnames(obj, ssnames) | |
421 obj.statenames = ssnames; | |
422 end | |
423 | |
424 end | |
425 | |
426 %% -------- constructor ------ | |
427 methods(Access = public) | |
428 | |
429 function s = ssm(varargin) | |
430 import utils.const.* | |
431 | |
432 utils.helper.msg(msg.PROC3, 'running %s/%s', mfilename('class'), mfilename); | |
433 % Check the supported version | |
434 utils.helper.checkMatlabVersion; | |
435 | |
436 % Initialize the properties to make sure that the pointer points to a | |
437 % new object. | |
438 s.numparams = plist(); | |
439 s.numparams.setName('numparams'); | |
440 s.params = plist(); | |
441 s.params.setName('params'); | |
442 | |
443 % empty constructor | |
444 if nargin == 0 | |
445 %%%%%%%%%% s = ssm() %%%%%%%%%% | |
446 s.addHistory(ssm.getInfo('ssm', 'None'), plist(), [], []); | |
447 return | |
448 end | |
449 | |
450 % copy constructor | |
451 % Collect all ssm objects to check for copy constructor | |
452 sss = utils.helper.collect_objects(varargin(:), 'ssm'); | |
453 if ~isempty(sss) | |
454 %%%%%%%%%% s = ssm(<ssm objects>) %%%%%%%%%% | |
455 utils.helper.msg(msg.OPROC1, 'copy constructor'); | |
456 s = copy(sss, 1); | |
457 for kk=1:numel(s) | |
458 s(kk).addHistory(ssm.getInfo('ssm', 'None'), [], [], s(kk).hist); | |
459 end | |
460 return | |
461 end | |
462 | |
463 % one input constructor | |
464 if (nargin == 1) | |
465 | |
466 % constructor with one object | |
467 vin = varargin{1}; | |
468 if any( strcmp(class(vin), {'pzmodel', 'rational', 'parfrac', 'struct', 'miir', 'ss' } )) | |
469 %%%%%%%%%% s = ssm(<model object>) %%%%%%%%%% | |
470 s = ssm(vin, plist); | |
471 return | |
472 end | |
473 | |
474 | |
475 % constructor from a plist with no object inside | |
476 % | |
477 % the object may only be validated in the constructor | |
478 % the history may only be added in the constructor | |
479 if isa(vin, 'plist') | |
480 %%%%%%%%%% s = ssm(<empty plist>) %%%%%%%%%% | |
481 if vin.nparams == 0 % empty constructor with a plist | |
482 utils.helper.msg(msg.OPROC1, 'empty constructor %s', varargin{1}.name); | |
483 s.addHistory(ssm.getInfo('ssm', 'None'), vin, [], []); | |
484 return | |
485 %%%%%%%%%% s = ssm(<plist with no model object inside>) %%%%%%%%%% | |
486 elseif isparam(vin,'amats') % construct from a plist description | |
487 utils.helper.msg(msg.OPROC1, 'constructor from a description %s', varargin{1}.name); | |
488 s = ssm.ssmFromDescription(vin); | |
489 s.addHistory(ssm.getInfo('ssm', 'None'), vin, [], []); | |
490 return | |
491 elseif isparam(vin,'Built-in') % Construct from built-in models | |
492 utils.helper.msg(msg.OPROC1, 'constructing from Built-in model %s', varargin{1}.name); | |
493 vin.pset('Built-in', vin.find('Built-in')); | |
494 if isparam(vin, 'withparams') | |
495 error('The WITHPARAMS key has been changed to SYMBOLIC PARAMS. Please check your plist'); | |
496 end | |
497 s = fromModel(s,vin); | |
498 s.validate; % validate when a new object is built | |
499 return | |
500 elseif isparam(vin,'Hostname') % Retrieve from repository | |
501 utils.helper.msg(msg.OPROC1, 'constructing from repository %s', varargin{1}.name); | |
502 s = s.fromRepository(vin); | |
503 return | |
504 elseif isparam(vin,'Filename') % filename constructor | |
505 utils.helper.msg(msg.OPROC1, 'constructing from filename %s', varargin{1}.name); | |
506 s = s.fromFile(vin); | |
507 return | |
508 | |
509 % constructor from a plist with an object inside | |
510 % | |
511 % the object is retrieved out of the plist and removed from the | |
512 % plist to make it lighter. The input is parsed to the ssm | |
513 % constructor with two inputs. History and validation are done in | |
514 % there. | |
515 % There is no message since it is displayed in the call to ssm | |
516 % later on | |
517 | |
518 %%%%%%%%%% s = ssm(<plist with model-object inside>) %%%%%%%%%% | |
519 elseif isparam(vin,'pzmodel') | |
520 obj = find(vin, 'pzmodel'); | |
521 vin.remove('pzmodel') | |
522 elseif isparam(vin,'rational') | |
523 obj = find(vin, 'rational'); | |
524 vin.remove('rational') | |
525 elseif isparam(vin,'parfrac') | |
526 obj = find(vin, 'parfrac'); | |
527 vin.remove('parfrac') | |
528 elseif isparam(vin,'struct') | |
529 obj = find(vin, 'struct'); | |
530 vin.remove('struct') | |
531 elseif isparam(vin,'miir') | |
532 obj = find(vin, 'miir'); | |
533 vin.remove('miir') | |
534 elseif isparam(vin,'ss') | |
535 obj = find(vin, 'ss'); | |
536 vin.remove('ss') | |
537 else | |
538 display('### Unknown ssm constructor could not find a valid parameter key ###') | |
539 display('### these are : ''Filename'' ''Built-in'' ''pzmodel'' ''miir'' ''amats'' ###') | |
540 display('### ''Hostname'' ''rational'' ''struct'' ''ss'' ###') | |
541 error(''); | |
542 end | |
543 s = ssm(obj, vin); | |
544 return | |
545 end | |
546 | |
547 | |
548 % constructor with an input string | |
549 if isa(vin, 'char') | |
550 %%%%%%%%%% s = ssm(filename) %%%%%%%%%% | |
551 s = ssm(plist('Filename', vin)); | |
552 return | |
553 end | |
554 | |
555 % in the worst case, try with the same input and a plist !? Not | |
556 % Yet (TBD) | |
557 display('### Unknown ssm one-object constructor, allowed object classes are: ###') | |
558 display('### ''plist'' ''pzmodel'' ''rational'' ''parfrac'' ''struct'' ''miir'' ''ss'' ###') | |
559 error(''); | |
560 end | |
561 | |
562 % two inputs constructors | |
563 switch nargin | |
564 case 2 | |
565 obj = varargin{1}; | |
566 pl = varargin{2}; | |
567 | |
568 if isa(pl, 'plist') | |
569 if isstruct(obj) | |
570 %%%%%%%%%% s = ssm(struct, plist) %%%%%%%%%% | |
571 utils.helper.msg(msg.OPROC1, 'contructing from a structure'); | |
572 s = fromStruct(s, obj); | |
573 doValidate = true; | |
574 elseif isa(obj, 'pzmodel') | |
575 %%%%%%%%%% s = ssm(pzmodel, plist) %%%%%%%%%% | |
576 utils.helper.msg(msg.OPROC1, 'constructing from pzmodel %s', varargin{1}.name); | |
577 s = ssm.ssmFromPzmodel( obj, pl); | |
578 doValidate = true; | |
579 elseif isa(obj, 'miir') | |
580 %%%%%%%%%% s = ssm(miir, plist) %%%%%%%%%% | |
581 utils.helper.msg(msg.OPROC1, 'constructing from miir %s', varargin{1}.name); | |
582 s = ssm.ssmFromMiir(obj, pl); | |
583 doValidate = true; | |
584 elseif isa(obj, 'ss') | |
585 %%%%%%%%%% s = ssm(ss, plist) %%%%%%%%%% | |
586 utils.helper.msg(msg.OPROC1, 'constructing from ss %s', varargin{1}.name); | |
587 s = ssm.ssmFromss(obj, pl); | |
588 doValidate = true; | |
589 elseif isa(obj,'char') && pl.isparam('filename') | |
590 %%%%%%%%%% s = ssm(filename, plist) %%%%%%%%%% | |
591 utils.helper.msg(msg.OPROC1, 'constructing from filename %s', varargin{1}.name); | |
592 filename = varargin{1}; | |
593 s = s.fromFile(filename); | |
594 doValidate = false; | |
595 elseif isa(obj, 'rational') | |
596 %%%%%%%%%% s = ssm(rational, plist) %%%%%%%%%% | |
597 utils.helper.msg(msg.OPROC1, 'constructing from rational %s', varargin{1}.name); | |
598 s = ssm.ssmFromRational(obj,pl); | |
599 doValidate = true; | |
600 elseif isa(obj, 'parfrac') | |
601 %%%%%%%%%% s = ssm(parFrac) %%%%%%%%%% | |
602 s = ssm.ssmFromParfrac(obj, pl); | |
603 doValidate = true; | |
604 elseif isa(obj, 'ssm') && pl.nparams == 0 | |
605 s = ssm(obj); | |
606 elseif isa(obj, 'plist') | |
607 % if for some reason we have two input plists, combine them. | |
608 %%%%%%%%%% s = ssm(plist, plist) %%%%%%%%%% | |
609 s = ssm(obj.combine(plist)); | |
610 return; | |
611 else | |
612 error(['### Error: ssm constructor cannot accept input of type : ',class(obj)]); | |
613 end | |
614 | |
615 % Now validate this object | |
616 if doValidate | |
617 s.validate(); | |
618 end | |
619 | |
620 elseif (isa(varargin{1}, 'database') || isa(varargin{1}, 'mpipeline.repository.RepositoryConnection')) && isnumeric(varargin{2}) | |
621 %%%%%%%%%% s = ssm(<database-object>, [IDs]) %%%%%%%%%% | |
622 utils.helper.msg(msg.OPROC1, 'retrieve from repository'); | |
623 s = s.fromRepository(plist('conn', varargin{1}, 'id', varargin{2})); | |
624 | |
625 elseif ischar(varargin{1}) | |
626 %%%%%%%%% s = ssm('str1', param1) %%%%%%%%%% | |
627 s = ssm(plist(varargin{1},varargin{2})); | |
628 s.validate(); | |
629 | |
630 elseif isa(varargin{1}, 'org.apache.xerces.dom.DeferredElementImpl') && ... | |
631 isa(varargin{2}, 'history') | |
632 %%%%%%%%%% obj = ssm(DOM node, history-objects) %%%%%%%%%% | |
633 s = fromDom(s, varargin{1}, varargin{2}); | |
634 | |
635 else | |
636 error('### Unknown two parameter constructor.'); | |
637 end | |
638 | |
639 % contructor with more than 2 inputs, which cannot be the copy | |
640 % constructor (done at the beggining) | |
641 otherwise | |
642 if ischar(varargin{1}) | |
643 %%%%%%%%%% s = ssm('str1', param1, 'str2', param2 ...) %%%%%%%%%% | |
644 try | |
645 vin = plist(varargin{:}); | |
646 catch | |
647 error('### Unknown constructor - ssm tried to make a plist with the constructor inputs, but it did not work.'); | |
648 end | |
649 s = ssm(vin); | |
650 else % Try shortcut call with a description | |
651 try | |
652 %%%%%%%%%% s = ssm(amats, bmats, cmats,...) %%%%%%%%%% | |
653 utils.helper.msg(msg.OPROC1, 'attempting building a description'); | |
654 keynames = {'amats', 'bmats', 'cmats', 'dmats', 'timestep', 'name', 'params'... | |
655 'statenames', 'inputnames', 'outputnames' }; | |
656 pli = plist; | |
657 for i=1:numel(keynames) | |
658 if i<=nargin | |
659 pli.append( plist(keynames{i},varargin{i}) ); | |
660 end | |
661 end | |
662 s = ssm(pli); | |
663 catch ME | |
664 error(ME.identifier, '### Unknown constructor with more than 2 arguments.'); | |
665 end | |
666 end | |
667 end | |
668 end | |
669 | |
670 end % -------- constructor ------ | |
671 | |
672 %% -------- Declaration of hidden methods -------- | |
673 methods (Hidden = true) | |
674 | |
675 varargout = setA(varargin); | |
676 varargout = setB(varargin); | |
677 varargout = setC(varargin); | |
678 varargout = setD(varargin); | |
679 | |
680 function clearNumParams(sys) | |
681 sys.numparams = plist; | |
682 end | |
683 | |
684 function clearAllUnits(sys) | |
685 sys.inputs.clearAllUnits; | |
686 sys.states.clearAllUnits; | |
687 sys.outputs.clearAllUnits; | |
688 end | |
689 | |
690 | |
691 % completion and error check | |
692 varargout = validate(varargin) | |
693 % copying one ssm | |
694 varargout = copy(varargin) | |
695 % process system simplification | |
696 varargout = doSimplify(varargin) | |
697 % process parameter setting | |
698 varargout = doSetParameters(varargin) | |
699 % process parameter substitution | |
700 varargout = doSubsParameters(varargin) | |
701 % re-arrangement of ssm | |
702 sys = reshuffle(sys, inputs1, inputs2, inputs3, states, outputs, outputStates) | |
703 % necessary for saving XML files | |
704 varargout = attachToDom(varargin) | |
705 end | |
706 | |
707 %% -------- Declaration of Public Static methods -------- | |
708 methods (Static=true, Access=public) | |
709 | |
710 function mdls = getBuiltInModels(varargin) | |
711 mdls = ltpda_uo.getBuiltInModels('ssm'); | |
712 end | |
713 | |
714 function ii = getInfo(varargin) | |
715 ii = utils.helper.generic_getInfo(varargin{:}, 'ssm'); | |
716 end | |
717 | |
718 function out = VEROUT() | |
719 out = '$Id: ssm.m,v 1.199 2011/05/13 15:14:39 ingo Exp $'; | |
720 end | |
721 | |
722 function out = SETS() | |
723 out = [SETS@ltpda_uoh, ... | |
724 {'From Description'}, ... | |
725 {'From Pzmodel'}, ... | |
726 {'From Miir'}, ... | |
727 {'From Rational'}]; | |
728 end | |
729 | |
730 function plout = getDefaultPlist(set) | |
731 persistent pl; | |
732 persistent lastset; | |
733 if exist('pl', 'var')==0 || isempty(pl) || ~strcmp(lastset, set) | |
734 pl = ssm.buildplist(set); | |
735 lastset = set; | |
736 end | |
737 plout = pl; | |
738 end | |
739 | |
740 function pl = buildplist(set) | |
741 if ~utils.helper.ismember(lower(ssm.SETS), lower(set)) | |
742 error('### Unknown set [%s]', set); | |
743 end | |
744 pl = plist(); | |
745 pl = ssm.addGlobalKeys(pl); | |
746 pl = buildplist@ltpda_uoh(pl, set); | |
747 switch lower(set) % Select parameter set | |
748 | |
749 case 'default' | |
750 % overide the default plist | |
751 pl = ssm.getDefaultPlist('From Description'); | |
752 | |
753 case 'from built-in model' | |
754 % Built-in | |
755 % This is inherited | |
756 pl = plist.FROM_BUILT_IN; | |
757 % withParams --> withparams changed to 'symbolic params' | |
758 p = param({'symbolic params',['Give a cell-array of parameter names to keep in the expression.<br>',... | |
759 'By default this is empty and the model will be returned fully numeric.',... | |
760 'You can also specify ''ALL'' to keep all parameters. Some models don''t support this',... | |
761 'option; see the specific help of the models for details.']}, {}); | |
762 pl.append(p); | |
763 % SETNAMES --> setnames changed to 'param names' | |
764 p = param({'param names',['Cell-array of parameter names for user defined values.<br>',... | |
765 'This way, parameter values can be modified even if they are never used symbolically.']},{}); | |
766 pl.append(p); | |
767 % SETVALUES --> setvalues changed to 'param values' | |
768 p = param({'param values','Array of parameter values for numerical substitutions.'}, paramValue.EMPTY_DOUBLE); | |
769 pl.append(p); | |
770 | |
771 case 'from description' | |
772 | |
773 % States | |
774 p = param({'states','State space blocks.'}, ssmblock.initObjectWithSize(1,0)); | |
775 pl.append(p); | |
776 % Outputs | |
777 p = param({'outputs','Output blocks.'}, ssmblock.initObjectWithSize(1,0)); | |
778 pl.append(p); | |
779 % Inputs | |
780 p = param({'inputs','Input blocks.'}, ssmblock.initObjectWithSize(1,0)); | |
781 pl.append(p); | |
782 % Timestep | |
783 p = param({'timestep',['Timestep of the difference equation. Zero means '... | |
784 'the representation is time continuous' ]}, paramValue.DOUBLE_VALUE(0)); | |
785 pl.append(p); | |
786 % AMATS | |
787 p = param({'amats',['A matrix representing a difference/differential term in the state equation.',... | |
788 'Specify as a cell-array of matrices.']}, cell(0,0)); | |
789 pl.append(p); | |
790 % BMATS | |
791 p = param({'bmats',['B matrix representing an input coefficient matrix in the state equation.',... | |
792 'Specify as a cell-array of matrices.']}, cell(0,0)); | |
793 pl.append(p); | |
794 % CMATS | |
795 p = param({'cmats',['C matrix representing the state projection in the observation equation.',... | |
796 'Specify as a cell-array of matrices.']}, cell(0,0)); | |
797 pl.append(p); | |
798 % DMATS | |
799 p = param({'dmats',['D matrix representing the direct feed through term in the observation equation.',... | |
800 'Specify as a cell-array of matrices.']}, cell(0,0)); | |
801 pl.append(p); | |
802 % Params | |
803 p = param({'params','Parameter data arrays.'}, {1, {plist}, paramValue.OPTIONAL}); | |
804 pl.append(p); | |
805 | |
806 case 'from pzmodel' | |
807 p = param({'pzmodel','A pole/zero model object.'}, {1, {pzmodel}, paramValue.OPTIONAL}); | |
808 pl.append(p); | |
809 | |
810 case 'from miir' | |
811 p = param({'miir','An IIR filter object (MIIR).'}, {1, {miir}, paramValue.OPTIONAL}); | |
812 pl.append(p); | |
813 | |
814 case 'from rational' | |
815 p = param({'rational','A rational (transfer function) model object.'}, {1, {rational}, paramValue.OPTIONAL}); | |
816 pl.append(p); | |
817 | |
818 end | |
819 end | |
820 | |
821 function obj = initObjectWithSize(n,m) | |
822 obj = ssm.newarray([n m]); | |
823 end | |
824 | |
825 end % End public static methods | |
826 | |
827 %% -------- Declaration of public methods -------- | |
828 methods | |
829 varargout = getParams(varargin) | |
830 varargout = setParams(varargin) | |
831 | |
832 varargout = setBlockProperties(varargin) | |
833 varargout = setBlockNames(varargin) | |
834 varargout = setBlockDescriptions(varargin) | |
835 varargout = setPortProperties(varargin) | |
836 varargout = setPortNames(varargin) | |
837 varargout = setPortUnits(varargin) | |
838 varargout = setPortDescriptions(varargin) | |
839 | |
840 % change timestep | |
841 varargout = modifyTimeStep(varargin) | |
842 % add, change and subsitute parameters | |
843 varargout = addParameters(varargin) | |
844 varargout = subsParameters(varargin) | |
845 varargout = setParameters(varargin) | |
846 varargout = keepParameters(varargin) | |
847 varargout = getParameters(varargin) | |
848 % copy one input block | |
849 varargout = duplicateInput(varargin) | |
850 % assemble systems | |
851 varargout = assemble(varargin) | |
852 % append systems | |
853 varargout = append(varargin) | |
854 % transform into a iir | |
855 varargout = ssm2miir(varargin) | |
856 % transform into a pzmodel | |
857 varargout = ssm2pzmodel(varargin) | |
858 % transform into ABCD doubles/symb | |
859 varargout = double(varargin) | |
860 % returns aos with impulse or step response | |
861 varargout = resp(varargin) | |
862 % returns aos with impulse or step response (uses control toolbox) | |
863 varargout = respcst(varargin) | |
864 % transform into a matlab ss object | |
865 varargout = ssm2ss(varargin) | |
866 % simulation | |
867 varargout = simulate(varargin) | |
868 % kalman filter | |
869 varargout = kalman(varargin) | |
870 % model simplification (variables) | |
871 varargout = simplify(varargin) | |
872 % char | |
873 varargout = char(varargin) | |
874 % display | |
875 varargout = display(varargin) | |
876 % give minimal realization | |
877 varargout = MinReal(varargin) | |
878 % give minimal systematic realization | |
879 varargout = sMinReal(varargin) | |
880 % tells if ssm is stable | |
881 varargout = isStable(varargin) | |
882 % returns a value for steady state | |
883 varargout = steadyState(varargin) | |
884 % returns a value for the system's settling time | |
885 varargout = settlingTime(varargin) | |
886 % returns a system with output diferrenciated in regards with parameters | |
887 varargout = parameterDiff(varargin) | |
888 % returns the expected output spectrum of the ssm | |
889 varargout = PSD(varargin) | |
890 varargout = CPSD(varargin) % takes coupled inputs but does not return individual contributions | |
891 % fitting ssm parameters | |
892 varargout = ssmFit(varargin); | |
893 % reorganize ssm for simulation, PSD, BODE... | |
894 varargout = reorganize(varargin) | |
895 % display ports/plists | |
896 varargout = displayProperties(varargin) | |
897 end | |
898 | |
899 methods (Access = private) | |
900 end | |
901 | |
902 %% -------- Declaration of Hidden Static methods -------- | |
903 methods (Static=true, Hidden=true) | |
904 % create from miir | |
905 varargout = ssmFromMiir(varargin) | |
906 % create from rational | |
907 varargout = ssmFromRational(varargin) | |
908 % create from parfrac object | |
909 varargout = ssmFromParfrac(varargin) | |
910 % create from ss | |
911 varargout = ssmFromss(varargin) | |
912 % create from plist | |
913 varargout = ssmFromDescription(varargin) | |
914 % create from pzmodel | |
915 varargout = ssmFromPzmodel(varargin) | |
916 % subroutines for block defined matrix calculus | |
917 a_out = blockMatRecut(a, rowsizes, colsizes) | |
918 a_out = blockMatFusion(a, rowsizes, colsizes) | |
919 c = blockMatMult(varargin) | |
920 a = blockMatAdd(varargin) | |
921 a = blockMatIndex(amats, blockIndex1, portIndex1, blockIndex2, portIndex2) | |
922 a = blockMatIndexSym(amats, blockIndex1, portIndex1, blockIndex2, portIndex2) | |
923 varargout = blockMatPrune(varargin) | |
924 a = blockMatFillDiag(a, isizes, jsizes) | |
925 varargout = loadobj(varargin) | |
926 varargout = update_struct(varargin) | |
927 % for built-in models | |
928 varargout = modelHelper_checkParameters(varargin) | |
929 varargout = modelHelper_processInputPlist(varargin) | |
930 [params, numParams] = modelHelper_declareParameters(pl, paramNames, paramValues, paramDescriptions, paramUnits) | |
931 modelHelper_introScript | |
932 varargout = buildParamPlist(names, value, description, units, pl); | |
933 % indexing in a matrix and I/o block arrays, with selection and | |
934 % permuation matrices | |
935 varargout = getMatrixSelection(blockMat, colSizes, oldColumns, newColumns, rowSizes, oldRows, newRows) | |
936 | |
937 % Chi2 fitting computation | |
938 varargout = computeChiFit(varargin) | |
939 % simulation computation | |
940 [x, y, lastX] = doSimulate(varargin) | |
941 % bode computation | |
942 varargout = doBode(a, b, c, d, w, Ts) | |
943 | |
944 end | |
945 | |
946 methods (Access = protected) | |
947 varargout = fromStruct(varargin) | |
948 varargout = fromDom(varargin) | |
949 end | |
950 | |
951 | |
952 end % End classdef | |
953 |