Skip to content

Commit a8d46bb

Browse files
Add solve interface to OptimizationBase from SciMLBase.jl
This commit adds the missing solve.jl file to lib/OptimizationBase and implements the top-level solve interface functionality from SciMLBase.jl (lines 36-248), including: **New solve.jl functionality:** - IncompatibleOptimizerError and OptimizerMissingError exception types - _check_opt_alg function for comprehensive algorithm compatibility checking - Base dispatch functions: supports_opt_cache_interface, __solve, __init - Proper error handling with informative messages for missing optimizers **Algorithm validation for:** - Bounds compatibility (allowsbounds/requiresbounds) - Constraint handling (allowsconstraints/requiresconstraints) - Gradient/Hessian requirements (requiresgradient/requireshessian) - Constraint Jacobian/Hessian requirements (requiresconsjac/requiresconshess) - Callback support (allowscallback) **Modified OptimizationBase.jl:** - Added include("solve.jl") - Added exports: IncompatibleOptimizerError, OptimizerMissingError, _check_opt_alg, supports_opt_cache_interface This provides the foundation for moving optimization-specific functionality from SciMLBase.jl into the optimization ecosystem where it belongs. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
1 parent e1372a7 commit a8d46bb

File tree

2 files changed

+82
-1
lines changed

2 files changed

+82
-1
lines changed

lib/OptimizationBase/src/OptimizationBase.jl

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,10 @@ include("cache.jl")
2727
include("OptimizationDIExt.jl")
2828
include("OptimizationDISparseExt.jl")
2929
include("function.jl")
30+
include("solve.jl")
3031

31-
export solve, OptimizationCache, DEFAULT_CALLBACK, DEFAULT_DATA
32+
export solve, OptimizationCache, DEFAULT_CALLBACK, DEFAULT_DATA,
33+
IncompatibleOptimizerError, OptimizerMissingError, _check_opt_alg,
34+
supports_opt_cache_interface
3235

3336
end

