Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Errors in complex algebra with Symmetric and Hermitian #264

Closed
araujoms opened this issue Feb 29, 2024 · 7 comments · Fixed by #265
Closed

Errors in complex algebra with Symmetric and Hermitian #264

araujoms opened this issue Feb 29, 2024 · 7 comments · Fixed by #265
Labels
bug Something isn't working

Comments

@araujoms
Copy link
Contributor

The algebra with complex numbers and Symmetric or Hermitian matrices doesn't work as it should. First of all, multiplying a complex number by a Hermitian matrix gives an incorrect result wrapped in Hermitian:

using JuMP
julia> model = Model();
julia> @variable(model, m[1:2,1:2] in HermitianPSDCone());
julia> im*m
2×2 LinearAlgebra.Hermitian{GenericAffExpr{ComplexF64, VariableRef}, Matrix{GenericAffExpr{ComplexF64, VariableRef}}}:
 -real(m[1,1]) im                 real(m[1,2]) im - imag(m[1,2])
 -real(m[1,2]) im - imag(m[1,2])  -real(m[2,2]) im

Also, if I create a real variable and multiply it by a Symmetric or Hermitian matrix, I get the correct result, but it's no longer wrapped in Symmetric or Hermitian:

using JuMP
julia> model = Model();
julia> @variable(model, x);
julia> m = randn(ComplexF64,2,2);
julia> x*Symmetric(m)
2×2 Matrix{GenericAffExpr{ComplexF64, VariableRef}}:
 (-1.2483493211093275 + 0.5094508206087239im) x  (-0.6295524575806658 + 1.0006355385104637im) x
 (-0.6295524575806658 + 1.0006355385104637im) x  (-0.8701716643747957 - 0.27288163539446847im) x
julia> x*Hermitian(m)
2×2 Matrix{GenericAffExpr{ComplexF64, VariableRef}}:
 -1.2483493211093275 x                           (-0.6295524575806658 + 1.0006355385104637im) x
 (-0.6295524575806658 - 1.0006355385104637im) x  -0.8701716643747957 x

(Of course, Symmetric matrices multiplied by complex variables should still be Symmetric, but I don't think this will ever matter.)

@araujoms araujoms changed the title Erros in complex algebra with Symmetric and Hermitian Errors in complex algebra with Symmetric and Hermitian Feb 29, 2024
@blegat blegat transferred this issue from jump-dev/MathOptInterface.jl Feb 29, 2024
@blegat blegat transferred this issue from jump-dev/JuMP.jl Feb 29, 2024
@blegat blegat added the bug Something isn't working label Feb 29, 2024
@blegat
Copy link
Member

blegat commented Feb 29, 2024

The issue is that we shouldn't wrap in Hermitian something that's not Hermitian ^^

julia> B = MA._mult_upper(im, m)
2×2 Matrix{GenericAffExpr{ComplexF64, VariableRef}}:
 real(m[1,1]) im                 real(m[1,2]) im - imag(m[1,2])
 real(m[1,2]) im + imag(m[1,2])  real(m[2,2]) im

julia> h = Hermitian(B, :U)
2×2 Hermitian{GenericAffExpr{ComplexF64, VariableRef}, Matrix{GenericAffExpr{ComplexF64, VariableRef}}}:
 -real(m[1,1]) im                 real(m[1,2]) im - imag(m[1,2])
 -real(m[1,2]) im - imag(m[1,2])  -real(m[2,2]) im

julia> h.data
2×2 Matrix{GenericAffExpr{ComplexF64, VariableRef}}:
 real(m[1,1]) im                 real(m[1,2]) im - imag(m[1,2])
 real(m[1,2]) im + imag(m[1,2])  real(m[2,2]) im

@araujoms
Copy link
Contributor Author

That's weird. Shouldn't Hermitian(B) return instead

2×2 Hermitian{GenericAffExpr{ComplexF64, VariableRef}, Matrix{GenericAffExpr{ComplexF64, VariableRef}}}:
 0.0                              real(m[1,2]) im - imag(m[1,2])
 -real(m[1,2]) im - imag(m[1,2])  0.0

@blegat
Copy link
Member

blegat commented Feb 29, 2024

Yes, looks like another bug, it calls LinearAlgebra.hermitian(h.data[1, 1], :U) which doesn't seem to do the right thing see jump-dev/JuMP.jl#3692

@odow odow closed this as completed in #265 Feb 29, 2024
@odow
Copy link
Member

odow commented Feb 29, 2024

With #265, we now get:

julia> using JuMP

julia> model = Model();

julia> @variable(model, m[1:2,1:2] in HermitianPSDCone());

julia> im*m
2×2 Matrix{GenericAffExpr{ComplexF64, VariableRef}}:
 real(m[1,1]) im                 real(m[1,2]) im - imag(m[1,2])
 real(m[1,2]) im + imag(m[1,2])  real(m[2,2]) im

@araujoms
Copy link
Contributor Author

Wait, please, don't close the issue! What about getting a new dispatch so that a Hermitian matrix multiplied by a real variable stays Hermitian? It is the only reason I was even testing this stuff.

@odow
Copy link
Member

odow commented Feb 29, 2024

What about getting a new dispatch so that a Hermitian matrix multiplied by a real variable stays Hermitian?

I'll open a separate issue.

@araujoms
Copy link
Contributor Author

Great, thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Development

Successfully merging a pull request may close this issue.

3 participants