📄 min.m
字号:
function [x,fval,exitflag,output] = min(funfcn,x,options,varargin)
%MIN Multidimensional unconstrained nonlinear minimization (Nelder-Mead).
% X = MIN(FUN,X0) starts at X0 and attempts to find a local minimizer
% X of the function FUN. FUN accepts input X and returns a scalar function
% value F evaluated at X. X0 can be a scalar, vector or matrix.
%
% X = MIN(FUN,X0,OPTIONS) minimizes with the default optimization
% parameters replaced by values in the structure OPTIONS, created
% with the OPTIMSET function. See OPTIMSET for details. MIN uses
% these options: Display, TolX, TolFun, MaxFunEvals, MaxIter, FunValCheck,
% and OutputFcn.
%
% [X,FVAL]= MIN(...) returns the value of the objective function,
% described in FUN, at X.
%
% [X,FVAL,EXITFLAG] = MIN(...) returns an EXITFLAG that describes
% the exit condition of MIN. Possible values of EXITFLAG and the
% corresponding exit conditions are
%
% 1 MIN converged to a solution X.
% 0 Maximum number of function evaluations or iterations reached.
% -1 Algorithm terminated by the output function.
%
% [X,FVAL,EXITFLAG,OUTPUT] = MIN(...) returns a structure
% OUTPUT with the number of iterations taken in OUTPUT.iterations, the
% number of function evaluations in OUTPUT.funcCount, the algorithm name
% in OUTPUT.algorithm, and the exit message in OUTPUT.message.
%
% Examples
% FUN can be specified using @:
% X = min(@sin,3)
% finds a minimum of the SIN function near 3.
% In this case, SIN is a function that returns a scalar function value
% SIN evaluated at X.
%
% FUN can also be an anonymous function:
% X = min(@(x) norm(x),[1;2;3])
% returns a point near the minimizer [0;0;0].
%
% If FUN is parameterized, you can use anonymous functions to capture the
% problem-dependent parameters. Suppose you want to optimize the objective
% given in the function MYFUN, which is parameterized by its second argument A.
% Here MYFUN is an M-file function such as
%
% function F = myfun(x,a)
% f = x(1)^2 + a*x(2)^2;
%
% To optimize for a specific value of A, first assign the value to A. Then
% create a one-argument anonymous function that captures that value of A
% and calls MYFUN with two arguments. Finally, pass this anonymous function
% to FMISEARCH:
%
% a = 1.5; % define parameter first
% x = min(@(x) myfun(x,a),[0.3;1])
defaultopt = struct('Display','notify','MaxIter','200*numberOfVariables',...
'MaxFunEvals','200*numberOfVariables','TolX',1e-4,'TolFun',1e-4, ...
'FunValCheck','off','OutputFcn',[]);
% If just 'defaults' passed in, return the default options in X
if nargin==1 && nargout <= 1 && isequal(funfcn,'defaults')
x = defaultopt;
return
end
if nargin < 2,
error('MATLAB:min:NotEnoughInputs',...
'MIN requires at least two input arguments');
end
if nargin<3, options = []; end
% Check for non-double inputs
if ~isa(x,'double')
error('MATLAB:min:NonDoubleInput', ...
'MIN only accepts inputs of data type double.')
end
n = numel(x);
numberOfVariables = n;
printtype = optimget(options,'Display',defaultopt,'fast');
tolx = optimget(options,'TolX',defaultopt,'fast');
tolf = optimget(options,'TolFun',defaultopt,'fast');
maxfun = optimget(options,'MaxFunEvals',defaultopt,'fast');
maxiter = optimget(options,'MaxIter',defaultopt,'fast');
funValCheck = strcmp(optimget(options,'FunValCheck',defaultopt,'fast'),'on');
% In case the defaults were gathered from calling: optimset('min'):
if ischar(maxfun)
if isequal(lower(maxfun),'200*numberofvariables')
maxfun = 200*numberOfVariables;
else
error('MATLAB:min:OptMaxFunEvalsNotInteger',...
'Option ''MaxFunEvals'' must be an integer value if not the default.')
end
end
if ischar(maxiter)
if isequal(lower(maxiter),'200*numberofvariables')
maxiter = 200*numberOfVariables;
else
error('MATLAB:min:OptMaxIterNotInteger',...
'Option ''MaxIter'' must be an integer value if not the default.')
end
end
switch printtype
case 'notify'
prnt = 1;
case {'none','off'}
prnt = 0;
case 'iter'
prnt = 3;
case 'final'
prnt = 2;
case 'simplex'
prnt = 4;
otherwise
prnt = 1;
end
% Handle the output
outputfcn = optimget(options,'OutputFcn',defaultopt,'fast');
if isempty(outputfcn)
haveoutputfcn = false;
else
haveoutputfcn = true;
xOutputfcn = x; % Last x passed to outputfcn; has the input x's shape
% Convert to function handle as needed.
outputfcn = fcnchk(outputfcn,length(varargin));
end
header = ' Iteration Func-count min f(x) Procedure';
% Convert to function handle as needed.
funfcn = fcnchk(funfcn,length(varargin));
% Add a wrapper function to check for Inf/NaN/complex values
if funValCheck
% Add a wrapper function, CHECKFUN, to check for NaN/complex values without
% having to change the calls that look like this:
% f = funfcn(x,varargin{:});
% x is the first argument to CHECKFUN, then the user's function,
% then the elements of varargin. To accomplish this we need to add the
% user's function to the beginning of varargin, and change funfcn to be
% CHECKFUN.
varargin = {funfcn, varargin{:}};
funfcn = @checkfun;
end
n = numel(x);
% Initialize parameters
rho = 1; chi = 2; psi = 0.5; sigma = 0.5;
onesn = ones(1,n);
two2np1 = 2:n+1;
one2n = 1:n;
% Set up a simplex near the initial guess.
xin = x(:); % Force xin to be a column vector
v = zeros(n,n+1); fv = zeros(1,n+1);
v(:,1) = xin; % Place input guess in the simplex! (credit L.Pfeffer at Stanford)
x(:) = xin; % Change x to the form expected by funfcn
fv(:,1) = funfcn(x,varargin{:});
func_evals = 1;
itercount = 0;
how = '';
% Initialize the output function.
if haveoutputfcn
[xOutputfcn, optimValues, stop] = callOutputFcn(outputfcn,x,xOutputfcn,'init',itercount, ...
func_evals, how, fv(:,1),varargin{:});
if stop
[x,fval,exitflag,output] = cleanUpInterrupt(xOutputfcn,optimValues);
if prnt > 0
disp(output.message)
end
return;
end
end
% Print out initial f(x) as 0th iteration
if prnt == 3
disp(' ')
disp(header)
disp(sprintf(' %5.0f %5.0f %12.6g %s', itercount, func_evals, fv(1), how));
elseif prnt == 4
clc
formatsave = get(0,{'format','formatspacing'});
format compact
format short e
disp(' ')
disp(how)
v
fv
func_evals
end
% OutputFcn call
if haveoutputfcn
[xOutputfcn, optimValues, stop] = callOutputFcn(outputfcn,x,xOutputfcn,'iter',itercount, ...
func_evals, how, fv(:,1),varargin{:});
if stop % Stop per user request.
[x,fval,exitflag,output] = cleanUpInterrupt(xOutputfcn,optimValues);
if prnt > 0
disp(output.message)
end
return;
end
end
% Following improvement suggested by L.Pfeffer at Stanford
usual_delta = 0.05; % 5 percent deltas for non-zero terms
zero_term_delta = 0.00025; % Even smaller delta for zero elements of x
for j = 1:n
y = xin;
if y(j) ~= 0
y(j) = (1 + usual_delta)*y(j);
else
y(j) = zero_term_delta;
end
v(:,j+1) = y;
x(:) = y; f = funfcn(x,varargin{:});
fv(1,j+1) = f;
end
% sort so v(1,:) has the lowest function value
[fv,j] = sort(fv);
v = v(:,j);
how = 'initial simplex';
itercount = itercount + 1;
func_evals = n+1;
if prnt == 3
disp(sprintf(' %5.0f %5.0f %12.6g %s', itercount, func_evals, fv(1), how))
elseif prnt == 4
disp(' ')
disp(how)
v
fv
func_evals
end
% OutputFcn call
if haveoutputfcn
[xOutputfcn, optimValues, stop] = callOutputFcn(outputfcn,x,xOutputfcn,'iter',itercount, ...
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -