Mercurial > octave-nkf
view scripts/ode/odeset.m @ 20581:e368ce72a844
maint: Use Octave coding conventions for ode* functions.
Use '!' instead of '~' for logical not.
Use '##' only for comments which standalone on a line.
Use double quotes instead of single quotes where possible.
Wrap long lines to < 80 characters.
* ode45.m, odeget.m, odeset.m: Use Octave coding conventions.
author | Rik <rik@octave.org> |
---|---|
date | Sat, 03 Oct 2015 22:10:45 -0700 |
parents | 25623ef2ff4f |
children | 45151de7423f |
line wrap: on
line source
## Copyright (C) 2013, Roberto Porcu' <roberto.porcu@polimi.it> ## Copyright (C) 2006-2012, Thomas Treichl <treichl@users.sourceforge.net> ## ## This file is part of Octave. ## ## Octave is free software; you can redistribute it and/or modify it ## under the terms of the GNU General Public License as published by ## the Free Software Foundation; either version 3 of the License, or (at ## your option) any later version. ## ## Octave is distributed in the hope that it will be useful, but ## WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ## General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with Octave; see the file COPYING. If not, see ## <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {} odeset () ## @deftypefnx {Function File} {@var{odestruct} =} odeset (@var{"field1"}, @var{value1}, @var{"field2"}, @var{value2}, @dots{}) ## @deftypefnx {Function File} {@var{odestruct} =} odeset (@var{oldstruct}, @var{"field1"}, @var{value1}, @var{"field2"}, @var{value2}, @dots{}) ## @deftypefnx {Function File} {@var{odestruct} =} odeset (@var{oldstruct}, @var{newstruct}) ## ## Create or modify an ODE options structure. ## ## If this function is called without an input argument then return a new ODE ## options structure array that contains all the necessary fields and sets ## the values of all fields to default values. ## ## If this function is called with string input arguments @var{"field1"}, ## @var{"field2"}, @dots{} identifying valid ODE options then return a new ## ODE options structure with all necessary fields and set the values of the ## fields @var{"field1"}, @var{"field2"}, @dots{} to the values @var{value1}, ## @var{value2}, @dots{} ## ## If this function is called with a first input argument @var{oldstruct} of ## type structure array then overwrite all values of the options ## @var{"field1"}, @var{"field2"}, @dots{} of the structure @var{oldstruct} ## with new values @var{value1}, @var{value2}, @dots{} and return the ## modified structure array. ## ## If this function is called with two input arguments @var{oldstruct} and ## @var{newstruct} of type structure array then overwrite all values in the ## fields from the structure @var{oldstruct} with new values of the fields ## from the structure @var{newstruct}. Empty values of @var{newstruct} will ## not overwrite values in @var{oldstruct}. ## @seealso{odeget} ## @end deftypefn function opt = odeset (varargin) ## Check number and types of all input arguments if (nargin == 0 && nargout == 0) print_options; return; endif ## Creating a vector of OdePkg possible fields fields = ["AbsTol"; "Algorithm"; "BDF"; "Choice"; "Eta"; "Events"; "Explicit"; "InexactSolver"; "InitialSlope"; "InitialStep"; "Jacobian";"JConstant";"JPattern";"Mass"; "MassConstant"; "MassSingular"; "MaxNewtonIterations"; "MaxOrder"; "MaxStep"; "MStateDependence"; "MvPattern"; "NewtonTol"; "NonNegative"; "NormControl"; "OutputFcn"; "OutputSave"; "OutputSel"; "PolynomialDegree"; "QuadratureOrder"; "Refine"; "RelTol"; "Restart"; "Stats"; "TimeStepNumber"; "TimeStepSize"; "UseJacobian"; "Vectorized"]; fields_nb = size (fields, 1); ## initialize output opt = []; for i = 1:1:fields_nb opt.(deblank (fields(i,:))) = []; endfor opt.Refine = 0; opt.OutputSave = 1; if (nargin == 0 && nargout == 1) return; endif ode_fields = fieldnames (opt); if (isstruct (varargin{1})) ode_struct_value_check (varargin{1}); optA_fields = fieldnames (varargin{1}); optA_f_nb = length (optA_fields); ## loop on first struct options for updating for i = 1:optA_f_nb name = lower (deblank (optA_fields{i})); while (1) pos = fuzzy_compare (name, fields); if (size (pos, 1) == 0) warning ("OdePkg:InvalidArgument", "no property found with name '%s'", name); endif if (size (pos, 1) == 1) if (! strcmp (lower (deblank (name)), lower (deblank (fields(pos,:))))) warning ("OdePkg:InvalidArgument", "no exact matching for ", "'%s'. Assuming you were intending '%s'", name, deblank (fields(pos,:))); endif opt.(deblank (fields(pos,:))) = varargin{1}.(optA_fields{i}); break endif ## if there are more matching, ask the user to be more precise warning ("OdePkg:InvalidArgument", "no exact matching for '%s'. %d possible fields were found", name, size(pos, 1)); for j = 1:(size (pos, 1)) fprintf ("%s\n", deblank (fields(pos(j),:))); endfor do fprintf ("Please insert field name again\n"); name = input ("New field name: "); until (ischar (name)) endwhile endfor if (nargin == 2 && isstruct (varargin{2})) ode_struct_value_check (varargin{2}); optB_fields = fieldnames (varargin{2}); optB_f_nb = length (optB_fields); ## update the first struct with the values in the second one for i = 1:optB_f_nb name = lower (deblank (optB_fields{i})); while (1) pos = fuzzy_compare (name, fields); if (size (pos, 1) == 0) warning ("OdePkg:InvalidArgument", ... "no property found with name '%s'", name); endif if (size(pos, 1) == 1) if (! strcmp (lower (deblank (name)), ... lower (deblank (fields(pos,:))))) warning ("OdePkg:InvalidArgument", "no exact matching for ", "'%s'. Assuming you were intending '%s'", name, deblank (fields(pos,:))); endif opt.(deblank (fields(pos,:))) = varargin{2}.(optB_fields{i}); break endif ## if there are more matching, ask the user to be more precise warning ("OdePkg:InvalidArgument", "no exact matching for '%s'. ", "%d possible fields were found", name, size (pos, 1)); for j = 1:(size (pos, 1)) fprintf ("%s\n", deblank (fields(pos(j),:))); endfor do fprintf ("Please insert field name again\n"); name = input ("New field name: "); until (ischar (name)) endwhile endfor return; endif ## if the second argument is not a struct, ## pass new values of the OdePkg options to the first struct if (mod (nargin, 2) != 1) error ("OdePkg:InvalidArgument", "odeset expects an odd number of input arguments", " when the first is a ODE_STRUCT"); endif ## loop on the input arguments for i = 2:2:(nargin - 1) if (! ischar(varargin{i})) error ("OdePkg:InvalidArgument", "not all odd input arguments are strings"); endif name = varargin{i}; while (1) pos = fuzzy_compare (name, fields); if (size (pos, 1) == 0) error ("OdePkg:InvalidArgument", "no property found with name '%s'", name); endif if (size (pos, 1) == 1) if (! strcmp (lower (deblank (name)), lower (deblank (fields(pos,:))))) warning ("OdePkg:InvalidArgument", "no exact matching for '%s'. ", "%d possible fields were found", name, size (pos, 1)); endif opt.(deblank (fields(pos,:))) = varargin{i+1}; break endif ## if there are more matching, ask the user to be more precise warning ("OdePkg:InvalidArgument", "no exact matching for '%s'. ", "%d possible fields were found", name, size (pos, 1)); for j = 1:(size (pos, 1)) fprintf ("%s\n", deblank (fields(pos(j),:))); endfor do fprintf ("Please insert field name again\n"); name = input ("New field name: "); until (ischar (name)) endwhile endfor ## check if all has been done gives a valid OdePkg struct ode_struct_value_check (opt); return; endif ## first input argument was not a struct if (mod (nargin, 2) != 0) error ("OdePkg:InvalidArgument", "odeset expects an even number ", "of input arguments when the first is a string"); endif for i = 1:2:(nargin-1) if (! ischar (varargin{i})) error ("OdePkg:InvalidArgument", "not all even input arguments are strings"); endif name = varargin{i}; while (1) pos = fuzzy_compare (name, fields); if (size (pos, 1) == 0) error ("OdePkg:InvalidArgument", "invalid property. No property found with name '%s'", name); endif if (size (pos, 1) == 1) if (! strcmp (lower (deblank (name)), lower (deblank (fields(pos,:))))) warning ("OdePkg:InvalidArgument", "no exact matching for ", "'%s'. Assuming you were intending '%s'", name, deblank (fields(pos,:))); endif opt.(deblank (fields(pos,:))) = varargin{i+1}; break endif ## if there are more matching, ask the user to be more precise warning ("OdePkg:InvalidArgument", "no exact matching for '%s'. ", "%d possible fields were found", name, size (pos, 1)); for j = 1:(size (pos, 1)) fprintf ("%s\n", deblank (fields(pos(j),:))); endfor do fprintf ("Please insert field name again\n"); name = input ("New field name: "); until (ischar (name)) endwhile endfor ## check if all has been done gives a valid OdePkg struct ode_struct_value_check (opt); endfunction ## function useful to print all the possible options function print_options () printf ("These following are all possible options.\n", "Default values are put in square brackets.\n\n"); disp (" AbsTol: scalar or vector, >0, [1.e-6]"); disp (" Algorithm: string, {['gmres'], 'pcg', 'bicgstab'}"); disp (" BDF: binary, {'on', ['off']}"); disp (" Choice: switch, {[1], 2}"); disp (" Eta: scalar, >=0, <1, [0.5]"); disp (" Events: function_handle, []"); disp (" Explicit: binary, {'yes', ['no']}"); disp (" InexactSolver: string, {'inexact_newton', 'fsolve', []}"); disp (" InitialSlope: vector, []"); disp (" InitialStep: scalar, >0, []"); disp (" Jacobian: matrix or function_handle, []"); disp (" JConstant: binary, {'on', ['off']}"); disp (" JPattern: sparse matrix, []"); disp (" Mass: matrix or function_handle, []"); disp (" MassConstant: binary, {'on', ['off']}"); disp (" MassSingular: switch, {'yes', ['maybe'], 'no'}"); disp ("MaxNewtonIterations: scalar, integer, >0, [1.e3]"); disp (" MaxOrder: switch, {1, 2, 3, 4, [5]}"); disp (" MaxStep: scalar, >0, []"); disp (" MStateDependence: switch, {'none', ['weak'], 'strong'}"); disp (" MvPattern: sparse matrix, []"); disp (" NewtonTol: scalar or vector, >0, []"); disp (" NonNegative: vector of integers, []"); disp (" NormControl: binary, {'on', ['off']}"); disp (" OutputFcn: function_handle, []"); disp (" OutputSave: scalar, integer, >0, []"); disp (" OutputSel: scalar or vector, []"); disp (" PolynomialDegree: scalar, integer, >0, []"); disp (" QuadratureOrder: scalar, integer, >0, []"); disp (" Refine: scalar, integer, >0, []"); disp (" RelTol: scalar, >0, [1.e-3]"); disp (" Restart: scalar, integer, >0, [20]"); disp (" Stats: binary, {'on', ['off']}"); disp (" TimeStepNumber: scalar, integer, >0, []"); disp (" TimeStepSize: scalar, >0, []"); disp (" UseJacobian: binary, {'yes', ['no']}"); disp (" Vectorized: binary, {'on', ['off']}"); endfunction %!demo %! # A new OdePkg options structure with default values is created. %! %! odeoptA = odeset (); %! %!demo %! # A new OdePkg options structure with manually set options %! # "AbsTol" and "RelTol" is created. %! %! odeoptB = odeset ("AbsTol", 1e-2, "RelTol", 1e-1); %! %!demo %! # A new OdePkg options structure from odeoptB is created with %! # a modified value for option "NormControl". %! %! odeoptB = odeset ("AbsTol", 1e-2, "RelTol", 1e-1); %! odeoptC = odeset (odeoptB, "NormControl", "on"); ## All tests that are needed to check if a correct resp. valid option ## has been set are implemented in ode_struct_value_check.m. %! ## Turn off output of warning messages for all tests, turn them on %! ## again if the last test is called %! warning ("off", "OdePkg:InvalidArgument"); %!test odeoptA = odeset (); %!test odeoptB = odeset ("AbsTol", 1e-2, "RelTol", 1e-1); %! if (odeoptB.AbsTol != 1e-2), error; endif %! if (odeoptB.RelTol != 1e-1), error; endif %!test odeoptB = odeset ("AbsTol", 1e-2, "RelTol", 1e-1); %! odeoptC = odeset (odeoptB, "NormControl", "on"); %!test odeoptB = odeset ("AbsTol", 1e-2, "RelTol", 1e-1); %! odeoptC = odeset (odeoptB, "NormControl", "on"); %! odeoptD = odeset (odeoptC, odeoptB); %! %! warning ("on", "OdePkg:InvalidArgument");