# HG changeset patch # User Jaroslav Hajek # Date 1233347069 -3600 # Node ID 06f5dd901f301c7f87127004846d410046f26623 # Parent e01c6355304f5ca049cc3c05dc9d1a597c3c9910 implement registering of optimization options diff -r e01c6355304f -r 06f5dd901f30 scripts/ChangeLog --- a/scripts/ChangeLog Fri Jan 30 21:17:13 2009 +0100 +++ b/scripts/ChangeLog Fri Jan 30 21:24:29 2009 +0100 @@ -1,3 +1,11 @@ +2009-01-30 Jaroslav Hajek + + * optimization/__all_opts__.m: New source. + * optimization/optimset.m: Implement checking for registered options. + * optimization/optimget.m: Ditto. + * optimization/fsolve.m: Fix misspelled option. + * optimization/PKG_ADD: New startup file. + 2009-01-30 Kai Habel * plot/__go_draw_axes__.m: Add support for transparent surfaces. diff -r e01c6355304f -r 06f5dd901f30 scripts/optimization/PKG_ADD --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/optimization/PKG_ADD Fri Jan 30 21:24:29 2009 +0100 @@ -0,0 +1,2 @@ +__all_opts__ ("fzero", "fsolve", "lsqnonneg"); + diff -r e01c6355304f -r 06f5dd901f30 scripts/optimization/__all_opts__.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/optimization/__all_opts__.m Fri Jan 30 21:24:29 2009 +0100 @@ -0,0 +1,58 @@ +## Copyright (C) 2009 VZLU Prague +## +## 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 +## . + +## -*- texinfo -*- +## @deftypefn {Function File} {} __all_opts__ () +## internal function. Queries all options from all known optimization +## functions and returns a list of possible values. +## @end deftypefn + +function names = __all_opts__ (varargin) + + persistent saved_names = {}; + + ## guard against recursive calls. + persistent recursive = false; + + if (nargin == 0) + names = saved_names; + else + ## query all options from all known functions. These will call optimset, + ## which will in turn call us, but we won't answer. + names = saved_names; + for i = 1:nargin + try + opts = optimset (varargin{i}); + fn = fieldnames (opts).'; + names = [names, fn]; + catch + # throw the error as a warning. + warning (lasterr ()); + end_try_catch + endfor + names = unique (names); + lnames = unique (tolower (names)); + if (length (lnames) < length (names)) + ## This is bad. + error ("__all_opts__: duplicate options with inconsistent case."); + endif + saved_names = names; + endif + +endfunction + diff -r e01c6355304f -r 06f5dd901f30 scripts/optimization/fsolve.m --- a/scripts/optimization/fsolve.m Fri Jan 30 21:17:13 2009 +0100 +++ b/scripts/optimization/fsolve.m Fri Jan 30 21:24:29 2009 +0100 @@ -77,7 +77,7 @@ ## Get default options if requested. if (nargin == 1 && ischar (fcn) && strcmp (fcn, 'defaults')) x = optimset ("MaxIter", 400, "MaxFunEvals", Inf, \ - "Jacobian", "off", "TolX", 1.5e-8, "TolF", 1.5e-8, + "Jacobian", "off", "TolX", 1.5e-8, "TolFun", 1.5e-8, "OutputFcn", [], "Updating", "on", "FunValCheck", "off"); return; endif diff -r e01c6355304f -r 06f5dd901f30 scripts/optimization/optimget.m --- a/scripts/optimization/optimget.m Fri Jan 30 21:17:13 2009 +0100 +++ b/scripts/optimization/optimget.m Fri Jan 30 21:24:29 2009 +0100 @@ -1,4 +1,5 @@ ## Copyright (C) 2008 Jaroslav Hajek +## Copyright (C) 2009 VZLU Prague ## ## This file is part of Octave. ## @@ -27,6 +28,18 @@ function retval = optimget (options, parname, default) + if (nargin < 2 || nargin > 4 || ! isstruct (options) || ! ischar (parname)) + print_usage (); + endif + + opts = __all_opts__ (); + idx = lookup (opts, parname, "i"); + + if (idx > 0 && strcmpi (parname, opts{idx})) + parname = opts{idx}; + else + warning ("unrecognized option: %s", parname) + endif if (isfield (options, parname)) retval = options.(parname); elseif (nargin > 2) diff -r e01c6355304f -r 06f5dd901f30 scripts/optimization/optimset.m --- a/scripts/optimization/optimset.m Fri Jan 30 21:17:13 2009 +0100 +++ b/scripts/optimization/optimset.m Fri Jan 30 21:24:29 2009 +0100 @@ -1,4 +1,5 @@ ## Copyright (C) 2007 John W. Eaton +## Copyright (C) 2009 VZLU Prague ## ## This file is part of Octave. ## @@ -29,21 +30,14 @@ nargs = nargin (); ## Add more as needed. - persistent opts = { - "Display", "\"off\"|\"iter\"|{\"final\"}|\"notify\""; - "FunValCheck", "{\"off\"}|\"on\""; - "MaxFunEvals", "positive integer"; - "MaxIter", "positive integer"; - "OutputFun", "function|{[]}"; - "TolFun", "positive scalar"; - "TolX", "positive scalar" - }; + opts = __all_opts__ (); if (nargs == 0) if (nargout == 0) ## Display possibilities. - tmp = opts'; - disp (struct (tmp{:})); + puts ("\nAll possible optimization options:\n\n"); + printf (" %s\n", opts{:}); + puts ("\n"); else ## Return empty structure. ## We're incompatible with Matlab at this point. @@ -63,10 +57,19 @@ old = varargin{1}; new = varargin{2}; fnames = fieldnames (old); + ## skip validation if we're in the internal query + validation = ! isempty (opts); for [val, key] = new - mask = strcmpi (fnames, key); - if (any (mask)) - key = fnames (mask); + if (validation) + ## Case insensitive lookup in all options. + i = lookup (opts, key, "i"); + ## Validate option. + if (i > 0 && strcmpi (opts{i}, key)) + ## Use correct case. + key = opts{i}; + else + warning ("unrecognized option: %s", key); + endif endif old.(key) = val; endfor @@ -83,3 +86,6 @@ endif endfunction + +%!assert (optimget (optimset ('tolx', 1e-2), 'tOLx'), 1e-2) +%!assert (isfield (optimset ('tolFun', 1e-3), 'TolFun'))