?? qpsub.m
字號:
function [X,lambda,exitflag,output,how,ACTIND,msg] = ...
qpsub(H,f,A,B,lb,ub,X,neqcstr,verbosity,caller,ncstr, ...
numberOfVariables,options,defaultopt,ACTIND,phaseOneTotalScaling)
%QP Quadratic programming subproblem. Handles qp and constrained
% linear least-squares as well as subproblems generated from NLCONST.
%
% X=QP(H,f,A,b) solves the quadratic programming problem:
%
% min 0.5*x'Hx + f'x subject to: Ax <= b
% x
%
% Copyright 1990-2004 The MathWorks, Inc.
% $Revision: 1.37.6.5 $ $Date: 2004/04/20 23:19:27 $
%
% Define constant strings
NewtonStep = 'Newton';
NegCurv = 'negative curvature chol';
ZeroStep = 'zero step';
SteepDescent = 'steepest descent';
Conls = 'lsqlin';
Lp = 'linprog';
Qp = 'quadprog';
Qpsub = 'qpsub';
Nlconst = 'nlconst';
how = 'ok';
exitflag = 1;
output = [];
msg = []; % initialize to ensure appending is successful
iterations = 0;
if nargin < 16
phaseOneTotalScaling = false;
if nargin < 15
ACTIND = [];
if nargin < 13
options = [];
end
end
end
lb=lb(:); ub = ub(:);
if isempty(verbosity), verbosity = 1; end
if isempty(neqcstr), neqcstr = 0; end
LLS = 0;
if strcmp(caller, Conls)
LLS = 1;
[rowH,colH]=size(H);
numberOfVariables = colH;
end
if strcmp(caller, Qpsub)
normalize = -1;
else
normalize = 1;
end
simplex_iter = 0;
if norm(H,'inf')==0 || isempty(H), is_qp=0; else, is_qp=1; end
if LLS==1
is_qp=0;
end
normf = 1;
if normalize > 0
% Check for lp
if ~is_qp && ~LLS
normf = norm(f);
if normf > 0
f = f./normf;
end
end
end
% Handle bounds as linear constraints
arglb = ~eq(lb,-inf);
lenlb=length(lb); % maybe less than numberOfVariables due to old code
if nnz(arglb) > 0
lbmatrix = -eye(lenlb,numberOfVariables);
A=[A; lbmatrix(arglb,1:numberOfVariables)]; % select non-Inf bounds
B=[B;-lb(arglb)];
end
argub = ~eq(ub,inf);
lenub=length(ub);
if nnz(argub) > 0
ubmatrix = eye(lenub,numberOfVariables);
A=[A; ubmatrix(argub,1:numberOfVariables)];
B=[B; ub(argub)];
end
% Bounds are treated as constraints: Reset ncstr accordingly
ncstr=ncstr + nnz(arglb) + nnz(argub);
% Figure out max iteration count
% For linprog/quadprog/lsqlin/qpsub problems, use 'MaxIter' for this.
% For nlconst (fmincon, etc) problems, use 'MaxSQPIter' for this.
if isequal(caller,Nlconst)
maxiter = optimget(options,'MaxSQPIter',defaultopt,'fast');
if ischar(maxiter)
if isequal(lower(maxiter),'10*max(numberofvariables,numberofinequalities+numberofbounds)')
maxiter = 10*max(numberOfVariables,ncstr-neqcstr);
else
error('optim:qpsub:InvalidMaxSQPIter', ...
'Option ''MaxSQPIter'' must be an integer value if not the default.')
end
end
elseif isequal(caller,Lp)
maxiter = optimget(options,'MaxIter',defaultopt,'fast');
if ischar(maxiter)
if isequal(lower(maxiter),'10*max(numberofvariables,numberofinequalities+numberofbounds)')
maxiter = 10*max(numberOfVariables,ncstr-neqcstr);
else
error('optim:qpsub:InvalidMaxIter', ...
'Option ''MaxIter'' must be an integer value if not the default.')
end
end
elseif isequal(caller,Qpsub)
% Feasible point finding phase for qpsub
maxiter = 10*max(numberOfVariables,ncstr-neqcstr);
else
maxiter = optimget(options,'MaxIter',defaultopt,'fast');
end
% Used for determining threshold for whether a direction will violate
% a constraint.
normA = ones(ncstr,1);
if normalize > 0
for i=1:ncstr
n = norm(A(i,:));
if (n ~= 0)
A(i,:) = A(i,:)/n;
B(i) = B(i)/n;
normA(i,1) = n;
end
end
else
normA = ones(ncstr,1);
end
errnorm = 0.01*sqrt(eps);
tolDep = 100*numberOfVariables*eps;
lambda = zeros(ncstr,1);
eqix = 1:neqcstr;
% Modifications for warm-start.
% Do some error checking on the incoming working set indices.
ACTCNT = length(ACTIND);
if isempty(ACTIND)
ACTIND = eqix;
elseif neqcstr > 0
i = max(find(ACTIND<=neqcstr));
if isempty(i) || i > neqcstr % safeguard which should not occur
ACTIND = eqix;
elseif i < neqcstr
% A redundant equality constraint was removed on the last
% SQP iteration. We will go ahead and reinsert it here.
numremoved = neqcstr - i;
ACTIND(neqcstr+1:ACTCNT+numremoved) = ACTIND(i+1:ACTCNT);
ACTIND(1:neqcstr) = eqix;
end
end
aix = zeros(ncstr,1);
aix(ACTIND) = 1;
ACTCNT = length(ACTIND);
ACTSET = A(ACTIND,:);
% Check that the constraints in the initial working set are
% not dependent and find an initial point which satisfies the
% initial working set.
indepInd = 1:ncstr;
remove = [];
if ACTCNT > 0 && normalize ~= -1
% call constraint solver
[Q,R,A,B,X,Z,how,ACTSET,ACTIND,ACTCNT,aix,eqix,neqcstr,ncstr, ...
remove,exitflag,msg]= ...
eqnsolv(A,B,eqix,neqcstr,ncstr,numberOfVariables,LLS,H,X,f, ...
normf,normA,verbosity,aix,ACTSET,ACTIND,ACTCNT,how,exitflag);
if ~isempty(remove)
indepInd(remove)=[];
normA = normA(indepInd);
end
if strcmp(how,'infeasible')
% Equalities are inconsistent, so X and lambda have no valid values
% Return original X and zeros for lambda.
ACTIND = indepInd(ACTIND);
output.iterations = iterations;
exitflag = -2;
return
end
err = 0;
if neqcstr >= numberOfVariables
err = max(abs(A(eqix,:)*X-B(eqix)));
if (err > 1e-8) % Equalities not met
how='infeasible';
exitflag = -2;
msg = sprintf(['Exiting: the equality constraints are overly stringent;\n' ...
' there is no feasible solution.']);
if verbosity > 0
disp(msg)
end
% Equalities are inconsistent, X and lambda have no valid values
% Return original X and zeros for lambda.
ACTIND = indepInd(ACTIND);
output.iterations = iterations;
return
else % Check inequalities
if (max(A*X-B) > 1e-8)
how = 'infeasible';
exitflag = -2;
msg = sprintf(['Exiting: the constraints or bounds are overly stringent;\n' ...
' there is no feasible solution. Equality constraints have been met.']);
if verbosity > 0
disp(msg)
end
end
end
if is_qp
actlambda = -R\(Q'*(H*X+f));
elseif LLS
actlambda = -R\(Q'*(H'*(H*X-f)));
else
actlambda = -R\(Q'*f);
end
lambda(indepInd(ACTIND)) = normf * (actlambda ./normA(ACTIND));
ACTIND = indepInd(ACTIND);
output.iterations = iterations;
return
end
% Check whether in Phase 1 of feasibility point finding.
if (verbosity == -2)
cstr = A*X-B;
mc=max(cstr(neqcstr+1:ncstr));
if (mc > 0)
X(numberOfVariables) = mc + 1;
end
end
else
if ACTCNT == 0 % initial working set is empty
Q = eye(numberOfVariables,numberOfVariables);
R = [];
Z = 1;
else % in Phase I and working set not empty
[Q,R] = qr(ACTSET');
Z = Q(:,ACTCNT+1:numberOfVariables);
end
end
% Find Initial Feasible Solution
cstr = A*X-B;
if ncstr > neqcstr
mc = max(cstr(neqcstr+1:ncstr));
else
mc = 0;
end
if mc > eps
quiet = -2;
optionsPhase1 = []; % Use default options in phase 1
ACTIND2 = 1:neqcstr;
if ~phaseOneTotalScaling
A2=[[A;zeros(1,numberOfVariables)],[zeros(neqcstr,1);-ones(ncstr+1-neqcstr,1)]];
else
% Scale the slack variable as well
A2 = [[A [zeros(neqcstr,1);-ones(ncstr-neqcstr,1)]./normA]; ...
[zeros(1,numberOfVariables) -1]];
end
[XS,lambdaS,exitflagS,outputS,howS,ACTIND2] = ...
qpsub([],[zeros(numberOfVariables,1);1],A2,[B;1e-5], ...
[],[],[X;mc+1],neqcstr,quiet,Qpsub,size(A2,1),numberOfVariables+1, ...
optionsPhase1,defaultopt,ACTIND2);
slack = XS(numberOfVariables+1);
X=XS(1:numberOfVariables);
cstr=A*X-B;
if slack > eps
if slack > 1e-8
how='infeasible';
exitflag = -2;
msg = sprintf(['Exiting: the constraints are overly stringent;\n' ...
' no feasible starting point found.']);
if verbosity > 0
disp(msg)
end
else
how = 'overly constrained';
exitflag = -2;
msg = sprintf(['Exiting: the constraints are overly stringent;\n' ...
' initial feasible point found violates constraints\n' ...
' by more than eps.']);
if verbosity > 0
disp(msg)
end
end
lambda(indepInd) = normf * (lambdaS((1:ncstr)')./normA);
ACTIND = 1:neqcstr;
ACTIND = indepInd(ACTIND);
output.iterations = iterations;
return
else
% Initialize active set info based on solution of Phase I.
% ACTIND = ACTIND2(find(ACTIND2<=ncstr));
ACTIND = 1:neqcstr;
ACTSET = A(ACTIND,:);
ACTCNT = length(ACTIND);
aix = zeros(ncstr,1);
aix(ACTIND) = 1;
if ACTCNT == 0
Q = zeros(numberOfVariables,numberOfVariables);
R = [];
Z = 1;
else
[Q,R] = qr(ACTSET');
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -