@@ -51,6 +51,22 @@ function _has_parameters(f::MOI.ScalarQuadraticFunction{T}) where {T}
5151 return false
5252end
5353
54+ function _has_parameters (f:: MOI.VectorQuadraticFunction )
55+ # quadratic part
56+ for qt in f. quadratic_terms
57+ if _is_parameter (qt. scalar_term. variable_1) || _is_parameter (qt. scalar_term. variable_2)
58+ return true
59+ end
60+ end
61+ # affine part
62+ for at in f. affine_terms
63+ if _is_parameter (at. scalar_term. variable)
64+ return true
65+ end
66+ end
67+ return false
68+ end
69+
5470function _cache_multiplicative_params! (
5571 model:: Optimizer{T} ,
5672 f:: ParametricQuadraticFunction{T} ,
@@ -65,6 +81,21 @@ function _cache_multiplicative_params!(
6581 return
6682end
6783
84+ function _cache_multiplicative_params! (
85+ model:: Optimizer{T} ,
86+ f:: ParametricVectorQuadraticFunction{T} ,
87+ ) where {T}
88+ for term in f. pv
89+ push! (model. multiplicative_parameters_pv,
90+ term. scalar_term. variable_1. value)
91+ end
92+ for term in f. pp
93+ push! (model. multiplicative_parameters_pp, term. scalar_term. variable_1. value)
94+ push! (model. multiplicative_parameters_pp, term. scalar_term. variable_2. value)
95+ end
96+ return
97+ end
98+
6899#
69100# Empty
70101#
@@ -88,6 +119,8 @@ function MOI.is_empty(model::Optimizer)
88119 isempty (model. quadratic_outer_to_inner) &&
89120 isempty (model. quadratic_constraint_cache) &&
90121 isempty (model. quadratic_constraint_cache_set) &&
122+ isempty (model. vector_quadratic_constraint_cache) &&
123+ isempty (model. vector_quadratic_constraint_cache_set) &&
91124 # obj
92125 model. affine_objective_cache === nothing &&
93126 model. quadratic_objective_cache === nothing &&
@@ -123,6 +156,8 @@ function MOI.empty!(model::Optimizer{T}) where {T}
123156 empty! (model. quadratic_outer_to_inner)
124157 empty! (model. quadratic_constraint_cache)
125158 empty! (model. quadratic_constraint_cache_set)
159+ empty! (model. vector_quadratic_constraint_cache)
160+ empty! (model. vector_quadratic_constraint_cache_set)
126161 # obj
127162 model. affine_objective_cache = nothing
128163 model. quadratic_objective_cache = nothing
@@ -538,6 +573,10 @@ function MOI.get(
538573 return _original_function (
539574 model. quadratic_constraint_cache[inner_ci],
540575 )
576+ elseif haskey (model. vector_quadratic_constraint_cache, inner_ci)
577+ return _original_function (
578+ model. vector_quadratic_constraint_cache[inner_ci],
579+ )
541580 else
542581 return convert (
543582 MOI. ScalarQuadraticFunction{T},
@@ -583,6 +622,9 @@ function MOI.get(
583622 if haskey (model. quadratic_outer_to_inner, ci)
584623 inner_ci = model. quadratic_outer_to_inner[ci]
585624 return model. quadratic_constraint_cache_set[inner_ci]
625+ elseif haskey (model. vector_quadratic_constraint_cache, ci)
626+ inner_ci = model. vector_quadratic_constraint_cache[ci]
627+ return model. vector_quadratic_constraint_cache_set[inner_ci]
586628 elseif haskey (model. affine_outer_to_inner, ci)
587629 inner_ci = model. affine_outer_to_inner[ci]
588630 return model. affine_constraint_cache_set[inner_ci]
@@ -858,6 +900,80 @@ function MOI.add_constraint(
858900 end
859901end
860902
903+ function _is_vector_affine (f:: MOI.VectorQuadraticFunction{T} ) where {T}
904+ return isempty (f. quadratic_terms)
905+ end
906+
907+ function _is_vector_affine (:: MOI.VectorAffineFunction{T} ) where {T}
908+ return true # VectorAffineFunction is always affine
909+ end
910+
911+ function _add_constraint_with_parameters_on_function (
912+ model:: Optimizer ,
913+ f:: MOI.VectorQuadraticFunction{T} ,
914+ set:: S ,
915+ ) where {T,S}
916+ # Create parametric vector quadratic function
917+ pf = ParametricVectorQuadraticFunction (f)
918+ _cache_multiplicative_params! (model, pf)
919+ _update_cache! (pf, model)
920+
921+ # Get the current function after parameter substitution
922+ func = _current_function (pf)
923+ if ! _is_vector_affine (func)
924+ fq = func
925+ inner_ci = MOI. add_constraint (model. optimizer, fq, set)
926+ model. last_quad_add_added += 1
927+ outer_ci = MOI. ConstraintIndex {MOI.VectorQuadraticFunction{T},S} (
928+ model. last_quad_add_added,
929+ )
930+ model. quadratic_outer_to_inner[outer_ci] = inner_ci
931+ model. constraint_outer_to_inner[outer_ci] = inner_ci
932+ else
933+ fa = MOI. VectorAffineFunction (func. affine_terms, func. constants)
934+ inner_ci = MOI. add_constraint (model. optimizer, fa, set)
935+ model. last_quad_add_added += 1
936+ outer_ci = MOI. ConstraintIndex {MOI.VectorQuadraticFunction{T},S} (
937+ model. last_quad_add_added,
938+ )
939+ # This part is used to remember that ci came from a quadratic function
940+ # It is particularly useful because sometimes the constraint mutates
941+ model. quadratic_outer_to_inner[outer_ci] = inner_ci
942+ model. constraint_outer_to_inner[outer_ci] = inner_ci
943+ end
944+ model. vector_quadratic_constraint_cache[inner_ci] = pf
945+ model. vector_quadratic_constraint_cache_set[inner_ci] = set
946+ return outer_ci
947+ end
948+
949+ function MOI. add_constraint (
950+ model:: Optimizer ,
951+ f:: MOI.VectorQuadraticFunction{T} ,
952+ set:: MOI.AbstractVectorSet ,
953+ ) where {T}
954+ if ! _has_parameters (f)
955+ return _add_constraint_direct_and_cache_map! (model, f, set)
956+ else
957+ return _add_constraint_with_parameters_on_function (model, f, set)
958+ end
959+ end
960+
961+ function MOI. delete (
962+ model:: Optimizer ,
963+ c:: MOI.ConstraintIndex{F,S} ,
964+ ) where {F<: MOI.VectorQuadraticFunction ,S<: MOI.AbstractSet }
965+ ci_inner = model. constraint_outer_to_inner[c]
966+ if haskey (model. quadratic_constraint_cache, ci_inner)
967+ delete! (model. quadratic_constraint_cache, ci_inner)
968+ delete! (model. quadratic_constraint_cache_set, ci_inner)
969+ MOI. delete (model. optimizer, ci_inner)
970+ else
971+ MOI. delete (model. optimizer, c)
972+ end
973+ delete! (model. constraint_outer_to_inner, c)
974+ return
975+ end
976+
861977function MOI. delete (
862978 model:: Optimizer ,
863979 c:: MOI.ConstraintIndex{F,S} ,
@@ -1411,6 +1527,13 @@ function MOI.get(
14111527 return model. quadratic_constraint_cache[F, S]
14121528end
14131529
1530+ function MOI. get (
1531+ model:: Optimizer ,
1532+ :: DictOfParametricConstraintIndicesAndFunctions{F,S,P} ,
1533+ ) where {F,S,P<: ParametricVectorQuadraticFunction }
1534+ return model. vector_quadratic_constraint_cache[F, S]
1535+ end
1536+
14141537"""
14151538 NumberOfPureVariables
14161539
0 commit comments