diff --git a/Project.toml b/Project.toml index 8cc7f5d8..ef42c634 100644 --- a/Project.toml +++ b/Project.toml @@ -1,13 +1,13 @@ name = "ParametricOptInterface" uuid = "0ce4ce61-57bf-432b-a095-efac525d185e" authors = ["Tomás Gutierrez "] -version = "0.3.5" +version = "0.4.0" [deps] MathOptInterface = "b8f27783-ece8-5eb3-8dc8-9495eed66fee" [compat] -MathOptInterface = "1" +MathOptInterface = "1.3" julia = "1.6" [extras] diff --git a/src/update_parameters.jl b/src/update_parameters.jl index 37714f46..49393d3b 100644 --- a/src/update_parameters.jl +++ b/src/update_parameters.jl @@ -307,13 +307,21 @@ function update_parameter_in_quadratic_constraints_pv!(model::Optimizer) end end old_ci = model.quadratic_added_cache[ci] + changes = Vector{MOI.ScalarCoefficientChange}( + undef, + length(new_coeff_per_variable), + ) + i = 1 for (vi, value) in new_coeff_per_variable - MOI.modify( - model.optimizer, - old_ci, - MOI.ScalarCoefficientChange(vi, value), - ) + changes[i] = MOI.ScalarCoefficientChange(vi, value) + i += 1 end + # Make multiple changes at once. + MOI.modify( + model.optimizer, + fill(old_ci, length(new_coeff_per_variable)), + changes, + ) end return model end @@ -347,13 +355,16 @@ function update_parameter_in_quadratic_objective_pv!(model::Optimizer) end F_pv = MOI.get(model.optimizer, MOI.ObjectiveFunctionType()) + changes = Vector{MOI.ScalarCoefficientChange}( + undef, + length(new_coeff_per_variable), + ) + i = 1 for (vi, value) in new_coeff_per_variable - MOI.modify( - model.optimizer, - MOI.ObjectiveFunction{F_pv}(), - MOI.ScalarCoefficientChange(vi, value), - ) + changes[i] = MOI.ScalarCoefficientChange(vi, value) + i += 1 end + MOI.modify(model.optimizer, MOI.ObjectiveFunction{F_pv}(), changes) return model end diff --git a/test/modifications_tests.jl b/test/modifications_tests.jl new file mode 100644 index 00000000..aa8a350a --- /dev/null +++ b/test/modifications_tests.jl @@ -0,0 +1,61 @@ +@testset "Multiple modifications" begin + model = POI.Optimizer(MOI.Utilities.Model{Float64}()) + + x = MOI.add_variables(model, 3) + + saf = MOI.ScalarAffineFunction( + [ + MOI.ScalarAffineTerm(1.0, x[1]), + MOI.ScalarAffineTerm(1.0, x[2]), + MOI.ScalarAffineTerm(1.0, x[3]), + ], + 0.0, + ) + ci1 = MOI.add_constraint(model, saf, MOI.LessThan(1.0)) + ci2 = MOI.add_constraint(model, saf, MOI.LessThan(2.0)) + + MOI.set( + model, + MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}(), + saf, + ) + + fc1 = MOI.get(model, MOI.ConstraintFunction(), ci1) + @test MOI.coefficient.(fc1.terms) == [1.0, 1.0, 1.0] + fc2 = MOI.get(model, MOI.ConstraintFunction(), ci2) + @test MOI.coefficient.(fc2.terms) == [1.0, 1.0, 1.0] + obj = MOI.get( + model, + MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}(), + ) + @test MOI.coefficient.(obj.terms) == [1.0, 1.0, 1.0] + + changes_cis = [ + MOI.ScalarCoefficientChange(MOI.VariableIndex(1), 4.0) + MOI.ScalarCoefficientChange(MOI.VariableIndex(1), 0.5) + MOI.ScalarCoefficientChange(MOI.VariableIndex(3), 2.0) + ] + MOI.modify(model, [ci1, ci2, ci2], changes_cis) + + fc1 = MOI.get(model, MOI.ConstraintFunction(), ci1) + @test MOI.coefficient.(fc1.terms) == [4.0, 1.0, 1.0] + fc2 = MOI.get(model, MOI.ConstraintFunction(), ci2) + @test MOI.coefficient.(fc2.terms) == [0.5, 1.0, 2.0] + + changes_obj = [ + MOI.ScalarCoefficientChange(MOI.VariableIndex(1), 4.0) + MOI.ScalarCoefficientChange(MOI.VariableIndex(2), 10.0) + MOI.ScalarCoefficientChange(MOI.VariableIndex(3), 2.0) + ] + MOI.modify( + model, + MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}(), + changes_obj, + ) + + obj = MOI.get( + model, + MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}(), + ) + @test MOI.coefficient.(obj.terms) == [4.0, 10.0, 2.0] +end diff --git a/test/runtests.jl b/test/runtests.jl index ef0f642b..8a5387eb 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -21,4 +21,5 @@ include("dual_tests.jl") include("quad_tests.jl") include("sdp_tests.jl") include("vector_affine_tests.jl") +include("modifications_tests.jl") include("jump_tests.jl")