1 %# Copyright (C) 2006-2012, Thomas Treichl <treichl@users.sourceforge.net>
2 %# OdePkg - A package for solving ordinary differential equations and more
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.
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.
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/>.
18 %# @deftypefn {Function File} {[@var{newstruct}] =} odepkg_structure_check (@var{oldstruct}, [@var{"solver"}])
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.
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.
24 %# Run examples with the command
26 %# demo odepkg_structure_check
32 function [vret] = odepkg_structure_check (varargin)
34 %# Check the number of input arguments
36 help ('odepkg_structure_check');
37 error ('OdePkg:InvalidArgument', ...
38 'Number of input arguments must be greater than zero');
41 elseif (nargin == 1 && isstruct (varargin{1}))
44 vfld = fieldnames (vret);
46 elseif (nargin == 2 && isstruct (varargin{1}) && ischar (varargin{2}))
49 vfld = fieldnames (vret);
53 for vcntarg = 1:vlen %# Run through the number of given structure field names
55 switch (vfld{vcntarg})
58 if (isnumeric (vret.(vfld{vcntarg})) && ...
59 isreal (vret.(vfld{vcntarg})) && ...
60 all (vret.(vfld{vcntarg}) > 0)) %# 'all' is a MatLab need
62 error ('OdePkg:InvalidParameter', ...
63 'Unknown parameter name "%s" or no valid parameter value', ...
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');
80 if (isnumeric (vret.(vfld{vcntarg})) && ...
81 isreal (vret.(vfld{vcntarg})) && ...
82 all (vret.(vfld{vcntarg}) > 0))
84 error ('OdePkg:InvalidParameter', ...
85 'Unknown parameter name "%s" or no valid parameter value', ...
90 if (strcmp (vret.(vfld{vcntarg}), 'on') || ...
91 strcmp (vret.(vfld{vcntarg}), 'off'))
93 error ('OdePkg:InvalidParameter', ...
94 'Unknown parameter name "%s" or no valid parameter value', ...
99 if (isempty (vret.(vfld{vcntarg})) || ...
100 (isnumeric (vret.(vfld{vcntarg})) && isvector (vret.(vfld{vcntarg}))))
102 error ('OdePkg:InvalidParameter', ...
103 'Unknown parameter name "%s" or no valid parameter value', ...
108 if (isempty (vret.(vfld{vcntarg})) || ...
109 isa (vret.(vfld{vcntarg}), 'function_handle'))
111 error ('OdePkg:InvalidParameter', ...
112 'Unknown parameter name "%s" or no valid parameter value', ...
117 if (isempty (vret.(vfld{vcntarg})) || ...
118 (isnumeric (vret.(vfld{vcntarg})) && isvector (vret.(vfld{vcntarg}))) || ...
119 isscalar (vret.(vfld{vcntarg})))
121 error ('OdePkg:InvalidParameter', ...
122 'Unknown parameter name "%s" or no valid parameter value', ...
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)
133 error ('OdePkg:InvalidParameter', ...
134 'Unknown parameter name "%s" or no valid parameter value', ...
139 if (isscalar (vret.(vfld{vcntarg})) && ...
140 mod (vret.(vfld{vcntarg}), 1) == 0 && ...
141 vret.(vfld{vcntarg}) >= 0 && ...
142 vret.(vfld{vcntarg}) <= 5)
144 error ('OdePkg:InvalidParameter', ...
145 'Unknown parameter name "%s" or no valid parameter value', ...
150 if (strcmp (vret.(vfld{vcntarg}), 'on') || ...
151 strcmp (vret.(vfld{vcntarg}), 'off'))
153 error ('OdePkg:InvalidParameter', ...
154 'Unknown parameter name "%s" or no valid parameter value', ...
159 if (isempty (vret.(vfld{vcntarg})) || ...
160 (isscalar (vret.(vfld{vcntarg})) && ...
161 isreal (vret.(vfld{vcntarg}))))
163 error ('OdePkg:InvalidParameter', ...
164 'Unknown parameter name "%s" or no valid parameter value', ...
169 if (isempty (vret.(vfld{vcntarg})) || ...
170 (isscalar (vret.(vfld{vcntarg})) && ...
171 vret.(vfld{vcntarg}) > 0) )
173 error ('OdePkg:InvalidParameter', ...
174 'Unknown parameter name "%s" or no valid parameter value', ...
179 if (isempty (vret.(vfld{vcntarg})) || ...
180 isa (vret.(vfld{vcntarg}), 'function_handle'))
182 error ('OdePkg:InvalidParameter', ...
183 'Unknown parameter name "%s" or no valid parameter value', ...
188 if (isempty (vret.(vfld{vcntarg})) || ...
189 isnumeric (vret.(vfld{vcntarg})) || ...
190 isa (vret.(vfld{vcntarg}), 'function_handle') || ...
191 iscell (vret.(vfld{vcntarg})))
193 error ('OdePkg:InvalidParameter', ...
194 'Unknown parameter name "%s" or no valid parameter value', ...
199 if (isempty (vret.(vfld{vcntarg})) || ...
200 isvector (vret.(vfld{vcntarg})) || ...
201 isnumeric (vret.(vfld{vcntarg})))
203 error ('OdePkg:InvalidParameter', ...
204 'Unknown parameter name "%s" or no valid parameter value', ...
209 if (strcmp (vret.(vfld{vcntarg}), 'on') || ...
210 strcmp (vret.(vfld{vcntarg}), 'off'))
212 error ('OdePkg:InvalidParameter', ...
213 'Unknown parameter name "%s" or no valid parameter value', ...
218 if (isempty (vret.(vfld{vcntarg})) || ...
219 isnumeric (vret.(vfld{vcntarg})) || ...
220 isa (vret.(vfld{vcntarg}), 'function_handle'))
222 error ('OdePkg:InvalidParameter', ...
223 'Unknown parameter name "%s" or no valid parameter value', ...
227 case 'MStateDependence'
228 if (strcmp (vret.(vfld{vcntarg}), 'none') || ...
229 strcmp (vret.(vfld{vcntarg}), 'weak') || ...
230 strcmp (vret.(vfld{vcntarg}), 'strong'))
232 error ('OdePkg:InvalidParameter', ...
233 'Unknown parameter name "%s" or no valid parameter value', ...
238 if (isempty (vret.(vfld{vcntarg})) || ...
239 isvector (vret.(vfld{vcntarg})) || ...
240 isnumeric (vret.(vfld{vcntarg})))
242 error ('OdePkg:InvalidParameter', ...
243 'Unknown parameter name "%s" or no valid parameter value', ...
248 if (strcmp (vret.(vfld{vcntarg}), 'yes') || ...
249 strcmp (vret.(vfld{vcntarg}), 'no') || ...
250 strcmp (vret.(vfld{vcntarg}), 'maybe'))
252 error ('OdePkg:InvalidParameter', ...
253 'Unknown parameter name "%s" or no valid parameter value', ...
258 if (isempty (vret.(vfld{vcntarg})) || ...
259 isvector (vret.(vfld{vcntarg})))
261 error ('OdePkg:InvalidParameter', ...
262 'Unknown parameter name "%s" or no valid parameter value', ...
267 if (isempty (vret.(vfld{vcntarg})) || ...
268 (mod (vret.(vfld{vcntarg}), 1) == 0 && ...
269 vret.(vfld{vcntarg}) > 0 && ...
270 vret.(vfld{vcntarg}) < 8))
272 error ('OdePkg:InvalidParameter', ...
273 'Unknown parameter name "%s" or no valid parameter value', ...
278 if (isempty (vret.(vfld{vcntarg})) || ...
279 (strcmp (vret.(vfld{vcntarg}), 'on') || ...
280 strcmp (vret.(vfld{vcntarg}), 'off')))
282 error ('OdePkg:InvalidParameter', ...
283 'Unknown parameter name "%s" or no valid parameter value', ...
288 if (isnumeric (vret.(vfld{vcntarg})) && ...
289 isreal (vret.(vfld{vcntarg})) && ...
290 all (vret.(vfld{vcntarg}) > 0)) %# 'all' is a MatLab need
292 error ('OdePkg:InvalidParameter', ...
293 'Unknown parameter name "%s" or no valid parameter value', ...
297 case 'MaxNewtonIterations'
298 if (isempty (vret.(vfld{vcntarg})) || ...
299 (mod (vret.(vfld{vcntarg}), 1) == 0 && ...
300 vret.(vfld{vcntarg}) > 0))
302 error ('OdePkg:InvalidParameter', ...
303 'Unknown parameter name "%s" or no valid parameter value', ...
308 error ('OdePkg:InvalidParameter', ...
309 'Unknown parameter name "%s"', ...
316 %# The following line can be uncommented for a even higher level error
319 %# vmsg = sprintf ('Number of fields in structure must match 21');
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');
420 %! # Return the checked OdePkg options structure that is created by
421 %! # the command odeset.
423 %! odepkg_structure_check (odeset);
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
431 %! A = odeset (); odepkg_structure_check (A);
433 %# Local Variables: ***