This is an implementation of Powell's conjugate gradient descent
method that might go in the minimization section of optim.
Best,
Nir
## Copyright (C) 2011 Nir Krakauer
##
## This program 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.
##
## This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
## -*- texinfo -*-
## @deftypefn {Function File} [@var{p}, @var{obj_value}, @var{convergence}, @var{iters}, @var{nevs}] = powell (@var{f}, @var{args}, @var{control})
##powell: implements a direction-set (Powell's) method for minimizing a function of several variables without calculation of the gradient [1, 2]
##
## @subheading Arguments
##
## @itemize @bullet
## @item
## @var{f}: name of function to minimize (string or handle)
##
## @item
## @var{args}: a cell array that holds all arguments of the function
## The argument with respect to which minimization is done
## must be numeric
##
## @item
## @var{control}: an optional cell array of 1-10 elements. If a cell array shorter than 10 elements is provided, the trailing elements are provided with default values. (currently, only elements 1, 4, 6, 9, 10 are used)
## @itemize @minus
## @item
## elem 1: maximum iterations (positive integer, or -1 or Inf for unlimited (default))
## @item
## elem 2: verbosity
## @itemize
## @item
## 0 = no screen output (default)
## @item
## 1 = only final results
## @item
## 2 = summary every iteration
## @item
## 3 = detailed information
## @end itemize
## @item
## elem 3: convergence criterion
## @itemize
## @item
## 1 = strict (function, gradient and param change) (default)
## @item
## 0 = weak - only function convergence required
## @end itemize
## @item
## elem 4: order of argument in args with respect to which minimization is done (default is 1, first argument to the objective function)
## @item
## elem 5: (optional) Memory limit
## @item
## elem 6: function change tolerance, default 1e-8
## @item
## elem 7: parameter change tolerance, default 1e-6
## @item
## elem 8: gradient tolerance, default 1e-5
## @item
## elem 9: maximum function evaluations (positive integer, or -1 or Inf for unlimited (default))
## @item
## elem 10: an n*n matrix containing the initial set of (presumably orthogonal) directions to minimize along, where n is the number of elements in the argument to be minimized for; or an n*1 vector of magnitudes for the initial directions (defaults to the set of unit direction vectors)
## @end itemize
## @end itemize
##
## @subheading Examples
##
## @example
## @group
## y = @@(x, s) x(1) .^ 2 + x(2) .^ 2 + s;
## [x_optim, y_min, conv, iters, nevs] = powell(y, @{[1 0.5], 1@});
## %should return something like x_optim = [5E-14 1E-14], y_min = 1, conv = 1, iters = 2, nevs = 24
## @end group
##
## @end example
##
## @subheading Returns:
##
## @itemize @bullet
## @item
## @var{p}: the minimizing value of the function argument
## @item
## @var{obj_value}: the value of @var{f}() at @var{p}
## @item
## @var{convergence}: 1 if normal convergence, 0 if not
## @item
## @var{iters}: number of iterations performed
## @item
## @var{nevs}: number of function evaluations
## @end itemize
##
## @subheading References
##
## @enumerate
## @item
## Powell MJD (1964), An efficient method for finding the minimum of a function of several variables without calculating derivatives, @cite{Computer Journal}, 7 :155-162
##
## @item
## Press, WH; Teukolsky, SA; Vetterling, WT; Flannery, BP (1992). @cite{Numerical Recipes in Fortran: The Art of Scientific Computing} (2nd Ed.). New York: Cambridge University Press (Section 10.5)
## @end enumerate
## @end deftypefn
## Author: Nir Krakauer <nkraka...@ccny.cuny.edu>
## Description: Multidimensional minimization (direction-set method)
function [p, obj_value, convergence, iters, nevs] = powell(f, args, control);
# check number and types of arguments
if ((nargin < 2) || (nargin > 3))
usage('powell: you must supply 2 or 3 arguments');
endif
if (~iscell(args))
usage('powell: the second argument should be a cell array of function input arguments');
end
%default values
narg = 1; %position of minimized variable
ftol = 1E-8;
maxiter = Inf;
maxev = Inf;
xi_set = 0;
%read in user settings, if provided
if (nargin == 3) && iscell(control)
if (numel(control) >= 1) && ~isempty(control{1}) && isnumeric(control{1}) && (control{1} >= 0)
maxiter = control{1};
end
if (numel(control) >= 4) && ~isempty(control{4}) && isnumeric(control{4}) && (control{4} >= 1)
narg = control{4};
end
if (numel(control) >= 6) && ~isempty(control{6}) && isnumeric(control{6}) && (control{6} >= 0)
ftol = control{6};
end
if (numel(control) >= 9) && ~isempty(control{9}) && isnumeric(control{9}) && (control{9} >= 0)
maxev = control{9};
end
if (numel(control) >= 10) && ~isempty(control{10}) && isnumeric(control{10})
if isvector(control{10}) %control{10} is n*1 or 1*n
xi = diag(control{10});
else %control{10} is n*n
xi = control{10};
end
xi_set = 1;
end
end
nevs = 0;
iters = 0;
convergence = 0;
try
obj_value = feval(f, args{:});
catch
error("function does not exist or cannot be evaluated");
end
nevs++;
n = numel(args{narg}); %number of dimensions to minimize over
xit = zeros(n, 1);
if ~xi_set
xi = eye(n);
end
p = args{narg}; %initial value of the argument being minimized
%do an iteration
while (iters <= maxiter) && (nevs <= maxev) && (~convergence)
iters++;
pt = p; %best point as iteration begins
fp = obj_value; %value of the objective function as iteration begins
ibig = 0; %will hold direction along which the objective function decreased the most in this iteration
dlt = 0; %will hold decrease in objective function value in this iteration
for i = 1:n
xit = reshape(xi(:, i), size(p));
fptt = obj_value;
%%args = splice(args, narg, 1, {p});
args{narg} = p;
[a, obj_value, nev] = line_min(f, xit, args, narg);
%[a, obj_value, nev] = linmin(f, args, xit, narg, ftol, narg);
nevs = nevs + nev;
p = p + a*xit;
change = fptt - obj_value;
if (change > dlt)
dlt = change;
ibig = i;
end
end
if ( 2*abs(fp-obj_value) <= ftol*(abs(fp) + abs(obj_value)) )
convergence = 1;
return
end
if iters == maxiter
disp('iteration maximum exceeded')
return
end
%attempt parabolic extrapolation
ptt = 2*p - pt;
xit = p - pt;
%%args = splice(args, narg, 1, {ptt});
args{narg} = ptt;
fptt = feval(f, args{:});
nevs++;
if fptt < fp %check whether the extrapolation actually makes the objective function smaller
t = 2 * (fp - 2*obj_value + fptt) * (fp-obj_value-dlt)^2 - dlt * (fp-fptt)^2;
if t < 0
p = ptt;
%%args = splice(args, narg, 1, {p});
args{narg} = p;
[a,obj_value,nev] = line_min(f, xit, args, narg);
nevs = nevs + nev;
p = p + a*xit;
%add the net direction from this iteration to the direction set
xi(:, ibig) = xi(:, n);
xi(:, n) = xit(:);
end
end
end
------------------------------------------------------------------------------
All the data continuously generated in your IT infrastructure
contains a definitive record of customers, application performance,
security threats, fraudulent activity, and more. Splunk takes this
data and makes sense of it. IT sense. And common sense.
http://p.sf.net/sfu/splunk-novd2d
_______________________________________________
Octave-dev mailing list
Octave-dev@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/octave-dev