function [x, iter] = boxcqp(G, d, xl, xu) % % Description: % Solves the convex quadratic minimization problem % % min 1/2 x' G x + x' d % s.t. xl <= x <= xu % % Input: % G : (nxn) Hessian matrix (positive definite) % d : (nx1) linear term % xl: (nx1) lower bound % xu: (nx1) upper bound % % Output: % x : (nx1) Solution % iter: Number of iterations % n = length(d); i = 1:n; % % Inititalize iteration counter iter = 1; % % Calculate initial point (Newton point) l(i) = 0; m(i) = 0; l= l'; m = m'; x = -G \ d; % % Check for feasibility of the Newton point if ( isfeas(x, xu, xl)==0) disp('Newton point solution: ') disp(x); return; end % % Loop until convergence to KKT point while 1>0, % % 1. Step: Define L, U, S sets Lset = find((x=0))>0); Uset = find((x>xu | (x==xu & m>=0))>0); Sset = find(((x>xl & x0); % % 2. Step: Projections x(Lset) = xl(Lset); m(Lset) = 0; x(Uset) = xu(Uset); l(Uset) = 0; m(Sset) = 0; l(Sset) = 0; % % 3. Step: Form reduced Ax = b!!! if (~isempty(Sset)) b(Sset) = 0; b = b'; if (~isempty(Lset)) b(Sset) = b(Sset) - G(Sset,Lset)*xl(Lset); end if (~isempty(Uset)) b(Sset) = b(Sset) - G(Sset,Uset)*xu(Uset); end b(Sset) = b(Sset) - d(Sset); A = G(Sset, Sset); % % 3.1 Calculate x in S x(Sset) = A\b(Sset); clear('A', 'b'); end % % 3.2 Calculate lamda in L if (~isempty(Lset)) l(Lset) = G(Lset, i) * x(i) + d(Lset) ; end % % 3.2 Calculate mu in U if (~isempty(Uset)) m(Uset) = -G(Uset, i) * x(i) - d(Uset); end % 4. Step: Check if KKT conditions are satisfied iter = iter + 1; f = quadratic(G, d, proj(x, xu, xl)); fprintf(1, 'Iter: %i, F = %f \n', iter, f); if (isempty(Sset) | (x(Sset)>xl(Sset) & x(Sset)=0 | isempty(Uset))) if ((~isempty(Lset) & l(Lset)>=0 | isempty(Lset))) disp('Point reached: ') return; end end end % % Extra check: Do not iterate more than 20 times % the problem dimension if iter > n*20 return; end end end % % Check if x is feasible (i.e inside the box defined by xl, xu) function res = isfeas(x, xu, xl) n = length(x); for i=1:n if (x(i)>xu(i) | x(i)=xu(i)) y(i) = xu(i); elseif (x(i)<=xl(i)) y(i) = xl(i); end end end function f = quadratic(B, d, x) f = 1/2 * (x' * B * x) + x'* d; end