What am I missing about the Hessian checker in Ipopt?

216 Views Asked by At

I have a (constrained linear least squares) problem that has valid first derivatives according to the checker, but it flags every nonzero Lagrangian Hessian entry as being nonzero (and equal) on every constraint, while the approximate value is correctly evaluated as zero. This being a least squares problem, the second derivatives should be constant; independent of all problem variables and constraints.

So I went looking through the Ipopt source code, and it seems like it uses a value of the Hessian at the reference point without any kind of processing to filter out contributions unrelated to the constraint being considered. In src/Interfaces/IpTNLPAdapter.cpp, starting at 3106:

           for( Index i = 0; i < nz_hess_lag; i++ )
           {
              if( (h_iRow[i] == ivar && h_jCol[i] == ivar2) || (h_jCol[i] == ivar && h_iRow[i] == ivar2) )
              {
                 deriv_exact += h_values[i];
                 found = true;
              }
           }

And then it outputs deriv_exact in the error message a few lines later

Is this a bug in Ipopt, or am I missing something? I'm getting strange behavior and an incorrect answer from the actual algorithm so I suspect I'm missing something.

1

There are 1 best solutions below

0
On

Ipopt's Hessian checker calls your eval_h callback with either objfact=1 and all entries of lambda being 0, or objfact=0 and exactly one entry of lambda being 1.0 (all others zero). So your implementation of eval_h should return the values of the Hessian for the objective or this one constraint, but also set all other entries in the Hessian to zero.

Ipopt does not distinguish the sparsity patterns of the Hessian for the objective and constraints. It does everything in terms of the Hessian of the Lagrangian function.