📄 min.m
字号:
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
exitflag = 1;
% Main algorithm
% Iterate until the diameter of the simplex is less than tolx
% AND the function values differ from the min by less than tolf,
% or the max function evaluations are exceeded. (Cannot use OR instead of
% AND.)
while func_evals < maxfun && itercount < maxiter
if max(abs(fv(1)-fv(two2np1))) <= tolf && ...
max(max(abs(v(:,two2np1)-v(:,onesn)))) <= tolx
break
end
% Compute the reflection point
% xbar = average of the n (NOT n+1) best points
xbar = sum(v(:,one2n), 2)/n;
xr = (1 + rho)*xbar - rho*v(:,end);
x(:) = xr; fxr = funfcn(x,varargin{:});
func_evals = func_evals+1;
if fxr < fv(:,1)
% Calculate the expansion point
xe = (1 + rho*chi)*xbar - rho*chi*v(:,end);
x(:) = xe; fxe = funfcn(x,varargin{:});
func_evals = func_evals+1;
if fxe < fxr
v(:,end) = xe;
fv(:,end) = fxe;
how = 'expand';
else
v(:,end) = xr;
fv(:,end) = fxr;
how = 'reflect';
end
else % fv(:,1) <= fxr
if fxr < fv(:,n)
v(:,end) = xr;
fv(:,end) = fxr;
how = 'reflect';
else % fxr >= fv(:,n)
% Perform contraction
if fxr < fv(:,end)
% Perform an outside contraction
xc = (1 + psi*rho)*xbar - psi*rho*v(:,end);
x(:) = xc; fxc = funfcn(x,varargin{:});
func_evals = func_evals+1;
if fxc <= fxr
v(:,end) = xc;
fv(:,end) = fxc;
how = 'contract outside';
else
% perform a shrink
how = 'shrink';
end
else
% Perform an inside contraction
xcc = (1-psi)*xbar + psi*v(:,end);
x(:) = xcc; fxcc = funfcn(x,varargin{:});
func_evals = func_evals+1;
if fxcc < fv(:,end)
v(:,end) = xcc;
fv(:,end) = fxcc;
how = 'contract inside';
else
% perform a shrink
how = 'shrink';
end
end
if strcmp(how,'shrink')
for j=two2np1
v(:,j)=v(:,1)+sigma*(v(:,j) - v(:,1));
x(:) = v(:,j); fv(:,j) = funfcn(x,varargin{:});
end
func_evals = func_evals + n;
end
end
end
[fv,j] = sort(fv);
v = v(:,j);
itercount = itercount + 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, ...
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
end % while
x(:) = v(:,1);
if prnt == 4,
% reset format
set(0,{'format','formatspacing'},formatsave);
end
output.iterations = itercount;
output.funcCount = func_evals;
output.algorithm = 'Nelder-Mead simplex direct search';
fval = min(fv);
% OutputFcn call
if haveoutputfcn
callOutputFcn(outputfcn,x,xOutputfcn,'done',itercount, func_evals, how, f, varargin{:});
end
if func_evals >= maxfun
msg = sprintf(['Exiting: Maximum number of function evaluations has been exceeded\n' ...
' - increase MaxFunEvals option.\n' ...
' Current function value: %f \n'], fval);
if prnt > 0
disp(' ')
disp(msg)
end
exitflag = 0;
elseif itercount >= maxiter
msg = sprintf(['Exiting: Maximum number of iterations has been exceeded\n' ...
' - increase MaxIter option.\n' ...
' Current function value: %f \n'], fval);
if prnt > 0
disp(' ')
disp(msg)
end
exitflag = 0;
else
msg = ...
sprintf(['Optimization terminated:\n', ...
' the current x satisfies the termination criteria using OPTIONS.TolX of %e \n' ...
' and F(X) satisfies the convergence criteria using OPTIONS.TolFun of %e \n'], ...
tolx, tolf);
if prnt > 1
disp(' ')
disp(msg)
end
exitflag = 1;
end
output.message = msg;
%--------------------------------------------------------------------------
function [xOutputfcn, optimValues, stop] = callOutputFcn(outputfcn,x,xOutputfcn,state,iter,...
numf,how,f,varargin)
% CALLOUTPUTFCN assigns values to the struct OptimValues and then calls the
% outputfcn.
%
% state - can have the values 'init','iter', or 'done'.
% We do not handle the case 'interrupt' because we do not want to update
% xOutputfcn or optimValues (since the values could be inconsistent) before calling
% the outputfcn; in that case the outputfcn is called directly rather than
% calling it inside callOutputFcn.
% For the 'done' state we do not check the value of 'stop' because the
% optimization is already done.
optimValues.iteration = iter;
optimValues.funccount = numf;
optimValues.fval = f;
optimValues.procedure = how;
xOutputfcn(:) = x; % Set x to have user expected size
switch state
case {'iter','init'}
stop = outputfcn(xOutputfcn,optimValues,state,varargin{:});
case 'done'
stop = false;
outputfcn(xOutputfcn,optimValues,state,varargin{:});
otherwise
error('MATLAB:min:InvalidState', ...
'Unknown state in CALLOUTPUTFCN.')
end
%--------------------------------------------------------------------------
function [x,FVAL,EXITFLAG,OUTPUT] = cleanUpInterrupt(xOutputfcn,optimValues)
% CLEANUPINTERRUPT updates or sets all the output arguments of FMINBND when the optimization
% is interrupted.
x = xOutputfcn;
FVAL = optimValues.fval;
EXITFLAG = -1;
OUTPUT.iterations = optimValues.iteration;
OUTPUT.funcCount = optimValues.funccount;
OUTPUT.algorithm = 'golden section search, parabolic interpolation';
OUTPUT.message = 'Optimization terminated prematurely by user.';
%--------------------------------------------------------------------------
function f = checkfun(x,userfcn,varargin)
% CHECKFUN checks for complex or NaN results from userfcn.
f = userfcn(x,varargin{:});
% Note: we do not check for Inf as MIN handles it naturally.
if isnan(f)
error('MATLAB:min:checkfun:NaNFval', ...
'User function ''%s'' returned NaN when evaluated at %g;\n MIN cannot continue.', ...
localChar(userfcn), x);
elseif ~isreal(f)
error('MATLAB:min:checkfun:ComplexFval', ...
'User function ''%s'' returned a complex value when evaluated at %g;\n MIN cannot continue.', ...
localChar(userfcn),x);
end
%--------------------------------------------------------------------------
function strfcn = localChar(fcn)
% Convert the fcn to a string for printing
if ischar(fcn)
strfcn = fcn;
elseif isa(fcn,'inline')
strfcn = char(fcn);
elseif isa(fcn,'function_handle')
strfcn = func2str(fcn);
else
try
strfcn = char(fcn);
catch
strfcn = '(name not printable)';
end
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -