From 7c778ae2ebc9a1bf234fde77ffa273611cc8490d Mon Sep 17 00:00:00 2001 From: Christopher Rackauckas Date: Sun, 4 May 2025 13:59:18 -0400 Subject: [PATCH 1/3] Simplify calls to Optim.jl Much of the complexity in the issues with the Optim.jl wrapper is simply because it doesn't treat Optim well. It makes things always complete, instead of simplifying the call. This simplifies the call, so the less you use the less machinery is required. In particular: * TwiceDifferentiable is only made and used if the optimizer needs to use Hessians. This fixes https://github.com/SciML/Optimization.jl/issues/859, fixes https://github.com/SciML/Optimization.jl/issues/893 * Only uses constraints and bounds when the user sets them. Fixes https://github.com/SciML/Optimization.jl/issues/863 and fixes https://github.com/SciML/Optimization.jl/issues/558 --- .../src/OptimizationOptimJL.jl | 55 +++++++++++++------ 1 file changed, 39 insertions(+), 16 deletions(-) diff --git a/lib/OptimizationOptimJL/src/OptimizationOptimJL.jl b/lib/OptimizationOptimJL/src/OptimizationOptimJL.jl index 34a2ae679..7459b0fc2 100644 --- a/lib/OptimizationOptimJL/src/OptimizationOptimJL.jl +++ b/lib/OptimizationOptimJL/src/OptimizationOptimJL.jl @@ -393,14 +393,22 @@ function SciMLBase.__solve(cache::OptimizationCache{ end end u0_type = eltype(cache.u0) - optim_f = Optim.TwiceDifferentiable(_loss, gg, fg!, hh, cache.u0, - real(zero(u0_type)), - Optim.NLSolversBase.alloc_DF(cache.u0, - real(zero(u0_type))), - isnothing(cache.f.hess_prototype) ? - Optim.NLSolversBase.alloc_H(cache.u0, - real(zero(u0_type))) : - convert.(u0_type, cache.f.hess_prototype)) + + optim_f = if SciMLBase.requireshessian(cache.opt) + Optim.TwiceDifferentiable(_loss, gg, fg!, hh, cache.u0, + real(zero(u0_type)), + Optim.NLSolversBase.alloc_DF(cache.u0, + real(zero(u0_type))), + isnothing(cache.f.hess_prototype) ? + Optim.NLSolversBase.alloc_H(cache.u0, + real(zero(u0_type))) : + convert.(u0_type, cache.f.hess_prototype)) + else + Optim.OnceDifferentiable(_loss, gg, fg!, cache.u0, + real(zero(u0_type)), + Optim.NLSolversBase.alloc_DF(cache.u0, + real(zero(u0_type)))) + end cons_hl! = function (h, θ, λ) res = [similar(h) for i in 1:length(λ)] @@ -412,15 +420,26 @@ function SciMLBase.__solve(cache::OptimizationCache{ lb = cache.lb === nothing ? [] : cache.lb ub = cache.ub === nothing ? [] : cache.ub - if cache.f.cons !== nothing - optim_fc = Optim.TwiceDifferentiableConstraints(cache.f.cons, cache.f.cons_j, - cons_hl!, - lb, ub, - cache.lcons, cache.ucons) + + optim_fc = if SciMLBase.requireshessian(opt) + if cache.f.cons !== nothing + Optim.TwiceDifferentiableConstraints(cache.f.cons, cache.f.cons_j, + cons_hl!, + lb, ub, + cache.lcons, cache.ucons) + else + Optim.TwiceDifferentiableConstraints(lb, ub) + end else - optim_fc = Optim.TwiceDifferentiableConstraints(lb, ub) + if cache.f.cons !== nothing + Optim.OnceDifferentiableConstraints(cache.f.cons, cache.f.cons_j + lb, ub, + cache.lcons, cache.ucons) + else + Optim.OnceDifferentiableConstraints(lb, ub) + end end - + opt_args = __map_optimizer_args(cache, cache.opt, callback = _cb, maxiters = cache.solver_args.maxiters, maxtime = cache.solver_args.maxtime, @@ -429,7 +448,11 @@ function SciMLBase.__solve(cache::OptimizationCache{ cache.solver_args...) t0 = time() - opt_res = Optim.optimize(optim_f, optim_fc, cache.u0, cache.opt, opt_args) + if lb === nothing && ub === nothing && cache.f.cons === nothing + opt_res = Optim.optimize(optim_f, cache.u0, cache.opt, opt_args) + else + opt_res = Optim.optimize(optim_f, optim_fc, cache.u0, cache.opt, opt_args) + end t1 = time() opt_ret = Symbol(Optim.converged(opt_res)) stats = Optimization.OptimizationStats(; iterations = opt_res.iterations, From 7643ccf9a47ce6823db9f992faa6d705d9b49bae Mon Sep 17 00:00:00 2001 From: Christopher Rackauckas Date: Tue, 6 May 2025 01:25:31 -0400 Subject: [PATCH 2/3] Update lib/OptimizationOptimJL/src/OptimizationOptimJL.jl --- lib/OptimizationOptimJL/src/OptimizationOptimJL.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/OptimizationOptimJL/src/OptimizationOptimJL.jl b/lib/OptimizationOptimJL/src/OptimizationOptimJL.jl index 7459b0fc2..39a8b663e 100644 --- a/lib/OptimizationOptimJL/src/OptimizationOptimJL.jl +++ b/lib/OptimizationOptimJL/src/OptimizationOptimJL.jl @@ -432,7 +432,7 @@ function SciMLBase.__solve(cache::OptimizationCache{ end else if cache.f.cons !== nothing - Optim.OnceDifferentiableConstraints(cache.f.cons, cache.f.cons_j + Optim.OnceDifferentiableConstraints(cache.f.cons, cache.f.cons_j, lb, ub, cache.lcons, cache.ucons) else From 2f3366ed240fc853bf1bae1a9c93e3bf5de49ad3 Mon Sep 17 00:00:00 2001 From: Christopher Rackauckas Date: Tue, 6 May 2025 09:43:59 -0400 Subject: [PATCH 3/3] Update lib/OptimizationOptimJL/src/OptimizationOptimJL.jl --- lib/OptimizationOptimJL/src/OptimizationOptimJL.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/OptimizationOptimJL/src/OptimizationOptimJL.jl b/lib/OptimizationOptimJL/src/OptimizationOptimJL.jl index 39a8b663e..e2ff98bd4 100644 --- a/lib/OptimizationOptimJL/src/OptimizationOptimJL.jl +++ b/lib/OptimizationOptimJL/src/OptimizationOptimJL.jl @@ -421,7 +421,7 @@ function SciMLBase.__solve(cache::OptimizationCache{ lb = cache.lb === nothing ? [] : cache.lb ub = cache.ub === nothing ? [] : cache.ub - optim_fc = if SciMLBase.requireshessian(opt) + optim_fc = if SciMLBase.requireshessian(cache.opt) if cache.f.cons !== nothing Optim.TwiceDifferentiableConstraints(cache.f.cons, cache.f.cons_j, cons_hl!,