-
-
Notifications
You must be signed in to change notification settings - Fork 32
Add hermitianpart method for Number types #1445
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
base: master
Are you sure you want to change the base?
Add hermitianpart method for Number types #1445
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #1445 +/- ##
=======================================
Coverage 93.89% 93.89%
=======================================
Files 34 34
Lines 15920 15921 +1
=======================================
+ Hits 14948 14949 +1
Misses 972 972 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for your PR!
Co-authored-by: Daniel Karrasch <[email protected]>
Co-authored-by: Steven G. Johnson <[email protected]>
I think we should have |
I see the point, but I’d lean towards keeping hermitianpart(x::Number) = real(x) for scalars. What do you think @stevengj ? Could this make sense? |
I think the general principle here is that we shouldn't change the type unless it is required to represent the output, since type conversions may incur a loss of data. |
I think it would be the perfect solution for the sister PR #1439, which currently has an unsatisfactory behavior: julia> Z = complex([1 0;0 2]);
julia> inv(Diagonal(Z))
2×2 Diagonal{ComplexF64, Vector{ComplexF64}}:
1.0-0.0im ⋅
⋅ 0.5-0.0im
julia> inv(Hermitian(Diagonal(Z)))
2×2 Hermitian{Float64, Diagonal{Float64, Vector{Float64}}}:
1.0 ⋅
⋅ 0.5 |
It doesn't change the underlying numeric type — it just extracts a component, like
Why? You want the meaning between both cases to be consistent, so that you can use it in generic code. But the return type is different anyway, so what does it matter if the matrix case (by necessity) also does a floating-point conversion? |
Because we'd get type instability. |
It's not a type instability to return different output types for different input types. |
It's bound to happen with any non-trivial code. It's very common to have special cases for diagonal, symmetric, Hermitian matrices in LinearAlgebra, where we wrap the matrix, do the computation, and unwrap it again. I fixed a lot of type instabilities resulting from this: #1360 Letting the inverse of a complex matrix be a real matrix is just asking for trouble. |
What is bound to happen?
What specific problem are you worried about?
I agree that it's asking for trouble, because the inverse of a complex matrix is generally not real. I don't understand what that has to do with the current PR. |
I think it makes sense to have hermitian(A::Number, ::Symbol=:U) = convert(typeof(A), real(A)) |
Fixes #1438
This PR implements
hermitianpart
forNumber
types as requested in the issue.Changes:
hermitianpart(x::Number) = real(x)
method insrc/symmetric.jl
test/symmetric.jl
This resolves the
MethodError
when callinghermitianpart
on complex numbers and enables the generic code usage mentioned in the issue.