I want to switch between Symmetric and Hermitian variables depending on the input data. For data I’d like to define a variable a, that can be either and then create the variable, e.g.
a = Symmetric
model = Model()
@variable(model, x[1:2,1:2], a)
but that errors. How do I pass them correctly?
Looking at the source code of the @variable macro, it seems like it wants to have Symmetric or Hermitian as a symbol, but
a = :Symmetric
model = Model()
@variable(model, x[1:2,1:2], a)
also fails. It does work if I do
a = :Symmetric
model = Model()
@eval @variable(model, x[1:2,1:2], $a)
but that’s a bit insane. What is going on here? What kind of argument does @variable want? Is it possible to do it without @eval?
Why not just use Hermitian in all cases? For real data, Hermitian is functionally (and mathematically) equivalent to Symmetric. For complex data, Symmetric is of limited utility in linear algebra.
What I’m doing is switching between a variable that belongs to the d(d+1)/2 dimensional vector space of real Hermitian matrices, or one that belongs to the d^2 dimensional vector space of complex Hermitian matrices. “Symmetric” and “Hermitian” are just the names JuMP uses for these vector spaces.
I am using an if-else now, that’s what I want to avoid. It leads to a lot of copy-pasting, since I need to switch between real and complex variables in several places.
julia> model = Model();
julia> a = SymmetricMatrixSpace()
SymmetricMatrixSpace()
julia> @variable(model, x[1:2,1:2], set=a)
2×2 LinearAlgebra.Symmetric{VariableRef, Matrix{VariableRef}}:
x[1,1] x[1,2]
x[1,2] x[2,2]
where it’s HermitianMatrixSpace() for Hermitian matrices. The docs mention set= in this section and SymmetricMatrixSpacehere, but I don’t see anywhere they mention using it for programmatic construction, maybe that would be useful to add to the docs.