# HG changeset patch
# User Jaroslav Hajek
# Date 1233307713 -3600
# Node ID 0f13b720e3b134793bfb8381fe6022c2230187ca
# Parent 4385bb503467d6cbd834378dd4023b1f5052b858
implement registering of optimization options
diff --git a/scripts/ChangeLog b/scripts/ChangeLog
--- a/scripts/ChangeLog
+++ b/scripts/ChangeLog
@@ -0,0 +1,7 @@
+2009-01-30 Jaroslav Hajek
+
+ * optimization/__all_opts__.m: New source.
+ * optimization/optimset.m: Implement checking for registered options.
+ * optimization/optimget.m: Ditto.
+ * optimzation/fsolve.m: Fix misspelled option.
+
diff --git a/scripts/optimization/__all_opts__.m b/scripts/optimization/__all_opts__.m
new file mode 100644
--- /dev/null
+++ b/scripts/optimization/__all_opts__.m
@@ -0,0 +1,77 @@
+## 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)
+
+ ## add more here as necessary
+ persistent funcs = {"fzero", "fsolve", "lsqnonneg"};
+
+ persistent saved_names = {};
+
+ ## guard against recursive calls
+ persistent recursive = false;
+
+ if (recursive)
+ names = {};
+ return;
+ else
+ if (isempty (saved_names))
+ regquery = funcs;
+ else
+ regquery = {};
+ endif
+ if (nargin > 0)
+ regquery = [regquery, varargin];
+ endif
+
+ if (isempty (regquery))
+ names = saved_names;
+ else
+ recursive = true;
+ ## 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:length (regquery)
+ try
+ opts = optimset (regquery{i});
+ fn = fieldnames (opts).';
+ names = [names, fn];
+ catch
+ # throw the error as a warning.
+ warning (lasterr ());
+ end_try_catch
+ endfor
+ recursive = false;
+ 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
+ endif
+
+endfunction
+
diff --git a/scripts/optimization/fsolve.m b/scripts/optimization/fsolve.m
--- a/scripts/optimization/fsolve.m
+++ b/scripts/optimization/fsolve.m
@@ -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 --git a/scripts/optimization/optimget.m b/scripts/optimization/optimget.m
--- a/scripts/optimization/optimget.m
+++ b/scripts/optimization/optimget.m
@@ -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 --git a/scripts/optimization/optimset.m b/scripts/optimization/optimset.m
--- a/scripts/optimization/optimset.m
+++ b/scripts/optimization/optimset.m
@@ -1,4 +1,5 @@
## Copyright (C) 2007 John W. Eaton
+## Copyright (C) 2009 VZLU Prague
##
## This file is part of Octave.
##
@@ -29,15 +30,7 @@
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)
@@ -63,10 +56,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