📄 optimfcnchk.m
字号:
function [allfcns,idandmsg] = optimfcnchk(funstr,caller,lenVarIn,funValCheck,gradflag,hessflag,constrflag,ntheta)
%OPTIMFCNCHK Pre- and post-process function expression for FCNCHK.
%
% This is a helper function.
% [ALLFCNS,idandmsg] = OPTIMFCNCHK(FUNSTR,CALLER,lenVarIn,GRADFLAG) takes
% the (nonempty) function handle or 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 idandmsg.
%
% 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).
%
% If funValCheck is 'on', then we update the funfcn's (fun/grad/hess) so
% they are called through CHECKFUN to check for NaN's, Inf's, or complex
% values. 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{:});
% CHECKFUN is a nested function so we can get the 'caller', 'userfcn', and
% 'ntheta' (for fseminf constraint functions) information from this function
% and the user's function and CHECKFUN can both be called with the same
% arguments.
% NOTE: we assume FUNSTR is nonempty.
% Copyright 1990-2004 The MathWorks, Inc.
% $Revision: 1.1.4.1 $ $Date: 2004/03/26 13:27:21 $
% Initialize
if nargin < 8
ntheta = 0;
if nargin < 7
constrflag = false;
if nargin < 6
hessflag = false;
if nargin < 5
gradflag = false;
end,end,end,end
if constrflag
graderrid = 'optimlib:optimfcnchk:NoConstraintGradientFunction';
graderrmsg = 'Constraint gradient function expected (OPTIONS.GradConstr=''on'') but not found.';
warnid = 'optimlib:optimfcnchk:ConstraintGradientOptionOff';
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
graderrid = 'optimlib:optimfcnchk:NoGradientFunction';
graderrmsg = 'Gradient function expected (OPTIONS.GradObj=''on'') but not found.';
warnid = 'optimlib:optimfcnchk:GradientOptionOff';
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
idandmsg='';
if isequal(caller,'fseminf')
nonlconmsg = 'SEMINFCON must be a function.';
nonlconid = 'optimlib:optimfcnchk:SeminfconNotAFunction';
else
nonlconmsg = 'NONLCON must be a function.';
nonlconid = 'optimlib:optimfcnchk:NonlconNotAFunction';
end
allfcns = {};
funfcn = [];
gradfcn = [];
hessfcn = [];
if gradflag && hessflag
calltype = 'fungradhess';
elseif gradflag
calltype = 'fungrad';
else % ~gradflag & ~hessflag, OR ~gradflag & hessflag: this problem handled later
calltype = 'fun';
end
if isa(funstr, 'cell') && length(funstr)==1 % {fun}
% take the cellarray apart: we know it is nonempty
if gradflag
error(graderrid,graderrmsg)
end
[funfcn, idandmsg] = fcnchk(funstr{1},lenVarIn);
% Insert call to nested function checkfun which calls user funfcn
if funValCheck
userfcn = funfcn;
funfcn = @checkfun; %caller and userfcn are in scope in nested checkfun
end
if ~isempty(idandmsg)
if constrflag % Constraint, not objective, function, so adjust error message
error(nonlconid,nonlconmsg);
else
error(idandmsg);
end
end
elseif isa(funstr, 'cell') && length(funstr)==2 && isempty(funstr{2}) % {fun,[]}
if gradflag
error(graderrid,graderrmsg)
end
[funfcn, idandmsg] = fcnchk(funstr{1},lenVarIn);
if funValCheck
userfcn = funfcn;
funfcn = @checkfun; %caller and userfcn are in scope in nested checkfun
end
if ~isempty(idandmsg)
if constrflag
error(nonlconid,nonlconmsg);
else
error(idandmsg);
end
end
elseif isa(funstr, 'cell') && length(funstr)==2 % {fun, grad} and ~isempty(funstr{2})
[funfcn, idandmsg] = fcnchk(funstr{1},lenVarIn);
if funValCheck
userfcn = funfcn;
funfcn = @checkfun; %caller and userfcn are in scope in nested checkfun
end
if ~isempty(idandmsg)
if constrflag
error(nonlconid,nonlconmsg);
else
error(idandmsg);
end
end
[gradfcn, idandmsg] = fcnchk(funstr{2},lenVarIn);
if funValCheck
userfcn = gradfcn;
gradfcn = @checkfun; %caller and userfcn are in scope in nested checkfun
end
if ~isempty(idandmsg)
if constrflag
error(nonlconid,nonlconmsg);
else
error(idandmsg);
end
end
calltype = 'fun_then_grad';
if ~gradflag
warning(warnid,warnstr);
calltype = 'fun';
end
elseif isa(funstr, 'cell') && length(funstr)==3 ...
&& ~isempty(funstr{1}) && isempty(funstr{2}) && isempty(funstr{3}) % {fun, [], []}
if gradflag
error(graderrid,graderrmsg)
end
if hessflag
error('optimlib:optimfcnchk:NoHessianFunction','Hessian function expected but not found.')
end
[funfcn, idandmsg] = fcnchk(funstr{1},lenVarIn);
if funValCheck
userfcn = funfcn;
funfcn = @checkfun; %caller and userfcn are in scope in nested checkfun
end
if ~isempty(idandmsg)
if constrflag
error(nonlconid,nonlconmsg);
else
error(idandmsg);
end
end
elseif isa(funstr, 'cell') && length(funstr)==3 ...
&& ~isempty(funstr{2}) && ~isempty(funstr{3}) % {fun, grad, hess}
[funfcn, idandmsg] = fcnchk(funstr{1},lenVarIn);
if funValCheck
userfcn = funfcn;
funfcn = @checkfun; %caller and userfcn are in scope in nested checkfun
end
if ~isempty(idandmsg)
if constrflag
error(nonlconid,nonlconmsg);
else
error(idandmsg);
end
end
[gradfcn, idandmsg] = fcnchk(funstr{2},lenVarIn);
if funValCheck
userfcn = gradfcn;
gradfcn = @checkfun; %caller and userfcn are in scope in nested checkfun
end
if ~isempty(idandmsg)
if constrflag
error(nonlconid,nonlconmsg);
else
error(idandmsg);
end
end
[hessfcn, idandmsg] = fcnchk(funstr{3},lenVarIn);
if funValCheck
userfcn = hessfcn;
hessfcn = @checkfun; %caller and userfcn are in scope in nested checkfun
end
if ~isempty(idandmsg)
if constrflag
error(nonlconid,nonlconmsg);
else
error(idandmsg);
end
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('optimlib:optimfcnchk:HessianAndGradientOptionsOff',hwarnstr)
calltype = 'fun';
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -