changeset 25739:8eec0403a370

fminsearch.m: Update default TolFun to 1e-4 for Matlab compatibility. * NEWS: Announce change in the default value of TolFun. * fminsearch.m: Redo parts of docstring to be clearer. Change default TolFun value to 1e-4. Change reported optimset defaults for MaxFunEvals and MaxIter to [] rather than 400. Change optional output messages to be clearer.
author Rik <rik@octave.org>
date Fri, 03 Aug 2018 14:46:08 -0700
parents 8cdaef4c6d44
children b1e0e58971f9
files NEWS scripts/optimization/fminsearch.m
diffstat 2 files changed, 45 insertions(+), 23 deletions(-) [+]
line wrap: on
line diff
--- a/NEWS	Fri Aug 03 14:00:17 2018 -0700
+++ b/NEWS	Fri Aug 03 14:46:08 2018 -0700
@@ -32,6 +32,10 @@
         TolX         |     1e-6       |     1e-7
         Updating     |     "off"      |     "on"
 
+ ** The fminsearch function has changed default TolFun accuracy to 1e-4
+    from 1e-7.  This change was made for Matlab compatibility, but may
+    result in different results from existing code.
+
  ** Figure graphic objects have a new property "Number" which is
     read-only and will return the handle (number) of the figure.
     However, if the property "IntegerHandle" has been set to "off" then
--- a/scripts/optimization/fminsearch.m	Fri Aug 03 14:00:17 2018 -0700
+++ b/scripts/optimization/fminsearch.m	Fri Aug 03 14:46:08 2018 -0700
@@ -23,7 +23,8 @@
 ## @deftypefnx {} {@var{x} =} fminsearch (@var{fun}, @var{x0}, @var{options}, @var{fun_arg1}, @var{fun_arg2}, @dots{})
 ## @deftypefnx {} {[@var{x}, @var{fval}, @var{exitflag}, @var{output}] =} fminsearch (@dots{})
 ##
-## Find a value of @var{x} which minimizes the function @var{fun}.
+## Find a value of @var{x} which minimizes the multi-variable function
+## @var{fun}.
 ##
 ## The search begins at the point @var{x0} and iterates using the
 ## @nospell{Nelder & Mead} Simplex algorithm (a derivative-free method).  This
@@ -32,9 +33,22 @@
 ##
 ## Options for the search are provided in the parameter @var{options} using the
 ## function @code{optimset}.  Currently, @code{fminsearch} accepts the options:
-## @qcode{"TolX"}, @qcode{"TolFun"}, @qcode{"MaxFunEvals"}, @qcode{"MaxIter"},
-## @qcode{"Display"}, @qcode{"FunValCheck"}, and @qcode{"OutputFcn"}.
-## For a description of these options, see @code{optimset}.
+## @qcode{"Display"}, @qcode{"FunValCheck"},@qcode{"MaxFunEvals"},
+## @qcode{"MaxIter"}, @qcode{"OutputFcn"}, @qcode{"TolFun"}, @qcode{"TolX"}. 
+##
+## @qcode{"MaxFunEvals"} proscribes the maximum number of function evaluations
+## before optimization is halted.  The default value is
+## @code{200 * number_of_variables}, i.e., @code{200 * length (@var{x0})}.
+## The value must be a positive integer.
+##
+## @qcode{"MaxIter"} proscribes the maximum number of algorithm iterations
+## before optimization is halted.  The default value is
+## @code{200 * number_of_variables}, i.e., @code{200 * length (@var{x0})}.
+## The value must be a positive integer.
+## 
+## For a description of the other options, see @code{optimset}.  To initialize
+## an options structure with default values for @code{fminsearch} use
+## @code{options = optimset ("fminsearch")}.
 ##
 ## Additional inputs for the function @var{fun} can be passed as the fourth
 ## and higher arguments.  To pass function arguments while using the default
@@ -43,14 +57,14 @@
 ## On exit, the function returns @var{x}, the minimum point, and @var{fval},
 ## the function value at the minimum.
 ##
-## The third return value @var{exitflag} is
+## The third output @var{exitflag} reports whether the algorithm succeeded and
+## may take one of the following values:
 ##
 ## @table @asis
 ## @item 1
 ## if the algorithm converged
-## (size of the simplex is smaller than @code{@var{options}.TolX} @strong{AND}
-## the step in the function value between iterations is smaller than
-## @code{@var{options}.TolFun}).
+## (size of the simplex is smaller than @code{TolX} @strong{AND} the step in
+## function value between iterations is smaller than @code{TolFun}).
 ##
 ## @item 0
 ## if the maximum number of iterations or the maximum number of function
@@ -60,10 +74,11 @@
 ## if the iteration is stopped by the @qcode{"OutputFcn"}.
 ## @end table
 ##
-## The fourth return value is a structure @var{output} with the fields,
-## @code{funcCount} containing the number of function calls to @var{fun},
-## @code{iterations} containing the number of iteration steps,
-## @code{algorithm} with the name of the search algorithm (always:
+## The fourth output is a structure @var{output} containing runtime
+## about the algorithm.  Fields in the structure are @code{funcCount}
+## containing the number of function calls to @var{fun}, @code{iterations}
+## containing the number of iteration steps, @code{algorithm} with the name of
+## the search algorithm (always: 
 ## @nospell{@qcode{"Nelder-Mead simplex direct search"}}), and @code{message}
 ## with the exit message.
 ##
@@ -72,6 +87,9 @@
 ## @example
 ## fminsearch (@@(x) (x(1)-5).^2+(x(2)-8).^4, [0;0])
 ## @end example
+##
+## Note: If you need to find the minimum of a single variable function it is
+## probably better to use @code{fminbnd}.
 ## @seealso{fminbnd, fminunc, optimset}
 ## @end deftypefn
 
@@ -85,9 +103,9 @@
   ## Get default options if requested.
   if (nargin == 1 && ischar (fun) && strcmp (fun, "defaults"))
     x = optimset ("Display", "notify", "FunValCheck", "off",
-                  "MaxFunEvals", 400, "MaxIter", 400,
+                  "MaxFunEvals", [], "MaxIter", [],
                   "OutputFcn", [],
-                  "TolFun", 1e-7, "TolX", 1e-4);
+                  "TolFun", 1e-4, "TolX", 1e-4);
     return;
   endif
 
@@ -154,13 +172,13 @@
   stopit(1) = tol = optimget (options, "TolX", 1e-4);
 
   ## Tolerance for cgce test based on step in function value.
-  tol_f = optimget (options, "TolFun", 1e-7);
+  tol_f = optimget (options, "TolFun", 1e-4);
 
   ## Max number of function evaluations.
-  stopit(2) = optimget (options, "MaxFunEvals", length (x) * 200);
+  stopit(2) = optimget (options, "MaxFunEvals", 200 * length (x));
 
   ## Max number of iterations
-  maxiter = optimget (options, "MaxIter", length (x) * 200);
+  maxiter = optimget (options, "MaxIter", 200 * length (x));
 
   ## Default target for function values.
   stopit(3) = Inf;  # FIXME: expose this parameter to the outside
@@ -269,7 +287,7 @@
     k += 1;
 
     if (k > maxiter)
-      msg = "Exceeded maximum iterations...quitting\n";
+      msg = "Exceeded maximum iterations\n";
       break;
     endif
 
@@ -293,14 +311,15 @@
     ## Stopping Test 1 - f reached target value?
     if (fmax >= stopit(3))
       msg = "Exceeded target...quitting\n";
-      ## FIXME: Add docu when stopit(3) gets exposed to the outside
+      ## FIXME: Add documentation when stopit(3) gets exposed to the outside
       exitflag = -1;
       break;
     endif
 
     ## Stopping Test 2 - too many f-evals?
     if (nf >= stopit(2))
-      msg = "Max no. of function evaluations exceeded...quitting\n";
+      msg = "Exceeded maximum number of function evaluations\n";
+      exitflag = 0;
       break;
     endif
 
@@ -309,8 +328,8 @@
     size_simplex = norm (V(:,2:n+1)-v1(:,ones (1,n)),1) / max (1, norm (v1,1));
     step_f = max (abs (f(1) - f(2:n+1)));
     if (size_simplex <= tol && step_f <= tol_f )
-      msg = sprintf (["Simplex size %9.4e <= %9.4e and ", ...
-                      "step in function value %9.4e <= %9.4e...quitting\n"], ...
+      msg = sprintf (["Algorithm converged.  Simplex size %9.4e <= %9.4e ", ...
+                      "and step in function value %9.4e <= %9.4e\n"], ...
                       size_simplex, tol, step_f, tol_f);
       exitflag = 1;
       break;
@@ -490,4 +509,3 @@
 ## Test input validation
 %!error fminsearch ()
 %!error fminsearch (1)
-