当前位置:   article > 正文

MATLAB优化函数fmincon解析_fmincon函数原理

fmincon函数原理

MATLAB,优化函数fmincon解析

[x,fval,exitflag,output,lambda,grad,hessian]=fmincon(fun,x0,A,b,Aeq,beq,lb,ub,nonlcon,options);                                                                                      

输入参数:fun要求解的函数值;x0函数fun参数值的初始化;

                   参数值的线性不等式约束A,b

                  参数值的等式线性约束Aeq,beq,

                   参数值的上界和下界lb,ub

                   非线性约束nonlcon

                 

输出参数:X输出最优参数值

                   Fval输出fun在X参数的值

                   Exitflag输出fmincon额外条件值

  1. function [X,FVAL,EXITFLAG,OUTPUT,LAMBDA,GRAD,HESSIAN] = fmincon(FUN,X,A,B,Aeq,Beq,LB,UB,NONLCON,options,varargin)
  2. /*fmincon可以在多元函数中找到最小值
  3. FMINCON attempts to solve problems of the form:
  4. min F(X) subject to: A*X <= B, Aeq*X = Beq (linear constraints)线性约束
  5. X C(X) <= 0, Ceq(X) = 0 (nonlinear constraints)非线性约束
  6. LB <= X <= UB (bounds)
  7. */
  8. /*FMINCON implements four different algorithms: interior point, SQP,
  9. % active set, and trust region reflective. Choose one via the option
  10. % Algorithm: for instance, to choose SQP, set OPTIONS =
  11. % optimoptions('fmincon','Algorithm','sqp'), and then pass OPTIONS to
  12. % FMINCON.
  13. fmincon函数应用四种不同的算法:内点法(interior point);序列二次规划算法(SQP);有效集法(active set);信赖域有效算法(trust region reflective)。
  14. 如果采用SQP算法可以设置 OPTIONS = optimoptions('fmincon','Algorithm','sqp'),再把OPTIONS赋给fmincon
  15. */
  16. /*
  17. % X = FMINCON(FUN,X0,A,B) starts at X0 and finds a minimum X to the
  18. % function FUN, subject to the linear inequalities A*X <= B. FUN accepts
  19. % input X and returns a scalar function value F evaluated at X. X0 may be
  20. % a scalar, vector, or matrix.
  21. %
  22. % X = FMINCON(FUN,X0,A,B,Aeq,Beq) minimizes FUN subject to the linear
  23. % equalities Aeq*X = Beq as well as A*X <= B. (Set A=[] and B=[] if no
  24. % inequalities exist.)
  25. %
  26. % X = FMINCON(FUN,X0,A,B,Aeq,Beq,LB,UB) defines a set of lower and upper
  27. % bounds on the design variables, X, so that a solution is found in
  28. % the range LB <= X <= UB. Use empty matrices for LB and UB
  29. % if no bounds exist. Set LB(i) = -Inf if X(i) is unbounded below;
  30. % set UB(i) = Inf if X(i) is unbounded above.
  31. %
  32. % X = FMINCON(FUN,X0,A,B,Aeq,Beq,LB,UB,NONLCON) subjects the minimization
  33. % to the constraints defined in NONLCON. The function NONLCON accepts X
  34. % and returns the vectors C and Ceq, representing the nonlinear
  35. % inequalities and equalities respectively. FMINCON minimizes FUN such
  36. % that C(X) <= 0 and Ceq(X) = 0. (Set LB = [] and/or UB = [] if no bounds
  37. % exist.)
  38. %
  39. % X = FMINCON(FUN,X0,A,B,Aeq,Beq,LB,UB,NONLCON,OPTIONS) minimizes with
  40. % the default optimization parameters replaced by values in OPTIONS, an
  41. % argument created with the OPTIMOPTIONS function. See OPTIMOPTIONS for
  42. % details. For a list of options accepted by FMINCON refer to the
  43. % documentation.
  44. %
  45. % X = FMINCON(PROBLEM) finds the minimum for PROBLEM. PROBLEM is a
  46. % structure with the function FUN in PROBLEM.objective, the start point
  47. % in PROBLEM.x0, the linear inequality constraints in PROBLEM.Aineq
  48. % and PROBLEM.bineq, the linear equality constraints in PROBLEM.Aeq and
  49. % PROBLEM.beq, the lower bounds in PROBLEM.lb, the upper bounds in
  50. % PROBLEM.ub, the nonlinear constraint function in PROBLEM.nonlcon, the
  51. % options structure in PROBLEM.options, and solver name 'fmincon' in
  52. % PROBLEM.solver. Use this syntax to solve at the command line a problem
  53. % exported from OPTIMTOOL. The structure PROBLEM must have all the fields.
  54. %
  55. % [X,FVAL] = FMINCON(FUN,X0,...) returns the value of the objective
  56. % function FUN at the solution X.
  57. %
  58. % [X,FVAL,EXITFLAG] = FMINCON(FUN,X0,...) returns an EXITFLAG that
  59. % describes the exit condition of FMINCON. Possible values of EXITFLAG
  60. % and the corresponding exit conditions are listed below. See the
  61. % documentation for a complete description.
  62. % */
  63. /*
  64. % All algorithms:
  65. % 1 First order optimality conditions satisfied.
  66. % 0 Too many function evaluations or iterations.
  67. % -1 Stopped by output/plot function.
  68. % -2 No feasible point found.
  69. % Trust-region-reflective, interior-point, and sqp:
  70. % 2 Change in X too small.
  71. % Trust-region-reflective:
  72. % 3 Change in objective function too small.
  73. % Active-set only:
  74. % 4 Computed search direction too small.
  75. % 5 Predicted change in objective function too small.
  76. % Interior-point and sqp:
  77. % -3 Problem seems unbounded.
  78. 所有算法中EXITFLAG返回值涵义
  79. 1 满足一阶最优性条件
  80. 0 函数计算或迭代太多。无法求解
  81. -1 被输出和绘图功能阻止
  82. -2 找不到可行点
  83. Trust-region-reflective, interior-point, and sqp:三种算法才有的返回值
  84. 2 X变化太小
  85. Active-set 算法才有的返回值
  86. 4 计算搜索的方向太小
  87. 5 目标函数的预测变化太小。
  88. Interior-point and sqp才有的
  89. -3 问题没有边界
  90. */
  91. /*
  92. % [X,FVAL,EXITFLAG,OUTPUT] = FMINCON(FUN,X0,...) returns a structure
  93. % OUTPUT with information such as total number of iterations, and final
  94. % objective function value. See the documentation for a complete list.
  95. 返回包含迭代总数和最终目标函数值等信息的结构输出
  96. */
  97. /*
  98. % [X,FVAL,EXITFLAG,OUTPUT,LAMBDA] = FMINCON(FUN,X0,...) returns the
  99. % Lagrange multipliers at the solution X: LAMBDA.lower for LB,
  100. % LAMBDA.upper for UB, LAMBDA.ineqlin is for the linear inequalities,
  101. % LAMBDA.eqlin is for the linear equalities, LAMBDA.ineqnonlin is for the
  102. % nonlinear inequalities, and LAMBDA.eqnonlin is for the nonlinear
  103. % equalities.
  104. 返回解x处的拉格朗日乘数:lambda.lower表示lb,lambda.upper表示ub,
  105. lambda.ineqlin表示线性不等式,lambda.eqlin表示线性等式,
  106. lambda.ineqnonlin表示非线性不等式,lambda.eqnonlin表示非线性不等式。
  107. */
  108. /*
  109. % [X,FVAL,EXITFLAG,OUTPUT,LAMBDA,GRAD] = FMINCON(FUN,X0,...) returns the
  110. % value of the gradient of FUN at the solution X.
  111. 返回解决方案x的fun渐变值。
  112. %*/
  113. /* [X,FVAL,EXITFLAG,OUTPUT,LAMBDA,GRAD,HESSIAN] = FMINCON(FUN,X0,...)
  114. % returns the value of the exact or approximate Hessian of the Lagrangian
  115. % at X.
  116. 返回X的朗格朗日精确解或者近似Hessian矩阵
  117. */
  118. /* Examples
  119. % FUN can be specified using @:
  120. % X = fmincon(@humps,...)
  121. % In this case, F = humps(X) returns the scalar function value F of
  122. % the HUMPS function evaluated at X.
  123. %
  124. % FUN can also be an anonymous function:
  125. % X = fmincon(@(x) 3*sin(x(1))+exp(x(2)),[1;1],[],[],[],[],[0 0])
  126. % returns X = [0;0].
  127. %
  128. % If FUN or NONLCON are parameterized, you can use anonymous functions to
  129. % capture the problem-dependent parameters. Suppose you want to minimize
  130. % the objective given in the function myfun, subject to the nonlinear
  131. % constraint mycon, where these two functions are parameterized by their
  132. % second argument a1 and a2, respectively. Here myfun and mycon are
  133. % MATLAB file functions such as
  134. %
  135. % function f = myfun(x,a1)
  136. % f = x(1)^2 + a1*x(2)^2;
  137. %
  138. % function [c,ceq] = mycon(x,a2)
  139. % c = a2/x(1) - x(2);
  140. % ceq = [];
  141. %
  142. % To optimize for specific values of a1 and a2, first assign the values
  143. % to these two parameters. Then create two one-argument anonymous
  144. % functions that capture the values of a1 and a2, and call myfun and
  145. % mycon with two arguments. Finally, pass these anonymous functions to
  146. % FMINCON:
  147. %
  148. % a1 = 2; a2 = 1.5; % define parameters first
  149. % options = optimoptions('fmincon','Algorithm','interior-point'); % run interior-point algorithm
  150. % x = fmincon(@(x) myfun(x,a1),[1;2],[],[],[],[],[],[],@(x) mycon(x,a2),options)
  151. %
  152. % See also OPTIMOPTIONS, OPTIMTOOL, FMINUNC, FMINBND, FMINSEARCH, @, FUNCTION_HANDLE.
  153. % Copyright 1990-2013 The MathWorks, Inc.
  154. */
  155. defaultopt = struct( ...
  156. 'Algorithm','interior-point', ...
  157. 'AlwaysHonorConstraints','bounds', ...
  158. 'DerivativeCheck','off', ...
  159. 'Diagnostics','off', ...
  160. 'DiffMaxChange',Inf, ...
  161. 'DiffMinChange',0, ...
  162. 'Display','final', ...
  163. 'FinDiffRelStep', [], ...
  164. 'FinDiffType','forward', ...
  165. 'FunValCheck','off', ...
  166. 'GradConstr','off', ...
  167. 'GradObj','off', ...
  168. 'HessFcn',[], ...
  169. 'Hessian',[], ...
  170. 'HessMult',[], ...
  171. 'HessPattern','sparse(ones(numberOfVariables))', ...
  172. 'InitBarrierParam',0.1, ...
  173. 'InitTrustRegionRadius','sqrt(numberOfVariables)', ...
  174. 'MaxFunEvals',[], ...
  175. 'MaxIter',[], ...
  176. 'MaxPCGIter','max(1,floor(numberOfVariables/2))', ...
  177. 'MaxProjCGIter','2*(numberOfVariables-numberOfEqualities)', ...
  178. 'MaxSQPIter','10*max(numberOfVariables,numberOfInequalities+numberOfBounds)', ...
  179. 'ObjectiveLimit',-1e20, ...
  180. 'OutputFcn',[], ...
  181. 'PlotFcns',[], ...
  182. 'PrecondBandWidth',0, ...
  183. 'RelLineSrchBnd',[], ...
  184. 'RelLineSrchBndDuration',1, ...
  185. 'ScaleProblem','none', ...
  186. 'SubproblemAlgorithm','ldl-factorization', ...
  187. 'TolCon',1e-6, ...
  188. 'TolConSQP',1e-6, ...
  189. 'TolFun',1e-6, ...
  190. 'TolPCG',0.1, ...
  191. 'TolProjCG',1e-2, ...
  192. 'TolProjCGAbs',1e-10, ...
  193. 'TolX',[], ...
  194. 'TypicalX','ones(numberOfVariables,1)', ...
  195. 'UseParallel',false ...
  196. );
  197. % If just 'defaults' passed in, return the default options in X
  198. if nargin==1 && nargout <= 1 && strcmpi(FUN,'defaults')
  199. X = defaultopt;
  200. return
  201. end
  202. if nargin < 10
  203. options = [];
  204. if nargin < 9
  205. NONLCON = [];
  206. if nargin < 8
  207. UB = [];
  208. if nargin < 7
  209. LB = [];
  210. if nargin < 6
  211. Beq = [];
  212. if nargin < 5
  213. Aeq = [];
  214. end
  215. end
  216. end
  217. end
  218. end
  219. end
  220. problemInput = false;
  221. if nargin == 1
  222. if isa(FUN,'struct')
  223. problemInput = true;
  224. [FUN,X,A,B,Aeq,Beq,LB,UB,NONLCON,options] = separateOptimStruct(FUN);
  225. else % Single input and non-structure.
  226. error(message('optimlib:fmincon:InputArg'));
  227. end
  228. end
  229. % Prepare the options for the solver
  230. [options, optionFeedback] = prepareOptionsForSolver(options, 'fmincon');
  231. if nargin < 4 && ~problemInput
  232. error(message('optimlib:fmincon:AtLeastFourInputs'))
  233. end
  234. if isempty(NONLCON) && isempty(A) && isempty(Aeq) && isempty(UB) && isempty(LB)
  235. error(message('optimlib:fmincon:ConstrainedProblemsOnly'))
  236. end
  237. % Check for non-double inputs
  238. msg = isoptimargdbl('FMINCON', {'X0','A','B','Aeq','Beq','LB','UB'}, ...
  239. X, A, B, Aeq, Beq, LB, UB);
  240. if ~isempty(msg)
  241. error('optimlib:fmincon:NonDoubleInput',msg);
  242. end
  243. if nargout > 4
  244. computeLambda = true;
  245. else
  246. computeLambda = false;
  247. end
  248. activeSet = 'medium-scale: SQP, Quasi-Newton, line-search';
  249. sqp = 'sequential quadratic programming';
  250. trustRegionReflective = 'trust-region-reflective';
  251. interiorPoint = 'interior-point';
  252. [sizes.xRows,sizes.xCols] = size(X);
  253. XOUT = X(:);
  254. sizes.nVar = length(XOUT);
  255. % Check for empty X
  256. if sizes.nVar == 0
  257. error(message('optimlib:fmincon:EmptyX'));
  258. end
  259. display = optimget(options,'Display',defaultopt,'fast');
  260. flags.detailedExitMsg = ~isempty(strfind(display,'detailed'));
  261. switch display
  262. case {'off','none'}
  263. verbosity = 0;
  264. case {'notify','notify-detailed'}
  265. verbosity = 1;
  266. case {'final','final-detailed'}
  267. verbosity = 2;
  268. case {'iter','iter-detailed'}
  269. verbosity = 3;
  270. case 'testing'
  271. verbosity = 4;
  272. otherwise
  273. verbosity = 2;
  274. end
  275. % Set linear constraint right hand sides to column vectors
  276. % (in particular, if empty, they will be made the correct
  277. % size, 0-by-1)
  278. B = B(:);
  279. Beq = Beq(:);
  280. % Check for consistency of linear constraints, before evaluating
  281. % (potentially expensive) user functions
  282. % Set empty linear constraint matrices to the correct size, 0-by-n
  283. if isempty(Aeq)
  284. Aeq = reshape(Aeq,0,sizes.nVar);
  285. end
  286. if isempty(A)
  287. A = reshape(A,0,sizes.nVar);
  288. end
  289. [lin_eq,Aeqcol] = size(Aeq);
  290. [lin_ineq,Acol] = size(A);
  291. % These sizes checks assume that empty matrices have already been made the correct size
  292. if Aeqcol ~= sizes.nVar
  293. error(message('optimlib:fmincon:WrongNumberOfColumnsInAeq', sizes.nVar))
  294. end
  295. if lin_eq ~= length(Beq)
  296. error(message('optimlib:fmincon:AeqAndBeqInconsistent'))
  297. end
  298. if Acol ~= sizes.nVar
  299. error(message('optimlib:fmincon:WrongNumberOfColumnsInA', sizes.nVar))
  300. end
  301. if lin_ineq ~= length(B)
  302. error(message('optimlib:fmincon:AeqAndBinInconsistent'))
  303. end
  304. % End of linear constraint consistency check
  305. Algorithm = optimget(options,'Algorithm',defaultopt,'fast');
  306. % Option needed for processing initial guess
  307. AlwaysHonorConstraints = optimget(options,'AlwaysHonorConstraints',defaultopt,'fast');
  308. % Determine algorithm user chose via options. (We need this now
  309. % to set OUTPUT.algorithm in case of early termination due to
  310. % inconsistent bounds.)
  311. if strcmpi(Algorithm,'active-set')
  312. OUTPUT.algorithm = activeSet;
  313. elseif strcmpi(Algorithm,'sqp')
  314. OUTPUT.algorithm = sqp;
  315. elseif strcmpi(Algorithm,'interior-point')
  316. OUTPUT.algorithm = interiorPoint;
  317. elseif strcmpi(Algorithm,'trust-region-reflective')
  318. OUTPUT.algorithm = trustRegionReflective;
  319. else
  320. error(message('optimlib:fmincon:InvalidAlgorithm'));
  321. end
  322. [XOUT,l,u,msg] = checkbounds(XOUT,LB,UB,sizes.nVar);
  323. if ~isempty(msg)
  324. EXITFLAG = -2;
  325. [FVAL,LAMBDA,GRAD,HESSIAN] = deal([]);
  326. OUTPUT.iterations = 0;
  327. OUTPUT.funcCount = 0;
  328. OUTPUT.stepsize = [];
  329. if strcmpi(OUTPUT.algorithm,activeSet) || strcmpi(OUTPUT.algorithm,sqp)
  330. OUTPUT.lssteplength = [];
  331. else % trust-region-reflective, interior-point
  332. OUTPUT.cgiterations = [];
  333. end
  334. if strcmpi(OUTPUT.algorithm,interiorPoint) || strcmpi(OUTPUT.algorithm,activeSet) || ...
  335. strcmpi(OUTPUT.algorithm,sqp)
  336. OUTPUT.constrviolation = [];
  337. end
  338. OUTPUT.firstorderopt = [];
  339. OUTPUT.message = msg;
  340. X(:) = XOUT;
  341. if verbosity > 0
  342. disp(msg)
  343. end
  344. return
  345. end
  346. % Get logical list of finite lower and upper bounds
  347. finDiffFlags.hasLBs = isfinite(l);
  348. finDiffFlags.hasUBs = isfinite(u);
  349. lFinite = l(finDiffFlags.hasLBs);
  350. uFinite = u(finDiffFlags.hasUBs);
  351. % Create structure of flags and initial values, initialize merit function
  352. % type and the original shape of X.
  353. flags.meritFunction = 0;
  354. initVals.xOrigShape = X;
  355. diagnostics = strcmpi(optimget(options,'Diagnostics',defaultopt,'fast'),'on');
  356. funValCheck = strcmpi(optimget(options,'FunValCheck',defaultopt,'fast'),'on');
  357. derivativeCheck = strcmpi(optimget(options,'DerivativeCheck',defaultopt,'fast'),'on');
  358. % Gather options needed for finitedifferences
  359. % Write checked DiffMaxChange, DiffMinChage, FinDiffType, FinDiffRelStep,
  360. % GradObj and GradConstr options back into struct for later use
  361. options.DiffMinChange = optimget(options,'DiffMinChange',defaultopt,'fast');
  362. options.DiffMaxChange = optimget(options,'DiffMaxChange',defaultopt,'fast');
  363. if options.DiffMinChange >= options.DiffMaxChange
  364. error(message('optimlib:fmincon:DiffChangesInconsistent', sprintf( '%0.5g', options.DiffMinChange ), sprintf( '%0.5g', options.DiffMaxChange )))
  365. end
  366. % Read in and error check option TypicalX
  367. [typicalx,ME] = getNumericOrStringFieldValue('TypicalX','ones(numberOfVariables,1)', ...
  368. ones(sizes.nVar,1),'a numeric value',options,defaultopt);
  369. if ~isempty(ME)
  370. throw(ME)
  371. end
  372. checkoptionsize('TypicalX', size(typicalx), sizes.nVar);
  373. options.TypicalX = typicalx;
  374. options.FinDiffType = optimget(options,'FinDiffType',defaultopt,'fast');
  375. options = validateFinDiffRelStep(sizes.nVar,options,defaultopt);
  376. options.GradObj = optimget(options,'GradObj',defaultopt,'fast');
  377. options.GradConstr = optimget(options,'GradConstr',defaultopt,'fast');
  378. flags.grad = strcmpi(options.GradObj,'on');
  379. % Notice that defaultopt.Hessian = [], so the variable "hessian" can be empty
  380. hessian = optimget(options,'Hessian',defaultopt,'fast');
  381. % If calling trust-region-reflective with an unavailable Hessian option value,
  382. % issue informative error message
  383. if strcmpi(OUTPUT.algorithm,trustRegionReflective) && ...
  384. ~( isempty(hessian) || strcmpi(hessian,'on') || strcmpi(hessian,'user-supplied') || ...
  385. strcmpi(hessian,'off') || strcmpi(hessian,'fin-diff-grads') )
  386. error(message('optimlib:fmincon:BadTRReflectHessianValue'))
  387. end
  388. if ~iscell(hessian) && ( strcmpi(hessian,'user-supplied') || strcmpi(hessian,'on') )
  389. flags.hess = true;
  390. else
  391. flags.hess = false;
  392. end
  393. if isempty(NONLCON)
  394. flags.constr = false;
  395. else
  396. flags.constr = true;
  397. end
  398. % Process objective function
  399. if ~isempty(FUN) % will detect empty string, empty matrix, empty cell array
  400. % constrflag in optimfcnchk set to false because we're checking the objective, not constraint
  401. funfcn = optimfcnchk(FUN,'fmincon',length(varargin),funValCheck,flags.grad,flags.hess,false,Algorithm);
  402. else
  403. error(message('optimlib:fmincon:InvalidFUN'));
  404. end
  405. % Process constraint function
  406. if flags.constr % NONLCON is non-empty
  407. flags.gradconst = strcmpi(options.GradConstr,'on');
  408. % hessflag in optimfcnchk set to false because hessian is never returned by nonlinear constraint
  409. % function
  410. %
  411. % constrflag in optimfcnchk set to true because we're checking the constraints
  412. confcn = optimfcnchk(NONLCON,'fmincon',length(varargin),funValCheck,flags.gradconst,false,true);
  413. else
  414. flags.gradconst = false;
  415. confcn = {'','','','',''};
  416. end
  417. [rowAeq,colAeq] = size(Aeq);
  418. if strcmpi(OUTPUT.algorithm,activeSet) || strcmpi(OUTPUT.algorithm,sqp)
  419. % See if linear constraints are sparse and if user passed in Hessian
  420. if issparse(Aeq) || issparse(A)
  421. warning(message('optimlib:fmincon:ConvertingToFull', Algorithm))
  422. end
  423. if flags.hess % conflicting options
  424. flags.hess = false;
  425. warning(message('optimlib:fmincon:HessianIgnoredForAlg', Algorithm));
  426. if strcmpi(funfcn{1},'fungradhess')
  427. funfcn{1}='fungrad';
  428. elseif strcmpi(funfcn{1},'fun_then_grad_then_hess')
  429. funfcn{1}='fun_then_grad';
  430. end
  431. end
  432. elseif strcmpi(OUTPUT.algorithm,trustRegionReflective)
  433. % Look at constraint type and supplied derivatives, and determine if
  434. % trust-region-reflective can solve problem
  435. isBoundedNLP = isempty(NONLCON) && isempty(A) && isempty(Aeq); % problem has only bounds and no other constraints
  436. isLinEqNLP = isempty(NONLCON) && isempty(A) && isempty(lFinite) ...
  437. && isempty(uFinite) && colAeq > rowAeq;
  438. if isBoundedNLP && flags.grad
  439. % if only l and u then call sfminbx
  440. elseif isLinEqNLP && flags.grad
  441. % if only Aeq beq and Aeq has more columns than rows, then call sfminle
  442. else
  443. if ~isBoundedNLP && ~isLinEqNLP
  444. error(message('optimlib:fmincon:ConstrTRR', ...
  445. addLink( 'Choosing the Algorithm', 'choose_algorithm' )))
  446. else
  447. % The user has a problem that satisfies the TRR constraint
  448. % restrictions but they haven't supplied gradients.
  449. error(message('optimlib:fmincon:GradOffTRR', ...
  450. addLink( 'Choosing the Algorithm', 'choose_algorithm' )))
  451. end
  452. end
  453. end
  454. lenvlb = length(l);
  455. lenvub = length(u);
  456. % Process initial point
  457. shiftedX0 = false; % boolean that indicates if initial point was shifted
  458. if strcmpi(OUTPUT.algorithm,activeSet)
  459. %
  460. % Ensure starting point lies within bounds
  461. %
  462. i=1:lenvlb;
  463. lindex = XOUT(i)<l(i);
  464. if any(lindex)
  465. XOUT(lindex)=l(lindex);
  466. shiftedX0 = true;
  467. end
  468. i=1:lenvub;
  469. uindex = XOUT(i)>u(i);
  470. if any(uindex)
  471. XOUT(uindex)=u(uindex);
  472. shiftedX0 = true;
  473. end
  474. X(:) = XOUT;
  475. elseif strcmpi(OUTPUT.algorithm,trustRegionReflective)
  476. %
  477. % If components of initial x not within bounds, set those components
  478. % of initial point to a "box-centered" point
  479. %
  480. if isempty(Aeq)
  481. arg = (u >= 1e10); arg2 = (l <= -1e10);
  482. u(arg) = inf;
  483. l(arg2) = -inf;
  484. xinitOutOfBounds_idx = XOUT < l | XOUT > u;
  485. if any(xinitOutOfBounds_idx)
  486. shiftedX0 = true;
  487. XOUT = startx(u,l,XOUT,xinitOutOfBounds_idx);
  488. X(:) = XOUT;
  489. end
  490. else
  491. % Phase-1 for sfminle nearest feas. pt. to XOUT. Don't print a
  492. % message for this change in X0 for sfminle.
  493. XOUT = feasibl(Aeq,Beq,XOUT);
  494. X(:) = XOUT;
  495. end
  496. elseif strcmpi(OUTPUT.algorithm,interiorPoint)
  497. % Variables: fixed, finite lower bounds, finite upper bounds
  498. xIndices = classifyBoundsOnVars(l,u,sizes.nVar,true);
  499. % If honor bounds mode, then check that initial point strictly satisfies the
  500. % simple inequality bounds on the variables and exactly satisfies fixed variable
  501. % bounds.
  502. if strcmpi(AlwaysHonorConstraints,'bounds') || strcmpi(AlwaysHonorConstraints,'bounds-ineqs')
  503. violatedFixedBnds_idx = XOUT(xIndices.fixed) ~= l(xIndices.fixed);
  504. violatedLowerBnds_idx = XOUT(xIndices.finiteLb) <= l(xIndices.finiteLb);
  505. violatedUpperBnds_idx = XOUT(xIndices.finiteUb) >= u(xIndices.finiteUb);
  506. if any(violatedLowerBnds_idx) || any(violatedUpperBnds_idx) || any(violatedFixedBnds_idx)
  507. XOUT = shiftInitPtToInterior(sizes.nVar,XOUT,l,u,Inf);
  508. X(:) = XOUT;
  509. shiftedX0 = true;
  510. end
  511. end
  512. else % SQP
  513. % Classify variables: finite lower bounds, finite upper bounds
  514. xIndices = classifyBoundsOnVars(l,u,sizes.nVar,false);
  515. % SQP always honors the bounds. Check that initial point
  516. % strictly satisfies the bounds on the variables.
  517. violatedLowerBnds_idx = XOUT(xIndices.finiteLb) < l(xIndices.finiteLb);
  518. violatedUpperBnds_idx = XOUT(xIndices.finiteUb) > u(xIndices.finiteUb);
  519. if any(violatedLowerBnds_idx) || any(violatedUpperBnds_idx)
  520. finiteLbIdx = find(xIndices.finiteLb);
  521. finiteUbIdx = find(xIndices.finiteUb);
  522. XOUT(finiteLbIdx(violatedLowerBnds_idx)) = l(finiteLbIdx(violatedLowerBnds_idx));
  523. XOUT(finiteUbIdx(violatedUpperBnds_idx)) = u(finiteUbIdx(violatedUpperBnds_idx));
  524. X(:) = XOUT;
  525. shiftedX0 = true;
  526. end
  527. end
  528. % Display that x0 was shifted in order to honor bounds
  529. if shiftedX0
  530. if verbosity >= 3
  531. if strcmpi(OUTPUT.algorithm,interiorPoint)
  532. fprintf(getString(message('optimlib:fmincon:ShiftX0StrictInterior')));
  533. fprintf('\n');
  534. else
  535. fprintf(getString(message('optimlib:fmincon:ShiftX0ToBnds')));
  536. fprintf('\n');
  537. end
  538. end
  539. end
  540. % Evaluate function
  541. initVals.g = zeros(sizes.nVar,1);
  542. HESSIAN = [];
  543. switch funfcn{1}
  544. case 'fun'
  545. try
  546. initVals.f = feval(funfcn{3},X,varargin{:});
  547. catch userFcn_ME
  548. optim_ME = MException('optimlib:fmincon:ObjectiveError', ...
  549. getString(message('optimlib:fmincon:ObjectiveError')));
  550. userFcn_ME = addCause(userFcn_ME,optim_ME);
  551. rethrow(userFcn_ME)
  552. end
  553. case 'fungrad'
  554. try
  555. [initVals.f,initVals.g] = feval(funfcn{3},X,varargin{:});
  556. catch userFcn_ME
  557. optim_ME = MException('optimlib:fmincon:ObjectiveError', ...
  558. getString(message('optimlib:fmincon:ObjectiveError')));
  559. userFcn_ME = addCause(userFcn_ME,optim_ME);
  560. rethrow(userFcn_ME)
  561. end
  562. case 'fungradhess'
  563. try
  564. [initVals.f,initVals.g,HESSIAN] = feval(funfcn{3},X,varargin{:});
  565. catch userFcn_ME
  566. optim_ME = MException('optimlib:fmincon:ObjectiveError', ...
  567. getString(message('optimlib:fmincon:ObjectiveError')));
  568. userFcn_ME = addCause(userFcn_ME,optim_ME);
  569. rethrow(userFcn_ME)
  570. end
  571. case 'fun_then_grad'
  572. try
  573. initVals.f = feval(funfcn{3},X,varargin{:});
  574. catch userFcn_ME
  575. optim_ME = MException('optimlib:fmincon:ObjectiveError', ...
  576. getString(message('optimlib:fmincon:ObjectiveError')));
  577. userFcn_ME = addCause(userFcn_ME,optim_ME);
  578. rethrow(userFcn_ME)
  579. end
  580. try
  581. initVals.g = feval(funfcn{4},X,varargin{:});
  582. catch userFcn_ME
  583. optim_ME = MException('optimlib:fmincon:GradientError', ...
  584. getString(message('optimlib:fmincon:GradientError')));
  585. userFcn_ME = addCause(userFcn_ME,optim_ME);
  586. rethrow(userFcn_ME)
  587. end
  588. case 'fun_then_grad_then_hess'
  589. try
  590. initVals.f = feval(funfcn{3},X,varargin{:});
  591. catch userFcn_ME
  592. optim_ME = MException('optimlib:fmincon:ObjectiveError', ...
  593. getString(message('optimlib:fmincon:ObjectiveError')));
  594. userFcn_ME = addCause(userFcn_ME,optim_ME);
  595. rethrow(userFcn_ME)
  596. end
  597. try
  598. initVals.g = feval(funfcn{4},X,varargin{:});
  599. catch userFcn_ME
  600. optim_ME = MException('optimlib:fmincon:GradientError', ...
  601. getString(message('optimlib:fmincon:GradientError')));
  602. userFcn_ME = addCause(userFcn_ME,optim_ME);
  603. rethrow(userFcn_ME)
  604. end
  605. try
  606. HESSIAN = feval(funfcn{5},X,varargin{:});
  607. catch userFcn_ME
  608. optim_ME = MException('optimlib:fmincon:HessianError', ...
  609. getString(message('optimlib:fmincon:HessianError')));
  610. userFcn_ME = addCause(userFcn_ME,optim_ME);
  611. rethrow(userFcn_ME)
  612. end
  613. otherwise
  614. error(message('optimlib:fmincon:UndefinedCallType'));
  615. end
  616. % Check that the objective value is a scalar
  617. if numel(initVals.f) ~= 1
  618. error(message('optimlib:fmincon:NonScalarObj'))
  619. end
  620. % Check that the objective gradient is the right size
  621. initVals.g = initVals.g(:);
  622. if numel(initVals.g) ~= sizes.nVar
  623. error('optimlib:fmincon:InvalidSizeOfGradient', ...
  624. getString(message('optimlib:commonMsgs:InvalidSizeOfGradient',sizes.nVar)));
  625. end
  626. % Evaluate constraints
  627. switch confcn{1}
  628. case 'fun'
  629. try
  630. [ctmp,ceqtmp] = feval(confcn{3},X,varargin{:});
  631. catch userFcn_ME
  632. if strcmpi('MATLAB:maxlhs',userFcn_ME.identifier)
  633. error(message('optimlib:fmincon:InvalidHandleNonlcon'))
  634. else
  635. optim_ME = MException('optimlib:fmincon:NonlconError', ...
  636. getString(message('optimlib:fmincon:NonlconError')));
  637. userFcn_ME = addCause(userFcn_ME,optim_ME);
  638. rethrow(userFcn_ME)
  639. end
  640. end
  641. initVals.ncineq = ctmp(:);
  642. initVals.nceq = ceqtmp(:);
  643. initVals.gnc = zeros(sizes.nVar,length(initVals.ncineq));
  644. initVals.gnceq = zeros(sizes.nVar,length(initVals.nceq));
  645. case 'fungrad'
  646. try
  647. [ctmp,ceqtmp,initVals.gnc,initVals.gnceq] = feval(confcn{3},X,varargin{:});
  648. catch userFcn_ME
  649. optim_ME = MException('optimlib:fmincon:NonlconError', ...
  650. getString(message('optimlib:fmincon:NonlconError')));
  651. userFcn_ME = addCause(userFcn_ME,optim_ME);
  652. rethrow(userFcn_ME)
  653. end
  654. initVals.ncineq = ctmp(:);
  655. initVals.nceq = ceqtmp(:);
  656. case 'fun_then_grad'
  657. try
  658. [ctmp,ceqtmp] = feval(confcn{3},X,varargin{:});
  659. catch userFcn_ME
  660. optim_ME = MException('optimlib:fmincon:NonlconError', ...
  661. getString(message('optimlib:fmincon:NonlconError')));
  662. userFcn_ME = addCause(userFcn_ME,optim_ME);
  663. rethrow(userFcn_ME)
  664. end
  665. initVals.ncineq = ctmp(:);
  666. initVals.nceq = ceqtmp(:);
  667. try
  668. [initVals.gnc,initVals.gnceq] = feval(confcn{4},X,varargin{:});
  669. catch userFcn_ME
  670. optim_ME = MException('optimlib:fmincon:NonlconFunOrGradError', ...
  671. getString(message('optimlib:fmincon:NonlconFunOrGradError')));
  672. userFcn_ME = addCause(userFcn_ME,optim_ME);
  673. rethrow(userFcn_ME)
  674. end
  675. case ''
  676. % No nonlinear constraints. Reshaping of empty quantities is done later
  677. % in this file, where both cases, (i) no nonlinear constraints and (ii)
  678. % nonlinear constraints that have one type missing (equalities or
  679. % inequalities), are handled in one place
  680. initVals.ncineq = [];
  681. initVals.nceq = [];
  682. initVals.gnc = [];
  683. initVals.gnceq = [];
  684. otherwise
  685. error(message('optimlib:fmincon:UndefinedCallType'));
  686. end
  687. % Check for non-double data typed values returned by user functions
  688. if ~isempty( isoptimargdbl('FMINCON', {'f','g','H','c','ceq','gc','gceq'}, ...
  689. initVals.f, initVals.g, HESSIAN, initVals.ncineq, initVals.nceq, initVals.gnc, initVals.gnceq) )
  690. error('optimlib:fmincon:NonDoubleFunVal',getString(message('optimlib:commonMsgs:NonDoubleFunVal','FMINCON')));
  691. end
  692. sizes.mNonlinEq = length(initVals.nceq);
  693. sizes.mNonlinIneq = length(initVals.ncineq);
  694. % Make sure empty constraint and their derivatives have correct sizes (not 0-by-0):
  695. if isempty(initVals.ncineq)
  696. initVals.ncineq = reshape(initVals.ncineq,0,1);
  697. end
  698. if isempty(initVals.nceq)
  699. initVals.nceq = reshape(initVals.nceq,0,1);
  700. end
  701. if isempty(initVals.gnc)
  702. initVals.gnc = reshape(initVals.gnc,sizes.nVar,0);
  703. end
  704. if isempty(initVals.gnceq)
  705. initVals.gnceq = reshape(initVals.gnceq,sizes.nVar,0);
  706. end
  707. [cgrow,cgcol] = size(initVals.gnc);
  708. [ceqgrow,ceqgcol] = size(initVals.gnceq);
  709. if cgrow ~= sizes.nVar || cgcol ~= sizes.mNonlinIneq
  710. error(message('optimlib:fmincon:WrongSizeGradNonlinIneq', sizes.nVar, sizes.mNonlinIneq))
  711. end
  712. if ceqgrow ~= sizes.nVar || ceqgcol ~= sizes.mNonlinEq
  713. error(message('optimlib:fmincon:WrongSizeGradNonlinEq', sizes.nVar, sizes.mNonlinEq))
  714. end
  715. if diagnostics
  716. % Do diagnostics on information so far
  717. diagnose('fmincon',OUTPUT,flags.grad,flags.hess,flags.constr,flags.gradconst,...
  718. XOUT,sizes.mNonlinEq,sizes.mNonlinIneq,lin_eq,lin_ineq,l,u,funfcn,confcn);
  719. end
  720. % Create default structure of flags for finitedifferences:
  721. % This structure will (temporarily) ignore some of the features that are
  722. % algorithm-specific (e.g. scaling and fault-tolerance) and can be turned
  723. % on later for the main algorithm.
  724. finDiffFlags.fwdFinDiff = strcmpi(options.FinDiffType,'forward');
  725. finDiffFlags.scaleObjConstr = false; % No scaling for now
  726. finDiffFlags.chkFunEval = false; % No fault-tolerance yet
  727. finDiffFlags.chkComplexObj = false; % No need to check for complex values
  728. finDiffFlags.isGrad = true; % Scalar objective
  729. % Check derivatives
  730. if derivativeCheck && ... % User wants to check derivatives...
  731. (flags.grad || ... % of either objective or ...
  732. flags.gradconst && sizes.mNonlinEq+sizes.mNonlinIneq > 0) % nonlinear constraint function.
  733. validateFirstDerivatives(funfcn,confcn,X, ...
  734. l,u,options,finDiffFlags,sizes,varargin{:});
  735. end
  736. % call algorithm
  737. if strcmpi(OUTPUT.algorithm,activeSet) % active-set
  738. defaultopt.MaxIter = 400; defaultopt.MaxFunEvals = '100*numberofvariables'; defaultopt.TolX = 1e-6;
  739. defaultopt.Hessian = 'off';
  740. problemInfo = []; % No problem related data
  741. [X,FVAL,LAMBDA,EXITFLAG,OUTPUT,GRAD,HESSIAN]=...
  742. nlconst(funfcn,X,l,u,full(A),B,full(Aeq),Beq,confcn,options,defaultopt, ...
  743. finDiffFlags,verbosity,flags,initVals,problemInfo,optionFeedback,varargin{:});
  744. elseif strcmpi(OUTPUT.algorithm,trustRegionReflective) % trust-region-reflective
  745. if (strcmpi(funfcn{1}, 'fun_then_grad_then_hess') || strcmpi(funfcn{1}, 'fungradhess'))
  746. Hstr = [];
  747. elseif (strcmpi(funfcn{1}, 'fun_then_grad') || strcmpi(funfcn{1}, 'fungrad'))
  748. n = length(XOUT);
  749. Hstr = optimget(options,'HessPattern',defaultopt,'fast');
  750. if ischar(Hstr)
  751. if strcmpi(Hstr,'sparse(ones(numberofvariables))')
  752. Hstr = sparse(ones(n));
  753. else
  754. error(message('optimlib:fmincon:InvalidHessPattern'))
  755. end
  756. end
  757. checkoptionsize('HessPattern', size(Hstr), n);
  758. end
  759. defaultopt.MaxIter = 400; defaultopt.MaxFunEvals = '100*numberofvariables'; defaultopt.TolX = 1e-6;
  760. defaultopt.Hessian = 'off';
  761. % Trust-region-reflective algorithm does not compute constraint
  762. % violation as it progresses. If the user requests the output structure,
  763. % we need to calculate the constraint violation at the returned
  764. % solution.
  765. if nargout > 3
  766. computeConstrViolForOutput = true;
  767. else
  768. computeConstrViolForOutput = false;
  769. end
  770. if isempty(Aeq)
  771. [X,FVAL,LAMBDA,EXITFLAG,OUTPUT,GRAD,HESSIAN] = ...
  772. sfminbx(funfcn,X,l,u,verbosity,options,defaultopt,computeLambda,initVals.f,initVals.g, ...
  773. HESSIAN,Hstr,flags.detailedExitMsg,computeConstrViolForOutput,optionFeedback,varargin{:});
  774. else
  775. [X,FVAL,LAMBDA,EXITFLAG,OUTPUT,GRAD,HESSIAN] = ...
  776. sfminle(funfcn,X,sparse(Aeq),Beq,verbosity,options,defaultopt,computeLambda,initVals.f, ...
  777. initVals.g,HESSIAN,Hstr,flags.detailedExitMsg,computeConstrViolForOutput,optionFeedback,varargin{:});
  778. end
  779. elseif strcmpi(OUTPUT.algorithm,interiorPoint)
  780. defaultopt.MaxIter = 1000; defaultopt.MaxFunEvals = 3000; defaultopt.TolX = 1e-10;
  781. defaultopt.Hessian = 'bfgs';
  782. mEq = lin_eq + sizes.mNonlinEq + nnz(xIndices.fixed); % number of equalities
  783. % Interior-point-specific options. Default values for lbfgs memory is 10, and
  784. % ldl pivot threshold is 0.01
  785. options = getIpOptions(options,sizes.nVar,mEq,flags.constr,defaultopt,10,0.01);
  786. [X,FVAL,EXITFLAG,OUTPUT,LAMBDA,GRAD,HESSIAN] = barrier(funfcn,X,A,B,Aeq,Beq,l,u,confcn,options.HessFcn, ...
  787. initVals.f,initVals.g,initVals.ncineq,initVals.nceq,initVals.gnc,initVals.gnceq,HESSIAN, ...
  788. xIndices,options,optionFeedback,finDiffFlags,varargin{:});
  789. else % sqp
  790. defaultopt.MaxIter = 400; defaultopt.MaxFunEvals = '100*numberofvariables';
  791. defaultopt.TolX = 1e-6; defaultopt.Hessian = 'bfgs';
  792. % Validate options used by sqp
  793. options = getSQPOptions(options,defaultopt,sizes.nVar);
  794. optionFeedback.detailedExitMsg = flags.detailedExitMsg;
  795. % Call algorithm
  796. [X,FVAL,EXITFLAG,OUTPUT,LAMBDA,GRAD,HESSIAN] = sqpLineSearch(funfcn,X,full(A),full(B),full(Aeq),full(Beq), ...
  797. full(l),full(u),confcn,initVals.f,full(initVals.g),full(initVals.ncineq),full(initVals.nceq), ...
  798. full(initVals.gnc),full(initVals.gnceq),xIndices,options,finDiffFlags,verbosity,optionFeedback,varargin{:});
  799. end

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小丑西瓜9/article/detail/350661
推荐阅读
相关标签
  

闽ICP备14008679号