@@ -859,93 +859,114 @@ end
859
859
function modify_function (f:: VQF , change:: MOI.VectorConstantChange )
860
860
return VQF (f. affine_terms, f. quadratic_terms, change. new_constant)
861
861
end
862
+
862
863
function _modifycoefficient (
863
- terms:: Vector{<: MOI.ScalarAffineTerm} ,
864
- variable:: VI ,
865
- new_coefficient,
866
- )
864
+ terms:: Vector{MOI.ScalarAffineTerm{T} } ,
865
+ variable:: MOI.VariableIndex ,
866
+ new_coefficient:: T ,
867
+ ) where {T}
867
868
terms = copy (terms)
868
869
i = something (findfirst (t -> t. variable_index == variable, terms), 0 )
869
- if iszero (i)
870
- # The variable was not already in the function
870
+ if iszero (i) # The variable was not already in the function
871
871
if ! iszero (new_coefficient)
872
872
push! (terms, MOI. ScalarAffineTerm (new_coefficient, variable))
873
873
end
874
- else
875
- # The variable was already in the function
874
+ else # The variable was already in the function
876
875
if iszero (new_coefficient)
877
876
deleteat! (terms, i)
878
877
else
879
878
terms[i] = MOI. ScalarAffineTerm (new_coefficient, variable)
880
879
end
880
+ # To account for duplicates, we need to delete any other instances of
881
+ # `variable` in `terms`.
882
+ for j = length (terms): - 1 : (i + 1 )
883
+ if terms[j]. variable_index == variable
884
+ deleteat! (terms, j)
885
+ end
886
+ end
881
887
end
882
888
return terms
883
889
end
884
- function modify_function (f:: SAF , change:: MOI.ScalarCoefficientChange )
885
- lin = _modifycoefficient (f. terms, change. variable, change. new_coefficient)
886
- return SAF (lin, f. constant)
890
+
891
+ function modify_function (
892
+ f:: MOI.ScalarAffineFunction{T} ,
893
+ change:: MOI.ScalarCoefficientChange{T} ,
894
+ ) where {T}
895
+ terms = _modifycoefficient (f. terms, change. variable, change. new_coefficient)
896
+ return MOI. ScalarAffineFunction (terms, f. constant)
887
897
end
888
- function modify_function (f:: SQF , change:: MOI.ScalarCoefficientChange )
889
- lin = _modifycoefficient (
898
+
899
+ function modify_function (
900
+ f:: MOI.ScalarQuadraticFunction{T} ,
901
+ change:: MOI.ScalarCoefficientChange{T} ,
902
+ ) where {T}
903
+ terms = _modifycoefficient (
890
904
f. affine_terms,
891
905
change. variable,
892
906
change. new_coefficient,
893
907
)
894
- return SQF (lin , f. quadratic_terms, f. constant)
908
+ return MOI . ScalarQuadraticFunction (terms , f. quadratic_terms, f. constant)
895
909
end
910
+
896
911
function _modifycoefficients (
897
- n,
898
- terms:: Vector{<:MOI.VectorAffineTerm} ,
899
- variable:: VI ,
900
- new_coefficients,
901
- )
912
+ terms:: Vector{MOI.VectorAffineTerm{T}} ,
913
+ variable:: MOI.VariableIndex ,
914
+ new_coefficients:: Vector{Tuple{Int64,T}} ,
915
+ ) where {T}
902
916
terms = copy (terms)
903
- # Maps between rows in the `MOI.VectorAffineTerm`s and indices in new_coefficients
904
- rowmap = Dict (c[1 ] => i for (i, c) in enumerate (new_coefficients))
905
- del = Int[]
906
- for i in 1 : length (terms)
907
- if terms[i]. scalar_term. variable_index == variable
908
- row = terms[i]. output_index
909
- j = Base. get (rowmap, row, 0 )
910
- if ! iszero (j) # If it is zero, it means that the row should not be changed
911
- if iszero (new_coefficients[j][2 ])
912
- push! (del, i)
913
- else
914
- terms[i] = MOI. VectorAffineTerm (
915
- row,
916
- MOI. ScalarAffineTerm (new_coefficients[j][2 ], variable),
917
- )
918
- end
919
- rowmap[row] = 0 # We only change the first term of a row
920
- end
917
+ coef_dict = Dict (k => v for (k, v) in new_coefficients)
918
+ elements_to_delete = Int[]
919
+ for (i, term) in enumerate (terms)
920
+ if term. scalar_term. variable_index != variable
921
+ continue
921
922
end
922
- end
923
- deleteat! (terms, del)
924
- for (row, j) in rowmap
925
- if ! iszero (j)
926
- push! (
927
- terms,
928
- MOI. VectorAffineTerm (
929
- row,
930
- MOI. ScalarAffineTerm (new_coefficients[j][2 ], variable),
931
- ),
923
+ new_coef = Base. get (coef_dict, term. output_index, nothing )
924
+ if new_coef === nothing
925
+ continue
926
+ elseif iszero (new_coef)
927
+ push! (elements_to_delete, i)
928
+ else
929
+ terms[i] = MOI. VectorAffineTerm (
930
+ term. output_index,
931
+ MOI. ScalarAffineTerm (new_coef, variable),
932
932
)
933
+ # Set the coefficient to 0.0 so we don't add duplicates.
934
+ coef_dict[term. output_index] = zero (T)
933
935
end
934
936
end
937
+ deleteat! (terms, elements_to_delete)
938
+ # Add elements that were not previously in `terms`.
939
+ for (k, v) in coef_dict
940
+ if iszero (v)
941
+ continue
942
+ end
943
+ push! (terms, MOI. VectorAffineTerm (k, MOI. ScalarAffineTerm (v, variable)))
944
+ end
935
945
return terms
936
946
end
937
- function modify_function (f:: VAF , change:: MOI.MultirowChange )
938
- dim = MOI. output_dimension (f)
939
- coefficients = change. new_coefficients
940
- lin = _modifycoefficients (dim, f. terms, change. variable, coefficients)
941
- return VAF (lin, f. constants)
942
- end
943
- function modify_function (f:: VQF , change:: MOI.MultirowChange )
944
- dim = MOI. output_dimension (f)
945
- coefficients = change. new_coefficients
946
- lin =
947
- _modifycoefficients (dim, f. affine_terms, change. variable, coefficients)
948
- return VQF (lin, f. quadratic_terms, f. constants)
947
+
948
+ function modify_function (
949
+ f:: MOI.VectorAffineFunction{T} ,
950
+ change:: MOI.MultirowChange{T} ,
951
+ ) where {T}
952
+ terms = _modifycoefficients (
953
+ f. terms,
954
+ change. variable,
955
+ change. new_coefficients,
956
+ )
957
+ return MOI. VectorAffineFunction (terms, f. constants)
958
+ end
959
+
960
+ function modify_function (
961
+ f:: MOI.VectorQuadraticFunction{T} ,
962
+ change:: MOI.MultirowChange{T} ,
963
+ ) where {T}
964
+ terms = _modifycoefficients (
965
+ f. affine_terms,
966
+ change. variable,
967
+ change. new_coefficients,
968
+ )
969
+ return MOI. VectorQuadraticFunction (terms, f. quadratic_terms, f. constants)
949
970
end
950
971
951
972
# Arithmetic
0 commit comments