diff scripts/ode/odeget.m @ 20585:45151de7423f

maint: Clean up implementations of ode45.m, odeget.m, odeset.m. * ode45.m: Match variable names in function to docstring. Don't use '...' line continuation unless strictly necessary. Remove incorrect isa check for inline function. Use '( )' around switch statement test variable. Use printf, rather than fprintf, where possible. * odeget.m: Match variable names in function to docstring. Rephrase error messages to begin with 'odeget:'. Use try/catch blocks to speed up "fast" and "fast_not_empty" code. Use rows() rather than "size (xxx, 1)". Use isempty rather than "size (xxx, 1) == 0". Use printf, rather than fprintf, where possible. Use unwind_protect block in BIST tests to restore warning state. * odeset.m: Match variable names in function to docstring. Use rows() rather than "size (xxx, 1)". Use isempty rather than "size (xxx, 1) == 0". Use printf, rather than fprintf, where possible. Eliminate for loop with cell2struct for odestruct initialization. Introduce temporary vars oldstruct, newstruct to clarify code. Restate some error messages to begin with 'odeset:'. Use cellfun to quickl check that all field inputs are strings. Use unwind_protect block in BIST tests to restore warning state.
author Rik <rik@octave.org>
date Mon, 05 Oct 2015 11:59:18 -0700
parents e368ce72a844
children e5f36a7854a5
line wrap: on
line diff
--- a/scripts/ode/odeget.m	Sun Oct 04 22:18:54 2015 -0700
+++ b/scripts/ode/odeget.m	Mon Oct 05 11:59:18 2015 -0700
@@ -18,79 +18,71 @@
 ## <http://www.gnu.org/licenses/>.
 
 ## -*- texinfo -*-
-## @deftypefn  {Function File} {@var{option} =} odeget (@var{ode_opt}, @var{field})
-## @deftypefnx {Function File} {@var{option} =} odeget (@var{ode_opt}, @var{field}, @var{default})
+## @deftypefn  {Function File} {@var{val} =} odeget (@var{ode_opt}, @var{field})
+## @deftypefnx {Function File} {@var{val} =} odeget (@var{ode_opt}, @var{field}, @var{default})
 ##
 ## Query the value of the property @var{field} in the ODE options structure
 ## @var{ode_opt}.
 ##
-## If this function is called with two input arguments and the first input
-## argument @var{ode_opt} is of type structure array and the second input
-## argument @var{field} is of type string then return the option value
-## @var{res} that is specified by the option name @var{field} in the ODE
-## option structure @var{ode_opt}.
+## If called with two input arguments and the first input argument @var{ode_opt}
+## is a structure and the second input argument @var{field} is a string then
+## return the option value @var{val} that is specified by the option name
+## @var{field} in the ODE option structure @var{ode_opt}.
 ##
-## Optionally if this function is called with a third input argument then
-## return the default value @var{default} if @var{field} is not set in the
-## structure @var{ode_opt}.
+## If called called with an optional third input argument then return the
+## default value @var{default} if @var{field} is not set in the structure
+## @var{ode_opt}.
 ## @seealso{odeset}
 ## @end deftypefn
 
+## FIXME: 4th input argument 'opt' is undocumented.
+
 ## Note: 2006-10-22, Thomas Treichl
 ##   We cannot create a function of the form odeget (@var{odestruct},
 ##   @var{name1}, @var{name2}) because we would get a mismatch with
 ##   the function form 1 like described above.
 
-function res = odeget (ode_opt, field, default, opt)
+function val = odeget (ode_opt, field, default = [], opt)
 
-  ## Check number and types of input arguments
-  if (nargin == 1)
-    error ("OdePkg:InvalidArgument",
-           "input arguments number must be at least 2")
+  if (nargin == 1 || nargin > 4)
+    print_usage ();
   endif
 
+  ## Shortcut for empty options structures
   if (isempty (ode_opt))
-    if (nargin == 2)
-      res = [];
-      return
+    if (nargin < 3)
+      val = [];
+    else
+      val = default;
     endif
-    res = default;
-    return
+    return;
   endif
 
   if (! isstruct (ode_opt))
-    error ("OdePkg:InvalidArgument",
-           "first input argument must be a valid ODE_STRUCT.");
-  endif
-
-  if (! ischar (field))
-    error ("OdePkg:InvalidArgument",
-           "second input argument must be a string.");
-  endif
-
-  if (nargin == 2)
-    default = [];
+    error ("odeget: ODE_OPT must be a valid ODE_STRUCT");
+  elseif (! ischar (field))
+    error ("odeget: FIELD must be a string");
   endif
 
-  if ((nargin == 4)
-      && strcmp (lower (deblank (opt)), "fast"))
-    if (isfield (ode_opt, field))
-      res = ode_opt.(field);
-    else
-      res = default;
-    endif
-    return
+  if (nargin == 4 && strcmpi (opt, "fast"))
+    try
+      val = ode_opt.(field);
+    catch
+      val = default;
+    end_try_catch
+    return;
   endif
 
