Repository navigation
Conversation
Prioritize saved iterates that satisfy the relaxed objective-gap tolerance and use consistent gap normalization during recovery. Add selection-policy regression tests and detailed objective/complementarity diagnostics. Validation: 13 focused barrier tests and 198 convex QP, SOCP, and Maros benchmarks at 1e-6 tolerances. Both prior numerical-error cases recover valid suboptimal solutions; two pre-existing input parsing errors remain. Signed-off-by: Rajesh Gandham <rgandham@nvidia.com>
Update the cache-refinement test to use the templated barrier cache API introduced upstream. Signed-off-by: Rajesh Gandham <rgandham@nvidia.com>
|
/ok to test 76b20ec |
Signed-off-by: Rajesh Gandham <rgandham@nvidia.com>
|
/ok to test eb12ae2 |
CI Test Summary✅ All 32 test job(s) passed. |
| const bool saved_gap_pass = !check_objective_gap || saved.objective_gap < tolerance.objective_gap; | ||
|
|
||
| // Preserve a recoverable iterate even when better feasibility comes with a worse objective gap. | ||
| if (current_gap_pass != saved_gap_pass) { return current_gap_pass; } |
There was a problem hiding this comment.
So this saves when current_gap_pass is true and save_gap_pass is false. And it does not save when current_gap_pass is false and save_gap_pass is true.
But if they are both true, then you check to see if the current improved upon the saved for primal, dual and complementarity. But you don't check that the objective gap improved.
Is there a reason not to require that all: primal, dual, complementarity, and objective improve?
Signed-off-by: Rajesh Gandham <rgandham@nvidia.com>
Signed-off-by: Rajesh Gandham <rgandham@nvidia.com>
| relative_objective_gap); | ||
| } | ||
| settings.log.printf("Search direction computation failed\n"); | ||
| settings.log.printf("Current and saved solutions do not satisfy relaxed barrier tolerances\n"); |
There was a problem hiding this comment.
You probably want to keep "Search direction computation failed" that explains why we need to stop the solver.
Maybe "Search direction computation failed. No solutions satisfy barrier tolerances"
| !(tolerances[i] > 0) || !(current_residuals[i] < tolerances[i])) { | ||
| return false; | ||
| } | ||
| current_merit = std::max(current_merit, current_residuals[i] / tolerances[i]); |
There was a problem hiding this comment.
This is hard to understand. I think it would be better to first check if the current_residuals satisfy the tolerances. Then check to see if the max residual is less for the current than for the saved.
Signed-off-by: Rajesh Gandham <rgandham@nvidia.com>
|
/ok to test 95face7 |
Description
This PR preserves an iterate that satisfies the relaxed tolerances so it can be returned as a suboptimal solution if later iterations encounter numerical difficulties.
Previously, an iterate was saved only when primal feasibility, dual feasibility, and complementarity all improved. This could retain an iterate with an unacceptable objective gap while discarding later iterates that satisfied all relaxed tolerances. The new policy prioritizes preserving a qualifying iterate for recovery.
QPLIB_8547
With relaxed tolerances set to 1e-6:
Before: Iterations 55 and 56 satisfy the relaxed criteria, but are not retained by the old selection policy. When primal feasibility deteriorates at iteration 57, the solver reports a numerical error.
After: The solver preserves iteration 55 and restores it when subsequent iterations deteriorate, returning a valid suboptimal solution
chainsing-50000-2
With relaxed tolerances set to 1e-6:
Before: Iterations 22–24 satisfy the relaxed criteria, but are not retained because their dual residuals are worse than the previously saved iterate’s. That earlier iterate does not satisfy the objective-gap tolerance. Subsequent numerical trouble therefore results in a numerical-error status.
After: The solver preserves a qualifying iterate and restores iteration 23 after the numerical error.
Checklist