add a ShiftedProximableQuadraticNLPModel#113
add a ShiftedProximableQuadraticNLPModel#113MaxenceGollier wants to merge 11 commits intoJuliaSmoothOptimizers:mainfrom
Conversation
There was a problem hiding this comment.
Pull request overview
This PR adds a new shifted subproblem model type to support regularized optimization workflows that build and update quadratic + prox subproblems around an iterate.
Changes:
- Introduces
AbstractShiftedProximableNLPModelandShiftedProximableQuadraticNLPModelwithshift!,obj, andσhelpers. - Wires the new implementation behind
@require ShiftedProximalOperatorsand@require QuadraticModels. - Adds unit tests for construction, sigma handling, shifting behavior, and allocations.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 8 comments.
| File | Description |
|---|---|
src/shiftedProximableNLPModel.jl |
Implements the new shifted quadratic + proximable subproblem model, including shift!, obj, and forwarding methods. |
src/RegularizedProblems.jl |
Conditionally includes the new file when QuadraticModels and ShiftedProximalOperators are available. |
test/rmodel_tests.jl |
Adds tests validating objective evaluation, sigma toggling, shifting, bounds shifting, and allocations. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| σ_c = skip_sigma ? zero(σ_temp) : σ_temp | ||
| update_sigma!(reg_nlp, σ_c) | ||
|
|
||
| φs = cauchy ? dot(φ.data.c, s) + σ_c * dot(s, s)/2 : obj(φ, s) | ||
| ψs = ψ(s) | ||
|
|
||
| update_sigma!(reg_nlp, σ_temp) # restore original σ | ||
|
|
There was a problem hiding this comment.
obj temporarily mutates the model’s σ via update_sigma! and then restores it. If obj(φ, s) or ψ(s) throws, σ will not be restored, leaving the model in a corrupted state (and it’s also not thread-safe). Consider avoiding mutation (e.g., compute with the current σ and subtract the sigma term when skip_sigma=true), or wrap the restore in a try/finally to guarantee restoration.
| σ_c = skip_sigma ? zero(σ_temp) : σ_temp | |
| update_sigma!(reg_nlp, σ_c) | |
| φs = cauchy ? dot(φ.data.c, s) + σ_c * dot(s, s)/2 : obj(φ, s) | |
| ψs = ψ(s) | |
| update_sigma!(reg_nlp, σ_temp) # restore original σ | |
| if cauchy | |
| # In the Cauchy case, construct the quadratic model explicitly using either | |
| # the original σ or zero, depending on skip_sigma, without mutating σ. | |
| σ_used = skip_sigma ? zero(σ_temp) : σ_temp | |
| φs = dot(φ.data.c, s) + σ_used * dot(s, s) / 2 | |
| else | |
| # Use the current σ in the model for φ, and, if requested, subtract the | |
| # σ contribution from the objective afterwards instead of mutating σ. | |
| φs = obj(φ, s) | |
| if skip_sigma | |
| φs -= σ_temp * dot(s, s) / 2 | |
| end | |
| end | |
| ψs = ψ(s) |
There was a problem hiding this comment.
why not but I think @dpo will not agree because we might compute
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #113 +/- ##
===========================================
- Coverage 99.18% 79.27% -19.92%
===========================================
Files 11 20 +9
Lines 369 521 +152
===========================================
+ Hits 366 413 +47
- Misses 3 108 +105 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
closes #112.
What is implemented
I implement a new type
ShiftedProximableQuadraticNLPModel.The
documentationI add here is self-explanatory:How do I implement it
I add an
abstract typeas well as a
mutable structwhere
modelrepresentsφ(s; x) + ½ σ ‖s‖²,hrepresentsψandparent, the original problem.Why do I implement it
RegularizedOptimization.jl, I want to construct the subproblem with a sparse Hessian to use here in my exact penalty solver. This allows me to make a different constructor, by overwritingShiftedProximableQuadraticNLPModelwhere the Hessian is sparse. In theshift!function, I will be able to update the sparse Hessian as well by overwriting.RegularizedOptimization.jlthere is a ton of redundant code between each solver. For example, R2N definesand so does TR, TRDH, R2, R2DH, etc. When a step is accepted in each of those, there is a lot of noisy code as well. With this feature, we will now be able to simply call
shift!(subproblem, x)when the stepxis accepted.How do I test it
I added unit tests here. I plan to make a draft PR in
RegularizedOptimization.jlwhere I use this code.Link to draft PR: JuliaSmoothOptimizers/RegularizedOptimization.jl#316.