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)
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
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
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)
33% x : the solution, size nx1
34% fval : the minimum found
35% exitflag : exit status
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
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
53% abc.consultant Copyright 2018
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
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
64p=length(be);%number of equality constraints
65m=length(bi);%number of inequality constraints
67if length(ub)~=n||length(lb)~=n
68 error([
'lb and ub length must be ',num2str(n)]);
73 error([
'Matrix Ae must have ',num2str(p),
' rows and ',numstr(n),
' columns']);
81 error([
'Matrix Ai must have ',num2str(m),
' rows and ',numstr(n),
' columns']);
86ub=ub(:);lb=lb(:);ub=max(ub,lb);
87%set
default options values
88Maxiter=10*(n+m+p);tol=1e-12;
90 option.maxiter=Maxiter;option.tol=tol;
92 if ~isfield(option,
'maxiter'), option.maxiter=Maxiter;end
93 if ~isfield(option,
'tol'), option.tol=tol;end
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);
101 [Es,Error]=ExtendedFactorization(H,option.tol);
104 output.status=
'H is not positive definite';exitflag=-3;
105 output.iter=[];output.drop=[];
108 R=Es;fr=f;Air=Ai;bir=bi;y1=[];Q=eye(n);
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=[];
120 y2=[];u2=[];%only equality constrained problem
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);
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);
131 lambda.eqlin=-Ae'\(H*x+f+Ai
'*lambda.ineqlin+lambda.upper-lambda.lower);
135 %check for fixed variables
137 gx=H(fixed,:)*x+f(fixed);
138 Lx=find(fixed);nx=length(Lx);
139 %among the two equal bounds only one is active!!
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
149%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%