comparison scripts/ode/odeget.m @ 20620:e5f36a7854a5

Remove fuzzy matching from odeset/odeget. * levenshtein.cc: Deleted file. * libinterp/corefcn/module.mk: Remove levenshtein.cc from build system. * fuzzy_compare.m: Deleted file. * scripts/ode/module.mk: Remove fuzzy_compare.m from build system * odeget.m: Reword docstring. Use a persistent cellstr variable to keep track of all options. Replace fuzzy_compare() calls with combination of strcmpi and strncmpi. Report errors relative to function odeget rather than OdePkg. Rewrite and extend BIST tests. Add input validation BIST tests. * odeset.m: Reword docstring. Use a persistent cellstr variable to keep track of all options. Replace fuzzy_compare() calls with combination of strcmpi and strncmpi. Report errors relative to function odeset rather than OdePkg. Use more meaningful variables names and create intermediate variables with logical names to help make code readable. Remove interactive input when multiple property names match and just issue an error. Rewrite BIST tests. * ode_struct_value_check.m: Remove input checking for private function which must always be invoked correctly by caller. Use intermediate variables opt and val to make the code more understandable. Consolidate checks on values into single if statements. Use 'val == fix (val)' to check for integer. * __unimplemented__.m: Removed odeset, odeget, ode45 from list.
author Rik <rik@octave.org>
date Fri, 09 Oct 2015 12:03:23 -0700
parents 45151de7423f
children
comparison
equal deleted inserted replaced
20619:eef93a493ce3 20620:e5f36a7854a5
23 ## 23 ##
24 ## Query the value of the property @var{field} in the ODE options structure 24 ## Query the value of the property @var{field} in the ODE options structure
25 ## @var{ode_opt}. 25 ## @var{ode_opt}.
26 ## 26 ##
27 ## If called with two input arguments and the first input argument @var{ode_opt} 27 ## If called with two input arguments and the first input argument @var{ode_opt}
28 ## is a structure and the second input argument @var{field} is a string then 28 ## is an ODE option structure and the second input argument @var{field} is a
29 ## return the option value @var{val} that is specified by the option name 29 ## string specifying an option name then return the option value @var{val}
30 ## @var{field} in the ODE option structure @var{ode_opt}. 30 ## corresponding to to @var{field} from @var{ode_opt}.
31 ## 31 ##
32 ## If called called with an optional third input argument then return the 32 ## If called called with an optional third input argument, and @var{field} is
33 ## default value @var{default} if @var{field} is not set in the structure 33 ## not set in the structure @var{ode_opt}, then return the default value
34 ## @var{ode_opt}. 34 ## @var{default} instead.
35 ## @seealso{odeset} 35 ## @seealso{odeset}
36 ## @end deftypefn 36 ## @end deftypefn
37 37
38 ## FIXME: 4th input argument 'opt' is undocumented. 38 ## FIXME: 4th input argument "opt" is undocumented.
39
40 ## Note: 2006-10-22, Thomas Treichl
41 ## We cannot create a function of the form odeget (@var{odestruct},
42 ## @var{name1}, @var{name2}) because we would get a mismatch with
43 ## the function form 1 like described above.
44 39
45 function val = odeget (ode_opt, field, default = [], opt) 40 function val = odeget (ode_opt, field, default = [], opt)
46 41
47 if (nargin == 1 || nargin > 4) 42 if (nargin < 1 || nargin > 4)
48 print_usage (); 43 print_usage ();
49 endif 44 endif
50 45
51 ## Shortcut for empty options structures 46 ## Shortcut for empty options structures
52 if (isempty (ode_opt)) 47 if (isempty (ode_opt))
83 val = default; 78 val = default;
84 end_try_catch 79 end_try_catch
85 return; 80 return;
86 endif 81 endif
87 82
88 ## check if the given struct is a valid OdePkg struct 83 ## Check if the given struct is a valid OdePkg struct
89 ode_struct_value_check (ode_opt); 84 ode_struct_value_check (ode_opt);
90 85
91 ## define all the possible OdePkg fields 86 ## Define all the possible OdePkg fields
92 options = ["AbsTol"; "Algorithm"; "BDF"; "Choice"; "Eta"; "Events"; 87 persistent options = {"AbsTol"; "Algorithm"; "BDF"; "Choice"; "Eta"; "Events";
93 "Explicit"; "InexactSolver"; "InitialSlope"; "InitialStep"; 88 "Explicit"; "InexactSolver"; "InitialSlope";
94 "Jacobian";"JConstant";"JPattern";"Mass"; "MassConstant"; 89 "InitialStep"; "Jacobian"; "JConstant"; "JPattern";
95 "MassSingular"; "MaxNewtonIterations"; "MaxOrder"; "MaxStep"; 90 "Mass"; "MassConstant"; "MassSingular";
96 "MStateDependence"; "MvPattern"; "NewtonTol"; "NonNegative"; 91 "MaxNewtonIterations"; "MaxOrder"; "MaxStep";
97 "NormControl"; "OutputFcn"; "OutputSave"; "OutputSel"; 92 "MStateDependence"; "MvPattern"; "NewtonTol";
98 "PolynomialDegree"; "QuadratureOrder"; "Refine"; "RelTol"; 93 "NonNegative"; "NormControl"; "OutputFcn"; "OutputSave";
99 "Restart"; "Stats"; "TimeStepNumber"; "TimeStepSize"; 94 "OutputSel"; "PolynomialDegree"; "QuadratureOrder";
100 "UseJacobian"; "Vectorized"]; 95 "Refine"; "RelTol"; "Restart"; "Stats";
96 "TimeStepNumber"; "TimeStepSize"; "UseJacobian";
97 "Vectorized"};
98
99 exactmatch = true;
100 match = find (strcmpi (field, options));
101 if (isempty (match))
102 match = find (strncmpi (field, options, length (field)));
103 exactmatch = false;
104 endif
101 105
102 while (1) 106 if (isempty (match))
103 pos = fuzzy_compare (field, options); 107 if (nargin == 2)
104 108 error ("odeget: invalid property '%s'", field);
105 if (isempty (pos)) # no match for the given option 109 else
106 if (nargin == 2) 110 ## FIXME: Should we warn, but complete the action, or just error out?
107 error ("odeget: invalid property. No property found with name '%s'", 111 warning ("odeget:InvalidArgument",
112 "odeget: invalid property '%s'. Using supplied default value.",
108 field); 113 field);
109 endif 114 val = default;
115 endif
116 elseif (numel (match) == 1)
117 if (! exactmatch)
110 warning ("odeget:NoExactMatching", 118 warning ("odeget:NoExactMatching",
111 "no property found with name '%s'. ", 119 "odeget: no exact match for '%s'. Assuming '%s'.\n",
112 "Assuming default value.", field); 120 field, options{match});
121 endif
122 val = [];
123 try
124 val = ode_opt.(options{match});
125 end_try_catch
126 if (isempty (val))
113 val = default; 127 val = default;
114 return;
115 endif 128 endif
116 129 else
117 if (rows (pos) == 1) # one matching 130 error ("odeget: no exact match for '%s'. Possible fields found: %s.",
118 if (! strcmp (lower (deblank (field)), 131 field, strjoin (options(match), ", "));
119 lower (deblank (options(pos,:)))) ) 132 endif
120 warning ("odeget:InvalidArgument",
121 "no exact matching for '%s'. ",
122 "Assuming you were intending '%s'.",
123 field, deblank (options(pos,:)));
124 endif
125 val = ode_opt.(deblank (options(pos,:)));
126 if (isempty (val))
127 val = default;
128 endif
129 return;
130 endif
131
132 ## FIXME: Do we really need interactive selection?
133 ## Matlab doesn't appear to offer this.
134 ## if there are more matching, ask the user to be more precise
135 warning ("OdePkg:InvalidArgument",
136 "no exact matching for '%s'. %d possible fields were found.",
137 field, rows (pos));
138 for j = 1:(rows (pos))
139 printf ("%s\n", deblank (options(pos(j),:)));
140 endfor
141 do
142 printf ("Please insert field name again.\n");
143 field = input ("New field name: ");
144 until (ischar (field))
145 endwhile
146 133
147 endfunction 134 endfunction
148 135
149 136
150 %!demo 137 %!demo
153 %! # empty matrix value would have been returned. 140 %! # empty matrix value would have been returned.
154 %! 141 %!
155 %! A = odeset ("RelTol", 1e-1, "AbsTol", 1e-2); 142 %! A = odeset ("RelTol", 1e-1, "AbsTol", 1e-2);
156 %! odeget (A, "RelTol", []) 143 %! odeget (A, "RelTol", [])
157 144
158 %!test 145 %!assert (odeget (odeset (), "RelTol"), [])
159 %! wstate = warning ("off", "OdePkg:InvalidArgument"); 146 %!assert (odeget (odeset ("RelTol", 10), "RelTol"), 10)
160 %! unwind_protect 147 %!assert (odeget (odeset (), "RelTol", 10), 10)
161 %! assert (odeget (odeset (), "RelTol"), []); 148 %!assert (odeget (odeset (), "Stats"), [])
162 %! assert (odeget (odeset (), "RelTol", 10), 10); 149 %!assert (odeget (odeset (), "Stats", "on"), "on")
163 %! assert (odeget (odeset (), "Stats"), []); 150 %!assert (odeget (odeset (), "Mass"), [])
164 %! assert (odeget (odeset (), "Stats", "on"), "on"); 151 %!assert (odeget (odeset (), "AbsTol", 1e-6, "fast"), [])
165 %! assert (odeget (odeset (), "AbsTol", 1e-6, "fast"), []); 152 %!assert (odeget (odeset (), "AbsTol", 1e-6, "fast_not_empty"), 1e-6)
166 %! assert (odeget (odeset (), "AbsTol", 1e-6, "fast_not_empty"), 1e-6); 153 %!assert (odeget (odeset (), "AbsTol", 1e-9), 1e-9)
167 %! assert (odeget (odeset (), "AbsTol", 1e-9), 1e-9);
168 %! unwind_protect_cleanup
169 %! warning (wstate);
170 %! end_unwind_protect
171 154
155 %!error odeget ()
156 %!error odeget (1)
157 %!error odeget (1,2,3,4,5)
158 %!error <ODE_OPT must be a valid ODE_STRUCT> odeget (1, "opt1")
159 %!error <FIELD must be a string> odeget (struct ("opt1", 1), 1)
160 %!error <invalid property 'foo'> odeget (struct ("opt1", 1), "foo")
161 %!warning <Using supplied default value> odeget (struct ("opt1", 1), "foo", 3);
162 %!warning <no exact match for 'Rel'. Assuming 'RelTol'> odeget (struct ("RelTol", 1), "Rel");
163 %!error <Possible fields found: InitialSlope, InitialStep> odeget (odeset (), "Initial")
164