LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
QP.m
1function [x,fval,exitflag,output,lambda]=QP(H,f,Ai,bi,Ae,be,lb,ub,option)
2% [x,fmin,errflag,output,lambda]=QP(H,f,Ai,bi,Ae,be,bi,lb,ub,option)
3% [x,fmin,errflag,output,lambda]=QP(H,f,Ai,bi,Ae,be,lb,ub)
4% [x,fmin,errflag,output,lambda]=QP(H,f,Ai,bi,Ae,be,lb)
5% [x,fmin,errflag,output,lambda]=QP(H,f,Ai,bi,Ae,be)
6% [x,fmin,errflag,output,lambda]=QP(H,f,Ai,bi)
7% [x,fmin,errflag,output,lambda]=QP(H,f)
8%
9% Solves dense General Convex Quadratic Program :
10% min 0.5*x'*H*x + f'*x , such that Ae*x=be; Ai*x<=bi; lb<=x<=ub
11% x
12% with the following hypothesis :H'=H>=0 and rank([H;Ae])=n
13% i.e. reduced Hessian > 0 when Ae is not empty
14% Hessian H > 0 when Ae is empty
15%
16% Input
17% H : cost H term, H'=H>=0 matrix, size nxn
18% f : cost f term , size nx1
19% Ai : The inequality constraint matrix, size mxn, m>=0
20% bi : The right hand side, size mx1
21% Ae : The equality constraint matrix, size pxn, p>=0
22% be : The right hand side, size px1
23% lb : defines the lower bounds, lb<=x set lb(j)=-inf for any lower unbounded x(j); size nx1
24% when unspecified, the problem is considered as lower unbounded
25% ub : defines the upper bounds, x<=ub; set ub(j)=+inf for any upper unbounded x(j); size nx1
26% when unspecified, the problem is considered as unbounded
27% In any case ub>=lb, fixed variables are supported.
28% option : a structure with 2 fields
29% .maxiter controls the maximum number of iterations, (default 10*(n+m+p);
30% .tol tolerance for infeasibility and linear independance, (default 1e-12)
31%
32% Ouput
33% x : the solution, size nx1
34% fval : the minimum found
35% exitflag : exit status
36% 1 - Proven Optimal
37% 0 - Maximum Iterations reached
38% -1 - Infeasible Linear Equality
39% -2 - Infeasible Linear Inequality
40% -3 - Reduced Hessain singular
41% -4 - Non ConvexQP Problem
42% output : a structure with 4 fields
43% .status strings indicating what happens
44% .iter the number of iterations to achieve convergence
45% .drop the number of removed constraints
46% .tcpu the cpu time
47% lambda : the Lagrange multipliers a structure with fields .lower, .upper, .eqlin, .ineqlin
48% lambda>0 for an active inequality or bound constraint
49% lambda=0 for inactive inequality or bound constraint
50% lambda~=0 for equality constraints
51%
52% Author Alain Barraud
53% abc.consultant Copyright 2018
54%
55%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
56if nargin<2,n=5;f=-ones(n,1);end;if nargin<1,H=eye(n);end%to avoid error
57n=length(f);f=f(:);%problem size
58%set default arguments
59if nargin<8, ub=inf(n,1);end
60if nargin<7, lb=-inf(n,1);end
61if nargin<6, Ae=[];be=[];end
62if nargin<4, Ai=[];bi=[];end
63%get constraints sizes
64p=length(be);%number of equality constraints
65m=length(bi);%number of inequality constraints
66%check parameters
67if length(ub)~=n||length(lb)~=n
68 error(['lb and ub length must be ',num2str(n)]);
69end
70if p>0
71 [pp,nn]=size(Ae);
72 if pp~=p||nn~=n
73 error(['Matrix Ae must have ',num2str(p),' rows and ',numstr(n),' columns']);
74 else
75 be=be(:);
76 end
77end
78if m>0
79 [mm,nn]=size(Ai);
80 if mm~=m||nn~=n
81 error(['Matrix Ai must have ',num2str(m),' rows and ',numstr(n),' columns']);
82 else
83 bi=bi(:);
84 end
85end
86ub=ub(:);lb=lb(:);ub=max(ub,lb);
87%set default options values
88Maxiter=10*(n+m+p);tol=1e-12;
89if nargin<9
90 option.maxiter=Maxiter;option.tol=tol;
91else
92 if ~isfield(option,'maxiter'), option.maxiter=Maxiter;end
93 if ~isfield(option,'tol'), option.tol=tol;end
94end
95tic;
96%%%
97if p>0%Reduce the original QP problem
98 [R,fr,Air,bir,y1,Q,Es,status,Flag]=ReduceQP(H,f,Ae,be,Ai,bi,lb,ub,tol);
99 exitflag=Flag;
100else
101 [Es,Error]=ExtendedFactorization(H,option.tol);
102 Flag=nan;
103 if Error
104 output.status='H is not positive definite';exitflag=-3;
105 output.iter=[];output.drop=[];
106 else
107 exitflag=1;
108 R=Es;fr=f;Air=Ai;bir=bi;y1=[];Q=eye(n);
109 end
110end
111if exitflag<0
112 x=[];fval=[];lambda=[];output.status=status;
113else%solves a inequality contraints strictly convex QP
114 mr=length(bir);%number of inequality constraints
115 if mr>0%call Goldfard and Idnani algorithm
116 [y2,~,exitflag,output,u2]=GoldfarfIdnani(R,fr,Air,bir,option);
117 elseif p==0%unconstrained explicit solution
118 y2=-H\f;u2=[];output.status='OK';output.iter=[];output.drop=[];
119 else
120 y2=[];u2=[];%only equality constrained problem
121 end
122 x=Q*[y1;y2];%full solution
123 if Flag==2;output.status{2}=status;end
124 fval=0.5*sum((Es*x).^2)+f'*x;%optimum value
125 Lu=isfinite(ub);Ll=isfinite(lb);
126 nu=sum(Lu);
127 lambda.ineqlin=u2(1:m);
128 lambda.upper=zeros(n,1);lambda.upper(Lu)=u2(m+1:m+nu);
129 lambda.lower=zeros(n,1);lambda.lower(Ll)=u2(m+nu+1:mr);
130 if p>0
131 lambda.eqlin=-Ae'\‍(H*x+f+Ai'*lambda.ineqlin+lambda.upper-lambda.lower);
132 else
133 lambda.eqlin=[];
134 end
135 %check for fixed variables
136 fixed=lb==ub;
137 gx=H(fixed,:)*x+f(fixed);
138 Lx=find(fixed);nx=length(Lx);
139 %among the two equal bounds only one is active!!
140 for k=1:nx
141 val=max(lambda.lower(Lx(k)),lambda.upper(Lx(k)));
142 %lower bound is active when gradient > 0
143 if gx(k)>0 , lambda.lower(Lx(k))=val;lambda.upper(Lx(k))=0;end
144 %upper bound is active when gradient < 0
145 if gx(k)<0 , lambda.upper(Lx(k))=val;lambda.lower(Lx(k))=0;end
146 end
147end
148output.tcpu=toc;
149%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%