📄 fmincon.m
字号:
[ctmp,ceqtmp] = feval(confcn{3},X,varargin{:});
c = ctmp(:); ceq = ceqtmp(:);
cGRAD = zeros(numberOfVariables,length(c));
ceqGRAD = zeros(numberOfVariables,length(ceq));
catch
if findstr(xlate('Too many output arguments'),lasterr)
if isa(confcn{3},'inline')
errmsg = sprintf('%s%s%s\n%s\n%s\n%s', ...
'The inline function ',formula(confcn{3}),' representing the constraints',...
' must return two outputs: the nonlinear inequality constraints and', ...
' the nonlinear equality constraints. At this time, inline objects may',...
' only return one output argument: use an M-file function instead.');
else
errmsg = sprintf('%s%s%s\n%s%s', ...
'The constraint function ',confcn{3},' must return two outputs:',...
' the nonlinear inequality constraints and', ...
' the nonlinear equality constraints.');
end
error(errmsg)
else
errmsg = sprintf('%s\n%s\n\n%s',...
'FMINCON cannot continue because user supplied nonlinear constraint function', ...
' failed with the following error:', lasterr);
error(errmsg);
end
end
case 'fungrad'
try
[ctmp,ceqtmp,cGRAD,ceqGRAD] = feval(confcn{3},X,varargin{:});
c = ctmp(:); ceq = ceqtmp(:);
catch
errmsg = sprintf('%s\n%s\n\n%s',...
'FMINCON cannot continue because user supplied nonlinear constraint function', ...
' failed with the following error:', lasterr);
error(errmsg);
end
case 'fun_then_grad'
try
[ctmp,ceqtmp] = feval(confcn{3},X,varargin{:});
c = ctmp(:); ceq = ceqtmp(:);
[cGRAD,ceqGRAD] = feval(confcn{4},X,varargin{:});
catch
errmsg = sprintf('%s\n%s%s\n\n%s',...
'FMINCON cannot continue because user supplied nonlinear constraint function', ...
'or nonlinear constraint gradient function',...
' failed with the following error:', lasterr);
error(errmsg);
end
case ''
c=[]; ceq =[];
cGRAD = zeros(numberOfVariables,length(c));
ceqGRAD = zeros(numberOfVariables,length(ceq));
otherwise
error('Undefined calltype in FMINCON');
end
non_eq = length(ceq);
non_ineq = length(c);
[lin_eq,Aeqcol] = size(Aeq);
[lin_ineq,Acol] = size(A);
[cgrow, cgcol]= size(cGRAD);
[ceqgrow, ceqgcol]= size(ceqGRAD);
eq = non_eq + lin_eq;
ineq = non_ineq + lin_ineq;
if ~isempty(Aeq) & Aeqcol ~= numberOfVariables
error('Aeq has the wrong number of columns.')
end
if ~isempty(A) & Acol ~= numberOfVariables
error('A has the wrong number of columns.')
end
if cgrow~=numberOfVariables & cgcol~=non_ineq
error('Gradient of the nonlinear inequality constraints is the wrong size.')
end
if ceqgrow~=numberOfVariables & ceqgcol~=non_eq
error('Gradient of the nonlinear equality constraints is the wrong size.')
end
if diagnostics > 0
% Do diagnostics on information so far
msg = diagnose('fmincon',OUTPUT,gradflag,hessflag,constflag,gradconstflag,...
line_search,options,XOUT,non_eq,...
non_ineq,lin_eq,lin_ineq,l,u,funfcn,confcn,f,GRAD,HESS,c,ceq,cGRAD,ceqGRAD);
end
% call algorithm
if isequal(OUTPUT.algorithm,medium)
[X,FVAL,lambda,EXITFLAG,OUTPUT,GRAD,HESSIAN]=...
nlconst(funfcn,X,l,u,full(A),B,full(Aeq),Beq,confcn,options, ...
verbosity,gradflag,gradconstflag,hessflag,meritFunctionType,...
CHG,f,GRAD,HESS,c,ceq,cGRAD,ceqGRAD,varargin{:});
LAMBDA=lambda;
else
if (isequal(funfcn{1}, 'fun_then_grad_then_hess') | isequal(funfcn{1}, 'fungradhess'))
Hstr=[];
elseif (isequal(funfcn{1}, 'fun_then_grad') | isequal(funfcn{1}, 'fungrad'))
n = length(XOUT);
Hstr = optimget(options,'HessPattern',[]);
if isempty(Hstr)
% Put this code separate as it might generate OUT OF MEMORY error
Hstr = sparse(ones(n));
end
if ischar(Hstr)
Hstr = eval(Hstr);
end
end
if isempty(Aeq)
[X,FVAL,LAMBDA,EXITFLAG,OUTPUT,GRAD,HESSIAN] = ...
sfminbx(funfcn,X,l,u,verbosity,options,computeLambda,f,GRAD,HESS,Hstr,varargin{:});
else
[X,FVAL,LAMBDA,EXITFLAG,OUTPUT,GRAD,HESSIAN] = ...
sfminle(funfcn,X,sparse(Aeq),Beq,verbosity,options,computeLambda,f,GRAD,HESS,Hstr,varargin{:});
end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [allfcns,msg] = fprefcnchk(funstr,caller,lenVarIn,gradflag,hessflag,constrflag)
%PREFCNCHK Pre- and post-process function expression for FUNCHK.
% [ALLFCNS,MSG] = PREFUNCHK(FUNSTR,CALLER,lenVarIn,GRADFLAG) takes
% the (nonempty) expression FUNSTR from CALLER with LenVarIn extra arguments,
% parses it according to what CALLER is, then returns a string or inline
% object in ALLFCNS. If an error occurs, this message is put in MSG.
%
% ALLFCNS is a cell array:
% ALLFCNS{1} contains a flag
% that says if the objective and gradients are together in one function
% (calltype=='fungrad') or in two functions (calltype='fun_then_grad')
% or there is no gradient (calltype=='fun'), etc.
% ALLFCNS{2} contains the string CALLER.
% ALLFCNS{3} contains the objective (or constraint) function
% ALLFCNS{4} contains the gradient function
% ALLFCNS{5} contains the hessian function (not used for constraint function).
%
% NOTE: we assume FUNSTR is nonempty.
% Initialize
if nargin < 6
constrflag = 0;
end
if constrflag
graderrmsg = 'Constraint gradient function expected (OPTIONS.GradConstr==''on'') but not found.';
warnstr = ...
sprintf('%s\n%s\n%s\n','Constraint gradient function provided but OPTIONS.GradConstr==''off'';', ...
' ignoring constraint gradient function and using finite-differencing.', ...
' Rerun with OPTIONS.GradConstr==''on'' to use constraint gradient function.');
else
graderrmsg = 'Gradient function expected OPTIONS.GradObj==''on'' but not found.';
warnstr = ...
sprintf('%s\n%s\n%s\n','Gradient function provided but OPTIONS.GradObj==''off'';', ...
' ignoring gradient function and using finite-differencing.', ...
' Rerun with OPTIONS.GradObj==''on'' to use gradient function.');
end
msg='';
allfcns = {};
funfcn = [];
gradfcn = [];
hessfcn = [];
if gradflag & hessflag
calltype = 'fungradhess';
elseif gradflag
calltype = 'fungrad';
else
calltype = 'fun';
end
% {fun}
if isa(funstr, 'cell') & length(funstr)==1
% take the cellarray apart: we know it is nonempty
if gradflag
error(graderrmsg)
end
[funfcn, msg] = fcnchk(funstr{1},lenVarIn);
if ~isempty(msg)
if constrflag
msg = ['NONLCON must be a function name.'];
end
error(msg);
end
% {fun,[]}
elseif isa(funstr, 'cell') & length(funstr)==2 & isempty(funstr{2})
if gradflag
error(graderrmsg)
end
[funfcn, msg] = fcnchk(funstr{1},lenVarIn);
if ~isempty(msg)
if constrflag
msg = ['NONLCON must be a function name.'];
end
error(msg);
end
% {fun, grad}
elseif isa(funstr, 'cell') & length(funstr)==2 % and ~isempty(funstr{2})
[funfcn, msg] = fcnchk(funstr{1},lenVarIn);
if ~isempty(msg)
if constrflag
msg = ['NONLCON must be a function name.'];
end
error(msg);
end
[gradfcn, msg] = fcnchk(funstr{2},lenVarIn);
if ~isempty(msg)
if constrflag
msg = ['NONLCON must be a function name.'];
end
error(msg);
end
calltype = 'fun_then_grad';
if ~gradflag
warning(warnstr);
calltype = 'fun';
end
% {fun, [], []}
elseif isa(funstr, 'cell') & length(funstr)==3 ...
& ~isempty(funstr{1}) & isempty(funstr{2}) & isempty(funstr{3})
if gradflag
error(graderrmsg)
end
if hessflag
error('Hessian function expected but not found.')
end
[funfcn, msg] = fcnchk(funstr{1},lenVarIn);
if ~isempty(msg)
if constrflag
msg = ['NONLCON must be a function name.'];
end
error(msg);
end
% {fun, grad, hess}
elseif isa(funstr, 'cell') & length(funstr)==3 ...
& ~isempty(funstr{2}) & ~isempty(funstr{3})
[funfcn, msg] = fcnchk(funstr{1},lenVarIn);
if ~isempty(msg)
if constrflag
msg = ['NONLCON must be a function name.'];
end
error(msg);
end
[gradfcn, msg] = fcnchk(funstr{2},lenVarIn);
if ~isempty(msg)
if constrflag
msg = ['NONLCON must be a function name.'];
end
error(msg);
end
[hessfcn, msg] = fcnchk(funstr{3},lenVarIn);
if ~isempty(msg)
if constrflag
msg = ['NONLCON must be a function name.'];
end
error(msg);
end
calltype = 'fun_then_grad_then_hess';
if ~hessflag & ~gradflag
hwarnstr = sprintf('%s\n%s\n%s\n','Hessian and gradient functions provided ', ...
' but OPTIONS.Hessian==''off'' and OPTIONS.GradObj==''off''; ignoring Hessian and gradient functions.', ...
' Rerun with OPTIONS.Hessian==''on'' and OPTIONS.GradObj==''on'' to use derivative functions.');
warning(hwarnstr)
calltype = 'fun';
elseif hessflag & ~gradflag
warnstr = ...
sprintf('%s\n%s\n%s\n','Hessian and gradient functions provided ', ...
' but OPTIONS.GradObj==''off''; ignoring Hessian and gradient functions.', ...
' Rerun with OPTIONS.Hessian==''on'' and OPTIONS.GradObj==''on'' to use derivative functions.');
warning(warnstr)
calltype = 'fun';
elseif ~hessflag & gradflag
hwarnstr = ...
sprintf('%s\n%s\n%s\n','Hessian function provided but OPTIONS.Hessian==''off'';', ...
' ignoring Hessian function,', ...
' Rerun with OPTIONS.Hessian==''on'' to use Hessian function.');
warning(hwarnstr);
calltype = 'fun_then_grad';
end
% {fun, grad, []}
elseif isa(funstr, 'cell') & length(funstr)==3 ...
& ~isempty(funstr{2}) & isempty(funstr{3})
if hessflag
error('Hessian function expected but not found.')
end
[funfcn, msg] = fcnchk(funstr{1},lenVarIn);
if ~isempty(msg)
if constrflag
msg = ['NONLCON must be a function name.'];
end
error(msg);
end
[gradfcn, msg] = fcnchk(funstr{2},lenVarIn);
if ~isempty(msg)
if constrflag
msg = ['NONLCON must be a function name.'];
end
error(msg);
end
calltype = 'fun_then_grad';
if ~gradflag
warning(warnstr);
calltype = 'fun';
end
% {fun, [], hess}
elseif isa(funstr, 'cell') & length(funstr)==3 ...
& isempty(funstr{2}) & ~isempty(funstr{3})
error('Hessian function given without gradient function.')
elseif ~isa(funstr, 'cell') %Not a cell; is a string expression, function name string or inline object
[funfcn, msg] = fcnchk(funstr,lenVarIn);
if ~isempty(msg)
if constrflag
msg = ['NONLCON must be a function name.'];
end
error(msg);
end
if gradflag % gradient and function in one function/M-file
gradfcn = funfcn; % Do this so graderr will print the correct name
end
if hessflag & ~gradflag
hwarnstr = ...
sprintf('%s\n%s\n%s\n','OPTIONS.Hessian==''on'' ', ...
' but OPTIONS.GradObj==''off''; ignoring Hessian and gradient functions.', ...
' Rerun with OPTIONS.Hessian==''on'' and OPTIONS.GradObj==''on'' to use derivative functions.');
warning(hwarnstr)
end
else
errmsg = sprintf('%s\n%s', ...
'FUN must be a function name or inline object;', ...
' or, FUN may be a cell array that contains these type of objects.');
error(errmsg)
end
allfcns{1} = calltype;
allfcns{2} = caller;
allfcns{3} = funfcn;
allfcns{4} = gradfcn;
allfcns{5} = hessfcn;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -