Skip to content

Commit f31be21

Browse files
authored
[Utilities] fix operate(vcat for VectorNonlinearFunction (#2682)
1 parent 6e9fcac commit f31be21

File tree

2 files changed

+27
-1
lines changed

2 files changed

+27
-1
lines changed

src/Utilities/operate.jl

+9-1
Original file line numberDiff line numberDiff line change
@@ -991,7 +991,15 @@ function operate(
991991
append!(out, scalarize(a))
992992
end
993993
end
994-
return MOI.VectorNonlinearFunction(out)
994+
_to_new_snf(f::MOI.ScalarNonlinearFunction) = copy(f)
995+
_to_new_snf(f) = convert(MOI.ScalarNonlinearFunction, f)
996+
# We need to `copy` the ScalarNonlinearFunction rows here, everything else
997+
# will be `convert(ScalarNonlinearFunction, row)` into a new object, but the
998+
# ScalarNonlinearFunction rows won't be, so mutating the return value of
999+
# this `operate` method will mutate the inputs. This _is_ what Base.vcat
1000+
# does, but it doesn't fit with the general assumption that
1001+
# `Utilities.operate(` returns a new object.
1002+
return MOI.VectorNonlinearFunction(_to_new_snf.(out))
9951003
end
9961004

9971005
### 6a: operate(::typeof(imag), ::Type{T}, ::F)

test/Utilities/test_operate!.jl

+18
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,24 @@ function test_operate_5a()
399399
return
400400
end
401401

402+
function test_operate_5a_VectorNonlinearFunction()
403+
x = MOI.ScalarNonlinearFunction(:+, Any[])
404+
f = MOI.VectorNonlinearFunction([x])
405+
g = MOI.Utilities.operate(vcat, Float64, f, f, x)
406+
rows = [MOI.ScalarNonlinearFunction(:+, Any[]) for _ in 1:3]
407+
h = MOI.VectorNonlinearFunction(rows)
408+
@test g h
409+
push!(x.args, 0.0)
410+
@test g h
411+
@test g.rows[1] !== g.rows[2]
412+
@test g.rows[1] !== g.rows[3]
413+
@test g.rows[2] !== g.rows[3]
414+
rows = [MOI.ScalarNonlinearFunction(:+, Any[0.0])]
415+
f_new = MOI.VectorNonlinearFunction(rows)
416+
@test f f_new
417+
return
418+
end
419+
402420
function test_operate_6a()
403421
T = Float64
404422
@test MOI.Utilities.operate(imag, T, _test_function((0.0, 0.0, 0.0)))

0 commit comments

Comments
 (0)