Skip to content

Commit 129e0de

Browse files
committed
[Utilities] fix quadratic operate with non-Int coefficient
1 parent 34c41d0 commit 129e0de

File tree

2 files changed

+27
-21
lines changed

2 files changed

+27
-21
lines changed

src/Utilities/operate.jl

Lines changed: 16 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -442,7 +442,7 @@ function operate(
442442
f::MOI.ScalarAffineFunction{T},
443443
g::MOI.ScalarQuadraticFunction{T},
444444
) where {T<:Number}
445-
return MOI.ScalarQuadraticFunction(
445+
return MOI.ScalarQuadraticFunction{T}(
446446
operate_terms(-, g.quadratic_terms),
447447
vcat(f.terms, operate_terms(-, g.affine_terms)),
448448
f.constant .- g.constant,
@@ -569,9 +569,9 @@ function operate(
569569
f::MOI.VectorAffineFunction{T},
570570
g::MOI.VectorQuadraticFunction{T},
571571
) where {T<:Number}
572-
return MOI.VectorQuadraticFunction(
572+
return MOI.VectorQuadraticFunction{T}(
573573
operate_terms(-, g.quadratic_terms),
574-
[f.terms; operate_terms(-, g.affine_terms)],
574+
MOI.VectorAffineTerm{T}[f.terms; operate_terms(-, g.affine_terms)],
575575
f.constants .- g.constants,
576576
)
577577
end
@@ -762,7 +762,7 @@ function operate(
762762
end
763763
end
764764
constant = f.constant * g.constant
765-
return MOI.ScalarQuadraticFunction(quad_terms, aff_terms, constant)
765+
return MOI.ScalarQuadraticFunction{T}(quad_terms, aff_terms, constant)
766766
end
767767

768768
function operate(
@@ -771,8 +771,8 @@ function operate(
771771
f::MOI.VariableIndex,
772772
g::MOI.VariableIndex,
773773
) where {T<:Number}
774-
return MOI.ScalarQuadraticFunction(
775-
[MOI.ScalarQuadraticTerm(f == g ? 2one(T) : one(T), f, g)],
774+
return MOI.ScalarQuadraticFunction{T}(
775+
[MOI.ScalarQuadraticTerm{T}(f == g ? T(2) : one(T), f, g)],
776776
MOI.ScalarAffineTerm{T}[],
777777
zero(T),
778778
)
@@ -784,20 +784,15 @@ function operate(
784784
f::MOI.ScalarAffineFunction{T},
785785
g::MOI.VariableIndex,
786786
) where {T<:Number}
787-
if iszero(f.constant)
788-
aff_terms = MOI.ScalarAffineTerm{T}[]
789-
else
790-
aff_terms = [MOI.ScalarAffineTerm(f.constant, g)]
787+
aff_terms = MOI.ScalarAffineTerm{T}[]
788+
if !iszero(f.constant)
789+
push!(aff_terms, MOI.ScalarAffineTerm{T}(f.constant, g))
791790
end
792-
quad_terms = map(
793-
t -> MOI.ScalarQuadraticTerm(
794-
t.variable == g ? 2t.coefficient : t.coefficient,
795-
t.variable,
796-
g,
797-
),
798-
f.terms,
799-
)
800-
return MOI.ScalarQuadraticFunction(quad_terms, aff_terms, zero(T))
791+
quad_terms = map(f.terms) do t
792+
scale = t.variable == g ? T(2) : one(T)
793+
return MOI.ScalarQuadraticTerm{T}(scale * t.coefficient, t.variable, g)
794+
end
795+
return MOI.ScalarQuadraticFunction{T}(quad_terms, aff_terms, zero(T))
801796
end
802797

803798
### 3d: operate(::typeof(*), ::Type{T}, ::Diagonal{T}, ::F)
@@ -935,7 +930,7 @@ function operate(
935930
fill_vector(aterms, T, 0, 0, fill_terms, number_of_affine_terms, f...)
936931
constants = zeros(T, sum(f -> output_dim(T, f), f))
937932
fill_vector(constants, T, 0, 0, fill_constant, output_dim, f...)
938-
return MOI.VectorAffineFunction(aterms, constants)
933+
return MOI.VectorAffineFunction{T}(aterms, constants)
939934
end
940935

941936
function operate(
@@ -960,7 +955,7 @@ function operate(
960955
fill_vector(qterms, T, 0, 0, fill_terms, number_of_quadratic_terms, f...)
961956
constants = zeros(T, sum(f -> output_dim(T, f), f))
962957
fill_vector(constants, T, 0, 0, fill_constant, output_dim, f...)
963-
return MOI.VectorQuadraticFunction(qterms, aterms, constants)
958+
return MOI.VectorQuadraticFunction{T}(qterms, aterms, constants)
964959
end
965960

966961
function operate(

test/Utilities/test_operate!.jl

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -696,6 +696,17 @@ function test_operate_coefficients_functions()
696696
return
697697
end
698698

699+
function test_operate_int32()
700+
x = MOI.VariableIndex(1)
701+
y = one(Int32) * x
702+
@test y isa MOI.ScalarAffineFunction{Int32}
703+
q1 = MOI.Utilities.operate(*, Int32, x, x)
704+
q2 = MOI.Utilities.operate(*, Int32, y, x)
705+
@test q1 isa MOI.ScalarQuadraticFunction{Int32}
706+
@test isapprox(q1, q2)
707+
return
708+
end
709+
699710
end # module
700711

701712
TestOperate.runtests()

0 commit comments

Comments
 (0)