lib/OptimizationBase/src/solve.jl

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
# This file contains the top level solve interface functionality moved from SciMLBase.jl
2+
# These functions provide the core optimization solving interface
3+
4+
struct IncompatibleOptimizerError <: Exception
5+
err::String
6+
end
7+
8+
function Base.showerror(io::IO, e::IncompatibleOptimizerError)
9+
print(io, e.err)
10+
end
11+
12+
const OPTIMIZER_MISSING_ERROR_MESSAGE = """
13+
Optimization algorithm not found. Either the chosen algorithm is not a valid solver
14+
choice for the `OptimizationProblem`, or the Optimization solver library is not loaded.
15+
Make sure that you have loaded an appropriate Optimization.jl solver library, for example,
16+
`solve(prob,Optim.BFGS())` requires `using OptimizationOptimJL` and
17+
`solve(prob,Adam())` requires `using OptimizationOptimisers`.
18+
19+
For more information, see the Optimization.jl documentation: <https://docs.sciml.ai/Optimization/stable/>.
20+
"""
21+
22+
struct OptimizerMissingError <: Exception
23+
alg::Any
24+
end
25+
26+
function Base.showerror(io::IO, e::OptimizerMissingError)
27+
println(io, OPTIMIZER_MISSING_ERROR_MESSAGE)
28+
print(io, "Chosen Optimizer: ")
29+
print(e.alg)
30+
end
31+
32+
# Algorithm compatibility checking function
33+
function _check_opt_alg(prob::SciMLBase.OptimizationProblem, alg; kwargs...)
34+
!SciMLBase.allowsbounds(alg) && (!isnothing(prob.lb) || !isnothing(prob.ub)) &&
35+
throw(IncompatibleOptimizerError("The algorithm $(typeof(alg)) does not support box constraints. Either remove the `lb` or `ub` bounds passed to `OptimizationProblem` or use a different algorithm."))
36+
SciMLBase.requiresbounds(alg) && isnothing(prob.lb) &&
37+
throw(IncompatibleOptimizerError("The algorithm $(typeof(alg)) requires box constraints. Either pass `lb` and `ub` bounds to `OptimizationProblem` or use a different algorithm."))
38+
!SciMLBase.allowsconstraints(alg) && !isnothing(prob.f.cons) &&
39+
throw(IncompatibleOptimizerError("The algorithm $(typeof(alg)) does not support constraints. Either remove the `cons` function passed to `OptimizationFunction` or use a different algorithm."))
40+
SciMLBase.requiresconstraints(alg) && isnothing(prob.f.cons) &&
41+
throw(IncompatibleOptimizerError("The algorithm $(typeof(alg)) requires constraints, pass them with the `cons` kwarg in `OptimizationFunction`."))
42+
# Check that if constraints are present and the algorithm supports constraints, both lcons and ucons are provided
43+
SciMLBase.allowsconstraints(alg) && !isnothing(prob.f.cons) &&
44+
(isnothing(prob.lcons) || isnothing(prob.ucons)) &&
45+
throw(ArgumentError("Constrained optimization problem requires both `lcons` and `ucons` to be provided to OptimizationProblem. " *
46+
"Example: OptimizationProblem(optf, u0, p; lcons=[-Inf], ucons=[0.0])"))
47+
!SciMLBase.allowscallback(alg) && haskey(kwargs, :callback) &&
48+
throw(IncompatibleOptimizerError("The algorithm $(typeof(alg)) does not support callbacks, remove the `callback` keyword argument from the `solve` call."))
49+
SciMLBase.requiresgradient(alg) &&
50+
!(prob.f isa SciMLBase.AbstractOptimizationFunction) &&
51+
throw(IncompatibleOptimizerError("The algorithm $(typeof(alg)) requires gradients, hence use `OptimizationFunction` to generate them with an automatic differentiation backend e.g. `OptimizationFunction(f, AutoForwardDiff())` or pass it in with `grad` kwarg."))
52+
SciMLBase.requireshessian(alg) &&
53+
!(prob.f isa SciMLBase.AbstractOptimizationFunction) &&
54+
throw(IncompatibleOptimizerError("The algorithm $(typeof(alg)) requires hessians, hence use `OptimizationFunction` to generate them with an automatic differentiation backend e.g. `OptimizationFunction(f, AutoFiniteDiff(); kwargs...)` or pass them in with `hess` kwarg."))
55+
SciMLBase.requiresconsjac(alg) &&
56+
!(prob.f isa SciMLBase.AbstractOptimizationFunction) &&
57+
throw(IncompatibleOptimizerError("The algorithm $(typeof(alg)) requires constraint jacobians, hence use `OptimizationFunction` to generate them with an automatic differentiation backend e.g. `OptimizationFunction(f, AutoFiniteDiff(); kwargs...)` or pass them in with `cons` kwarg."))
58+
SciMLBase.requiresconshess(alg) &&
59+
!(prob.f isa SciMLBase.AbstractOptimizationFunction) &&
60+
throw(IncompatibleOptimizerError("The algorithm $(typeof(alg)) requires constraint hessians, hence use `OptimizationFunction` to generate them with an automatic differentiation backend e.g. `OptimizationFunction(f, AutoFiniteDiff(), AutoFiniteDiff(hess=true); kwargs...)` or pass them in with `cons` kwarg."))
61+
return
62+
end
63+
64+
# Base solver dispatch functions (these will be extended by specific solver packages)
65+
supports_opt_cache_interface(alg) = false
66+
67+
function __solve(cache::SciMLBase.AbstractOptimizationCache)::SciMLBase.AbstractOptimizationSolution
68+
throw(OptimizerMissingError(cache.opt))
69+
end
70+
71+
function __init(prob::SciMLBase.OptimizationProblem, alg, args...;
72+
kwargs...)::SciMLBase.AbstractOptimizationCache
73+
throw(OptimizerMissingError(alg))
74+
end
75+
76+
function __solve(prob::SciMLBase.OptimizationProblem, alg, args...; kwargs...)
77+
throw(OptimizerMissingError(alg))
78+
end

0 commit comments

Comments
 (0)