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