Add sol.prob / get_prob to recover the OptimizationProblem from a solution (Optimization.jl#1191) - #1367
Conversation
…olution `OptimizationSolution` stores the solved `OptimizationCache` in `sol.cache`, not the original problem. `sol.prob` was previously deprecated to return the cache (2.x) and then removed entirely, so today there is no way to get the original `OptimizationProblem` back from a solution (SciML/Optimization.jl#1191). Add `SciMLBase.get_prob(sol)` (with `has_prob(sol)`), mirroring the existing `get_p`/`get_syms` accessors, returning the original problem retained by the cache (`sol.cache.prob`). Re-add `sol.prob` as sugar for `get_prob(sol)` via the solution `getproperty`, alongside the existing `:ps` accessor. Caches that do not retain the problem (e.g. `DefaultOptimizationCache`) raise a clear `ArgumentError` rather than silently returning the cache. This pairs with OptimizationBase storing the original problem on `OptimizationCache` (Optimization.jl). `propertynames`/`hasproperty` are intentionally left unchanged (matching `:ps`), so `wrap_sol`'s `hasproperty(sol, :prob)` guard is unaffected. Adds a self-contained test in solution_interface.jl using a mock prob-retaining cache and `DefaultOptimizationCache` for the negative path. Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com> Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Base PR storing the original problem on |
|
Note on the red downstream checks: they are CI-infrastructure noise, not this change. Two causes in the logs: (1) the package gracefully skips with |
Summary
Adds a way to recover the original
OptimizationProblemfrom anOptimizationSolution, addressing SciML/Optimization.jl#1191 (sol.probreturns the cache, not the problem).OptimizationSolutionstores the solved cache insol.cache. Historicallysol.probwas deprecated to return the cache (2.x) and then removed (3.x), so there is currently no supported way to get the original problem back from a solution.What changed
SciMLBase.get_prob(sol)andSciMLBase.has_prob(sol), mirroring the existingget_p/get_symsaccessors.get_probreturns the original problem retained by the cache (sol.cache.prob).sol.probas sugar forget_prob(sol)via the solutiongetproperty, alongside the existing:psaccessor.DefaultOptimizationCache) raise a clearArgumentErrorinstead of silently returning the cache.propertynames/haspropertyare intentionally left unchanged (matching:ps), sowrap_sol'shasproperty(sol, :prob)guard — and every otherhasproperty-gated path — is unaffected.3.16.0 → 3.17.0.Pairs with
OptimizationBase storing the original problem on
OptimizationCache(Optimization.jl PR). The two are complementary but independent: this PR works for anyAbstractOptimizationCachethat exposes aprobfield and errors otherwise.Note for review
This re-introduces
sol.prob(previously deprecated to return the cache, then removed). Here it returns the problem. If you'd rather keepsol.probretired and expose onlyget_prob(sol), thegetpropertybranch can be dropped — happy to do so.Tests (run locally)
Added a self-contained testset in
solution_interface.jlusing a mock prob-retainingAbstractOptimizationCacheandDefaultOptimizationCache(negative path). Verified the fullsolution_interface.jlpasses (existing + new 7-assertion set), and an end-to-end OptimizationBase+LBFGSB run wheresol.prob === prob,get_prob(sol) === prob,has_prob(sol). Runic-formatted.🚧 Draft — please ignore until reviewed by @ChrisRackauckas.