Mercurial > hg > ltpda
comparison m-toolbox/classes/@ssm/validate.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 % VALIDATE Completes and checks the content a ssm object | |
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
3 % | |
4 % DESCRIPTION: Completes and checks the content a ssm object | |
5 % checks consitency of sizes, class appartenance of fields. | |
6 % completes some missing fields. | |
7 % | |
8 % CALL: ssmin.validate | |
9 % This function is private. To check and copy an object use | |
10 % obj = ssm(old) instead | |
11 % | |
12 % INPUT VALUES : ssmin = ssm_matrix, ssm list | |
13 % OUTPUT VALUES : one ssm matrix, copy or handle to the inputs | |
14 % | |
15 % NOTE: This private method does not add history. | |
16 % | |
17 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
18 | |
19 function varargout = validate(varargin) | |
20 %% starting initial checks | |
21 utils.helper.msg(utils.const.msg.MNAME, ['running ', mfilename]); | |
22 | |
23 % Collect all SSMs | |
24 sys = utils.helper.collect_objects(varargin(:), 'ssm'); | |
25 | |
26 % use the caller is method flag | |
27 callerIsMethod = utils.helper.callerIsMethod; | |
28 | |
29 % Decide on a deep copy or a modify, depending on the output | |
30 sys = copy(sys, nargout); | |
31 | |
32 %% begin function body | |
33 | |
34 for i_sys = 1:numel(sys) % going through the input | |
35 | |
36 % load some data | |
37 inputsizes = sys(i_sys).inputsizes; | |
38 statesizes = sys(i_sys).statesizes; | |
39 outputsizes = sys(i_sys).outputsizes; | |
40 | |
41 %% =========== generating missing user defined fields =========== | |
42 | |
43 % data with linear system matrices | |
44 | |
45 if (numel(sys(i_sys).inputs) ~= numel(inputsizes)) | |
46 % generating inputs if it does not already exist | |
47 sys(i_sys).inputs = ssmblock.makeBlocksWithSize(inputsizes, 'input'); | |
48 else % check subfields are completely filled | |
49 for i=1:min(numel(sys(i_sys).inputs), numel(inputsizes)) | |
50 if ~ (numel(sys(i_sys).inputs(i).ports) == inputsizes(i)) | |
51 % generating level 2 plist for each input variable | |
52 sys(i_sys).inputs(i).setPortsWithSize(inputsizes(i)); | |
53 sys(i_sys).inputs(i).ports.setName('', sys(i_sys).inputs(i).name); | |
54 end | |
55 end | |
56 end | |
57 | |
58 % generating states if it does not already exist | |
59 if (numel(sys(i_sys).states) ~= numel(statesizes)) | |
60 % generating states if it does not already exist | |
61 sys(i_sys).states = ssmblock.makeBlocksWithSize(statesizes, 'state'); | |
62 else % check subfields are completely filled | |
63 for i=1:min(numel(sys(i_sys).states), numel(statesizes)) | |
64 if ~ (numel(sys(i_sys).states(i).ports) == statesizes(i)) | |
65 % generating level 2 plist for each state variable | |
66 sys(i_sys).states(i).setPortsWithSize(statesizes(i)); | |
67 sys(i_sys).states(i).ports.setName('', sys(i_sys).states(i).name); | |
68 end | |
69 end | |
70 end | |
71 | |
72 if (numel(sys(i_sys).outputs) ~= numel(outputsizes)) | |
73 % generating outputs if it does not already exist | |
74 sys(i_sys).outputs = ssmblock.makeBlocksWithSize(outputsizes, 'output'); | |
75 else % check subfields are completely filled | |
76 for i=1:min(numel(sys(i_sys).outputs), numel(outputsizes)) | |
77 if ~ (numel(sys(i_sys).outputs(i).ports) == outputsizes(i)) | |
78 % generating level 2 plist for each output variable | |
79 sys(i_sys).outputs(i).setPortsWithSize(outputsizes(i)); | |
80 sys(i_sys).outputs(i).ports.setName('', sys(i_sys).outputs(i).name); | |
81 end | |
82 end | |
83 end | |
84 | |
85 % checking diagonal content of matrices | |
86 sys(i_sys).bmats = ssm.blockMatFillDiag(sys(i_sys).bmats, statesizes, inputsizes); | |
87 sys(i_sys).cmats = ssm.blockMatFillDiag(sys(i_sys).cmats, outputsizes, statesizes); | |
88 sys(i_sys).dmats = ssm.blockMatFillDiag(sys(i_sys).dmats, outputsizes, inputsizes); | |
89 | |
90 %% =========== checking field sizes =========== | |
91 % checking compatibility with Ninputs | |
92 if ~( numel(sys(i_sys).inputs)==size(sys(i_sys).bmats,2) ... | |
93 && numel(sys(i_sys).inputs)==size(sys(i_sys).dmats,2) ... | |
94 && numel(sys(i_sys).inputs)==numel(inputsizes) ) | |
95 error(['error in ssm ',sys(i_sys).name,' because there are ',... | |
96 num2str(size(sys(i_sys).bmats,2)),' columns in B , ',... | |
97 num2str(size(sys(i_sys).dmats,2)),' columns in D , ',... | |
98 num2str(numel(sys(i_sys).inputs)),' inputs, ',... | |
99 num2str(numel(inputsizes)),' inputsizes'] ); | |
100 end | |
101 | |
102 % checking compatibility with Nss | |
103 if ~( numel(sys(i_sys).states)==size(sys(i_sys).amats,2) ... | |
104 && numel(sys(i_sys).states)==size(sys(i_sys).amats,1) ... | |
105 && numel(sys(i_sys).states)==size(sys(i_sys).bmats,1) ... | |
106 && numel(sys(i_sys).states)==size(sys(i_sys).cmats,2) ... | |
107 && numel(sys(i_sys).states)==numel(statesizes) ) | |
108 error(['error in ssm ',sys(i_sys).name,' because there are ',... | |
109 num2str(size(sys(i_sys).amats,2)),' columns in A, ',... | |
110 num2str(size(sys(i_sys).amats,1)),' lines in A, ',... | |
111 num2str(size(sys(i_sys).bmats,1)),' lines in B, ',... | |
112 num2str(size(sys(i_sys).cmats,2)),' columns in C, ',... | |
113 num2str(numel(sys(i_sys).states)),' states, ',... | |
114 num2str(numel(statesizes)),' sssizes'] ); | |
115 end | |
116 | |
117 % checking compatibility with Noutputs | |
118 if ~( numel(sys(i_sys).outputs)==size(sys(i_sys).cmats,1) ... | |
119 && numel(sys(i_sys).outputs)==size(sys(i_sys).dmats,1) ... | |
120 && numel(sys(i_sys).outputs)==numel(outputsizes) ) | |
121 error(['error in ssm ',sys(i_sys).name,' because there are ',... | |
122 num2str(size(sys(i_sys).cmats,1)),' lines in C, ',... | |
123 num2str(size(sys(i_sys).dmats,1)),' lines in D, ',... | |
124 num2str(numel(sys(i_sys).outputs)),' outputs, ',... | |
125 num2str(numel(outputsizes)),' outputsizes'] ); | |
126 end | |
127 | |
128 % Checking compatibility with Inputsizes | |
129 for i=1:numel(sys(i_sys).inputs) % check between *inputsizes* and *inputs* plist | |
130 if ~( inputsizes(i) == numel(sys(i_sys).inputs(i).ports) ) | |
131 error(['error in ssm ', sys(i_sys).name, ... | |
132 ' because the input number ', num2str(i),... | |
133 ' named ', sys(i_sys).inputs(i).name, ... | |
134 ' and of size ', num2str(inputsizes(i)), ... | |
135 ' has a port of length ', num2str(numel(sys(i_sys).inputs(i).ports)) ]); | |
136 end | |
137 if inputsizes(i) == 0 % send a warning in case an input is empty | |
138 if ~callerIsMethod | |
139 str=['warning, input named ',sys(i_sys).inputs(i).name,... | |
140 ' has all matrices empty, should be deleted'] ; | |
141 utils.helper.msg(utils.const.msg.MNAME,str); | |
142 end | |
143 end | |
144 for j=1:numel(sys(i_sys).outputs) % check between *inputsizes* and D matrix content | |
145 if ~isequal(sys(i_sys).dmats{j,i}, []) | |
146 if ~( inputsizes(i) == size(sys(i_sys).dmats{j,i},2) ) | |
147 error(['error in ssm ', sys(i_sys).name, ... | |
148 ' because the input number ', num2str(i),... | |
149 ' named ', sys(i_sys).inputs(i).name, ... | |
150 ' and of size ', num2str(inputsizes(i)), ... | |
151 ' has a D matrix of width ', num2str(size(sys(i_sys).dmats{j,i},2)) ]); | |
152 end | |
153 end | |
154 end | |
155 for j=1:numel(sys(i_sys).states) % check between *inputsizes* and B matrix content | |
156 if ~isequal(sys(i_sys).bmats{j,i}, []) | |
157 if ~( inputsizes(i) == size(sys(i_sys).bmats{j,i},2) ) | |
158 error(['error in ssm ', sys(i_sys).name, ... | |
159 ' because the input number ', num2str(i),... | |
160 ' named ', sys(i_sys).inputs(i).name, ... | |
161 ' and of size ', num2str(inputsizes(i)), ... | |
162 ' has a B matrix of width ', num2str(size(sys(i_sys).bmats{j,i},2)) ]); | |
163 end | |
164 end | |
165 end | |
166 end | |
167 | |
168 % Checking compatibility with Outputsizes | |
169 for i=1:numel(sys(i_sys).outputs) % check between *outputsizes* and *outputs* plist | |
170 if ~( outputsizes(i) == numel(sys(i_sys).outputs(i).ports) ) | |
171 error(['error in ssm ', sys(i_sys).name, ... | |
172 ' because the output number ', num2str(i),... | |
173 ' named ', sys(i_sys).outputs(i).name, ... | |
174 ' and of size ', num2str(outputsizes(i)), ... | |
175 ' has a port of length ', num2str(numel(sys(i_sys).outputs(i).ports)) ]); | |
176 end | |
177 if outputsizes(i) == 0 % send a warning in case an output is empty | |
178 if ~callerIsMethod | |
179 str=['warning, output named ',sys(i_sys).outputs(i).name,... | |
180 ' has all matrices empty, should be deleted'] ; | |
181 utils.helper.msg(utils.const.msg.MNAME,str); | |
182 end | |
183 end | |
184 for j=1:numel(sys(i_sys).inputs) % check between *outputsizes* and D matrix content | |
185 if ~isequal(sys(i_sys).dmats{i,j}, []) | |
186 if ~( outputsizes(i) == size(sys(i_sys).dmats{i,j},1) ) | |
187 error(['error in ssm ', sys(i_sys).name, ... | |
188 ' because the output number ', num2str(i),... | |
189 ' named ', sys(i_sys).outputs(i).name, ... | |
190 ' and of size ', num2str(outputsizes(i)), ... | |
191 ' has a D matrix of height ', num2str(size(sys(i_sys).dmats{i,j},1)) ]); | |
192 end | |
193 end | |
194 end | |
195 for j=1:numel(sys(i_sys).states) % check between *outputsizes* and C matrix content | |
196 if ~isequal(sys(i_sys).cmats{i,j}, []) | |
197 if ~( outputsizes(i) == size(sys(i_sys).cmats{i,j},1) ) | |
198 error(['error in ssm ', sys(i_sys).name, ... | |
199 ' because the output number ', num2str(i),... | |
200 ' named ', sys(i_sys).outputs(i).name, ... | |
201 ' and of size ', num2str(outputsizes(i)), ... | |
202 ' has a C matrix of height ', num2str(size(sys(i_sys).cmats{i,j},1)) ]); | |
203 end | |
204 end | |
205 end | |
206 end | |
207 | |
208 % Checking compatibility with sssizes | |
209 for i=1:numel(sys(i_sys).states) % check between *statesizes* and *states* plist | |
210 if ~( statesizes(i) == numel(sys(i_sys).states(i).ports) ) | |
211 error(['error in ssm ', sys(i_sys).name, ... | |
212 ' because the state number ', num2str(i),... | |
213 ' named ', sys(i_sys).states(i).name, ... | |
214 ' and of size ', num2str(statesizes(i)), ... | |
215 ' has a port of length ', num2str(numel(sys(i_sys).states(i).ports)) ]); | |
216 end | |
217 if statesizes(i) == 0 % send a warning in case an state is empty | |
218 if ~callerIsMethod | |
219 str=['warning, state named ',sys(i_sys).states(i).name,... | |
220 ' has all matrices empty, should be deleted'] ; | |
221 utils.helper.msg(utils.const.msg.MNAME,str); | |
222 end | |
223 end | |
224 for j=1:numel(sys(i_sys).inputs) % check between *sssizes* and B matrix content | |
225 if ~isequal(sys(i_sys).bmats{i,j}, []) | |
226 if ~( statesizes(i) == size(sys(i_sys).bmats{i,j},1) ) | |
227 error(['error in ssm ', sys(i_sys).name, ... | |
228 ' because the state space number ', num2str(i),... | |
229 ' named ', sys(i_sys).states(i).name, ... | |
230 ' and of size ', num2str(statesizes(i)), ... | |
231 ' has a B matrix of height ', num2str(size(sys(i_sys).bmats{i,j},1)) ]); | |
232 end | |
233 end | |
234 end | |
235 for j=1:numel(sys(i_sys).states) % check between *sssizes* and A matrix content | |
236 if ~isequal(sys(i_sys).amats{i,j}, []) | |
237 if ~( statesizes(i) == size(sys(i_sys).amats{i,j},1) ... | |
238 && statesizes(j) == size(sys(i_sys).amats{i,j},2) ) | |
239 error(['error in ssm ', sys(i_sys).name, ... | |
240 ' because the state space position (', num2str(i), ',' , num2str(j),... | |
241 ') named ', sys(i_sys).states(i).name, ' and ', sys(i_sys).states(i).name, ... | |
242 ' and of size ', num2str([statesizes(i),statesizes(j)] ), ... | |
243 ' has a A matrix of size ', num2str(size(sys(i_sys).amats{i,j})) ]); | |
244 end | |
245 end | |
246 end | |
247 for j=1:numel(sys(i_sys).outputs) % check between *sssizes* and C matrix content | |
248 if ~isequal(sys(i_sys).cmats{j,i}, []) | |
249 if ~( statesizes(i) == size(sys(i_sys).cmats{j,i},2) ) | |
250 error(['error in ssm ', sys(i_sys).name, ... | |
251 ' because the state space number ', num2str(i),... | |
252 ' named ', sys(i_sys).states(i).name, ... | |
253 ' and of size ', num2str(statesizes(i)), ... | |
254 ' has a C matrix of width ', num2str(size(sys(i_sys).cmats{j,i},2)) ]); | |
255 end | |
256 end | |
257 end | |
258 | |
259 | |
260 | |
261 %% =========== checking redundancies =========== | |
262 % ADD CHECK FOR VARIABLE NAME REDUNDANCIES | |
263 | |
264 % Not necessary anymore for model parameters !!! | |
265 | |
266 %% =========== checking field types =========== | |
267 | |
268 Fields = {... | |
269 'amats' 'bmats' 'cmats' 'dmats' 'isnumerical' 'timestep'... | |
270 'inputs' ... | |
271 'states' ... | |
272 'outputs' ... | |
273 'params' 'numparams' }; | |
274 Classes = {... | |
275 'cellDoubleSym' 'cellDoubleSym' 'cellDoubleSym' 'cellDoubleSym' 'logical' 'double'... | |
276 'ssmblock' ... | |
277 'ssmblock' ... | |
278 'ssmblock' ... | |
279 'plist' 'plist'... | |
280 }; | |
281 | |
282 for f = [Fields ; Classes] | |
283 fieldcontent = sys(i_sys).(f{1}); | |
284 if strcmpi(f{2},'double') | |
285 if ~( isa(fieldcontent,'double') ) | |
286 error(['error because in ssm ',sys(i_sys).name,... | |
287 ' because field ', f{1},... | |
288 ' is of type ',class(fieldcontent), ' instead of ''double'' ']); | |
289 end | |
290 elseif strcmpi(f{2},'cellDoubleSym') % case where both double and symbolic classes are allowed inside a cell array | |
291 for i_input = 1:numel(fieldcontent) | |
292 if ~( isa(fieldcontent{i_input},'double') || isa(fieldcontent{i_input},'sym') ) | |
293 error(['error because in ssm ',sys(i_sys).name,' because element ',num2str(i_input),... | |
294 ' of field ', f{1},' is of type ',class(fieldcontent),... | |
295 ' instead of ''double'' or ''sym'' ']); | |
296 end | |
297 end | |
298 elseif strcmpi(f{2},'ssmblock') | |
299 if ~( isa(fieldcontent,'ssmblock') ) | |
300 % if the field is not a plist | |
301 error(['error because in ssm ',sys(i_sys).name,... | |
302 ' because field ', f{1},... | |
303 ' is of type ',class(fieldcontent), ' instead of ''ssmblock'' ']); | |
304 end | |
305 elseif strcmpi(f{2},'plist') | |
306 if ~( isa(fieldcontent,'plist') ) | |
307 % if the field is not a plist | |
308 error(['error because in ssm ',sys(i_sys).name,... | |
309 ' because field ', f{1},... | |
310 ' is of type ',class(fieldcontent), ' instead of ''plist'' ']); | |
311 end | |
312 elseif strcmpi(f{2},'logical') | |
313 if ~( isa(fieldcontent,'logical') ) | |
314 error(['error because in ssm ',sys(i_sys).name,... | |
315 ' because field ', f{1},... | |
316 ' is of type ',class(fieldcontent), ' instead of ''logical'' ']); | |
317 end | |
318 else | |
319 if ~isa(fieldcontent,f{2}) | |
320 error(['error because in ssm ',sys(i_sys).name,' because field ',... | |
321 f{1},' is of type ',class(fieldcontent),' instead of ', f{2}]); | |
322 end | |
323 end | |
324 end | |
325 end | |
326 if nargout > 0 | |
327 varargout = {sys}; | |
328 end | |
329 end |