coin-or / qpOASES

Open-source C++ implementation of the recently proposed online active set strategy
GNU Lesser General Public License v2.1
360 stars 121 forks source link

Regularization is not working in Python #131

Open AeroTH310 opened 2 years ago

AeroTH310 commented 2 years ago

I'm on version qpOASES v3.2.1 running through the Python interface, and I'm using external LAPACK (v3.10.1). I'm using VSCode in Ubuntu 20.04.

I'm using qpOASES to search a 3-parameter surface for the lowest value. The surface is not convex, in general, but is very nearly so within my bounds. The Hessian is guaranteed to become positive definite close to the solution. I'm finding that Cholesky factorization fails if the Hessian is only very slightly indefinite, even when regularization is on.

After reading the manual, I understand that qpOASES could handle this case, so I've opened this issue. Note that qpOASES INFO messages indicate that regularization is being executed. The result indicates that regularization doesn't work at all, since it cannot handle a slight indefinite case (or a semidefinite case).

For example, computing the surface at [2.8729605, 3.75, 1.1] yields: Hessian: [[ 36.82, 17.80, -56.13], [ 17.80, 38.97, -63.87], [-56.13, -63.87, 130.0]] Hessian eigenvalues: [ 186, 20.2, -2.79e-06] INFO: Using regularisation as Hessian matrix is not positive definite ERROR: Initialisation failed due to Cholesky decomposition ->ERROR: Initialisation failed! QP could not be solved!

But computing the surface at [2.872961, 3.75, 1.1] yields: Hessian: [[ 36.82, 17.80, -56.13], [ 17.80, 38.97, -63.87], [-56.13, -63.87, 130.0]] Hessian eigenvalues: [ 186 20.2 1.45e-07] ################# qpOASES -- QP NO. 1 ##################

Iter   |    StepLength    |       Info       |   nFX    

----------+------------------+------------------+--------- 0 | 2.447971e-04 | ADD BND 1 | 1
1 | 9.997566e-01 | ADD BND 0 | 2
2 | 2.988562e-02 | ADD BND 2 | 3
3 | 5.739085e-02 | REM BND 0 | 2
4 | 8.748576e-01 | REM BND 1 | 1
5 | 1.000000e+00 | QP SOLVED | 1

solution = [ 0.163, 0.158, 0.1]

In both cases, the options are: ################### qpOASES -- QP OPTIONS ##################

printLevel = PL_MEDIUM

enableRamping = BT_TRUE enableFarBounds = BT_TRUE enableFlippingBounds = BT_FALSE enableRegularisation = BT_TRUE enableFullLITests = BT_FALSE enableNZCTests = BT_TRUE enableDriftCorrection = 1 enableCholeskyRefactorisation = 1 enableEqualities = BT_FALSE enableInertiaCorrection = BT_TRUE rcondSMin = 1.000000e-14

terminationTolerance = 1.110500e-09 boundTolerance = 2.221000e-10 boundRelaxation = 1.000000e+04 epsNum = -2.221000e-13 epsDen = 2.221000e-13 maxPrimalJump = 1.000000e+08 maxDualJump = 1.000000e+08

initialRamping = 5.000000e-01 finalRamping = 1.000000e+00 initialFarBounds = 1.000000e+06 growFarBounds = 1.000000e+03 initialStatusBounds = ST_INACTIVE epsFlipping = 2.221000e-13 numRegularisationSteps = 4 epsRegularisation = 1.000000e-12 numRefinementSteps = 4 epsIterRef = 2.221000e-14 epsLITests = 2.221000e-11 epsNZCTests = 6.663000e-13

Note that enableRegularisation = BT_TRUE both times. Now, why didn't regularization make the problem solvable when the Hessian is very slightly indefinite? Is there another setting I need to turn on? I believe I have set the problem up correctly, and that qpOASES should handle this case, therefore I have opened an issue.

For information, I am using the Python interface and executing the problem with the PyQProblemB class (there are no linear constraints).