home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 10 / 10.iso / l / l455 / 4.ddi / OPTIM.DI$ / QP.M < prev    next >
Encoding:
Text File  |  1993-03-11  |  12.0 KB  |  474 lines

  1. function [X,lambda,how]=qp(H,f,A,B,vlb,vub,X,neqcstr,verbosity,negdef,normalize)
  2. %QP    Quadratic programming. 
  3. %    X=QP(H,f,A,b) solves the quadratic programming problem:
  4. %
  5. %            min 0.5*x'Hx + f'x   subject to:  Ax <= b 
  6. %             x    
  7. %
  8. %       [x,LAMBDA]=QP(H,f,A,b) returns the set of Lagrangian multipliers,
  9. %       LAMBDA, at the solution.
  10. %
  11. %       X=QP(H,f,A,b,VLB,VUB) defines a set of lower and upper
  12. %       bounds on the design variables, X, so that the solution  
  13. %       is always in the range VLB < X < VUB.
  14. %
  15. %       X=QP(H,f,A,b,VLB,VUB,X0) sets the initial starting point to X0.
  16. %
  17. %       X=QP(H,f,A,b,VLB,VUB,X0,N) indicates that the first N constraints defined
  18. %       by A and b are equality constraints.
  19. %
  20. %       QP produces warning messages when the solution is either unbounded
  21. %       or infeasible. Warning messages can be turned off with the calling
  22. %       syntax: X=QP(H,f,A,b,VLB,VUB,X0,N,-1).
  23.  
  24. %    Copyright (c) 1990 by the MathWorks, Inc.
  25. %    Andy Grace 7-9-90.
  26.  
  27.  
  28. % Handle missing arguments
  29. if nargin < 11, normalize = 1;
  30.     if nargin <    10, negdef = 0; 
  31.         if nargin< 9, verbosity = []; 
  32.             if nargin< 8, neqcstr=[]; 
  33.                 if nargin < 7, X=[]; 
  34.                     if nargin<6, vub=[]; 
  35.                         if nargin<5, vlb=[];
  36. end, end, end, end, end, end, end
  37. [ncstr,nvars]=size(A);
  38. nvars = length(f); % In case A is empty
  39. if ~length(verbosity), verbosity = 0; end
  40. if ~length(neqcstr), neqcstr = 0; end
  41. if ~length(X), X=zeros(nvars,1); end
  42.  
  43. f=f(:);
  44. B=B(:);
  45.  
  46. simplex_iter = 0;
  47. if  norm(H,'inf')==0 | ~length(H), H=0; is_qp=0; else, is_qp=~negdef; end
  48. how = 'ok'; 
  49.  
  50. normf = 1;
  51. if normalize > 0
  52.     if ~is_qp
  53.         normf = norm(f);
  54.         f = f./normf;
  55.     end
  56. end
  57.  
  58. % Handle bounds as linear constraints
  59. lenvlb=length(vlb);
  60. if lenvlb > 0     
  61.     A=[A;-eye(lenvlb,nvars)];
  62.     B=[B;-vlb(:)];
  63. end
  64. lenvub=length(vub);
  65. if lenvub>0
  66.     A=[A;eye(lenvub,nvars)];
  67.     B=[B;vub(:)];
  68. end 
  69. ncstr=ncstr+lenvlb+lenvub;
  70.  
  71. errcstr = 100*sqrt(eps)*norm(A); 
  72. % Used for determining threshold for whether a direction will violate
  73. % a constraint.
  74. normA = ones(ncstr,1);
  75. if normalize > 0 
  76.     for i=1:ncstr
  77.         n = norm(A(i,:));
  78.         if (n ~= 0)
  79.             A(i,:) = A(i,:)/n;
  80.             B(i) = B(i)/n;
  81.             normA(i,1) = n;
  82.         end
  83.     end
  84. else 
  85.     normA = ones(ncstr,1);
  86. end
  87. errnorm = 0.01*sqrt(eps); 
  88.  
  89. lambda=zeros(ncstr,1);
  90. aix=lambda;
  91. ACTCNT=0;
  92. ACTSET=[];
  93. ACTIND=0;
  94. CIND=1;
  95. eqix = 1:neqcstr; 
  96. %------------EQUALITY CONSTRAINTS---------------------------
  97. Q = zeros(nvars,nvars);
  98. R = [];
  99. if neqcstr>0
  100.     aix(eqix)=ones(neqcstr,1);
  101.     ACTSET=A(eqix,:);
  102.     ACTIND=eqix;
  103.     ACTCNT=neqcstr;
  104.     if ACTCNT >= nvars - 1, simplex_iter = 1; end
  105.     CIND=neqcstr+1;
  106.     [Q,R] = qr(ACTSET');
  107.     if max(abs(A(eqix,:)*X-B(eqix)))>1e-10 
  108.         X = ACTSET\B(eqix);
  109.         % X2 = Q*(R'\B(eqix)); does not work here !
  110.     end
  111.     %    Z=null(ACTSET);
  112.     [m,n]=size(ACTSET);
  113.     Z = Q(:,m+1:n);
  114.     err = 0; 
  115.     if neqcstr > nvars 
  116.         err = max(abs(A(eqix,:)*X-B(eqix)));
  117.         if (err > 1e-8) 
  118.             how='infeasible'; 
  119.             if verbosity > -1
  120.                 disp('Warning: The equality constraints are overly stringent;')
  121.                 disp('         there is no feasible solution.') 
  122.             end
  123.         end
  124.         actlambda = -R\(Q'*(H*X+f)); 
  125.         lambda(eqix) = normf * (actlambda ./normA(eqix));
  126.         return
  127.     end
  128.     if ~length(Z) 
  129.         actlambda = -R\(Q'*(H*X+f)); 
  130.         lambda(eqix) = normf * (actlambda./normA(eqix));
  131.         if (max(A*X-B) > 1e-8)
  132.             how = 'infeasible';
  133.             disp('Warning: The constraints or bounds are overly stringent;')
  134.             disp('         there is no feasible solution.') 
  135.             disp('         Equality constraints have been met.')
  136.         end
  137.         return
  138.     end
  139. % Check whether in Phase 1 of feasibility point finding. 
  140.     if (verbosity == -2)
  141.         cstr = A*X-B; 
  142.         mc=max(cstr(neqcstr+1:ncstr));
  143.         if (mc > 0)
  144.             X(nvars) = mc + 1;
  145.         end
  146.     end
  147. else
  148.     Z=1;
  149. end
  150.  
  151. % Find Initial Feasible Solution
  152. cstr = A*X-B;
  153. mc=max(cstr(neqcstr+1:ncstr));
  154. if mc>eps
  155.     A2=[[A;zeros(1,nvars)],[zeros(neqcstr,1);-ones(ncstr+1-neqcstr,1)]];
  156.     [XS,lambdas]=qp([],[zeros(nvars,1);1],A2,[B;1e-5],[],[],[X;mc+1],neqcstr,-2,0,-1);
  157.     X=XS(1:nvars);
  158.     cstr=A*X-B;
  159.     if XS(nvars+1)>eps 
  160.         if XS(nvars+1)>1e-8 
  161.             how='infeasible';
  162.             if verbosity > -1
  163.                 disp('Warning: The constraints are overly stringent;')
  164.                 disp('         there is no feasible solution.')
  165.             end
  166.         else
  167.             how = 'overly constrained';
  168.         end
  169.         lambda = normf * (lambdas(1:ncstr)./normA);
  170.         return
  171.     end
  172. end
  173.  
  174. if (is_qp)
  175.     gf=H*X+f;
  176.     SD=-Z*((Z'*H*Z)\(Z'*gf));
  177. % Check for -ve definite problems:
  178. %  if SD'*gf>0, is_qp = 0; SD=-SD; end
  179. else
  180.     gf = f;
  181.     SD=-Z*Z'*gf;
  182.     if norm(SD) < 1e-10 & neqcstr
  183.         % This happens when equality constraint is perpendicular
  184.         % to objective function f.x.
  185.         actlambda = -R\(Q'*(H*X+f)); 
  186.         lambda(eqix) = normf * (actlambda ./ normA(eqix));
  187.         return;
  188.     end
  189. end
  190. % Sometimes the search direction goes to zero in negative
  191. % definite problems when the initial feasible point rests on
  192. % the top of the quadratic function. In this case we can move in
  193. % any direction to get an improvement in the function so try 
  194. % a random direction.
  195. if negdef
  196.     if norm(SD) < sqrt(eps)
  197.         SD = -Z*Z'*(rand(nvars,1) - 0.5);
  198.     end
  199. end
  200. oldind = 0; 
  201.  
  202.  
  203. t=zeros(10,2);
  204. tt = zeros(10,1);
  205.  
  206. % The maximum number of iterations for a simplex type method is:
  207. % maxiters = prod(1:ncstr)/(prod(1:nvars)*prod(1:max(1,ncstr-nvars)));
  208.  
  209. %--------------Main Routine-------------------
  210. while 1
  211. % Find distance we can move in search direction SD before a 
  212. % constraint is violated.
  213.     % Gradient with respect to search direction.
  214.     GSD=A*SD;
  215.  
  216.     % Note: we consider only constraints whose gradients are greater
  217.     % than some threshold. If we considered all gradients greater than 
  218.     % zero then it might be possible to add a constraint which would lead to
  219.     % a singular (rank deficient) working set. The gradient (GSD) of such
  220.     % a constraint in the direction of search would be very close to zero.
  221.     indf = find((GSD > errnorm * norm(SD))  &  ~aix);
  222.  
  223.     if ~length(indf)
  224.         STEPMIN=1e16;
  225.     else
  226.         dist = abs(cstr(indf)./GSD(indf));
  227.         [STEPMIN,ind2] =  min(dist);
  228.         ind2 = find(dist == STEPMIN);
  229. % Bland's rule for anti-cycling: if there is more than one blocking constraint
  230. % then add the one with the smallest index.
  231.         ind=indf(min(ind2));
  232. % Non-cycling rule:
  233.         % ind = indf(ind2(1));
  234.     end
  235. %------------------QP-------------
  236.     if (is_qp) 
  237. % If STEPMIN is 1 then this is the exact distance to the solution.
  238.         if STEPMIN>=1
  239.             X=X+SD;
  240.             if ACTCNT>0
  241.                 if ACTCNT>=nvars-1, ACTSET(CIND,:)=[];ACTIND(CIND)=[]; end
  242.                 
  243.                 rlambda = -R\(Q'*(H*X+f));
  244.                 actlambda = rlambda;
  245.                 actlambda(eqix) = abs(rlambda(eqix));
  246.                 indlam = find(actlambda < 0);
  247.                 if (~length(indlam)) 
  248.                     lambda(ACTIND) = normf * (rlambda./normA(ACTIND));
  249.                     return
  250.                 end
  251. % Remove constraint
  252.                 lind = find(ACTIND == min(ACTIND(indlam)));
  253.                 lind=lind(1);
  254.                 ACTSET(lind,:) = [];
  255.                 aix(ACTIND(lind)) = 0;
  256.                 [Q,R]=qrdelete(Q,R,lind);
  257.                 ACTIND(lind) = [];
  258.                 ACTCNT = ACTCNT - 2;
  259.                 simplex_iter = 0;
  260.                 ind = 0;
  261.             else
  262.                 return
  263.             end
  264.         else
  265.             X=X+STEPMIN*SD;
  266.         end
  267.         % Calculate gradient w.r.t objective at this point
  268.         gf=H*X+f;
  269.     else 
  270.         % Unbounded Solution
  271.         if ~length(indf) | ~finite(STEPMIN)
  272.             if norm(SD) > errnorm
  273.                 if normalize < 0
  274.                     STEPMIN=abs((X(nvars)+1e-5)/(SD(nvars)+eps));
  275.                 else 
  276.                     STEPMIN = 1e16;
  277.                 end
  278.                 X=X+STEPMIN*SD;
  279.                 how='unbounded'; 
  280.             else
  281.                 how = 'ill posed';
  282.             end
  283. keyboard
  284.             if verbosity > -1
  285.                 if norm(SD) > errnorm
  286.                     disp('Warning: The solution is unbounded and at infinity;')
  287.                     disp('         the constraints are not restrictive enough.') 
  288.                 else
  289.                     disp('Warning: The search direction is close to zero; the problem is ill posed.')
  290.                     disp('         The gradient of the objective function may be zero')
  291.                     disp('         or the problem may be badly conditioned.')
  292.                 end
  293.             end
  294.             return
  295.         else 
  296.             X=X+STEPMIN*SD;
  297.         end
  298.     end %if (qp)
  299.  
  300. % Update X and calculate constraints
  301.     cstr = A*X-B;
  302.     cstr(eqix) = abs(cstr(eqix));
  303. % Check no constraint is violated
  304.     if normalize < 0 
  305.         if X(nvars,1) < eps
  306.             return;
  307.         end
  308.     end
  309.             
  310.     if max(cstr) > 1e5 * errnorm
  311.         if max(cstr) > norm(X) * errnorm 
  312.             if verbosity > -1
  313.                 disp('Warning: The problem is badly conditioned;')
  314.                 disp('         the solution is not reliable') 
  315.                 verbosity = -1;
  316.             end
  317.             how='unreliable'; 
  318.             if 0
  319.                 X=X-STEPMIN*SD;
  320.                 return
  321.             end
  322.         end
  323.     end
  324.  
  325.  
  326. % Sometimes the search direction goes to zero in negative
  327. % definite problems when the current point rests on
  328. % the top of the quadratic function. In this case we can move in
  329. % any direction to get an improvement in the function so 
  330. % foil search direction by giving a random gradient.
  331.     if negdef
  332.         if norm(gf) < sqrt(eps)
  333.             gf = randn(nvars,1);
  334.         end
  335.     end
  336.     if ind
  337.         aix(ind)=1;
  338.         ACTSET(CIND,:)=A(ind,:);
  339.         ACTIND(CIND)=ind;
  340.         [m,n]=size(ACTSET);
  341.         [Q,R] = qrinsert(Q,R,CIND,A(ind,:)');
  342.     end
  343.     if oldind 
  344.         aix(oldind) = 0; 
  345.     end
  346.     if ~simplex_iter
  347.         % Z = null(ACTSET);
  348.         [m,n]=size(ACTSET);
  349.         Z = Q(:,m+1:n);
  350.         ACTCNT=ACTCNT+1;
  351.         if ACTCNT == nvars - 1, simplex_iter = 1; end
  352.         CIND=ACTCNT+1;
  353.         oldind = 0; 
  354.     else
  355.         rlambda = -R\(Q'*gf);
  356.         if rlambda(1) == -Inf
  357.             fprintf('         Working set is singular; results may still be reliable.\n');
  358.             [m,n] = size(ACTSET);
  359.             rlambda = -(ACTSET + sqrt(eps)*randn(m,n))'\gf;
  360.         end
  361.         actlambda = rlambda;
  362.         actlambda(eqix)=abs(actlambda(eqix));
  363.         indlam = find(actlambda<0);
  364.         if length(indlam)
  365.             if STEPMIN > errnorm
  366.                 % If there is no chance of cycling then pick the constraint which causes
  367.                 % the biggest reduction in the cost function. i.e the constraint with
  368.                 % the most negative Lagrangian multiplier. Since the constraints
  369.                 % are normalized this may result in less iterations.
  370.                 [minl,CIND] = min(actlambda);
  371.             else
  372.                 % Bland's rule for anti-cycling: if there is more than one 
  373.                 % negative Lagrangian multiplier then delete the constraint
  374.                 % with the smallest index in the active set.
  375.                 CIND = find(ACTIND == min(ACTIND(indlam)));
  376.             end
  377.  
  378.             [Q,R]=qrdelete(Q,R,CIND);
  379.             Z = Q(:,nvars);
  380.             oldind = ACTIND(CIND);
  381.         else
  382.             lambda(ACTIND)= normf * (rlambda./normA(ACTIND));
  383.             return
  384.         end
  385.     end %if ACTCNT<nvars
  386.     if (is_qp)
  387.         Zgf = Z'*gf; 
  388.         if (norm(Zgf) < 1e-15)
  389.             SD = zeros(nvars,1); 
  390.         elseif ~length(Zgf) 
  391.             % Only happens in -ve semi-definite problems
  392.             disp('Warning: QP problem is -ve semi-definite.')
  393.             SD = zeros(nvars,1);
  394.         else
  395.             SD=-Z*((Z'*H*Z)\(Zgf));
  396.         end
  397.         % Check for -ve definite problems
  398.         % if SD'*gf>0, is_qp = 0; SD=-SD; end
  399.     else
  400.         if ~simplex_iter
  401.             SD = -Z*Z'*gf;
  402.             gradsd = norm(SD);
  403.         else
  404.             gradsd = Z'*gf;
  405.             if  gradsd > 0
  406.                 SD = -Z;
  407.             else
  408.                 SD = Z;
  409.             end
  410.         end
  411.         if abs(gradsd) < 1e-10  % Search direction null
  412.             % Check whether any constraints can be deleted from active set.
  413.             % rlambda = -ACTSET'\gf;
  414.             if ~oldind
  415.                 rlambda = -R\(Q'*gf);
  416.             end
  417.             actlambda = rlambda;
  418.             actlambda(1:neqcstr) = abs(actlambda(1:neqcstr));
  419.             indlam = find(actlambda < errnorm);
  420.             lambda(ACTIND) = normf * (rlambda./normA(ACTIND));
  421.             if ~length(indlam)
  422.                 return
  423.             end
  424.             cindmax = length(indlam);
  425.             cindcnt = 0;
  426.             newactcnt = 0;
  427.             while (abs(gradsd) < 1e-10) & (cindcnt < cindmax)
  428.                 
  429.                 cindcnt = cindcnt + 1;
  430.                 if oldind
  431.                     % Put back constraint which we deleted
  432.                     [Q,R] = qrinsert(Q,R,CIND,A(oldind,:)');
  433.                 else
  434.                     simplex_iter = 0;
  435.                     if ~newactcnt
  436.                         newactcnt = ACTCNT - 1;
  437.                     end
  438.                 end
  439.                 CIND = indlam(cindcnt);
  440.                 oldind = ACTIND(CIND);
  441.  
  442.                 [Q,R]=qrdelete(Q,R,CIND);
  443.                 [m,n]=size(ACTSET);
  444.                 Z = Q(:,m:n);
  445.  
  446.                 if m ~= nvars
  447.                     SD = -Z*Z'*gf;
  448.                     gradsd = norm(SD);
  449.                 else
  450.                     gradsd = Z'*gf;
  451.                     if  gradsd > 0
  452.                         SD = -Z;
  453.                     else
  454.                         SD = Z;
  455.                     end
  456.                 end
  457.             end
  458.             if abs(gradsd) < 1e-10  % Search direction still null
  459.                 return;
  460.             end
  461.             lambda = zeros(ncstr,1);
  462.             if newactcnt 
  463.                 ACTCNT = newactcnt;
  464.             end
  465.         end
  466.     end
  467.  
  468.     if simplex_iter & oldind
  469.         ACTIND(CIND)=[];
  470.         ACTSET(CIND,:)=[];
  471.         CIND = nvars;
  472.     end 
  473. end % while 1
  474.