From a6e7a0c8b82f71e40e3639c74b56e346b7907f17 Mon Sep 17 00:00:00 2001 From: LukasBarner Date: Sun, 7 Sep 2025 14:47:48 +0200 Subject: [PATCH 1/5] adds NonlinearizeBridge for objectives --- src/Bridges/Objective/Objective.jl | 1 + .../bridges/FunctionConversionBridge.jl | 28 +++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/src/Bridges/Objective/Objective.jl b/src/Bridges/Objective/Objective.jl index 68be377bcb..0b2b7c9320 100644 --- a/src/Bridges/Objective/Objective.jl +++ b/src/Bridges/Objective/Objective.jl @@ -28,6 +28,7 @@ The coefficient type used is `T`. function add_all_bridges(model, ::Type{T}) where {T} MOI.Bridges.add_bridge(model, FunctionizeBridge{T}) MOI.Bridges.add_bridge(model, QuadratizeBridge{T}) + MOI.Bridges.add_bridge(model, NonlinearizeBridge{T}) MOI.Bridges.add_bridge(model, SlackBridge{T}) MOI.Bridges.add_bridge(model, VectorFunctionizeBridge{T}) MOI.Bridges.add_bridge(model, VectorSlackBridge{T}) diff --git a/src/Bridges/Objective/bridges/FunctionConversionBridge.jl b/src/Bridges/Objective/bridges/FunctionConversionBridge.jl index 92deb99bf9..fb0f4822fd 100644 --- a/src/Bridges/Objective/bridges/FunctionConversionBridge.jl +++ b/src/Bridges/Objective/bridges/FunctionConversionBridge.jl @@ -173,6 +173,34 @@ const QuadratizeBridge{T,G} = const Quadratize{T,OT<:MOI.ModelLike} = SingleBridgeOptimizer{QuadratizeBridge{T},OT} +""" + NonlinearizeBridge{T,G} <: FunctionConversionBridge{T,MOI.ScalarNonlinearFunction,G} + +`NonlinearizeBridge` implements the following reformulations: + + * ``\\min\\{x^\\top \\mathbf{𝑄} x + a^\\top x + b\\}`` into ``\\min\\{f(x)\\}`` + * ``\\max\\{x^\\top \\mathbf{𝑄} x + a^\\top x + b\\}`` into ``\\max\\{f(x)\\}`` + +where `f(x)` is a `MOI.ScalarNonlinearFunction`. + +## Source node + +`NonlinearizeBridge` supports: + + * [`MOI.ObjectiveFunction{G}`](@ref) + +## Target nodes + +`NonlinearizeBridge` creates: + + * One objective node: [`MOI.ObjectiveFunction{MOI.ScalarNonlinearFunction}`](@ref) +""" +const NonlinearizeBridge{T,G} = + FunctionConversionBridge{T,MOI.ScalarNonlinearFunction,G} + +const Nonlinearize{T,OT<:MOI.ModelLike} = + SingleBridgeOptimizer{NonlinearizeBridge{T},OT} + """ VectorFunctionizeBridge{T,G} <: FunctionConversionBridge{T,MOI.VectorAffineFunction{T},G} From 0ce740a15e98b8c3eb47bc6c9b9965113472e954 Mon Sep 17 00:00:00 2001 From: LukasBarner Date: Sun, 7 Sep 2025 21:09:52 +0200 Subject: [PATCH 2/5] add tests and some fixes for tests... --- .../bridges/FunctionConversionBridge.jl | 2 +- test/Bridges/Objective/NonlinearizeBridge.jl | 113 ++++++++++++++++++ test/Bridges/Objective/SlackBridge.jl | 1 + test/Bridges/debug.jl | 1 + 4 files changed, 116 insertions(+), 1 deletion(-) create mode 100644 test/Bridges/Objective/NonlinearizeBridge.jl diff --git a/src/Bridges/Objective/bridges/FunctionConversionBridge.jl b/src/Bridges/Objective/bridges/FunctionConversionBridge.jl index fb0f4822fd..7f525b2862 100644 --- a/src/Bridges/Objective/bridges/FunctionConversionBridge.jl +++ b/src/Bridges/Objective/bridges/FunctionConversionBridge.jl @@ -14,7 +14,7 @@ for these pairs of functions: - * [`MOI.ScalarAffineFunction`](@ref)` to [`MOI.ScalarQuadraticFunction`](@ref) + * [`MOI.ScalarAffineFunction`](@ref) to [`MOI.ScalarQuadraticFunction`](@ref) * [`MOI.ScalarQuadraticFunction`](@ref) to [`MOI.ScalarNonlinearFunction`](@ref) * [`MOI.VectorAffineFunction`](@ref) to [`MOI.VectorQuadraticFunction`](@ref) diff --git a/test/Bridges/Objective/NonlinearizeBridge.jl b/test/Bridges/Objective/NonlinearizeBridge.jl new file mode 100644 index 0000000000..e57f49c2ac --- /dev/null +++ b/test/Bridges/Objective/NonlinearizeBridge.jl @@ -0,0 +1,113 @@ +# Copyright (c) 2017: Miles Lubin and contributors +# Copyright (c) 2017: Google Inc. +# +# Use of this source code is governed by an MIT-style license that can be found +# in the LICENSE.md file or at https://opensource.org/licenses/MIT. + +module TestObjectiveNonlinearize + +using Test + +import MathOptInterface as MOI + +function runtests() + for name in names(@__MODULE__; all = true) + if startswith("$(name)", "test_") + @testset "$(name)" begin + getfield(@__MODULE__, name)() + end + end + end + return +end + +include("../utilities.jl") + +function test_solve_singlevariable_obj() + mock = MOI.Utilities.MockOptimizer(MOI.Utilities.Model{Float64}()) + model = MOI.Bridges.Objective.Nonlinearize{Float64}(mock) + MOI.Utilities.set_mock_optimize!( + mock, + (mock::MOI.Utilities.MockOptimizer) -> + MOI.Utilities.mock_optimize!(mock, [1.0], MOI.FEASIBLE_POINT), + ) + MOI.Test.test_objective_ObjectiveFunction_duplicate_terms( + model, + MOI.Test.Config(;exclude = Any[MOI.DualObjectiveValue, MOI.ConstraintDual, ]), + ) + @test MOI.get(mock, MOI.ObjectiveFunctionType()) == + MOI.ScalarNonlinearFunction + @test MOI.get(model, MOI.ObjectiveFunctionType()) == + MOI.ScalarAffineFunction{Float64} + @test MOI.get(mock, MOI.ObjectiveSense()) == MOI.MIN_SENSE + @test MOI.get(model, MOI.ObjectiveSense()) == MOI.MIN_SENSE + vis = MOI.get(model, MOI.ListOfVariableIndices()) + func = 3.0 * vis[1] + 0.0 + + @test MOI.get( + model, + MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}(), + ) ≈ func + MOI.set(model, MOI.ObjectiveSense(), MOI.MAX_SENSE) + @test MOI.get(mock, MOI.ObjectiveSense()) == MOI.MAX_SENSE + @test MOI.get(model, MOI.ObjectiveSense()) == MOI.MAX_SENSE + + _test_delete_objective(model, 1, tuple()) + return +end + +function test_solve_result_index() + mock = MOI.Utilities.MockOptimizer(MOI.Utilities.Model{Float64}()) + model = MOI.Bridges.Objective.Nonlinearize{Float64}(mock) + MOI.Utilities.set_mock_optimize!( + mock, + (mock::MOI.Utilities.MockOptimizer) -> MOI.Utilities.mock_optimize!( + mock, + MOI.OPTIMAL, + (MOI.FEASIBLE_POINT, [1.0]), + MOI.FEASIBLE_POINT, + (MOI.VariableIndex, MOI.GreaterThan{Float64}) => [1.0], + ), + ) + MOI.Test.test_solve_result_index(model, MOI.Test.Config(;exclude = Any[MOI.DualObjectiveValue, MOI.ConstraintDual, ])) + + return +end + +function test_runtests() + MOI.Bridges.runtests( + MOI.Bridges.Objective.NonlinearizeBridge, + model -> begin + x = MOI.add_variable(model) + aff = MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.([2.0], [x]), 1.0) + MOI.set(model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}(), aff) + MOI.set(model, MOI.ObjectiveSense(), MOI.MIN_SENSE) + end, + model -> begin + x = MOI.add_variable(model) + exp = MOI.ScalarNonlinearFunction(:+, [MOI.ScalarNonlinearFunction(:*, [2.0, MOI.VariableIndex(1)]), 1.0]) + MOI.set(model, MOI.ObjectiveFunction{MOI.ScalarNonlinearFunction}(), exp) + MOI.set(model, MOI.ObjectiveSense(), MOI.MIN_SENSE) + end, + ) + MOI.Bridges.runtests( + MOI.Bridges.Objective.NonlinearizeBridge, + model -> begin + x = MOI.add_variable(model) + aff = MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.([2.0], [x]), 1.0) + MOI.set(model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}(), aff) + MOI.set(model, MOI.ObjectiveSense(), MOI.MAX_SENSE) + end, + model -> begin + x = MOI.add_variable(model) + exp = MOI.ScalarNonlinearFunction(:+, [MOI.ScalarNonlinearFunction(:*, [2.0, MOI.VariableIndex(1)]), 1.0]) + MOI.set(model, MOI.ObjectiveFunction{MOI.ScalarNonlinearFunction}(), exp) + MOI.set(model, MOI.ObjectiveSense(), MOI.MAX_SENSE) + end, + ) + return +end + +end # module + +TestObjectiveNonlinearize.runtests() \ No newline at end of file diff --git a/test/Bridges/Objective/SlackBridge.jl b/test/Bridges/Objective/SlackBridge.jl index 9757aae392..34c288ccc2 100644 --- a/test/Bridges/Objective/SlackBridge.jl +++ b/test/Bridges/Objective/SlackBridge.jl @@ -525,6 +525,7 @@ function test_complex_objective() MOI.Utilities.Model{Float64}(), Float64, ) + MOI.Bridges.remove_bridge(dest, MOI.Bridges.Objective.NonlinearizeBridge{Float64}) # Otherwise, would be bridged to Nonlinear. @test_throws MOI.UnsupportedAttribute(attr) MOI.copy_to(dest, model) end return diff --git a/test/Bridges/debug.jl b/test/Bridges/debug.jl index 9be0192e6d..d6e05544f9 100644 --- a/test/Bridges/debug.jl +++ b/test/Bridges/debug.jl @@ -188,6 +188,7 @@ end function test_print_active_bridges_objective_unsupported() model = MOI.Bridges.full_bridge_optimizer(Model{Float64}(), Float64) + MOI.Bridges.remove_bridge(model, MOI.Bridges.Objective.NonlinearizeBridge{Float64}) # Otherwise, Int would be bridged to Nonlinear. F = MOI.ScalarAffineFunction{Int} @test_throws( MOI.UnsupportedAttribute{MOI.ObjectiveFunction{F}}, From d15a0846d4e8e9328ba3b83fa1d226721e86c1de Mon Sep 17 00:00:00 2001 From: LukasBarner Date: Sun, 7 Sep 2025 21:14:52 +0200 Subject: [PATCH 3/5] formatting --- test/Bridges/Objective/NonlinearizeBridge.jl | 75 ++++++++++++++++---- test/Bridges/Objective/SlackBridge.jl | 5 +- test/Bridges/debug.jl | 5 +- 3 files changed, 69 insertions(+), 16 deletions(-) diff --git a/test/Bridges/Objective/NonlinearizeBridge.jl b/test/Bridges/Objective/NonlinearizeBridge.jl index e57f49c2ac..ff4e8e0c11 100644 --- a/test/Bridges/Objective/NonlinearizeBridge.jl +++ b/test/Bridges/Objective/NonlinearizeBridge.jl @@ -33,7 +33,9 @@ function test_solve_singlevariable_obj() ) MOI.Test.test_objective_ObjectiveFunction_duplicate_terms( model, - MOI.Test.Config(;exclude = Any[MOI.DualObjectiveValue, MOI.ConstraintDual, ]), + MOI.Test.Config(; + exclude = Any[MOI.DualObjectiveValue, MOI.ConstraintDual], + ), ) @test MOI.get(mock, MOI.ObjectiveFunctionType()) == MOI.ScalarNonlinearFunction @@ -43,7 +45,7 @@ function test_solve_singlevariable_obj() @test MOI.get(model, MOI.ObjectiveSense()) == MOI.MIN_SENSE vis = MOI.get(model, MOI.ListOfVariableIndices()) func = 3.0 * vis[1] + 0.0 - + @test MOI.get( model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}(), @@ -69,7 +71,12 @@ function test_solve_result_index() (MOI.VariableIndex, MOI.GreaterThan{Float64}) => [1.0], ), ) - MOI.Test.test_solve_result_index(model, MOI.Test.Config(;exclude = Any[MOI.DualObjectiveValue, MOI.ConstraintDual, ])) + MOI.Test.test_solve_result_index( + model, + MOI.Test.Config(; + exclude = Any[MOI.DualObjectiveValue, MOI.ConstraintDual], + ), + ) return end @@ -77,31 +84,71 @@ end function test_runtests() MOI.Bridges.runtests( MOI.Bridges.Objective.NonlinearizeBridge, - model -> begin + model -> begin x = MOI.add_variable(model) - aff = MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.([2.0], [x]), 1.0) - MOI.set(model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}(), aff) + aff = MOI.ScalarAffineFunction( + MOI.ScalarAffineTerm.([2.0], [x]), + 1.0, + ) + MOI.set( + model, + MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}(), + aff, + ) MOI.set(model, MOI.ObjectiveSense(), MOI.MIN_SENSE) end, model -> begin x = MOI.add_variable(model) - exp = MOI.ScalarNonlinearFunction(:+, [MOI.ScalarNonlinearFunction(:*, [2.0, MOI.VariableIndex(1)]), 1.0]) - MOI.set(model, MOI.ObjectiveFunction{MOI.ScalarNonlinearFunction}(), exp) + exp = MOI.ScalarNonlinearFunction( + :+, + [ + MOI.ScalarNonlinearFunction( + :*, + [2.0, MOI.VariableIndex(1)], + ), + 1.0, + ], + ) + MOI.set( + model, + MOI.ObjectiveFunction{MOI.ScalarNonlinearFunction}(), + exp, + ) MOI.set(model, MOI.ObjectiveSense(), MOI.MIN_SENSE) end, ) MOI.Bridges.runtests( MOI.Bridges.Objective.NonlinearizeBridge, - model -> begin + model -> begin x = MOI.add_variable(model) - aff = MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.([2.0], [x]), 1.0) - MOI.set(model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}(), aff) + aff = MOI.ScalarAffineFunction( + MOI.ScalarAffineTerm.([2.0], [x]), + 1.0, + ) + MOI.set( + model, + MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}(), + aff, + ) MOI.set(model, MOI.ObjectiveSense(), MOI.MAX_SENSE) end, model -> begin x = MOI.add_variable(model) - exp = MOI.ScalarNonlinearFunction(:+, [MOI.ScalarNonlinearFunction(:*, [2.0, MOI.VariableIndex(1)]), 1.0]) - MOI.set(model, MOI.ObjectiveFunction{MOI.ScalarNonlinearFunction}(), exp) + exp = MOI.ScalarNonlinearFunction( + :+, + [ + MOI.ScalarNonlinearFunction( + :*, + [2.0, MOI.VariableIndex(1)], + ), + 1.0, + ], + ) + MOI.set( + model, + MOI.ObjectiveFunction{MOI.ScalarNonlinearFunction}(), + exp, + ) MOI.set(model, MOI.ObjectiveSense(), MOI.MAX_SENSE) end, ) @@ -110,4 +157,4 @@ end end # module -TestObjectiveNonlinearize.runtests() \ No newline at end of file +TestObjectiveNonlinearize.runtests() diff --git a/test/Bridges/Objective/SlackBridge.jl b/test/Bridges/Objective/SlackBridge.jl index 34c288ccc2..4d9505e299 100644 --- a/test/Bridges/Objective/SlackBridge.jl +++ b/test/Bridges/Objective/SlackBridge.jl @@ -525,7 +525,10 @@ function test_complex_objective() MOI.Utilities.Model{Float64}(), Float64, ) - MOI.Bridges.remove_bridge(dest, MOI.Bridges.Objective.NonlinearizeBridge{Float64}) # Otherwise, would be bridged to Nonlinear. + MOI.Bridges.remove_bridge( + dest, + MOI.Bridges.Objective.NonlinearizeBridge{Float64}, + ) # Otherwise, would be bridged to Nonlinear. @test_throws MOI.UnsupportedAttribute(attr) MOI.copy_to(dest, model) end return diff --git a/test/Bridges/debug.jl b/test/Bridges/debug.jl index d6e05544f9..fe9a042ddb 100644 --- a/test/Bridges/debug.jl +++ b/test/Bridges/debug.jl @@ -188,7 +188,10 @@ end function test_print_active_bridges_objective_unsupported() model = MOI.Bridges.full_bridge_optimizer(Model{Float64}(), Float64) - MOI.Bridges.remove_bridge(model, MOI.Bridges.Objective.NonlinearizeBridge{Float64}) # Otherwise, Int would be bridged to Nonlinear. + MOI.Bridges.remove_bridge( + model, + MOI.Bridges.Objective.NonlinearizeBridge{Float64}, + ) # Otherwise, Int would be bridged to Nonlinear. F = MOI.ScalarAffineFunction{Int} @test_throws( MOI.UnsupportedAttribute{MOI.ObjectiveFunction{F}}, From fc4e47fb0fec30d79ad7f1efcbef186db968e013 Mon Sep 17 00:00:00 2001 From: LukasBarner Date: Sun, 7 Sep 2025 21:33:07 +0200 Subject: [PATCH 4/5] rename NonlinearizeBridge to ToScalarNonlinearBridge --- src/Bridges/Objective/Objective.jl | 2 +- .../Objective/bridges/FunctionConversionBridge.jl | 14 +++++++------- test/Bridges/Objective/SlackBridge.jl | 2 +- ...nearizeBridge.jl => ToScalarNonlinearBridge.jl} | 12 ++++++------ test/Bridges/debug.jl | 2 +- 5 files changed, 16 insertions(+), 16 deletions(-) rename test/Bridges/Objective/{NonlinearizeBridge.jl => ToScalarNonlinearBridge.jl} (93%) diff --git a/src/Bridges/Objective/Objective.jl b/src/Bridges/Objective/Objective.jl index 0b2b7c9320..60ffcddf92 100644 --- a/src/Bridges/Objective/Objective.jl +++ b/src/Bridges/Objective/Objective.jl @@ -28,7 +28,7 @@ The coefficient type used is `T`. function add_all_bridges(model, ::Type{T}) where {T} MOI.Bridges.add_bridge(model, FunctionizeBridge{T}) MOI.Bridges.add_bridge(model, QuadratizeBridge{T}) - MOI.Bridges.add_bridge(model, NonlinearizeBridge{T}) + MOI.Bridges.add_bridge(model, ToScalarNonlinearBridge{T}) MOI.Bridges.add_bridge(model, SlackBridge{T}) MOI.Bridges.add_bridge(model, VectorFunctionizeBridge{T}) MOI.Bridges.add_bridge(model, VectorSlackBridge{T}) diff --git a/src/Bridges/Objective/bridges/FunctionConversionBridge.jl b/src/Bridges/Objective/bridges/FunctionConversionBridge.jl index 7f525b2862..28cf74bd49 100644 --- a/src/Bridges/Objective/bridges/FunctionConversionBridge.jl +++ b/src/Bridges/Objective/bridges/FunctionConversionBridge.jl @@ -174,9 +174,9 @@ const Quadratize{T,OT<:MOI.ModelLike} = SingleBridgeOptimizer{QuadratizeBridge{T},OT} """ - NonlinearizeBridge{T,G} <: FunctionConversionBridge{T,MOI.ScalarNonlinearFunction,G} + ToScalarNonlinearBridge{T,G} <: FunctionConversionBridge{T,MOI.ScalarNonlinearFunction,G} -`NonlinearizeBridge` implements the following reformulations: +`ToScalarNonlinearBridge` implements the following reformulations: * ``\\min\\{x^\\top \\mathbf{𝑄} x + a^\\top x + b\\}`` into ``\\min\\{f(x)\\}`` * ``\\max\\{x^\\top \\mathbf{𝑄} x + a^\\top x + b\\}`` into ``\\max\\{f(x)\\}`` @@ -185,21 +185,21 @@ where `f(x)` is a `MOI.ScalarNonlinearFunction`. ## Source node -`NonlinearizeBridge` supports: +`ToScalarNonlinearBridge` supports: * [`MOI.ObjectiveFunction{G}`](@ref) ## Target nodes -`NonlinearizeBridge` creates: +`ToScalarNonlinearBridge` creates: * One objective node: [`MOI.ObjectiveFunction{MOI.ScalarNonlinearFunction}`](@ref) """ -const NonlinearizeBridge{T,G} = +const ToScalarNonlinearBridge{T,G} = FunctionConversionBridge{T,MOI.ScalarNonlinearFunction,G} -const Nonlinearize{T,OT<:MOI.ModelLike} = - SingleBridgeOptimizer{NonlinearizeBridge{T},OT} +const ToScalarNonlinear{T,OT<:MOI.ModelLike} = + SingleBridgeOptimizer{ToScalarNonlinearBridge{T},OT} """ VectorFunctionizeBridge{T,G} <: FunctionConversionBridge{T,MOI.VectorAffineFunction{T},G} diff --git a/test/Bridges/Objective/SlackBridge.jl b/test/Bridges/Objective/SlackBridge.jl index 4d9505e299..32bf8bae73 100644 --- a/test/Bridges/Objective/SlackBridge.jl +++ b/test/Bridges/Objective/SlackBridge.jl @@ -527,7 +527,7 @@ function test_complex_objective() ) MOI.Bridges.remove_bridge( dest, - MOI.Bridges.Objective.NonlinearizeBridge{Float64}, + MOI.Bridges.Objective.ToScalarNonlinearBridge{Float64}, ) # Otherwise, would be bridged to Nonlinear. @test_throws MOI.UnsupportedAttribute(attr) MOI.copy_to(dest, model) end diff --git a/test/Bridges/Objective/NonlinearizeBridge.jl b/test/Bridges/Objective/ToScalarNonlinearBridge.jl similarity index 93% rename from test/Bridges/Objective/NonlinearizeBridge.jl rename to test/Bridges/Objective/ToScalarNonlinearBridge.jl index ff4e8e0c11..2a33005fb8 100644 --- a/test/Bridges/Objective/NonlinearizeBridge.jl +++ b/test/Bridges/Objective/ToScalarNonlinearBridge.jl @@ -4,7 +4,7 @@ # Use of this source code is governed by an MIT-style license that can be found # in the LICENSE.md file or at https://opensource.org/licenses/MIT. -module TestObjectiveNonlinearize +module TestObjectiveToScalarNonlinear using Test @@ -25,7 +25,7 @@ include("../utilities.jl") function test_solve_singlevariable_obj() mock = MOI.Utilities.MockOptimizer(MOI.Utilities.Model{Float64}()) - model = MOI.Bridges.Objective.Nonlinearize{Float64}(mock) + model = MOI.Bridges.Objective.ToScalarNonlinear{Float64}(mock) MOI.Utilities.set_mock_optimize!( mock, (mock::MOI.Utilities.MockOptimizer) -> @@ -60,7 +60,7 @@ end function test_solve_result_index() mock = MOI.Utilities.MockOptimizer(MOI.Utilities.Model{Float64}()) - model = MOI.Bridges.Objective.Nonlinearize{Float64}(mock) + model = MOI.Bridges.Objective.ToScalarNonlinear{Float64}(mock) MOI.Utilities.set_mock_optimize!( mock, (mock::MOI.Utilities.MockOptimizer) -> MOI.Utilities.mock_optimize!( @@ -83,7 +83,7 @@ end function test_runtests() MOI.Bridges.runtests( - MOI.Bridges.Objective.NonlinearizeBridge, + MOI.Bridges.Objective.ToScalarNonlinearBridge, model -> begin x = MOI.add_variable(model) aff = MOI.ScalarAffineFunction( @@ -118,7 +118,7 @@ function test_runtests() end, ) MOI.Bridges.runtests( - MOI.Bridges.Objective.NonlinearizeBridge, + MOI.Bridges.Objective.ToScalarNonlinearBridge, model -> begin x = MOI.add_variable(model) aff = MOI.ScalarAffineFunction( @@ -157,4 +157,4 @@ end end # module -TestObjectiveNonlinearize.runtests() +TestObjectiveToScalarNonlinear.runtests() diff --git a/test/Bridges/debug.jl b/test/Bridges/debug.jl index fe9a042ddb..5e71b8610a 100644 --- a/test/Bridges/debug.jl +++ b/test/Bridges/debug.jl @@ -190,7 +190,7 @@ function test_print_active_bridges_objective_unsupported() model = MOI.Bridges.full_bridge_optimizer(Model{Float64}(), Float64) MOI.Bridges.remove_bridge( model, - MOI.Bridges.Objective.NonlinearizeBridge{Float64}, + MOI.Bridges.Objective.ToScalarNonlinearBridge{Float64}, ) # Otherwise, Int would be bridged to Nonlinear. F = MOI.ScalarAffineFunction{Int} @test_throws( From 27acba2846ca1425eac447ea6c4dceec5cf914e9 Mon Sep 17 00:00:00 2001 From: Oscar Dowson Date: Mon, 8 Sep 2025 10:24:39 +1200 Subject: [PATCH 5/5] Make conversion_cost to ScalarNonlinearFunction work only for Float64 --- .../Constraint/bridges/AbstractFunctionConversionBridge.jl | 4 ++-- test/Bridges/Objective/SlackBridge.jl | 4 ---- test/Bridges/debug.jl | 4 ---- 3 files changed, 2 insertions(+), 10 deletions(-) diff --git a/src/Bridges/Constraint/bridges/AbstractFunctionConversionBridge.jl b/src/Bridges/Constraint/bridges/AbstractFunctionConversionBridge.jl index 6d91ffe695..aff3fad8a2 100644 --- a/src/Bridges/Constraint/bridges/AbstractFunctionConversionBridge.jl +++ b/src/Bridges/Constraint/bridges/AbstractFunctionConversionBridge.jl @@ -269,8 +269,8 @@ function conversion_cost( ::Type{ <:Union{ MOI.VariableIndex, - MOI.ScalarAffineFunction, - MOI.ScalarQuadraticFunction, + MOI.ScalarAffineFunction{Float64}, + MOI.ScalarQuadraticFunction{Float64}, }, }, ) diff --git a/test/Bridges/Objective/SlackBridge.jl b/test/Bridges/Objective/SlackBridge.jl index 32bf8bae73..9757aae392 100644 --- a/test/Bridges/Objective/SlackBridge.jl +++ b/test/Bridges/Objective/SlackBridge.jl @@ -525,10 +525,6 @@ function test_complex_objective() MOI.Utilities.Model{Float64}(), Float64, ) - MOI.Bridges.remove_bridge( - dest, - MOI.Bridges.Objective.ToScalarNonlinearBridge{Float64}, - ) # Otherwise, would be bridged to Nonlinear. @test_throws MOI.UnsupportedAttribute(attr) MOI.copy_to(dest, model) end return diff --git a/test/Bridges/debug.jl b/test/Bridges/debug.jl index 5e71b8610a..9be0192e6d 100644 --- a/test/Bridges/debug.jl +++ b/test/Bridges/debug.jl @@ -188,10 +188,6 @@ end function test_print_active_bridges_objective_unsupported() model = MOI.Bridges.full_bridge_optimizer(Model{Float64}(), Float64) - MOI.Bridges.remove_bridge( - model, - MOI.Bridges.Objective.ToScalarNonlinearBridge{Float64}, - ) # Otherwise, Int would be bridged to Nonlinear. F = MOI.ScalarAffineFunction{Int} @test_throws( MOI.UnsupportedAttribute{MOI.ObjectiveFunction{F}},