-
-
Notifications
You must be signed in to change notification settings - Fork 5.4k
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
RFC: Methods for eigen
on complex hermitian tridiagonal matrices
#49546
Conversation
Can't you dispatch to the lapack hermitian routine directly? |
Yeah, that might be preferable. I wonder if it's any faster than what I did. I preferred this approach because then I didn't have to worry about any of the different options which might be supplied to |
There doesn't seem to be such a direct hermitian routine. LAPACK suggests that users reduce a matrix of interest (probably dense hermitian?) to tridiagonal form first and then use one of the standard routines. For the time being, I think merging this PR as is is a good idea. If there is sufficient interest and room for further improvement, then we could do this later? |
Oh wow that's crazy but yeah that appears to be correct. So OK let's just merge this. Someone really needs to rewrite lapack at some point... |
@dkarrasch @antoine-levitt any thoughts on if I should try and add an intermediate method for regular My concern is that trying to intercept that case, and then if it isn't hermitian, carry on as before is kinda hard. I guess I'd need to do an |
It seems like this is already a significant performance improvement! |
Would this warrant a new Related reading: #43983.
As far as I understand, LAPACK's support for real symmetric tridiagonal matrices exists not so much for the interest in such matrices in their own right, but because they are an intermediate representation in the eigendecomposition of hermitian matrices, much like Hessenberg matrices for QR decomposition. Thus
|
Hi @MasonProtter , I agree with this PR; was missing the I will suggest some improvements in implementation, which are attached to the source code. |
LGTM. Needs tests, though. |
Is there anything in particular you'd like to see tested? This path is already in the test suite fwiw, and compared to the default dense result, both for eigenvectors and eigenvalues |
To elaborate on the argument for defining |
Where is this tested? I don't see the |
Ah yeah, I see how that's confusing. For some reason, this test lives in julia/stdlib/LinearAlgebra/test/eigen.jl Line 48 in c1e1d5c
The only reason I knew it was being tested was that I was getting test failures before because I wasn't checking if the |
While it'd be nice, adding a whole new I don't think it's really that unusual though to want to specialized on |
Co-authored-by: Steven G. Johnson <[email protected]>
Co-authored-by: Steven G. Johnson <[email protected]>
It's certainly not unusual to want to diagonalize a hermitian tridiagonal matrix, I've often wanted that myself. It's also reasonable that Perhaps this PR should also add methods for |
Btw., emphasizing this and that I'm really excited about having this transformation in LinearAlgebra. In the past, I've always resorted to making a dense copy. Thank you for making this happen! |
This appears to be NEWS-worthy, doesn't it? And then we can merge, I think. As for the real cases, we could have another PR, and then discuss whether we should have function Symmetric(A::Tridiagonal, uplo::Char)
checkuplo(uplo)
uplo == 'U' ? SymTridiagonal(A.d, A.dv) : SymTridiagonal(A.d, A.ev)
end or whether we want specialized |
Okay, I added the |
Background:
We have a type
SymTridiagonal
which is anunnatural abominationtype representing symmetric tridiagonal matrices, but we have no such type for hermitian tridiagonal matrices which are much more natural objects in linear algebra.This leads to an unfortunate situation where trying to get the eigenvalues of a real
SymTridiagonal
matrix is very fast, but if you have complex elements and a hermitian structure, then you end up hitting the generic fallback and performance will greatly suffer.The upside is that for any hermitian tridiagonal matrix
A
, there exists a diagonal unitary matrixS
such thatS' * A * S
is a real symmetric tridiagonal matrix.B = S' * A * S
will have the same main diagonal asA
, and the off diagonals will simply be the absolute values of the off-diagonals ofA
.This is something known by experts, and sounds plausible to people with some experience, but I think isn't particularly common knowledge amongst wider users of linear algebra, so if there's an easy way we can do this for them automatically, that'd be good.
This PR
I wasn't really sure what would be the best approach would be to put this transformation into LinearAlgebra, so I figured I'd just do the most obvious thing, put it out there and then request advice for how to integrate it better into the system.
Ideally, this would work with regular
Tridiagonal{<:Complex}
matrices by just checking if they're hermitian, but I was a bit wary of the resulting dispatch gymnastics, so I opted to only operate onHermitian{Complex{T}, <:Tridiagonal}
for now.The approach is that for
eigen
, I generate the similarity transformS
, and the then calculate the eigenvalues and eigenvectors ofand the plain eigenvalues, as well as the eigenvectors which are transformed by
S
.For
eigvals
, that transformation is not necessary, so I simply doeigvals(SymTridiagonal(real.(d), abs.(dl)); kwargs...)
which saves us a matmul relative toeigen
Any advice or comments on the implementation / approach before I start writing up some tests and such?
Performance comparisons
Before:
and after
Edit: I forgot to mention in the original post, this algorithm was sketched out in https://web.archive.org/web/20201028202318/http:https://icl.cs.utk.edu/lapack-forum/viewtopic.php?f=2&t=3592# , and it was brought to my attention by @stevengj with this Discourse post: https://discourse.julialang.org/t/what-is-the-point-of-the-symmetric-type/40773/5