1function [x,fval,exitflag,output,u]=GoldfarfIdnani(R,f,Ai,bi,option)
3% Solves the following strictly Convex QP problem
4%
using Goldfarb Idnani algorithm
5% min 0.5*x
'*(R'*R)*x + f
'*x , such that Ai*x<=bi;
6% with H'=H=R
'*R>0, R is a square regular factorization of H (not necessarely Choleky)
8% R,f,Ai,bi : Problem data
9% option : see calling program
11% x,fval : problem solution and minimun
12% exitflag : 1 optimum found
13% 0 maximum iteration reached
14% -2 Infeasible Inequality Constraints
15%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
16m=length(bi);n=length(f);
21iq=1;R=[];exitflag=1;output.drop=0;
23ListIn=(1:m);opts.UT=
true;iter=0;drop=0;u=zeros(m,1);
24while iter<=option.maxiter%main finite iterative loop
25 nact=setxor(ListIn,W);
26 %%% STEP1: check
for violated constraints
28 ctr = SelectConstraint(x,Ai,bi,nact,option.tol);
29 %all constraints are satisfied or maxiter reached
30 if isempty(ctr.ind)||iter==option.maxiter
31 if iter==option.maxiter
32 exitflag=0;status={
'Maximum iterations reached'};
34 exitflag=1;status={
'OK'};
36 output.iter=iter;output.status=status;output.drop=drop;
40 %%% STEP2: find primal and dual step directions
41 k=ctr.ind;%current constraint
42 d=(Ai(k,:)*J)
';%compute d
43 List=iq:n;z = - J(:,List)*d(List);%update z
45 if ~isempty(List), r=-linsolve(R(List,List),d(List),opts);else, r=[];end%update r
46 if norm(z) < option.tol
49 TauPrimal = (ctr.b - ctr.a'*x)/(ctr.a
'*z);
51 negative_dual_step_ind = find(r < -option.tol);
52 if isempty(W) || isempty(negative_dual_step_ind)
54 DualBlockingIndex = 0;
56 [TauDual,ind] = min(-u(W(negative_dual_step_ind))./r(negative_dual_step_ind));
57 DualBlockingIndex = negative_dual_step_ind(ind);
59 %%% if TauPrimal == TauDual, TauPrimal is chosen
60 [tau, TauCase] = min([TauPrimal, TauDual]);
61 %%% determine new S-pair and make a step
62 if TauPrimal == inf && TauDual == inf% no step in primal and dual space
63 status ={'Infeasible Inequality Constraints
'};
65 output.iter=iter;output.status=status;output.drop=drop;
67 elseif TauPrimal == inf % step in dual space
68 if ~isempty(W),u(W) = u(W) + tau * r;end
70 %%% drop blocking constraint
71 [R,J,iq]=Downdate(R,J,iq,DualBlockingIndex);
72 W(DualBlockingIndex) = [];%#ok
74 FullStep= false; %%% goto STEP2
75 else % step in primal and dual space
76 %TauPrimal < inf & TauDual < inf
78 if ~isempty(W),u(W) = u(W) + tau * r;end
80 if TauCase == 1 % TauPrimal: take a full step
81 %%% TauPrimal <= TauDual
82 %%% add selected primal constraint
84 [R,J,iq]=UpdateRJ(R,J,d,iq,n);
86 FullStep= true; %%% goto STEP1
88 %%% TauPrimal > TauDual & TauDual < inf
89 %%% drop blocking constraint
90 [R,J,iq]=Downdate(R,J,iq,DualBlockingIndex);
91 W(DualBlockingIndex) = [];%#ok
93 FullStep= false; %%% goto STEP2
98%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
99function ctr=SelectConstraint(x,Ai,bi,nact,tol)
100s=Ai*x-bi;s=s(nact);[val,ind]=max(s);
101if val> tol, ind=nact(ind);else, ind=[];end
102ctr.ind = ind;ctr.u = 0;ctr.a = Ai(ind,:)';ctr.b = bi(ind);
103%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
104function [R,J,iq]=UpdateRJ(R,J,d,iq,n)
106[R(:,iq),u,b]=CHouseholder(d,iqp1:n,iq);
107J=ApplyHouseholder(J,u,b,
'R');
109% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
110function [R,J,iq]=Downdate(R,J,iq,pos)
111R(:,pos)=[];%
delete column pos
112%reduce the Hessenberg part of R to triangular
115 %Compute the Givens rotation such that R(k+1,k)=0
116 [c,s,R(k,k),R(k+1,k)] = CGivens(R(k,k),R(k+1,k));%
117 %Apply the transformation to the following columns from the left
118 [R(k,L),R(k+1,L)] = ApplyGivens(c,s,R(k,L),R(k+1,L),
'L');
119 %apply the transposed transformation to J from the right
120 [J(:,k),J(:,k+1)]=ApplyGivens(c,s,J(:,k),J(:,k+1),
'RT');
123%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%