Skip to content

Commit e46644b

Browse files
authored
Add value(::Function, ::X) and value(::X; result::Int) for Symmetric and Hermitian (#4000)
1 parent a420d68 commit e46644b

File tree

2 files changed

+79
-9
lines changed

2 files changed

+79
-9
lines changed

src/sd.jl

Lines changed: 40 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -430,15 +430,6 @@ function build_variable(
430430
return build_variable(error_fn, variables, set)
431431
end
432432

433-
function value(
434-
Q::LinearAlgebra.Symmetric{V,Matrix{V}},
435-
) where {V<:AbstractVariableRef}
436-
return LinearAlgebra.Symmetric(
437-
value.(LinearAlgebra.parent(Q)),
438-
LinearAlgebra.sym_uplo(Q.uplo),
439-
)
440-
end
441-
442433
function build_constraint(
443434
error_fn::Function,
444435
Q::LinearAlgebra.Symmetric{V,M},
@@ -862,3 +853,43 @@ for S in (Nonnegatives, Nonpositives, Zeros)
862853
end
863854
end
864855
end
856+
857+
function value(
858+
var_value::Function,
859+
Q::LinearAlgebra.Symmetric{V,Matrix{V}},
860+
) where {V<:AbstractJuMPScalar}
861+
return LinearAlgebra.Symmetric(
862+
value.(var_value, LinearAlgebra.parent(Q)),
863+
LinearAlgebra.sym_uplo(Q.uplo),
864+
)
865+
end
866+
867+
function value(
868+
Q::LinearAlgebra.Symmetric{V,Matrix{V}};
869+
result::Int = 1,
870+
) where {V<:AbstractJuMPScalar}
871+
return LinearAlgebra.Symmetric(
872+
value.(LinearAlgebra.parent(Q); result),
873+
LinearAlgebra.sym_uplo(Q.uplo),
874+
)
875+
end
876+
877+
function value(
878+
var_value::Function,
879+
Q::LinearAlgebra.Hermitian{V,Matrix{V}},
880+
) where {V<:AbstractJuMPScalar}
881+
return LinearAlgebra.Hermitian(
882+
value.(var_value, LinearAlgebra.parent(Q)),
883+
LinearAlgebra.sym_uplo(Q.uplo),
884+
)
885+
end
886+
887+
function value(
888+
Q::LinearAlgebra.Hermitian{V,Matrix{V}};
889+
result::Int = 1,
890+
) where {V<:AbstractJuMPScalar}
891+
return LinearAlgebra.Hermitian(
892+
value.(LinearAlgebra.parent(Q); result),
893+
LinearAlgebra.sym_uplo(Q.uplo),
894+
)
895+
end

test/test_generate_and_solve.jl

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -647,4 +647,43 @@ function test__optimizer_for_precompile_tools()
647647
return
648648
end
649649

650+
function test_value_symmetric()
651+
inner = MOI.Utilities.MockOptimizer(
652+
MOI.Utilities.UniversalFallback(MOI.Utilities.Model{Float64}()),
653+
)
654+
model = direct_model(inner)
655+
@variable(model, x[i in 1:2, j in 1:2], Symmetric, start = i + j)
656+
Y = LinearAlgebra.Symmetric(1.0 .* x)
657+
@test_throws OptimizeNotCalled value(x)
658+
@test_throws OptimizeNotCalled value(Y)
659+
@test value(start_value, x) == LinearAlgebra.Symmetric([2 3; 3 4])
660+
@test value(start_value, Y) == LinearAlgebra.Symmetric([2 3; 3 4])
661+
optimize!(model)
662+
MOI.set(inner, MOI.TerminationStatus(), MOI.OPTIMAL)
663+
MOI.set.(inner, MOI.VariablePrimal(), index.(x), [3 4; 4 5])
664+
@test value(x) == LinearAlgebra.Symmetric([3 4; 4 5])
665+
@test value(Y) == LinearAlgebra.Symmetric([3 4; 4 5])
666+
@test_throws MOI.ResultIndexBoundsError value(x; result = 2)
667+
@test_throws MOI.ResultIndexBoundsError value(Y; result = 2)
668+
return
669+
end
670+
671+
function test_value_hermitian()
672+
inner = MOI.Utilities.MockOptimizer(
673+
MOI.Utilities.UniversalFallback(MOI.Utilities.Model{Float64}()),
674+
)
675+
model = direct_model(inner)
676+
H = [1 2+3im; 2-3im 4]
677+
@variable(model, x[i in 1:2, j in 1:2], Hermitian, start = H[i, j])
678+
@test_throws OptimizeNotCalled value(x)
679+
@test value(start_value, x) == LinearAlgebra.Hermitian(H)
680+
optimize!(model)
681+
MOI.set(inner, MOI.TerminationStatus(), MOI.OPTIMAL)
682+
y = index.(all_variables(model))
683+
MOI.set.(inner, MOI.VariablePrimal(), y, [3, 4, 5, 6])
684+
@test value(x) == LinearAlgebra.Hermitian([3 4+6im; 4-6im 5])
685+
@test_throws MOI.ResultIndexBoundsError value(x; result = 2)
686+
return
687+
end
688+
650689
end # module

0 commit comments

Comments
 (0)