Skip to content

Commit 0b93034

Browse files
authored
Add conversions in variable substitution (#1181)
* Add conversions in variable substitution * Add convert for substitute_variable of quad terms
1 parent 41e72bc commit 0b93034

2 files changed

Lines changed: 19 additions & 4 deletions

File tree

src/Utilities/functions.jl

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -161,8 +161,11 @@ end
161161

162162
function substitute_variables(variable_map::Function,
163163
term::MOI.ScalarQuadraticTerm{T}) where T
164-
f1 = variable_map(term.variable_index_1)
165-
f2 = variable_map(term.variable_index_2)
164+
# We could have `T = Complex{Float64}` and `variable_map(term.variable_index)`
165+
# be a `MOI.ScalarAffineFunction{Float64}` with the Hermitian to PSD bridge.
166+
# We convert to `MOI.ScalarAffineFunction{T}` to avoid any issue.
167+
f1::MOI.ScalarAffineFunction{T} = variable_map(term.variable_index_1)
168+
f2::MOI.ScalarAffineFunction{T} = variable_map(term.variable_index_2)
166169
f12 = operate(*, T, f1, f2)::MOI.ScalarQuadraticFunction{T}
167170
coef = term.coefficient
168171
# The quadratic terms are evaluated as x'Qx/2 so a diagonal term should
@@ -175,8 +178,9 @@ function substitute_variables(variable_map::Function,
175178
end
176179
function substitute_variables(variable_map::Function,
177180
term::MOI.ScalarAffineTerm{T}) where T
178-
return operate(*, T, term.coefficient,
179-
variable_map(term.variable_index))::MOI.ScalarAffineFunction{T}
181+
# See comment for `term::MOI.ScalarQuadraticTerm` for the conversion.
182+
func::MOI.ScalarAffineFunction{T} = variable_map(term.variable_index)
183+
return operate(*, T, term.coefficient, func)::MOI.ScalarAffineFunction{T}
180184
end
181185
function substitute_variables(
182186
variable_map::Function,

test/Utilities/functions.jl

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,17 @@ end
169169
@test MOIU.eval_variables(vi -> subs_vals[vi], fvq) == MOIU.eval_variables(vi -> vals[vi], subs_vq)
170170
@test MOIU.substitute_variables(vi -> subs[vi], fvq) subs_vq
171171
@test MOIU.substitute_variables(vi -> subs[vi], fvq) subs_vq
172+
173+
complex_aff = 2.0im * fy
174+
# Test that variables can be substituted for `MOI.ScalarAffineFunction{S}`
175+
# in a `MOI.ScalarAffineFunction{T}` where `S != T`.
176+
@test MOIU.substitute_variables(vi -> 1.5fx, complex_aff) 3.0im * fx
177+
float_aff = 2.0 * fy
178+
@test MOIU.substitute_variables(vi -> 3fx, float_aff) 6.0 * fx
179+
complex_quad = 1.5im * fy * fy
180+
@test MOIU.substitute_variables(vi -> 2fx, complex_quad) 6.0im * fx * fx
181+
int_quad = 3 * fy * fx
182+
@test MOIU.substitute_variables(vi -> true * fy, int_quad) 3 * fy * fy
172183
end
173184
@testset "map_indices" begin
174185
fsq = MOI.ScalarQuadraticFunction(MOI.ScalarAffineTerm.(1.0, [x, y]),

0 commit comments

Comments
 (0)