% function [x,la,flag] = eqp(G,c,A,b,opts) % % solves equality constrained quadratic programming (EQP) problem % % min 1/2 x'*G*x + c'*x % s.t. A*x = b % using the nullspace approach % % opts.tol tolerance for detecting vectors in the nullspace of A % (default 1e-8) % % See Nocedal and Wright section 16.2 % Fernando Guevara Vasquez function [x,la,flag] = eqp(G,c,A,b,opts) flag=0; if (nargin<5) opts=[]; end; % set default tolerance for nullspace of A any diagonal entry in the R of the % QR facto of A smaller than this tolerance indicates the corresponding column % in Q is in the nullspace of A. if (~isfield(opts,'tol')) opts.tol=1e-8; end; % get dimensions n = size(G,1); m=size(A,1); % sanity checks if (m>=n) error('n must be > m'); end; if (any(size(G) ~= [n,n])) error('G must be n x n'); end; if (any(size(A) ~= [m,n])) error('A must be m x n'); end; if (any(size(c) ~= [n,1])) error('c must be n x 1'); end; if (any(size(b) ~= [m,1])) error('b must be m x 1'); end; % obtain a basis Z for the nullspace of the constraints and its orthogonal % complement Y [Q,R,E] = qr(A'); iz = [find(abs(diag(R))0) fprintf('EQP: Hessian is not pos def in null space of constraint\n'); flag=1; x=[]; la=[]; return; end; rhs = - Z'*(G*Y*py) - Z'*g; pz = R\(R'\rhs); % get back solution x = Y*py + Z*pz; % and Lagrange multipliers if needed if (nargout>1) la = ((A*Y)')\(Y'*(g+G*x)); end;