-  if ((nargin == 4)
-      && strcmp (lower (deblank (opt)), "fast_not_empty"))
-    if (isfield (ode_opt, field)
-        && ! isempty (ode_opt.(field)) )
-      res = ode_opt.(field);
-    else
-      res = default;
-    endif
-    return
+  if (nargin == 4 && strcmpi (opt, "fast_not_empty"))
+    try
+      val = ode_opt.(field);
+      if (isempty (val))
+        val = default;
+      endif
+    catch
+      val = default;
+    end_try_catch
+    return;
   endif
 
   ## check if the given struct is a valid OdePkg struct
@@ -110,43 +102,44 @@
   while (1)
     pos = fuzzy_compare (field, options);
 
-    if (size (pos, 1) == 0) # no matching for the given option
+    if (isempty (pos))  # no match for the given option
       if (nargin == 2)
-        error ("OdePkg:InvalidArgument",
-               "invalid property. No property found with name '%s'.", field);
+        error ("odeget: invalid property. No property found with name '%s'",
+               field);
       endif
       warning ("odeget:NoExactMatching",
                "no property found with name '%s'. ",
                "Assuming default value.", field);
-      res = default;
-      return
+      val = default;
+      return;
     endif
 
-    if (size (pos, 1) == 1) # one matching
+    if (rows (pos) == 1)  # one matching
       if (! strcmp (lower (deblank (field)),
                     lower (deblank (options(pos,:)))) )
-        warning ("OdePkg:InvalidArgument",
+        warning ("odeget:InvalidArgument",
                  "no exact matching for '%s'. ",
-                 "Assuming you was intending '%s'.",
+                 "Assuming you were intending '%s'.",
                  field, deblank (options(pos,:)));
       endif
-      res = ode_opt.(deblank (options(pos,:)));
-      if (isempty (res))
-        res = default;
-        return
+      val = ode_opt.(deblank (options(pos,:)));
+      if (isempty (val))
+        val = default;
       endif
-      return
+      return;
     endif
 
+    ## FIXME: Do we really need interactive selection?
+    ##        Matlab doesn't appear to offer this.
     ## if there are more matching, ask the user to be more precise
-    warning ("OdePkg:InvalidArgument", ...
+    warning ("OdePkg:InvalidArgument",
              "no exact matching for '%s'. %d possible fields were found.",
-             field, size (pos, 1));
-    for j = 1:(size (pos, 1))
-      fprintf ("%s\n", deblank (options(pos(j),:)));
+             field, rows (pos));
+    for j = 1:(rows (pos))
+      printf ("%s\n", deblank (options(pos(j),:)));
     endfor
     do
-      fprintf ("Please insert field name again.\n");
+      printf ("Please insert field name again.\n");
       field = input ("New field name: ");
     until (ischar (field))
   endwhile
@@ -156,22 +149,23 @@
 
 %!demo
 %! # Return the manually changed value RelTol of the OdePkg options
-%! # strutcure A.  If RelTol wouldn't have been changed then an
+%! # structure A.  If RelTol wouldn't have been changed then an
 %! # empty matrix value would have been returned.
 %!
 %! A = odeset ("RelTol", 1e-1, "AbsTol", 1e-2);
 %! odeget (A, "RelTol", [])
 
-%! ## Turn off output of warning messages for all tests, turn them on
-%! ## again if the last test is called
-%!  warning ("off", "OdePkg:InvalidArgument");
-%!test assert (odeget (odeset (), "RelTol"), []);
-%!test assert (odeget (odeset (), "RelTol", 10), 10);
-%!test assert (odeget (odeset (), "Stats"), []);
-%!test assert (odeget (odeset (), "Stats", "on"), "on");
-%!test assert (odeget (odeset (), "AbsTol", 1.e-6, "fast"), []);
-%!test assert (odeget (odeset (), "AbsTol", 1.e-6, "fast_not_empty"), 1.e-6);
-%!test assert (odeget (odeset (), "AbsTol", 1e-9), 1e-9);
-%!
-%!  warning ("on", "OdePkg:InvalidArgument");
+%!test
+%! wstate = warning ("off", "OdePkg:InvalidArgument");
+%! unwind_protect
+%!   assert (odeget (odeset (), "RelTol"), []);
+%!   assert (odeget (odeset (), "RelTol", 10), 10);
+%!   assert (odeget (odeset (), "Stats"), []);
+%!   assert (odeget (odeset (), "Stats", "on"), "on");
+%!   assert (odeget (odeset (), "AbsTol", 1e-6, "fast"), []);
+%!   assert (odeget (odeset (), "AbsTol", 1e-6, "fast_not_empty"), 1e-6);
+%!   assert (odeget (odeset (), "AbsTol", 1e-9), 1e-9);
+%! unwind_protect_cleanup
+%!   warning (wstate);
+%! end_unwind_protect