diff --git a/Project.toml b/Project.toml index 809611303..003bb123e 100644 --- a/Project.toml +++ b/Project.toml @@ -64,7 +64,7 @@ SafeTestsets = "0.1" SciMLBase = "2.122.1" SciMLSensitivity = "7" SparseArrays = "1.10" -Symbolics = "6" +Symbolics = "6, 7" TerminalLoggers = "0.1" Test = "1.10" Tracker = "0.2" diff --git a/lib/OptimizationBase/Project.toml b/lib/OptimizationBase/Project.toml index a90d299ea..92727bafa 100644 --- a/lib/OptimizationBase/Project.toml +++ b/lib/OptimizationBase/Project.toml @@ -24,6 +24,7 @@ ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" MLDataDevices = "7e8f7934-dd98-4c1a-8fe8-92b47a384d40" MLUtils = "f1d291b0-491e-4a28-83b9-f70985020b54" ModelingToolkit = "961ee093-0014-501f-94e3-6117800e7a78" +ModelingToolkitBase = "7771a370-6774-4173-bd38-47e70ca0b839" ReverseDiff = "37e2e3b7-166d-5795-8a7a-e32c996b4267" SymbolicAnalysis = "4297ee4d-0239-47d8-ba5d-195ecdf594fe" Zygote = "e88e6eb3-aa80-5325-afca-941959d7151f" @@ -35,6 +36,7 @@ OptimizationForwardDiffExt = "ForwardDiff" OptimizationMLDataDevicesExt = "MLDataDevices" OptimizationMLUtilsExt = "MLUtils" OptimizationMTKExt = "ModelingToolkit" +OptimizationMTKBaseExt = "ModelingToolkitBase" OptimizationReverseDiffExt = "ReverseDiff" OptimizationSymbolicAnalysisExt = "SymbolicAnalysis" OptimizationZygoteExt = "Zygote" @@ -51,7 +53,8 @@ ForwardDiff = "0.10.26, 1" LinearAlgebra = "1.9, 1.10" MLDataDevices = "1" MLUtils = "0.4" -ModelingToolkit = "10.23" +ModelingToolkit = "10.23, 11" +ModelingToolkitBase = "1" PDMats = "0.11" Reexport = "1.2" ReverseDiff = "1.14" diff --git a/lib/OptimizationBase/ext/OptimizationMTKBaseExt.jl b/lib/OptimizationBase/ext/OptimizationMTKBaseExt.jl new file mode 100644 index 000000000..ee77ab014 --- /dev/null +++ b/lib/OptimizationBase/ext/OptimizationMTKBaseExt.jl @@ -0,0 +1,213 @@ +module OptimizationMTKBaseExt + +import OptimizationBase, OptimizationBase.ArrayInterface +import SciMLBase +import SciMLBase: OptimizationFunction +import OptimizationBase.ADTypes: AutoSymbolics, AutoSparse +using ModelingToolkitBase + +function OptimizationBase.instantiate_function( + f::OptimizationFunction{true}, x, adtype::AutoSparse{<:AutoSymbolics}, p, + num_cons = 0; + g = false, h = false, hv = false, fg = false, fgh = false, + cons_j = false, cons_vjp = false, cons_jvp = false, cons_h = false, + lag_h = false) + p = isnothing(p) ? SciMLBase.NullParameters() : p + + sys = complete(ModelingToolkitBase.modelingtoolkitize(OptimizationProblem(f, x, p; + lcons = fill(0.0, + num_cons), + ucons = fill(0.0, + num_cons)))) + #sys = ModelingToolkit.structural_simplify(sys) + # don't need to pass `x` or `p` since they're defaults now + mtkprob = OptimizationProblem(sys, nothing; grad = g, hess = h, + sparse = true, cons_j = cons_j, cons_h = cons_h, + cons_sparse = true) + f = mtkprob.f + + grad = (G, θ, args...) -> f.grad(G, θ, mtkprob.p, args...) + + hess = (H, θ, args...) -> f.hess(H, θ, mtkprob.p, args...) + + hv = function (H, θ, v, args...) + res = similar(f.hess_prototype, eltype(θ)) + hess(res, θ, args...) + H .= res * v + end + + if !isnothing(f.cons) + cons = (res, θ) -> f.cons(res, θ, mtkprob.p) + cons_j = (J, θ) -> f.cons_j(J, θ, mtkprob.p) + cons_h = (res, θ) -> f.cons_h(res, θ, mtkprob.p) + else + cons = nothing + cons_j = nothing + cons_h = nothing + end + + return OptimizationFunction{true}(f.f, adtype; grad = grad, hess = hess, hv = hv, + cons = cons, cons_j = cons_j, cons_h = cons_h, + hess_prototype = f.hess_prototype, + cons_jac_prototype = f.cons_jac_prototype, + cons_hess_prototype = f.cons_hess_prototype, + expr = OptimizationBase.symbolify(f.expr), + cons_expr = OptimizationBase.symbolify.(f.cons_expr), + sys = sys, + observed = f.observed) +end + +function OptimizationBase.instantiate_function( + f::OptimizationFunction{true}, cache::OptimizationBase.ReInitCache, + adtype::AutoSparse{<:AutoSymbolics}, num_cons = 0; + g = false, h = false, hv = false, fg = false, fgh = false, + cons_j = false, cons_vjp = false, cons_jvp = false, cons_h = false, + lag_h = false) + p = isnothing(cache.p) ? SciMLBase.NullParameters() : cache.p + + sys = complete(ModelingToolkitBase.modelingtoolkitize(OptimizationProblem(f, cache.u0, + cache.p; + lcons = fill(0.0, + num_cons), + ucons = fill(0.0, + num_cons)))) + #sys = ModelingToolkit.structural_simplify(sys) + # don't need to pass `x` or `p` since they're defaults now + mtkprob = OptimizationProblem(sys, nothing; grad = g, hess = h, + sparse = true, cons_j = cons_j, cons_h = cons_h, + cons_sparse = true) + f = mtkprob.f + + grad = (G, θ, args...) -> f.grad(G, θ, mtkprob.p, args...) + + hess = (H, θ, args...) -> f.hess(H, θ, mtkprob.p, args...) + + hv = function (H, θ, v, args...) + res = similar(f.hess_prototype, eltype(θ)) + hess(res, θ, args...) + H .= res * v + end + if !isnothing(f.cons) + cons = (res, θ) -> f.cons(res, θ, mtkprob.p) + cons_j = (J, θ) -> f.cons_j(J, θ, mtkprob.p) + cons_h = (res, θ) -> f.cons_h(res, θ, mtkprob.p) + else + cons = nothing + cons_j = nothing + cons_h = nothing + end + + return OptimizationFunction{true}(f.f, adtype; grad = grad, hess = hess, hv = hv, + cons = cons, cons_j = cons_j, cons_h = cons_h, + hess_prototype = f.hess_prototype, + cons_jac_prototype = f.cons_jac_prototype, + cons_hess_prototype = f.cons_hess_prototype, + expr = OptimizationBase.symbolify(f.expr), + cons_expr = OptimizationBase.symbolify.(f.cons_expr), + sys = sys, + observed = f.observed) +end + +function OptimizationBase.instantiate_function( + f::OptimizationFunction{true}, x, adtype::AutoSymbolics, p, + num_cons = 0; g = false, h = false, hv = false, fg = false, fgh = false, + cons_j = false, cons_vjp = false, cons_jvp = false, cons_h = false, + lag_h = false) + p = isnothing(p) ? SciMLBase.NullParameters() : p + + sys = complete(ModelingToolkitBase.modelingtoolkitize(OptimizationProblem(f, x, p; + lcons = fill(0.0, + num_cons), + ucons = fill(0.0, + num_cons)))) + #sys = ModelingToolkit.structural_simplify(sys) + # don't need to pass `x` or `p` since they're defaults now + mtkprob = OptimizationProblem(sys, nothing; grad = g, hess = h, + sparse = false, cons_j = cons_j, cons_h = cons_h, + cons_sparse = false) + f = mtkprob.f + + grad = (G, θ, args...) -> f.grad(G, θ, mtkprob.p, args...) + + hess = (H, θ, args...) -> f.hess(H, θ, mtkprob.p, args...) + + hv = function (H, θ, v, args...) + res = ArrayInterface.zeromatrix(θ) + hess(res, θ, args...) + H .= res * v + end + + if !isnothing(f.cons) + cons = (res, θ) -> f.cons(res, θ, mtkprob.p) + cons_j = (J, θ) -> f.cons_j(J, θ, mtkprob.p) + cons_h = (res, θ) -> f.cons_h(res, θ, mtkprob.p) + else + cons = nothing + cons_j = nothing + cons_h = nothing + end + + return OptimizationFunction{true}(f.f, adtype; grad = grad, hess = hess, hv = hv, + cons = cons, cons_j = cons_j, cons_h = cons_h, + hess_prototype = f.hess_prototype, + cons_jac_prototype = f.cons_jac_prototype, + cons_hess_prototype = f.cons_hess_prototype, + expr = OptimizationBase.symbolify(f.expr), + cons_expr = OptimizationBase.symbolify.(f.cons_expr), + sys = sys, + observed = f.observed) +end + +function OptimizationBase.instantiate_function( + f::OptimizationFunction{true}, cache::OptimizationBase.ReInitCache, + adtype::AutoSymbolics, num_cons = 0; + g = false, h = false, hv = false, fg = false, fgh = false, + cons_j = false, cons_vjp = false, cons_jvp = false, cons_h = false, + lag_h = false) + p = isnothing(cache.p) ? SciMLBase.NullParameters() : cache.p + + sys = complete(ModelingToolkitBase.modelingtoolkitize(OptimizationProblem(f, cache.u0, + cache.p; + lcons = fill(0.0, + num_cons), + ucons = fill(0.0, + num_cons)))) + #sys = ModelingToolkit.structural_simplify(sys) + # don't need to pass `x` or `p` since they're defaults now + mtkprob = OptimizationProblem(sys, nothing; grad = g, hess = h, + sparse = false, cons_j = cons_j, cons_h = cons_h, + cons_sparse = false) + f = mtkprob.f + + grad = (G, θ, args...) -> f.grad(G, θ, mtkprob.p, args...) + + hess = (H, θ, args...) -> f.hess(H, θ, mtkprob.p, args...) + + hv = function (H, θ, v, args...) + res = ArrayInterface.zeromatrix(θ) + hess(res, θ, args...) + H .= res * v + end + + if !isnothing(f.cons) + cons = (res, θ) -> f.cons(res, θ, mtkprob.p) + cons_j = (J, θ) -> f.cons_j(J, θ, mtkprob.p) + cons_h = (res, θ) -> f.cons_h(res, θ, mtkprob.p) + else + cons = nothing + cons_j = nothing + cons_h = nothing + end + + return OptimizationFunction{true}(f.f, adtype; grad = grad, hess = hess, hv = hv, + cons = cons, cons_j = cons_j, cons_h = cons_h, + hess_prototype = f.hess_prototype, + cons_jac_prototype = f.cons_jac_prototype, + cons_hess_prototype = f.cons_hess_prototype, + expr = OptimizationBase.symbolify(f.expr), + cons_expr = OptimizationBase.symbolify.(f.cons_expr), + sys = sys, + observed = f.observed) +end + +end diff --git a/lib/OptimizationBase/ext/OptimizationMTKExt.jl b/lib/OptimizationBase/ext/OptimizationMTKExt.jl index 7538d8c3c..383a674cb 100644 --- a/lib/OptimizationBase/ext/OptimizationMTKExt.jl +++ b/lib/OptimizationBase/ext/OptimizationMTKExt.jl @@ -6,208 +6,210 @@ import SciMLBase: OptimizationFunction import OptimizationBase.ADTypes: AutoSymbolics, AutoSparse using ModelingToolkit -function OptimizationBase.instantiate_function( - f::OptimizationFunction{true}, x, adtype::AutoSparse{<:AutoSymbolics}, p, - num_cons = 0; - g = false, h = false, hv = false, fg = false, fgh = false, - cons_j = false, cons_vjp = false, cons_jvp = false, cons_h = false, - lag_h = false) - p = isnothing(p) ? SciMLBase.NullParameters() : p - - sys = complete(ModelingToolkit.modelingtoolkitize(OptimizationProblem(f, x, p; - lcons = fill(0.0, - num_cons), - ucons = fill(0.0, - num_cons)))) - #sys = ModelingToolkit.structural_simplify(sys) - # don't need to pass `x` or `p` since they're defaults now - mtkprob = OptimizationProblem(sys, nothing; grad = g, hess = h, - sparse = true, cons_j = cons_j, cons_h = cons_h, - cons_sparse = true) - f = mtkprob.f - - grad = (G, θ, args...) -> f.grad(G, θ, mtkprob.p, args...) - - hess = (H, θ, args...) -> f.hess(H, θ, mtkprob.p, args...) - - hv = function (H, θ, v, args...) - res = similar(f.hess_prototype, eltype(θ)) - hess(res, θ, args...) - H .= res * v +@static if pkgversion(ModelingToolkit) < v"11.0" + function OptimizationBase.instantiate_function( + f::OptimizationFunction{true}, x, adtype::AutoSparse{<:AutoSymbolics}, p, + num_cons = 0; + g = false, h = false, hv = false, fg = false, fgh = false, + cons_j = false, cons_vjp = false, cons_jvp = false, cons_h = false, + lag_h = false) + p = isnothing(p) ? SciMLBase.NullParameters() : p + + sys = complete(ModelingToolkit.modelingtoolkitize(OptimizationProblem(f, x, p; + lcons = fill(0.0, + num_cons), + ucons = fill(0.0, + num_cons)))) + #sys = ModelingToolkit.structural_simplify(sys) + # don't need to pass `x` or `p` since they're defaults now + mtkprob = OptimizationProblem(sys, nothing; grad = g, hess = h, + sparse = true, cons_j = cons_j, cons_h = cons_h, + cons_sparse = true) + f = mtkprob.f + + grad = (G, θ, args...) -> f.grad(G, θ, mtkprob.p, args...) + + hess = (H, θ, args...) -> f.hess(H, θ, mtkprob.p, args...) + + hv = function (H, θ, v, args...) + res = similar(f.hess_prototype, eltype(θ)) + hess(res, θ, args...) + H .= res * v + end + + if !isnothing(f.cons) + cons = (res, θ) -> f.cons(res, θ, mtkprob.p) + cons_j = (J, θ) -> f.cons_j(J, θ, mtkprob.p) + cons_h = (res, θ) -> f.cons_h(res, θ, mtkprob.p) + else + cons = nothing + cons_j = nothing + cons_h = nothing + end + + return OptimizationFunction{true}(f.f, adtype; grad = grad, hess = hess, hv = hv, + cons = cons, cons_j = cons_j, cons_h = cons_h, + hess_prototype = f.hess_prototype, + cons_jac_prototype = f.cons_jac_prototype, + cons_hess_prototype = f.cons_hess_prototype, + expr = OptimizationBase.symbolify(f.expr), + cons_expr = OptimizationBase.symbolify.(f.cons_expr), + sys = sys, + observed = f.observed) end - if !isnothing(f.cons) - cons = (res, θ) -> f.cons(res, θ, mtkprob.p) - cons_j = (J, θ) -> f.cons_j(J, θ, mtkprob.p) - cons_h = (res, θ) -> f.cons_h(res, θ, mtkprob.p) - else - cons = nothing - cons_j = nothing - cons_h = nothing + function OptimizationBase.instantiate_function( + f::OptimizationFunction{true}, cache::OptimizationBase.ReInitCache, + adtype::AutoSparse{<:AutoSymbolics}, num_cons = 0; + g = false, h = false, hv = false, fg = false, fgh = false, + cons_j = false, cons_vjp = false, cons_jvp = false, cons_h = false, + lag_h = false) + p = isnothing(cache.p) ? SciMLBase.NullParameters() : cache.p + + sys = complete(ModelingToolkit.modelingtoolkitize(OptimizationProblem(f, cache.u0, + cache.p; + lcons = fill(0.0, + num_cons), + ucons = fill(0.0, + num_cons)))) + #sys = ModelingToolkit.structural_simplify(sys) + # don't need to pass `x` or `p` since they're defaults now + mtkprob = OptimizationProblem(sys, nothing; grad = g, hess = h, + sparse = true, cons_j = cons_j, cons_h = cons_h, + cons_sparse = true) + f = mtkprob.f + + grad = (G, θ, args...) -> f.grad(G, θ, mtkprob.p, args...) + + hess = (H, θ, args...) -> f.hess(H, θ, mtkprob.p, args...) + + hv = function (H, θ, v, args...) + res = similar(f.hess_prototype, eltype(θ)) + hess(res, θ, args...) + H .= res * v + end + if !isnothing(f.cons) + cons = (res, θ) -> f.cons(res, θ, mtkprob.p) + cons_j = (J, θ) -> f.cons_j(J, θ, mtkprob.p) + cons_h = (res, θ) -> f.cons_h(res, θ, mtkprob.p) + else + cons = nothing + cons_j = nothing + cons_h = nothing + end + + return OptimizationFunction{true}(f.f, adtype; grad = grad, hess = hess, hv = hv, + cons = cons, cons_j = cons_j, cons_h = cons_h, + hess_prototype = f.hess_prototype, + cons_jac_prototype = f.cons_jac_prototype, + cons_hess_prototype = f.cons_hess_prototype, + expr = OptimizationBase.symbolify(f.expr), + cons_expr = OptimizationBase.symbolify.(f.cons_expr), + sys = sys, + observed = f.observed) end - return OptimizationFunction{true}(f.f, adtype; grad = grad, hess = hess, hv = hv, - cons = cons, cons_j = cons_j, cons_h = cons_h, - hess_prototype = f.hess_prototype, - cons_jac_prototype = f.cons_jac_prototype, - cons_hess_prototype = f.cons_hess_prototype, - expr = OptimizationBase.symbolify(f.expr), - cons_expr = OptimizationBase.symbolify.(f.cons_expr), - sys = sys, - observed = f.observed) -end - -function OptimizationBase.instantiate_function( - f::OptimizationFunction{true}, cache::OptimizationBase.ReInitCache, - adtype::AutoSparse{<:AutoSymbolics}, num_cons = 0; - g = false, h = false, hv = false, fg = false, fgh = false, - cons_j = false, cons_vjp = false, cons_jvp = false, cons_h = false, - lag_h = false) - p = isnothing(cache.p) ? SciMLBase.NullParameters() : cache.p - - sys = complete(ModelingToolkit.modelingtoolkitize(OptimizationProblem(f, cache.u0, - cache.p; - lcons = fill(0.0, - num_cons), - ucons = fill(0.0, - num_cons)))) - #sys = ModelingToolkit.structural_simplify(sys) - # don't need to pass `x` or `p` since they're defaults now - mtkprob = OptimizationProblem(sys, nothing; grad = g, hess = h, - sparse = true, cons_j = cons_j, cons_h = cons_h, - cons_sparse = true) - f = mtkprob.f - - grad = (G, θ, args...) -> f.grad(G, θ, mtkprob.p, args...) - - hess = (H, θ, args...) -> f.hess(H, θ, mtkprob.p, args...) - - hv = function (H, θ, v, args...) - res = similar(f.hess_prototype, eltype(θ)) - hess(res, θ, args...) - H .= res * v - end - if !isnothing(f.cons) - cons = (res, θ) -> f.cons(res, θ, mtkprob.p) - cons_j = (J, θ) -> f.cons_j(J, θ, mtkprob.p) - cons_h = (res, θ) -> f.cons_h(res, θ, mtkprob.p) - else - cons = nothing - cons_j = nothing - cons_h = nothing - end - - return OptimizationFunction{true}(f.f, adtype; grad = grad, hess = hess, hv = hv, - cons = cons, cons_j = cons_j, cons_h = cons_h, - hess_prototype = f.hess_prototype, - cons_jac_prototype = f.cons_jac_prototype, - cons_hess_prototype = f.cons_hess_prototype, - expr = OptimizationBase.symbolify(f.expr), - cons_expr = OptimizationBase.symbolify.(f.cons_expr), - sys = sys, - observed = f.observed) -end - -function OptimizationBase.instantiate_function( - f::OptimizationFunction{true}, x, adtype::AutoSymbolics, p, - num_cons = 0; g = false, h = false, hv = false, fg = false, fgh = false, - cons_j = false, cons_vjp = false, cons_jvp = false, cons_h = false, - lag_h = false) - p = isnothing(p) ? SciMLBase.NullParameters() : p - - sys = complete(ModelingToolkit.modelingtoolkitize(OptimizationProblem(f, x, p; - lcons = fill(0.0, - num_cons), - ucons = fill(0.0, - num_cons)))) - #sys = ModelingToolkit.structural_simplify(sys) - # don't need to pass `x` or `p` since they're defaults now - mtkprob = OptimizationProblem(sys, nothing; grad = g, hess = h, - sparse = false, cons_j = cons_j, cons_h = cons_h, - cons_sparse = false) - f = mtkprob.f - - grad = (G, θ, args...) -> f.grad(G, θ, mtkprob.p, args...) - - hess = (H, θ, args...) -> f.hess(H, θ, mtkprob.p, args...) - - hv = function (H, θ, v, args...) - res = ArrayInterface.zeromatrix(θ) - hess(res, θ, args...) - H .= res * v + function OptimizationBase.instantiate_function( + f::OptimizationFunction{true}, x, adtype::AutoSymbolics, p, + num_cons = 0; g = false, h = false, hv = false, fg = false, fgh = false, + cons_j = false, cons_vjp = false, cons_jvp = false, cons_h = false, + lag_h = false) + p = isnothing(p) ? SciMLBase.NullParameters() : p + + sys = complete(ModelingToolkit.modelingtoolkitize(OptimizationProblem(f, x, p; + lcons = fill(0.0, + num_cons), + ucons = fill(0.0, + num_cons)))) + #sys = ModelingToolkit.structural_simplify(sys) + # don't need to pass `x` or `p` since they're defaults now + mtkprob = OptimizationProblem(sys, nothing; grad = g, hess = h, + sparse = false, cons_j = cons_j, cons_h = cons_h, + cons_sparse = false) + f = mtkprob.f + + grad = (G, θ, args...) -> f.grad(G, θ, mtkprob.p, args...) + + hess = (H, θ, args...) -> f.hess(H, θ, mtkprob.p, args...) + + hv = function (H, θ, v, args...) + res = ArrayInterface.zeromatrix(θ) + hess(res, θ, args...) + H .= res * v + end + + if !isnothing(f.cons) + cons = (res, θ) -> f.cons(res, θ, mtkprob.p) + cons_j = (J, θ) -> f.cons_j(J, θ, mtkprob.p) + cons_h = (res, θ) -> f.cons_h(res, θ, mtkprob.p) + else + cons = nothing + cons_j = nothing + cons_h = nothing + end + + return OptimizationFunction{true}(f.f, adtype; grad = grad, hess = hess, hv = hv, + cons = cons, cons_j = cons_j, cons_h = cons_h, + hess_prototype = f.hess_prototype, + cons_jac_prototype = f.cons_jac_prototype, + cons_hess_prototype = f.cons_hess_prototype, + expr = OptimizationBase.symbolify(f.expr), + cons_expr = OptimizationBase.symbolify.(f.cons_expr), + sys = sys, + observed = f.observed) end - if !isnothing(f.cons) - cons = (res, θ) -> f.cons(res, θ, mtkprob.p) - cons_j = (J, θ) -> f.cons_j(J, θ, mtkprob.p) - cons_h = (res, θ) -> f.cons_h(res, θ, mtkprob.p) - else - cons = nothing - cons_j = nothing - cons_h = nothing + function OptimizationBase.instantiate_function( + f::OptimizationFunction{true}, cache::OptimizationBase.ReInitCache, + adtype::AutoSymbolics, num_cons = 0; + g = false, h = false, hv = false, fg = false, fgh = false, + cons_j = false, cons_vjp = false, cons_jvp = false, cons_h = false, + lag_h = false) + p = isnothing(cache.p) ? SciMLBase.NullParameters() : cache.p + + sys = complete(ModelingToolkit.modelingtoolkitize(OptimizationProblem(f, cache.u0, + cache.p; + lcons = fill(0.0, + num_cons), + ucons = fill(0.0, + num_cons)))) + #sys = ModelingToolkit.structural_simplify(sys) + # don't need to pass `x` or `p` since they're defaults now + mtkprob = OptimizationProblem(sys, nothing; grad = g, hess = h, + sparse = false, cons_j = cons_j, cons_h = cons_h, + cons_sparse = false) + f = mtkprob.f + + grad = (G, θ, args...) -> f.grad(G, θ, mtkprob.p, args...) + + hess = (H, θ, args...) -> f.hess(H, θ, mtkprob.p, args...) + + hv = function (H, θ, v, args...) + res = ArrayInterface.zeromatrix(θ) + hess(res, θ, args...) + H .= res * v + end + + if !isnothing(f.cons) + cons = (res, θ) -> f.cons(res, θ, mtkprob.p) + cons_j = (J, θ) -> f.cons_j(J, θ, mtkprob.p) + cons_h = (res, θ) -> f.cons_h(res, θ, mtkprob.p) + else + cons = nothing + cons_j = nothing + cons_h = nothing + end + + return OptimizationFunction{true}(f.f, adtype; grad = grad, hess = hess, hv = hv, + cons = cons, cons_j = cons_j, cons_h = cons_h, + hess_prototype = f.hess_prototype, + cons_jac_prototype = f.cons_jac_prototype, + cons_hess_prototype = f.cons_hess_prototype, + expr = OptimizationBase.symbolify(f.expr), + cons_expr = OptimizationBase.symbolify.(f.cons_expr), + sys = sys, + observed = f.observed) end - - return OptimizationFunction{true}(f.f, adtype; grad = grad, hess = hess, hv = hv, - cons = cons, cons_j = cons_j, cons_h = cons_h, - hess_prototype = f.hess_prototype, - cons_jac_prototype = f.cons_jac_prototype, - cons_hess_prototype = f.cons_hess_prototype, - expr = OptimizationBase.symbolify(f.expr), - cons_expr = OptimizationBase.symbolify.(f.cons_expr), - sys = sys, - observed = f.observed) -end - -function OptimizationBase.instantiate_function( - f::OptimizationFunction{true}, cache::OptimizationBase.ReInitCache, - adtype::AutoSymbolics, num_cons = 0; - g = false, h = false, hv = false, fg = false, fgh = false, - cons_j = false, cons_vjp = false, cons_jvp = false, cons_h = false, - lag_h = false) - p = isnothing(cache.p) ? SciMLBase.NullParameters() : cache.p - - sys = complete(ModelingToolkit.modelingtoolkitize(OptimizationProblem(f, cache.u0, - cache.p; - lcons = fill(0.0, - num_cons), - ucons = fill(0.0, - num_cons)))) - #sys = ModelingToolkit.structural_simplify(sys) - # don't need to pass `x` or `p` since they're defaults now - mtkprob = OptimizationProblem(sys, nothing; grad = g, hess = h, - sparse = false, cons_j = cons_j, cons_h = cons_h, - cons_sparse = false) - f = mtkprob.f - - grad = (G, θ, args...) -> f.grad(G, θ, mtkprob.p, args...) - - hess = (H, θ, args...) -> f.hess(H, θ, mtkprob.p, args...) - - hv = function (H, θ, v, args...) - res = ArrayInterface.zeromatrix(θ) - hess(res, θ, args...) - H .= res * v - end - - if !isnothing(f.cons) - cons = (res, θ) -> f.cons(res, θ, mtkprob.p) - cons_j = (J, θ) -> f.cons_j(J, θ, mtkprob.p) - cons_h = (res, θ) -> f.cons_h(res, θ, mtkprob.p) - else - cons = nothing - cons_j = nothing - cons_h = nothing - end - - return OptimizationFunction{true}(f.f, adtype; grad = grad, hess = hess, hv = hv, - cons = cons, cons_j = cons_j, cons_h = cons_h, - hess_prototype = f.hess_prototype, - cons_jac_prototype = f.cons_jac_prototype, - cons_hess_prototype = f.cons_hess_prototype, - expr = OptimizationBase.symbolify(f.expr), - cons_expr = OptimizationBase.symbolify.(f.cons_expr), - sys = sys, - observed = f.observed) end end diff --git a/lib/OptimizationMOI/Project.toml b/lib/OptimizationMOI/Project.toml index a2e326911..029b37888 100644 --- a/lib/OptimizationMOI/Project.toml +++ b/lib/OptimizationMOI/Project.toml @@ -2,18 +2,22 @@ name = "OptimizationMOI" uuid = "fd9f6733-72f4-499f-8506-86b2bdd0dea1" authors = ["Vaibhav Dixit and contributors"] version = "0.5.11" + [deps] OptimizationBase = "bca83a33-5cc9-4baa-983d-23429ab6bcbb" Symbolics = "0c5d862f-8b57-4792-8d23-62f2024744c7" LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" -ModelingToolkit = "961ee093-0014-501f-94e3-6117800e7a78" +ModelingToolkitBase = "7771a370-6774-4173-bd38-47e70ca0b839" MathOptInterface = "b8f27783-ece8-5eb3-8dc8-9495eed66fee" SciMLBase = "0bca4576-84f4-4d90-8ffe-ffa030f20462" Reexport = "189a3867-3050-52da-a836-e630ba90ab69" SciMLStructures = "53ae85a6-f571-4167-b2af-e1d143709226" SymbolicIndexingInterface = "2efcf032-c050-4f8e-a9bb-153293bab1f5" +[weakdeps] +ModelingToolkit = "961ee093-0014-501f-94e3-6117800e7a78" + [extras] HiGHS = "87dc4568-4c63-4d18-b0c0-bb2238e4078b" AmplNLWriter = "7c4d4715-977e-5154-bfe0-e096adeac482" @@ -32,7 +36,7 @@ OptimizationBase = {path = "../OptimizationBase"} HiGHS = "1" OptimizationBase = "3.3.1, 4" Test = "1.6" -Symbolics = "6" +Symbolics = "6, 7" AmplNLWriter = "1" LinearAlgebra = "1" Ipopt_jll = "300.1400" @@ -41,7 +45,8 @@ Ipopt = "1.10.4" NLopt = "1" SciMLBase = "2.122.1" SparseArrays = "1.6" -ModelingToolkit = "10.23" +ModelingToolkit = "11" +ModelingToolkitBase = "1" SymbolicIndexingInterface = "0.3" julia = "1.10" Zygote = "0.6, 0.7" diff --git a/lib/OptimizationMOI/src/OptimizationMOI.jl b/lib/OptimizationMOI/src/OptimizationMOI.jl index 1678424a1..27a58f307 100644 --- a/lib/OptimizationMOI/src/OptimizationMOI.jl +++ b/lib/OptimizationMOI/src/OptimizationMOI.jl @@ -7,9 +7,9 @@ using SciMLBase using SciMLStructures using SymbolicIndexingInterface using SparseArrays -import ModelingToolkit: parameters, unknowns, varmap_to_vars, mergedefaults, toexpr -import ModelingToolkit -const MTK = ModelingToolkit +import ModelingToolkitBase: parameters, unknowns, varmap_to_vars, mergedefaults, toexpr +import ModelingToolkitBase +const MTK = ModelingToolkitBase using Symbolics using LinearAlgebra @@ -217,7 +217,7 @@ function convert_to_expr(eq, expr_map; expand_expr = false) Symbolics.expand(eq) end end - expr = ModelingToolkit.toexpr(eq) + expr = ModelingToolkitBase.toexpr(eq) expr = rep_pars_vals!(expr, expr_map) expr = symbolify!(expr) @@ -225,12 +225,12 @@ function convert_to_expr(eq, expr_map; expand_expr = false) end function get_expr_map(sys) - dvs = ModelingToolkit.unknowns(sys) - ps = ModelingToolkit.parameters(sys) + dvs = ModelingToolkitBase.unknowns(sys) + ps = ModelingToolkitBase.parameters(sys) return vcat( - [ModelingToolkit.toexpr(_s) => Expr(:ref, :x, i) + [ModelingToolkitBase.toexpr(_s) => Expr(:ref, :x, i) for (i, _s) in enumerate(dvs)], - [ModelingToolkit.toexpr(_p) => Expr(:ref, :p, i) + [ModelingToolkitBase.toexpr(_p) => Expr(:ref, :p, i) for (i, _p) in enumerate(ps)]) end