# Choosing between Symmetric and Hermitian programmatically in JuMP

**URL:** <https://discourse.julialang.org/t/choosing-between-symmetric-and-hermitian-programmatically-in-jump/125701>\
**Category:** Optimization (Mathematical)\
**Tags:** jump\
**Created:** [February 9, 2025, 10:06am UTC](https://discourse.julialang.org/t/choosing-between-symmetric-and-hermitian-programmatically-in-jump/125701 "2025-02-09T10:06:33Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![araujoms](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/araujoms/32/217734_2.png) [@araujoms](https://discourse.julialang.org/u/araujoms)\
**Post date:** [February 9, 2025, 10:06am UTC](https://discourse.julialang.org/t/choosing-between-symmetric-and-hermitian-programmatically-in-jump/125701/1 "2025-02-09T10:06:33Z")

</div>

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.

```julia
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

```julia
a = :Symmetric
model = Model()
@variable(model, x[1:2,1:2], a)

```

also fails. It does work if I do

```julia
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`?

---

<div class="post-metadata">

**Author:** ![nsajko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nsajko/32/221187_2.png) [@nsajko](https://discourse.julialang.org/u/nsajko)\
**Post date:** [February 9, 2025, 10:30am UTC](https://discourse.julialang.org/t/choosing-between-symmetric-and-hermitian-programmatically-in-jump/125701/2 "2025-02-09T10:30:46Z")

</div>

> [@araujoms](#):
>
> ```julia
> @eval @variable(model, x[1:2,1:2], $a)
> 
> ```

Try without the `@eval`: `@variable(model, x[1:2,1:2], $a)`.

---

<div class="post-metadata">

**Author:** ![araujoms](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/araujoms/32/217734_2.png) [@araujoms](https://discourse.julialang.org/u/araujoms)\
**Post date:** [February 9, 2025, 11:18am UTC](https://discourse.julialang.org/t/choosing-between-symmetric-and-hermitian-programmatically-in-jump/125701/3 "2025-02-09T11:18:17Z")

</div>

That gives me an error:

> ERROR: syntax: “$” expression outside quote

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [February 9, 2025, 2:31pm UTC](https://discourse.julialang.org/t/choosing-between-symmetric-and-hermitian-programmatically-in-jump/125701/4 "2025-02-09T14:31:25Z")

</div>

> [@araujoms](#):
>
> I want to switch between Symmetric and Hermitian variables depending on the input data.

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.

---

<div class="post-metadata">

**Author:** ![araujoms](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/araujoms/32/217734_2.png) [@araujoms](https://discourse.julialang.org/u/araujoms)\
**Post date:** [February 9, 2025, 2:33pm UTC](https://discourse.julialang.org/t/choosing-between-symmetric-and-hermitian-programmatically-in-jump/125701/5 "2025-02-09T14:33:26Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![abulak](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/abulak/32/28314_2.png) [@abulak](https://discourse.julialang.org/u/abulak)\
**Post date:** [February 9, 2025, 4:59pm UTC](https://discourse.julialang.org/t/choosing-between-symmetric-and-hermitian-programmatically-in-jump/125701/6 "2025-02-09T16:59:05Z")

</div>

`@variable` is a macro, so it operates before `a=:Symmetric` even takes place. I guess a simple if/else

```julia
if (...)
    @variable(model, x[...], Symmetric)
else
    @variable(model, x[...], Hermitian)
end

```

is your best option. Is there a tangible gain from passing a variable to the `@variable` macro?

Another possibility is to define

```julia
function add_variable(model, dim, ::Type{Symmetric})
    @variable(model, [1:dim, 1:dim], Symmetric)
end

```

at the cost of dealing with anonymous variables later on:

```julia
m[:x] = add_variable(m, 2, Symmetric)

```

---

<div class="post-metadata">

**Author:** ![araujoms](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/araujoms/32/217734_2.png) [@araujoms](https://discourse.julialang.org/u/araujoms)\
**Post date:** [February 9, 2025, 5:06pm UTC](https://discourse.julialang.org/t/choosing-between-symmetric-and-hermitian-programmatically-in-jump/125701/7 "2025-02-09T17:06:43Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![ericphanson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ericphanson/32/215186_2.png) [@ericphanson](https://discourse.julialang.org/u/ericphanson)\
**Post date:** [February 9, 2025, 5:07pm UTC](https://discourse.julialang.org/t/choosing-between-symmetric-and-hermitian-programmatically-in-jump/125701/8 "2025-02-09T17:07:04Z")

</div>

> [@araujoms](#):
>
> ```julia
> a = Symmetric
> model = Model()
> @variable(model, x[1:2,1:2], a)
> 
> ```

You can do:

```julia
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](https://jump.dev/JuMP.jl/stable/manual/variables/#jump_variables_on_creation) and `SymmetricMatrixSpace` [here](https://jump.dev/JuMP.jl/stable/manual/variables/#Example:-symmetric-variables), but I don’t see anywhere they mention using it for programmatic construction, maybe that would be useful to add to the docs.

---

<div class="post-metadata">

**Author:** ![araujoms](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/araujoms/32/217734_2.png) [@araujoms](https://discourse.julialang.org/u/araujoms)\
**Post date:** [February 9, 2025, 8:53pm UTC](https://discourse.julialang.org/t/choosing-between-symmetric-and-hermitian-programmatically-in-jump/125701/9 "2025-02-09T20:53:03Z")

</div>

Thanks a lot, that works. Testing a little bit I found a slightly nicer syntax:

```julia
model = Model()
a = HermitianMatrixSpace()
@variable(model, x[1:2,1:2] in a)

```

---

<div class="post-metadata">

**Author:** ![odow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/odow/32/28685_2.png) [@odow](https://discourse.julialang.org/u/odow)\
**Post date:** [February 9, 2025, 8:55pm UTC](https://discourse.julialang.org/t/choosing-between-symmetric-and-hermitian-programmatically-in-jump/125701/10 "2025-02-09T20:55:17Z")

</div>

I’ll update the docs: [[docs] clarify how to pass PSD and Symmetric via set kwarg by odow · Pull Request #3940 · jump-dev/JuMP.jl · GitHub](https://github.com/jump-dev/JuMP.jl/pull/3940)
