From 187e5a87078771d786ffea7c4362fcd628f2c83a Mon Sep 17 00:00:00 2001 From: joaquimg Date: Wed, 25 Feb 2026 00:07:29 -0300 Subject: [PATCH 1/2] minor fixes found --- src/MOI_wrapper.jl | 2 ++ src/parametric_functions.jl | 7 +++--- test/test_MathOptInterface.jl | 47 +++++++++++++++++++++++++++-------- 3 files changed, 41 insertions(+), 15 deletions(-) diff --git a/src/MOI_wrapper.jl b/src/MOI_wrapper.jl index 3d1d3197..e54be934 100644 --- a/src/MOI_wrapper.jl +++ b/src/MOI_wrapper.jl @@ -746,6 +746,8 @@ function MOI.get( elseif haskey(model.affine_outer_to_inner, ci) inner_ci = model.affine_outer_to_inner[ci] return _original_function(model.affine_constraint_cache[inner_ci]) + elseif haskey(model.vector_affine_constraint_cache, ci) + return _original_function(model.vector_affine_constraint_cache[ci]) else MOI.throw_if_not_valid(model, ci) return MOI.get(model.optimizer, attr, ci) diff --git a/src/parametric_functions.jl b/src/parametric_functions.jl index bd770fde..2d1561c7 100644 --- a/src/parametric_functions.jl +++ b/src/parametric_functions.jl @@ -62,7 +62,7 @@ function ParametricQuadraticFunction( affine_data = Dict{MOI.VariableIndex,T}() sizehint!(affine_data, length(v_in_pv)) affine_data_np = Dict{MOI.VariableIndex,T}() - sizehint!(affine_data, length(v)) + sizehint!(affine_data_np, length(v)) for term in v if term.variable in v_in_pv base = get(affine_data, term.variable, zero(T)) @@ -783,10 +783,9 @@ function _delta_parametric_affine_terms( p_idx_val = p_idx(term.scalar_term.variable_1) var = term.scalar_term.variable_2 output_idx = term.output_index - if haskey(model.updated_parameters, p_idx_val) && - !isnan(model.updated_parameters[p_idx_val]) + new_param_val = model.updated_parameters[p_idx_val] + if !isnan(new_param_val) old_param_val = model.parameters[p_idx_val] - new_param_val = model.updated_parameters[p_idx_val] delta_coef = term.scalar_term.coefficient * (new_param_val - old_param_val) base = get(delta_terms_dict, (var, output_idx), zero(T)) diff --git a/test/test_MathOptInterface.jl b/test/test_MathOptInterface.jl index cc9d0058..87ce5f41 100644 --- a/test/test_MathOptInterface.jl +++ b/test/test_MathOptInterface.jl @@ -377,9 +377,13 @@ function test_moi_ListOfConstraintTypesPresent() model = POI.Optimizer(ipopt) MOI.set(model, MOI.Silent(), true) x = MOI.add_variables(model, N / 2) - y = first.( - MOI.add_constrained_variable.(model, MOI.Parameter.(ones(Int(N / 2)))), - ) + y = + first.( + MOI.add_constrained_variable.( + model, + MOI.Parameter.(ones(Int(N / 2))), + ), + ) MOI.add_constraint( model, @@ -673,10 +677,11 @@ function test_vector_parameter_affine_nonnegatives() t, ct = MOI.add_constrained_variable(model, MOI.Parameter(5.0)) A = [1.0 0 -1; 0 1 -1] b = [1.0; 2] - terms = MOI.VectorAffineTerm.( - 1:2, - MOI.ScalarAffineTerm.(A, reshape([x, y, t], 1, 3)), - ) + terms = + MOI.VectorAffineTerm.( + 1:2, + MOI.ScalarAffineTerm.(A, reshape([x, y, t], 1, 3)), + ) f = MOI.VectorAffineFunction(vec(terms), b) set = MOI.Nonnegatives(2) cnn = MOI.add_constraint(model, f, MOI.Nonnegatives(2)) @@ -725,10 +730,11 @@ function test_vector_parameter_affine_nonpositives() t, ct = MOI.add_constrained_variable(model, MOI.Parameter(5.0)) A = [-1.0 0 1; 0 -1 1] b = [-1.0; -2] - terms = MOI.VectorAffineTerm.( - 1:2, - MOI.ScalarAffineTerm.(A, reshape([x, y, t], 1, 3)), - ) + terms = + MOI.VectorAffineTerm.( + 1:2, + MOI.ScalarAffineTerm.(A, reshape([x, y, t], 1, 3)), + ) f = MOI.VectorAffineFunction(vec(terms), b) set = MOI.Nonnegatives(2) cnn = MOI.add_constraint(model, f, MOI.Nonpositives(2)) @@ -2276,6 +2282,25 @@ function test_get_constraint_function_vector() return end +function test_get_constraint_function_vector_affine() + # MOI.get(ConstraintFunction) for a parametric + # VectorAffineFunction constraint must return the original function + # (with parameter VariableIndex terms), not the solver-side function + # (with parameters already substituted into constants). + model = POI.Optimizer(MOI.Utilities.Model{Float64}()) + x = MOI.add_variable(model) + p, pc = MOI.add_constrained_variable(model, MOI.Parameter(3.0)) + terms = [ + MOI.VectorAffineTerm(1, MOI.ScalarAffineTerm(2.0, x)), + MOI.VectorAffineTerm(1, MOI.ScalarAffineTerm(5.0, p)), + ] + f = MOI.VectorAffineFunction(terms, [0.0]) + ci = MOI.add_constraint(model, f, MOI.Zeros(1)) + f2 = MOI.get(model, MOI.ConstraintFunction(), ci) + @test canonical_compare(f, f2) + return +end + function test_multiplicative_dual_error() model = POI.Optimizer(MOI.Utilities.Model{Float64}()) x = MOI.add_variable(model) From 58a70b24165555a7e39c5d228cecab107ae22383 Mon Sep 17 00:00:00 2001 From: joaquimg Date: Wed, 25 Feb 2026 00:22:25 -0300 Subject: [PATCH 2/2] more fixes --- src/parametric_functions.jl | 11 +++++------ test/test_MathOptInterface.jl | 28 +++++++++++----------------- 2 files changed, 16 insertions(+), 23 deletions(-) diff --git a/src/parametric_functions.jl b/src/parametric_functions.jl index 42bc6301..90488656 100644 --- a/src/parametric_functions.jl +++ b/src/parametric_functions.jl @@ -276,12 +276,11 @@ function _delta_parametric_affine_terms( # remember a variable may appear more than once in pv for term in quadratic_parameter_variable_terms(f) p = p_idx(term.variable_1) - if !isnan(model.updated_parameters[p]) + new_p = model.updated_parameters[p] + if !isnan(new_p) base = get(delta_terms_dict, term.variable_2, zero(T)) delta_terms_dict[term.variable_2] = - base + - term.coefficient * - (model.updated_parameters[p] - model.parameters[p]) + base + term.coefficient * (new_p - model.parameters[p]) end end return delta_terms_dict @@ -725,9 +724,9 @@ function _delta_parametric_constant( p_idx_val = p_idx(term.scalar_term.variable) output_idx = term.output_index - if !isnan(model.updated_parameters[p_idx_val]) + new_param_val = model.updated_parameters[p_idx_val] + if !isnan(new_param_val) old_param_val = model.parameters[p_idx_val] - new_param_val = model.updated_parameters[p_idx_val] delta_constants[output_idx] += term.scalar_term.coefficient * (new_param_val - old_param_val) end diff --git a/test/test_MathOptInterface.jl b/test/test_MathOptInterface.jl index 87ce5f41..bc15cf5b 100644 --- a/test/test_MathOptInterface.jl +++ b/test/test_MathOptInterface.jl @@ -377,13 +377,9 @@ function test_moi_ListOfConstraintTypesPresent() model = POI.Optimizer(ipopt) MOI.set(model, MOI.Silent(), true) x = MOI.add_variables(model, N / 2) - y = - first.( - MOI.add_constrained_variable.( - model, - MOI.Parameter.(ones(Int(N / 2))), - ), - ) + y = first.( + MOI.add_constrained_variable.(model, MOI.Parameter.(ones(Int(N / 2)))), + ) MOI.add_constraint( model, @@ -677,11 +673,10 @@ function test_vector_parameter_affine_nonnegatives() t, ct = MOI.add_constrained_variable(model, MOI.Parameter(5.0)) A = [1.0 0 -1; 0 1 -1] b = [1.0; 2] - terms = - MOI.VectorAffineTerm.( - 1:2, - MOI.ScalarAffineTerm.(A, reshape([x, y, t], 1, 3)), - ) + terms = MOI.VectorAffineTerm.( + 1:2, + MOI.ScalarAffineTerm.(A, reshape([x, y, t], 1, 3)), + ) f = MOI.VectorAffineFunction(vec(terms), b) set = MOI.Nonnegatives(2) cnn = MOI.add_constraint(model, f, MOI.Nonnegatives(2)) @@ -730,11 +725,10 @@ function test_vector_parameter_affine_nonpositives() t, ct = MOI.add_constrained_variable(model, MOI.Parameter(5.0)) A = [-1.0 0 1; 0 -1 1] b = [-1.0; -2] - terms = - MOI.VectorAffineTerm.( - 1:2, - MOI.ScalarAffineTerm.(A, reshape([x, y, t], 1, 3)), - ) + terms = MOI.VectorAffineTerm.( + 1:2, + MOI.ScalarAffineTerm.(A, reshape([x, y, t], 1, 3)), + ) f = MOI.VectorAffineFunction(vec(terms), b) set = MOI.Nonnegatives(2) cnn = MOI.add_constraint(model, f, MOI.Nonpositives(2))