Repository navigation
solvers2: hvcompd and hvcomps can use the gradient from an earlier point - #32
Merged
Merged
Conversation
In solvers2, hvpcompd_ew_ASL and hvpcomps_ew_ASL (hvcompd and hvcomps) decide whether the gradient at the current x still has to be computed by testing ncxval[co] for constraints and noxval[no] for objectives. Those count function evaluations. The gradient evaluations are counted in ncxgval and noxgval, which xpsg_check_ASL uses. When the function value at x is known (these routines compute it first if it is not), the gradient is not computed, and the Hessian-vector product is formed with whatever the last gradient evaluation left: the product at an earlier point, or 0 if there was none. In solvers and solvers2, the test whether the objective value is known uses ncxval[no], a constraint's counter, instead of noxval[no]. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
In solvers2,
hvcompdandhvcomps(hvpcompd_ew_ASL,hvpcomps_ew_ASL) can return the Hessian-vector product for an earlier point. If no gradient was computed before, they return 0.The cause is the test that decides whether the gradient at the current x is still needed. It uses
ncxval[co]for constraints andnoxval[no]for objectives, but those count function evaluations. Gradient evaluations are counted inncxgvalandnoxgval, whichxpsg_check_ASLuses for the same decision.The routines compute the function value at x first when it isn't known. After that the test always says the gradient is current, so it isn't computed. The product is then built from whatever the last gradient evaluation left.
A smaller slip appears in both solvers and solvers2. The test for whether the objective value is known uses
ncxval[no], a constraint's counter, instead ofnoxval[no]. In solvers the gradient test usesf->nxval, so the result is right there.Fix
The fix changes 8 lines in
pshvprod.c:ncxgval[co]andnoxgval[no]for the gradient tests, andnoxval[no]for the objective value;noxval[no]for the objective value.Reproducer
This uses
sqrt0.nlfrom #31:min sqrt(x^2+y^2)s.t.sqrt(x^2+y^2) >= 0. The program computes values and gradients at (1,1), then only the values at (3,4), then callshvcompdandhvcompswith p = (1,2).stale.c
The correct product at (3,4) is (−0.064, 0.048). At (1,1) it is (−0.3536, 0.3536).
The same values came out for both routines, for the objective (
obj) and for the constraint (con):Other checks
I also ran a larger set of test cases at x = (3,4), read with
pfgh_read:sphes,fullhes,duthes,hvinit/hvcomp,hvcompdandhvcomps, plus thenerrorvariants;hvinit.Results:
hvcompd/hvcompsreturned 0 in 14 of the 20 cases. They were right only after the gradients had been computed, or, for the objective, by accident after only the constraint values.jacval/congrd/objgrdtests from Restore the caller's err_jmp on return from the evaluation routines #31, and the error tests at x = (0,0).This applies to master by itself and doesn't depend on #31. I found it while testing the Hessian routines for #31.
The build and test setup is the same as in #31. That means Linux x86_64 with gcc 11.4, compiling the library sources directly with
gcc -O2(solvers2 from thea =list inmakefile.u) rather than through CMake.I didn't add an entry to
solvers/changes, so that this PR doesn't conflict with the one in #31. Suggested text:Related, not changed here
I noticed these in solvers while testing:
fullhesemacro: insolvers/asl.hit callsp.Fulhes, the variant withoutnerror, with seven arguments. As a result,fullhese(...)doesn't compile ("too many arguments to function 'asl->p.Fulhes'"). It should callp.Fulhese, as insolvers2/asl.h.solvers/asl.hhas nosphesemacro.solvers2/asl.hhas one.Hvcompenever installed:pfg_read.cdoesn't setp.Hvcompe, althoughhvpcompe_ASLexists inpshvprod.candHviniteis set. Withpfgh_read,asl->p.Hvcompestops with "hvcompe called before pfgh_read or fgh_read." solvers2'spfghread.cdoes set it.Error evaluating "var =" definition -1: can't evaluate sqrt'(0).This happens for the objective and for a constraint. solvers2 names the objective gradient or the constraint gradient.🤖 Generated with Claude Code