Main Content

Quadratic Minimization with Dense, Structured Hessian

Take advantage of a structured Hessian

Thequadprogtrust-region-reflective method can solve large problems where the Hessian is dense but structured. For these problems,quadprogdoes not computeH*Ywith the HessianHdirectly, as it does for trust-region-reflective problems with sparseH, because formingHwould be memory-intensive. Instead, you must providequadprog函数,给定一个矩阵Yand information aboutH, computesW=H*Y.

In this example, the Hessian matrixHhas the structureH = B + A*A'whereBis a sparse 512-by-512 symmetric matrix, andAis a 512-by-10 sparse matrix composed of a number of dense columns. To avoid excessive memory usage that could happen by working withHdirectly becauseHis dense, the example provides a Hessian multiply function,qpbox4mult. This function, when passed a matrixY, uses sparse matricesAandBto compute the Hessian matrix productW = H*Y = (B + A*A')*Y.

In the first part of this example, the matricesAandBneed to be provided to the Hessian multiply functionqpbox4mult. You can pass one matrix as the first argument toquadprog, which is passed to the Hessian multiply function. You can use a nested function to provide the value of the second matrix.

The second part of the example shows how to tighten theTolPCGtolerance to compensate for an approximate preconditioner instead of an exactHmatrix.

Step 1: Decide what part of H to pass to quadprog as the first argument.

EitherAorBcan be passed as the first argument toquadprog. The example chooses to passBas the first argument because this results in a better preconditioner (seePreconditioning).

quadprog(B,f,[],[],[],[],l,u,xstart,options)

Step 2: Write a function to compute Hessian-matrix products for H.

Now, define a functionrunqpbox4that

  • Contains a nested functionqpbox4multthat usesAandBto compute the Hessian matrix productW, whereW = H*Y = (B + A*A')*Y. The nested function must have the form

    W = qpbox4mult(Hinfo,Y,...)

    The first two argumentsHinfoandYare required.

  • Loads the problem parameters fromqpbox4.mat.

  • Usesoptimoptionsto set theHessianMultiplyFcnoption to a function handle that points toqpbox4mult.

  • CallsquadprogwithBas the first argument.

The first argument to the nested functionqpbox4multmust be the same as the first argument passed toquadprog, which in this case is the matrix B.

The second argument toqpbox4multis the matrixY(ofW = H*Y). BecausequadprogexpectsYto be used to form the Hessian matrix product,Yis always a matrix withnrows, wherenis the number of dimensions in the problem. The number of columns inYcan vary. The functionqpbox4multis nested so that the value of the matrixAcomes from the outer function. Optimization Toolbox™ software includes therunqpbox4.mfile.

function [fval, exitflag, output, x] = runqpbox4 %RUNQPBOX4 demonstrates 'HessianMultiplyFcn' option for QUADPROG with bounds. problem = load('qpbox4'); % Get xstart, u, l, B, A, f xstart = problem.xstart; u = problem.u; l = problem.l; B = problem.B; A = problem.A; f = problem.f; mtxmpy = @qpbox4mult; % function handle to qpbox4mult nested function % Choose algorithm and the HessianMultiplyFcn option options = optimoptions(@quadprog,'Algorithm','trust-region-reflective','HessianMultiplyFcn',mtxmpy); % Pass B to qpbox4mult via the H argument. Also, B will be used in % computing a preconditioner for PCG. [x, fval, exitflag, output] = quadprog(B,f,[],[],[],[],l,u,xstart,options); function W = qpbox4mult(B,Y) %QPBOX4MULT Hessian matrix product with dense structured Hessian. % W = qpbox4mult(B,Y) computes W = (B + A*A')*Y where % INPUT: % B - sparse square matrix (512 by 512) % Y - vector (or matrix) to be multiplied by B + A'*A. % VARIABLES from outer function runqpbox4: % A - sparse matrix with 512 rows and 10 columns. % % OUTPUT: % W - The product (B + A*A')*Y. % % Order multiplies to avoid forming A*A', % which is large and dense W = B*Y + A*(A'*Y); end end

Step 3: Call a quadratic minimization routine with a starting point.

To call the quadratic minimizing routine contained inrunqpbox4, enter

[fval,exitflag,output] = runqpbox4;

to run the preceding code. Then display the values forfval,exitflag,output.iterations, andoutput.cgiterations.

fval,exitflag,output.iterations, output.cgiterations fval = -1.0538e+03 exitflag = 3 ans = 18 ans = 30

After 18 iterations with a total of 30 PCG iterations, the function value is reduced to

fval fval = -1.0538e+003

and the first-order optimality is

output.firstorderopt ans = 0.0043

Preconditioning

Sometimesquadprogcannot useHto compute a preconditioner becauseHonly exists implicitly. Instead,quadprogusesB, the argument passed in instead ofH, to compute a preconditioner.Bis a good choice because it is the same size asHand approximatesHto some degree. IfBwere not the same size asH,quadprogwould compute a preconditioner based on some diagonal scaling matrices determined from the algorithm. Typically, this would not perform as well.

Because the preconditioner is more approximate than whenHis available explicitly, adjusting theTolPCGparameter to a somewhat smaller value might be required. This example is the same as the previous one, but reducesTolPCGfrom the default 0.1 to 0.01.

function[fval, exitflag, output, x] = runqpbox4prec%RUNQPBOX4PREC demonstrates 'HessianMultiplyFcn' option for QUADPROG with bounds.problem = load('qpbox4');% Get xstart, u, l, B, A, fxstart = problem.xstart; u = problem.u; l = problem.l; B = problem.B; A = problem.A; f = problem.f; mtxmpy = @qpbox4mult;% function handle to qpbox4mult nested function% Choose algorithm, the HessianMultiplyFcn option, and override the TolPCG optionoptions = optimoptions(@quadprog,'Algorithm','trust-region-reflective',...'HessianMultiplyFcn',mtxmpy,'TolPCG',0.01);% Pass B to qpbox4mult via the H argument. Also, B will be used in% computing a preconditioner for PCG.% A is passed as an additional argument after 'options'[x, fval, exitflag, output] = quadprog(B,f,[],[],[],[],l,u,xstart,options);functionW = qpbox4mult(B,Y)%QPBOX4MULT Hessian matrix product with dense structured Hessian.% W = qpbox4mult(B,Y) computes W = (B + A*A')*Y where% INPUT:% B - sparse square matrix (512 by 512)% Y - vector (or matrix) to be multiplied by B + A'*A.% VARIABLES from outer function runqpbox4prec:% A - sparse matrix with 512 rows and 10 columns.%% OUTPUT:% W - The product (B + A*A')*Y.%% Order multiplies to avoid forming A*A',% which is large and denseW = B*Y + A*(A'*Y);endend

Now, enter

[fval,exitflag,output] = runqpbox4prec;

to run the preceding code. After 18 iterations and 50 PCG iterations, the function value has the same value to five significant digits

fval fval = -1.0538e+003

and the first-order optimality is essentially the same.

output.firstorderopt ans = 0.0043

Note

DecreasingTolPCGtoo much can substantially increase the number of PCG iterations.

Related Topics