# HG changeset patch # User Rik # Date 1396117499 25200 # Node ID 8d4d78285c8eb740abde560daf7a2ce5ab4912be # Parent 077575fe9a7e4d86ab2515356cb0e56188e23570 Overhaul optimset/optimget functions for Matlab compatibility (bug #41915). * optimget.m: Rewrite docstring. Use function name in all emitted warnings. Return the input DEFAULT when the options structure is empty rather than returning an empty matrix (Matlab compatibility). Add more tests for function and input validation. * optimset.m: Rewrite docstring. Use function name in all emitted warnings. Add more tests for function and input validation. diff -r 077575fe9a7e -r 8d4d78285c8e scripts/optimization/optimget.m --- a/scripts/optimization/optimget.m Fri Mar 28 15:59:54 2014 -0700 +++ b/scripts/optimization/optimget.m Sat Mar 29 11:24:59 2014 -0700 @@ -20,10 +20,12 @@ ## -*- texinfo -*- ## @deftypefn {Function File} {} optimget (@var{options}, @var{parname}) ## @deftypefnx {Function File} {} optimget (@var{options}, @var{parname}, @var{default}) -## Return a specific option from a structure created by -## @code{optimset}. If @var{parname} is not a field of the @var{options} -## structure, return @var{default} if supplied, otherwise return an -## empty matrix. +## Return the specific option @var{parname} from the optimization options +## structure @var{options} created by @code{optimset}. +## +## If @var{parname} is not defined then return @var{default} if supplied, +## otherwise return an empty matrix. +## @seealso{optimset} ## @end deftypefn function retval = optimget (options, parname, default) @@ -32,21 +34,22 @@ print_usage (); endif + ## Expand partial-length names into full names opts = __all_opts__ (); idx = strncmpi (opts, parname, length (parname)); - nmatch = sum (idx); if (nmatch == 1) parname = opts{idx}; elseif (nmatch == 0) - warning ("unrecognized option: %s", parname); + warning ("optimget: unrecognized option: %s", parname); else - fmt = sprintf ("ambiguous option: %%s (%s%%s)", + fmt = sprintf ("optimget: ambiguous option: %%s (%s%%s)", repmat ("%s, ", 1, nmatch-1)); warning (fmt, parname, opts{idx}); endif - if (isfield (options, parname)) + + if (isfield (options, parname) && ! isempty (options.(parname))) retval = options.(parname); elseif (nargin > 2) retval = default; @@ -57,13 +60,20 @@ endfunction -%!error optimget () - %!shared opts %! opts = optimset ("tolx", 0.1, "maxit", 100); -%!assert (optimget (opts, "TolX"), 0.1); -%!assert (optimget (opts, "maxit"), 100); -%!assert (optimget (opts, "MaxITer"), 100); -%!warning (optimget (opts, "Max")); -%!warning (optimget (opts, "foobar")); +%!assert (optimget (opts, "TolX"), 0.1) +%!assert (optimget (opts, "maxit"), 100) +%!assert (optimget (opts, "MaxITer"), 100) +%!assert (optimget (opts, "TolFun"), []) +%!assert (optimget (opts, "TolFun", 1e-3), 1e-3) +%% Test input validation +%!error optimget () +%!error optimget (1) +%!error optimget (1,2,3,4,5) +%!error optimget (1, "name") +%!error optimget (struct (), 2) +%!warning (optimget (opts, "foobar")); +%!warning (optimget (opts, "Max")); + diff -r 077575fe9a7e -r 8d4d78285c8e scripts/optimization/optimset.m --- a/scripts/optimization/optimset.m Fri Mar 28 15:59:54 2014 -0700 +++ b/scripts/optimization/optimset.m Sat Mar 29 11:24:59 2014 -0700 @@ -19,10 +19,24 @@ ## -*- texinfo -*- ## @deftypefn {Function File} {} optimset () -## @deftypefnx {Function File} {} optimset (@var{par}, @var{val}, @dots{}) -## @deftypefnx {Function File} {} optimset (@var{old}, @var{par}, @var{val}, @dots{}) -## @deftypefnx {Function File} {} optimset (@var{old}, @var{new}) -## Create options struct for optimization functions. +## @deftypefnx {Function File} {@var{options} =} optimset () +## @deftypefnx {Function File} {@var{options} =} optimset (@var{par}, @var{val}, @dots{}) +## @deftypefnx {Function File} {@var{options} =} optimset (@var{old}, @var{par}, @var{val}, @dots{}) +## @deftypefnx {Function File} {@var{options} =} optimset (@var{old}, @var{new}) +## Create options structure for optimization functions. +## +## When called without any input or output arguments, @code{optimset} prints +## a list of all valid optimization parameters. +## +## When called with one output and no inputs, return an options structure with +## all valid option parameters initialized to @code{[]}. +## +## When called with a list of parameter/value pairs, return an options +## structure with only the named parameters initialized. +## +## When the first input is an existing options structure @var{old}, the values +## are updated from either the @var{par}/@var{val} list or from the options +## structure @var{new}. ## ## Valid parameters are: ## @@ -96,13 +110,13 @@ ## ## @item Updating ## @end table +## @seealso{optimget} ## @end deftypefn function retval = optimset (varargin) nargs = nargin (); - ## Add more as needed. opts = __all_opts__ (); if (nargs == 0) @@ -124,8 +138,8 @@ error ("optimset: no defaults for function '%s'", fcn); end_try_catch elseif (nargs == 2 && isstruct (varargin{1}) && isstruct (varargin{2})) - ## Set slots in old from nonempties in new. Should we be checking - ## to ensure that the field names are expected? + ## Set slots in old from non-empties in new. + ## Should we be checking to ensure that the field names are expected? old = varargin{1}; new = varargin{2}; fnames = fieldnames (old); @@ -140,9 +154,9 @@ if (nmatch == 1) key = opts{find (i)}; elseif (nmatch == 0) - warning ("unrecognized option: %s", key); + warning ("optimset: unrecognized option: %s", key); else - fmt = sprintf ("ambiguous option: %%s (%s%%s)", + fmt = sprintf ("optimset: ambiguous option: %%s (%s%%s)", repmat ("%s, ", 1, nmatch-1)); warning (fmt, key, opts{i}); endif @@ -155,8 +169,8 @@ pairs = reshape (varargin(2:end), 2, []); retval = optimset (varargin{1}, cell2struct (pairs(2, :), pairs(1, :), 2)); elseif (rem (nargs, 2) == 0) - ## Create struct. Default values are replaced by those specified by - ## name/value pairs. + ## Create struct. + ## Default values are replaced by those specified by name/value pairs. pairs = reshape (varargin, 2, []); retval = optimset (struct (), cell2struct (pairs(2, :), pairs(1, :), 2)); else @@ -166,10 +180,13 @@ endfunction -%!assert (optimget (optimset ("tolx", 1e-2), "tOLx"), 1e-2) +%!assert (isfield (optimset (), "TolFun")) %!assert (isfield (optimset ("tolFun", 1e-3), "TolFun")) -%!warning (optimset ("Max", 10)); -%!warning (optimset ("foobar", 13)); +%!assert (optimget (optimset ("tolx", 1e-2), "tOLx"), 1e-2) -%!error (optimset ("%NOT_A_REAL_FUNCTION_NAME%")) +%% Test input validation +%!error optimset ("1_Parameter") +%!error optimset ("%NOT_A_REAL_FUNCTION_NAME%") +%!warning optimset ("foobar", 13); +%!warning optimset ("Max", 10);