diff --git a/src/polynomial.jl b/src/polynomial.jl index 9007e15..e28a5ce 100644 --- a/src/polynomial.jl +++ b/src/polynomial.jl @@ -17,6 +17,13 @@ struct PolynomialFunction{ func::MOI.ScalarNonlinearFunction end +function MOI.Utilities.value_type( + ::Type{T}, + ::Type{PolynomialFunction{F}}, +) where {T,F} + return MOI.Utilities.value_type(T, F) +end + function Base.copy(f::PolynomialFunction{F}) where {F} return PolynomialFunction{F}(copy(f.func)) end diff --git a/test/Bridges/polynomial_function.jl b/test/Bridges/polynomial_function.jl index f300049..a3712f3 100644 --- a/test/Bridges/polynomial_function.jl +++ b/test/Bridges/polynomial_function.jl @@ -209,6 +209,21 @@ function test_highs_polynomial_support() return end +function test_highs_lazy_sum_constraint_dual() + model = JuMP.Model(HiGHS.Optimizer) + JuMP.set_silent(model) + JuMP.add_bridge(model, GenOpt.PolynomialFunctionBridge) + JuMP.@variable(model, x[1:3] >= 0) + affine = GenOpt.lazy_sum(x[i] + 1 for i in 1:3) + constraint = JuMP.@constraint(model, affine <= 5) + JuMP.@objective(model, Max, 3 * sum(x)) + JuMP.optimize!(model) + @test JuMP.termination_status(model) == MOI.OPTIMAL + @test JuMP.has_duals(model) + @test JuMP.dual(constraint) ≈ -3.0 + return +end + function test_highs_lazy_sum_objectives_and_constraints() model = JuMP.Model(HiGHS.Optimizer) JuMP.set_silent(model) diff --git a/test/operators.jl b/test/operators.jl index 5668124..4b5e72a 100644 --- a/test/operators.jl +++ b/test/operators.jl @@ -554,6 +554,13 @@ function test_polynomial_scalar_arithmetic() end function test_polynomial_function_utilities() + for C in (Float32, Float64), + T in (Float32, Float64), + F in (MOI.ScalarAffineFunction{C}, MOI.ScalarQuadraticFunction{C}) + + V = @inferred MOI.Utilities.value_type(T, GenOpt.PolynomialFunction{F}) + @test V === promote_type(C, T) + end x = MOI.VariableIndex(1) f = GenOpt.PolynomialFunction{MOI.ScalarAffineFunction{Float64}}( MOI.ScalarNonlinearFunction(:+, Any[x, 2.0]),