]> Creatis software - CreaPhase.git/blob - octave_packages/odepkg-0.8.2/odepkg_structure_check.m
Add a useful package (from Source forge) for octave
[CreaPhase.git] / octave_packages / odepkg-0.8.2 / odepkg_structure_check.m
1 %# Copyright (C) 2006-2012, Thomas Treichl <treichl@users.sourceforge.net>
2 %# OdePkg - A package for solving ordinary differential equations and more
3 %#
4 %# This program is free software; you can redistribute it and/or modify
5 %# it under the terms of the GNU General Public License as published by
6 %# the Free Software Foundation; either version 2 of the License, or
7 %# (at your option) any later version.
8 %#
9 %# This program is distributed in the hope that it will be useful,
10 %# but WITHOUT ANY WARRANTY; without even the implied warranty of
11 %# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 %# GNU General Public License for more details.
13 %#
14 %# You should have received a copy of the GNU General Public License
15 %# along with this program; If not, see <http://www.gnu.org/licenses/>.
16
17 %# -*- texinfo -*-
18 %# @deftypefn {Function File} {[@var{newstruct}] =} odepkg_structure_check (@var{oldstruct}, [@var{"solver"}])
19 %#
20 %# If this function is called with one input argument of type structure array then check the field names and the field values of the OdePkg structure @var{oldstruct} and return the structure as @var{newstruct} if no error is found. Optionally if this function is called with a second input argument @var{"solver"} of type string taht specifies the name of a valid OdePkg solver then a higher level error detection is performed. The function does not modify any of the field names or field values but terminates with an error if an invalid option or value is found.
21 %#
22 %# This function is an OdePkg internal helper function therefore it should never be necessary that this function is called directly by a user. There is only little error detection implemented in this function file to achieve the highest performance.
23 %#
24 %# Run examples with the command
25 %# @example
26 %# demo odepkg_structure_check
27 %# @end example
28 %# @end deftypefn
29 %#
30 %# @seealso{odepkg}
31
32 function [vret] = odepkg_structure_check (varargin)
33
34   %# Check the number of input arguments
35   if (nargin == 0)
36     help ('odepkg_structure_check');
37     error ('OdePkg:InvalidArgument', ...
38       'Number of input arguments must be greater than zero');
39   elseif (nargin > 2)
40     print_usage;
41   elseif (nargin == 1 && isstruct (varargin{1}))
42     vret = varargin{1};
43     vsol = '';
44     vfld = fieldnames (vret);
45     vlen = length (vfld);
46   elseif (nargin == 2 && isstruct (varargin{1}) && ischar (varargin{2}))
47     vret = varargin{1};
48     vsol = varargin{2};
49     vfld = fieldnames (vret);
50     vlen = length (vfld);
51   end
52
53   for vcntarg = 1:vlen %# Run through the number of given structure field names
54
55     switch (vfld{vcntarg})
56
57       case 'RelTol'
58         if (isnumeric (vret.(vfld{vcntarg})) && ...
59             isreal    (vret.(vfld{vcntarg})) && ...
60             all       (vret.(vfld{vcntarg}) > 0)) %# 'all' is a MatLab need
61         else
62           error ('OdePkg:InvalidParameter', ...
63             'Unknown parameter name "%s" or no valid parameter value', ...
64             vfld{vcntarg});
65         end
66
67         switch (vsol)
68           case {'ode23', 'ode45', 'ode54', 'ode78', ...
69                 'ode23d', 'ode45d', 'ode54d', 'ode78d',}
70             if (~isscalar (vret.(vfld{vcntarg})) && ...
71                 ~isempty (vret.(vfld{vcntarg})))
72               error ('OdePkg:InvalidParameter', ...
73                 'Value of option "RelTol" must be a scalar');
74             end
75           otherwise
76
77           end
78
79       case 'AbsTol'
80         if (isnumeric (vret.(vfld{vcntarg})) && ...
81             isreal    (vret.(vfld{vcntarg})) && ...
82             all       (vret.(vfld{vcntarg}) > 0))
83         else
84           error ('OdePkg:InvalidParameter', ...
85             'Unknown parameter name "%s" or no valid parameter value', ...
86             vfld{vcntarg});
87         end
88
89       case 'NormControl'
90         if (strcmp (vret.(vfld{vcntarg}), 'on') || ...
91             strcmp (vret.(vfld{vcntarg}), 'off'))
92         else
93           error ('OdePkg:InvalidParameter', ...
94             'Unknown parameter name "%s" or no valid parameter value', ...
95             vfld{vcntarg});
96         end
97
98       case 'NonNegative'
99         if (isempty  (vret.(vfld{vcntarg})) || ...
100             (isnumeric (vret.(vfld{vcntarg})) && isvector (vret.(vfld{vcntarg}))))
101         else
102           error ('OdePkg:InvalidParameter', ...
103             'Unknown parameter name "%s" or no valid parameter value', ...
104             vfld{vcntarg});
105         end
106
107       case 'OutputFcn'
108         if (isempty (vret.(vfld{vcntarg})) || ...
109             isa     (vret.(vfld{vcntarg}), 'function_handle'))
110         else
111           error ('OdePkg:InvalidParameter', ...
112             'Unknown parameter name "%s" or no valid parameter value', ...
113             vfld{vcntarg});
114         end
115
116       case 'OutputSel'
117         if (isempty  (vret.(vfld{vcntarg})) || ...
118             (isnumeric (vret.(vfld{vcntarg})) && isvector (vret.(vfld{vcntarg}))) || ...
119             isscalar (vret.(vfld{vcntarg})))
120         else
121           error ('OdePkg:InvalidParameter', ...
122             'Unknown parameter name "%s" or no valid parameter value', ...
123             vfld{vcntarg});
124         end
125
126       case 'OutputSave'
127         if (isempty (vret.(vfld{vcntarg})) || ...
128             (isscalar (vret.(vfld{vcntarg})) && ...
129              mod (vret.(vfld{vcntarg}), 1) == 0 && ...
130              vret.(vfld{vcntarg}) > 0) || ...
131             vret.(vfld{vcntarg}) == Inf)
132         else
133           error ('OdePkg:InvalidParameter', ...
134             'Unknown parameter name "%s" or no valid parameter value', ...
135             vfld{vcntarg});
136         end
137         
138       case 'Refine'
139         if (isscalar (vret.(vfld{vcntarg})) && ...
140             mod (vret.(vfld{vcntarg}), 1) == 0 && ...
141             vret.(vfld{vcntarg}) >= 0 && ...
142             vret.(vfld{vcntarg}) <= 5)
143         else
144           error ('OdePkg:InvalidParameter', ...
145             'Unknown parameter name "%s" or no valid parameter value', ...
146             vfld{vcntarg});
147         end
148
149       case 'Stats'
150         if (strcmp (vret.(vfld{vcntarg}), 'on') || ...
151             strcmp (vret.(vfld{vcntarg}), 'off'))
152         else
153           error ('OdePkg:InvalidParameter', ...
154             'Unknown parameter name "%s" or no valid parameter value', ...
155             vfld{vcntarg});
156         end
157
158       case 'InitialStep'
159         if (isempty (vret.(vfld{vcntarg})) || ...
160             (isscalar (vret.(vfld{vcntarg})) && ...
161              isreal (vret.(vfld{vcntarg}))))
162         else
163           error ('OdePkg:InvalidParameter', ...
164             'Unknown parameter name "%s" or no valid parameter value', ...
165             vfld{vcntarg});
166         end
167
168       case 'MaxStep'
169         if (isempty (vret.(vfld{vcntarg})) || ...
170             (isscalar (vret.(vfld{vcntarg})) && ...
171              vret.(vfld{vcntarg}) > 0) )
172         else
173           error ('OdePkg:InvalidParameter', ...
174             'Unknown parameter name "%s" or no valid parameter value', ...
175             vfld{vcntarg});
176         end
177
178       case 'Events'
179         if (isempty (vret.(vfld{vcntarg})) || ...
180             isa     (vret.(vfld{vcntarg}), 'function_handle'))
181         else
182           error ('OdePkg:InvalidParameter', ...
183             'Unknown parameter name "%s" or no valid parameter value', ...
184             vfld{vcntarg});
185         end
186
187       case 'Jacobian'
188         if (isempty (vret.(vfld{vcntarg})) || ...
189             isnumeric (vret.(vfld{vcntarg})) || ...
190             isa (vret.(vfld{vcntarg}), 'function_handle') || ...
191             iscell (vret.(vfld{vcntarg})))
192         else
193           error ('OdePkg:InvalidParameter', ...
194                  'Unknown parameter name "%s" or no valid parameter value', ...
195                  vfld{vcntarg});
196         end
197
198       case 'JPattern'
199         if (isempty (vret.(vfld{vcntarg})) || ...
200             isvector (vret.(vfld{vcntarg})) || ...
201             isnumeric (vret.(vfld{vcntarg})))
202         else
203           error ('OdePkg:InvalidParameter', ...
204             'Unknown parameter name "%s" or no valid parameter value', ...
205             vfld{vcntarg});
206         end
207
208       case 'Vectorized'
209         if (strcmp (vret.(vfld{vcntarg}), 'on') || ...
210             strcmp (vret.(vfld{vcntarg}), 'off'))
211         else
212           error ('OdePkg:InvalidParameter', ...
213             'Unknown parameter name "%s" or no valid parameter value', ...
214             vfld{vcntarg});
215         end
216
217       case 'Mass'
218         if (isempty (vret.(vfld{vcntarg})) || ...
219             isnumeric (vret.(vfld{vcntarg})) || ...
220             isa (vret.(vfld{vcntarg}), 'function_handle'))
221         else
222           error ('OdePkg:InvalidParameter', ...
223             'Unknown parameter name "%s" or no valid parameter value', ...
224             vfld{vcntarg});
225         end
226
227       case 'MStateDependence'
228         if (strcmp (vret.(vfld{vcntarg}), 'none') || ...
229             strcmp (vret.(vfld{vcntarg}), 'weak') || ...
230             strcmp (vret.(vfld{vcntarg}), 'strong'))
231         else
232           error ('OdePkg:InvalidParameter', ...
233             'Unknown parameter name "%s" or no valid parameter value', ...
234             vfld{vcntarg});
235         end
236
237       case 'MvPattern'
238         if (isempty (vret.(vfld{vcntarg})) || ...
239             isvector (vret.(vfld{vcntarg})) || ...
240             isnumeric (vret.(vfld{vcntarg})))
241         else
242           error ('OdePkg:InvalidParameter', ...
243             'Unknown parameter name "%s" or no valid parameter value', ...
244             vfld{vcntarg});
245         end
246
247       case 'MassSingular'
248         if (strcmp (vret.(vfld{vcntarg}), 'yes') || ...
249             strcmp (vret.(vfld{vcntarg}), 'no') || ...
250             strcmp (vret.(vfld{vcntarg}), 'maybe'))
251         else
252           error ('OdePkg:InvalidParameter', ...
253             'Unknown parameter name "%s" or no valid parameter value', ...
254             vfld{vcntarg});
255         end
256
257       case 'InitialSlope'
258         if (isempty (vret.(vfld{vcntarg})) || ...
259             isvector (vret.(vfld{vcntarg})))
260         else
261           error ('OdePkg:InvalidParameter', ...
262             'Unknown parameter name "%s" or no valid parameter value', ...
263             vfld{vcntarg});
264         end
265
266       case 'MaxOrder'
267         if (isempty (vret.(vfld{vcntarg})) || ...
268             (mod (vret.(vfld{vcntarg}), 1) == 0 && ...
269              vret.(vfld{vcntarg}) > 0 && ...
270              vret.(vfld{vcntarg}) < 8))
271         else
272           error ('OdePkg:InvalidParameter', ...
273             'Unknown parameter name "%s" or no valid parameter value', ...
274             vfld{vcntarg});
275         end
276
277       case 'BDF'
278         if (isempty (vret.(vfld{vcntarg})) || ...
279             (strcmp (vret.(vfld{vcntarg}), 'on') || ...
280              strcmp (vret.(vfld{vcntarg}), 'off')))
281         else
282           error ('OdePkg:InvalidParameter', ...
283             'Unknown parameter name "%s" or no valid parameter value', ...
284             vfld{vcntarg});
285         end
286
287       case 'NewtonTol'
288         if (isnumeric (vret.(vfld{vcntarg})) && ...
289             isreal    (vret.(vfld{vcntarg})) && ...
290             all       (vret.(vfld{vcntarg}) > 0)) %# 'all' is a MatLab need
291         else
292           error ('OdePkg:InvalidParameter', ...
293             'Unknown parameter name "%s" or no valid parameter value', ...
294             vfld{vcntarg});
295         end
296
297       case 'MaxNewtonIterations'
298         if (isempty (vret.(vfld{vcntarg})) || ...
299             (mod (vret.(vfld{vcntarg}), 1) == 0 && ...
300              vret.(vfld{vcntarg}) > 0))
301         else
302           error ('OdePkg:InvalidParameter', ...
303             'Unknown parameter name "%s" or no valid parameter value', ...
304             vfld{vcntarg});
305         end
306
307       otherwise
308           error ('OdePkg:InvalidParameter', ...
309             'Unknown parameter name "%s"', ...
310             vfld{vcntarg});
311
312     end %# switch
313
314   end %# for
315
316 %# The following line can be uncommented for a even higher level error
317 %# detection
318 %# if (vlen ~= 21)
319 %#   vmsg = sprintf ('Number of fields in structure must match 21');
320 %#   error (vmsg);
321 %# end
322
323 %!test  A = odeset ('RelTol', 1e-4);
324 %!test  A = odeset ('RelTol', [1e-4, 1e-3]);
325 %!test  A = odeset ('RelTol', []);
326 %!error A = odeset ('RelTol', '1e-4');
327 %!test  A = odeset ('AbsTol', 1e-4);
328 %!test  A = odeset ('AbsTol', [1e-4, 1e-3]);
329 %!test  A = odeset ('AbsTol', []);
330 %!error A = odeset ('AbsTol', '1e-4');
331 %!test  A = odeset ('NormControl', 'on');
332 %!test  A = odeset ('NormControl', 'off');
333 %!error A = odeset ('NormControl', []);
334 %!error A = odeset ('NormControl', '12');
335 %!test  A = odeset ('NonNegative', 1);
336 %!test  A = odeset ('NonNegative', [1, 2, 3]);
337 %!test  A = odeset ('NonNegative', []);
338 %!error A = odeset ('NonNegative', '12');
339 %!test  A = odeset ('OutputFcn', @odeprint);
340 %!test  A = odeset ('OutputFcn', @odeplot);
341 %!test  A = odeset ('OutputFcn', []);
342 %!error A = odeset ('OutputFcn', 'odeprint');
343 %!test  A = odeset ('OutputSel', 1);
344 %!test  A = odeset ('OutputSel', [1, 2, 3]);
345 %!test  A = odeset ('OutputSel', []);
346 %!error A = odeset ('OutputSel', '12');
347 %!test  A = odeset ('Refine', 3);
348 %!error A = odeset ('Refine', [1, 2, 3]);
349 %!error A = odeset ('Refine', []);
350 %!error A = odeset ('Refine', 6);
351 %!test  A = odeset ('Stats', 'on');
352 %!test  A = odeset ('Stats', 'off');
353 %!error A = odeset ('Stats', []);
354 %!error A = odeset ('Stats', '12');
355 %!test  A = odeset ('InitialStep', 3);
356 %!error A = odeset ('InitialStep', [1, 2, 3]);
357 %!test  A = odeset ('InitialStep', []);
358 %!test  A = odeset ('InitialStep', 6);
359 %!test  A = odeset ('MaxStep', 3);
360 %!error A = odeset ('MaxStep', [1, 2, 3]);
361 %!test  A = odeset ('MaxStep', []);
362 %!test  A = odeset ('MaxStep', 6);
363 %!test  A = odeset ('Events', @demo);
364 %!error A = odeset ('Events', 'off');
365 %!test  A = odeset ('Events', []);
366 %!error A = odeset ('Events', '12');
367 %!test  A = odeset ('Jacobian', @demo);
368 %!test  A = odeset ('Jacobian', [1, 2; 3, 4]);
369 %!test  A = odeset ('Jacobian', []);
370 %!error A = odeset ('Jacobian', '12');
371 %!test  A = odeset ('JPattern', []);
372 %!test  A = odeset ('JPattern', [1, 2, 4]);
373 %!test  A = odeset ('JPattern', [1, 2; 3, 4]);
374 %!test  A = odeset ('JPattern', 1);
375 %!test  A = odeset ('Vectorized', 'on');
376 %!test  A = odeset ('Vectorized', 'off');
377 %!error A = odeset ('Vectorized', []);
378 %!error A = odeset ('Vectorized', '12');
379 %!test  A = odeset ('Mass', @demo);
380 %!test  A = odeset ('Mass', [1, 2; 3, 4]);
381 %!test  A = odeset ('Mass', []);
382 %!error A = odeset ('Mass', '12');
383 %!test  A = odeset ('MStateDependence', 'none');
384 %!test  A = odeset ('MStateDependence', 'weak');
385 %!test  A = odeset ('MStateDependence', 'strong');
386 %!error A = odeset ('MStateDependence', [1, 2; 3, 4]);
387 %!error A = odeset ('MStateDependence', []);
388 %!error A = odeset ('MStateDependence', '12');
389 %!test  A = odeset ('MvPattern', []);
390 %!test  A = odeset ('MvPattern', [1, 2, 3 ]);
391 %!test  A = odeset ('MvPattern', [1, 2; 3, 4]);
392 %!test  A = odeset ('MvPattern', 1);
393 %!test  A = odeset ('MassSingular', 'yes');
394 %!test  A = odeset ('MassSingular', 'no');
395 %!test  A = odeset ('MassSingular', 'maybe');
396 %!error A = odeset ('MassSingular', [1, 2; 3, 4]);
397 %!error A = odeset ('MassSingular', []);
398 %!error A = odeset ('MassSingular', '12');
399 %!test  A = odeset ('InitialSlope', [1, 2, 3]);
400 %!test  A = odeset ('InitialSlope', 1);
401 %!test  A = odeset ('InitialSlope', []);
402 %!test  A = odeset ('InitialSlope', '12');
403 %!test  A = odeset ('MaxOrder', 3);
404 %!error A = odeset ('MaxOrder', 3.5);
405 %!test  A = odeset ('MaxOrder', [1, 2; 3, 4]);
406 %!test  A = odeset ('MaxOrder', []);
407 %!test  A = odeset ('BDF', 'on');
408 %!test  A = odeset ('BDF', 'off');
409 %!test  A = odeset ('BDF', []);
410 %!error A = odeset ('BDF', [1, 2; 3, 4]);
411 %!test  A = odeset ('NewtonTol', []);
412 %!test  A = odeset ('NewtonTol', 1e-3);
413 %!test  A = odeset ('NewtonTol', [1e-3, 1e-3, 1e-3]);
414 %!error A = odeset ('NewtonTol', 'string');
415 %!test  A = odeset ('MaxNewtonIterations', []);
416 %!test  A = odeset ('MaxNewtonIterations', 2);
417 %!error A = odeset ('MaxNewtonIterations', 'string');
418
419 %!demo
420 %! # Return the checked OdePkg options structure that is created by
421 %! # the command odeset.
422 %!
423 %! odepkg_structure_check (odeset);
424 %!
425 %!demo
426 %! # Create the OdePkg options structure A with odeset and check it 
427 %! # with odepkg_structure_check. This actually is unnecessary
428 %! # because odeset automtically calls odepkg_structure_check before
429 %! # returning.
430 %!
431 %! A = odeset (); odepkg_structure_check (A);
432
433 %# Local Variables: ***
434 %# mode: octave ***
435 %# End: ***