-
Notifications
You must be signed in to change notification settings - Fork 18
Description
I am currently experimenting with a FOSS SQP method, SLSQP, trying to replace the old numerically unstable Lawson-Hanson LSEI solver with a more modern, more reliable QP solver. See: stevengj/nlopt#86 After some mixed experiences with OSQP (which does not have the numerical difficulties Lawson-Hanson has, but has others), I am now trying DAQP.
SLSQP maintains the Hessian approximation for the QPs in LDL-factored form. It does all the updates on the factored matrices, so H is never multiplied out explicitly. Therefore the QPs are in least-squares form (hence the name Sequential Least-SQuares Programming):
/* MINIMIZE with respect to X */
/* ||E*X - F|| */
/* 1/2 T */
/* WITH UPPER TRIANGULAR MATRIX E = +D *L , */
/* -1/2 -1 */
/* AND VECTOR F = -D *L *G, */
/* WHERE THE UNIT LOWER TRIDIANGULAR MATRIX L IS STORED COLUMNWISE */
/* DENSE IN THE N*(N+1)/2 ARRAY L WITH VECTOR D STORED IN ITS */
/* 'DIAGONAL' THUS SUBSTITUTING THE ONE-ELEMENTS OF L */
/* SUBJECT TO */
/* A(J)*X - B(J) = 0 , J=1,...,MEQ, */
/* A(J)*X - B(J) >=0, J=MEQ+1,...,M, */
/* XL(I) <= X(I) <= XU(I), I=1,...,N, */Compared to the standard QP formulation, this is factored, i.e., this is obviously the same as minimizing ||E*X - F||²=(E*X - F)^T * (E*X - F), which expands to a quadratic in X.
The question is now how to best get this into DAQP.
The documentation of OSQP recommends a variable transformation Y=E*X-F, which brings the problem into the form:
/* MINIMIZE with respect to Y */
/* T */
/* Y *I/2*Y */
/* SUBJECT TO */
/* XL(I) <= X(I) <= XU(I), I=1,...,N, */
/* F(I) <= E*X(I) - Y(I) <= F(I), I=1,...,N, */
/* B(J) <= A(J)*X <= B(J), J=1,...,MEQ, */
/* B(J) <= A(J)*X <= inf, J=MEQ+1,...,M, */The problem with that formulation is that the Hessian is highly singular, because it has a zero block (the coefficients of X) and an identity block (the coefficients of Y). As a result, DAQP by default rejects this as nonconvex (because it is not strictly convex). Enabling proximal iteration fixes that, but (unless I messed up the QP formulation somehow) the proximal iteration does not seem to work reliably: When I tried it on master, it worked for the simple NLOPT tutorial test case, but not for the application on which I am using SLSQP (where DAQP would just falsely claim optimality of all the QPs on the all-zero starting point, and as a result, SLSQP would also falsely claim optimality of the starting point). When I tried it on dev, even the NLOPT tutorial test case no longer worked, DAQP just ran out of iterations no matter how high I set the maximum iteration limit, probably getting stuck in some cycle or zigzagging. The proximal iteration has some special-casing for LPs (all-zero Hessian matrices), I wonder whether some of that would also be needed for a blockwise zero Hessian.
Another way would be to expand the quadratic and minimize X^T * (E^T*E) * X - 2 * (E^T*F)^T * X or equivalently ½ * X^T * (E^T*E) * X - (E^T*F)^T * X instead. (Obviously, the constant term F^T * F can be ignored.) Note that E'E=L√D√DL'=LDL'=H and E'F=L√D(-inv(√D))inv(L)G=-G, so this is ultimately just the standard SQP ½ * X^T * H * X + G^T * X. Is that the right way? I am somewhat hesitant to do that because this ultimately multiplies out an already LDL-factored matrix just to LDL-factor it again, which I fear is suboptimal both with respect to speed and numerical stability. But I may be fearing too much.
Finally, it might be possible to modify the DAQP algorithm to work directly on the factored form, but I do not know how that would best be done. (There are the Lawson-Hanson transformations from the above "LSEI" form to "LSI" form with only inequalities and then to unconstrained LDP form, which are implemented in the original SLSQP code, but those transformations might already be numerically problematic. Their transformation from LDP to NNLS definitely is problematic. And DAQP also has no documented API to call daqp_ldp directly.)
What would you recommend? (Or would you recommend trying another solver altogether?)