-
-
Notifications
You must be signed in to change notification settings - Fork 11
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
Exponential of a skew Hermitian matrix #417
Comments
might be worth making a package for skew symmetric matrices and operations on them, if there are many cases of specialized algorithms |
Just to follow up on @tkelman's comment. The usual approach in Julia would be to define a type for the matrix and then overload |
Yes, I defined it in this way because there isn't a skew-hermitian type. |
Note that we already have an Now that |
Argh, I knew there was such a function but I couldn't remember its name, and searching for "imaginary exponential" did not give anything. Where does the name "cis" come from?
That would be ideal, although I would be partial to the name "expi". |
cis = cosine + i sine, and seems to be at least somewhat standard. (I like |
Doesn't it need to be |
Your code assumes
Another case that I would be interested in is when the skew symmetric matrix itself is real-valued. This would probably require a new type, as suggested above (though I don't know if there are any shortcuts you could use for actual computation, other than converting to complex and back again) |
There are a few specialized algorithms for skew-symmetric and skew-Hermitian matrices, e.g.:
|
However, these skew-specific algorithms seem be specialized enough (there are hardly any papers on this topic) that a |
Note that the function above does not take directly skew-symmetric or skew-Hermitian matrices as input. If you have one of those, they will need to be multiplied by It might be worth it to have |
What I meant was that:
|
Oh right yes I changed that when I realized I could simply call 'complex(A)'. Here is the function I have right now. I'm not sure whether it's the best we can do. With complex Hermitian matrices of small sizes it is slower to call the eigendecomposition than to call the regular exp function. We might just need to find a threshold under which to call exp. function expim(A::Union{Symmetric,Hermitian})
# First decompose A into U*Λ*Uᴴ
(Λ,U) = eig(A)
# U must be a complex matrix
U = complex(U)
# Calculate the imaginary exponential of each eigenvalue and multiply
# each column of U to obtain B = U*exp(iΛ)
n = length(Λ)
B = similar(U)
for j = 1:n
@inbounds a = Complex(cos(Λ[j]),sin(Λ[j]))
@simd for i = 1:n
@inbounds B[i,j] = a * U[i,j]
end
end
# Finally multiply B by Uᴴ to obtain U*exp(iΛ)*Uᴴ = exp(i*A)
return B*U'
end |
Imaginary exponentiation of a Hermitian matrix often appears in quantum mechanics and quantum computing. It'd be nice to have this built-in, because the current implementation without the specialization is very slow (compared to Mathematica's MatrixExp). |
See my comment above — the way is now clear to define A PR should be pretty easy and short since it could just handle the |
I'm not sure if you were responding to me, but that's what I said
which is Regarding being "uncommon", again, this is a very common and pretty much a fundamental operation in quantum mechanics and quantum computing, but I can't speak for fields other than physics. |
It's common to compute (Maybe you misunderstood me: I wasn't saying that Hermitian |
I have had reason to do it, e.g. it appears in the geodesics of the Steifel manifold (p 310 of http://math.mit.edu/~edelman/publications/geometry_of_algorithms.pdf) |
@stevengj Oh, no, what I mean is, in quantum mechanics, we indeed have Regarding For two-level quantum systems, as you mention, Pauli matrices can be used to expand the exponent. But it is very rarely the case that quantum systems are two-levels. For N-level systems, there is no such analytical formula (even for three-level systems for which Gell-Mann matrices replace Pauli matrices). In quantum computing, two-level systems appear as qubits. Entangling operations involve at least four-level systems (a pair of qubits), for which SU(4) operations can't fit in the SU(2)xSU(2) subgroup. |
@seadra, I'm familiar with quantum mechanics (I have a PhD in physics). All I'm saying is that we can leave the specific case of [There are applications for such real anti-Hermitian exponentials, but they are not generally quantum mechanics. (e.g. real anti-Hermitian exponentials arise in time propagators for dissipation-free classical wave equations, though in practice classical wave simulations typically use other methods).] |
OK, and sure, I personally don't imagine I'd ever need cis of a purely imaginary Hermitian. I was only talking about cis of a Hermitian, which is currently very slow in Julia compared to Mathematica. |
If someone wants to put together a pull request to add: cis(A::AbstractMatrix) = exp!([float(-imag(a), real(a)) for a in A]) # fallback
function cis(A::RealHermSymComplexHerm)
# optimized Hermitian case
end etcetera to the LinearAlgebra stdlib, that would be great. |
Good to have a clear action to be taken here 🙂 |
I was testing again, and it seems that currently (new computer, Julia v1.1.1) the results aren't as clear cut as before. The |
@jebej, I'm not sure how you got these results. I got a speedup of about 2x for complex using BenchmarkTools, LinearAlgebra
Base.cis(A::AbstractMatrix) = exp(im*A) # fallback
function Base.cis(A::LinearAlgebra.RealHermSymComplexHerm)
F = eigen(A)
return F.vectors * Diagonal(cis.(F.values)) * F.vectors'
end
Base.cis(A::Diagonal) = Diagonal(cis.(A.diag)) compared to the naive implementation Getting a factor of 2–4 speedup on a common operation with ~5 lines of code (+ docs and tests) seems worth including in LinearAlgebra. |
I would prefer Somewhat unrelated, but |
Seems like this is closed by JuliaLang/julia#40194. The remaining task, defining specialized eigensolvers and |
Would there be interest in having a function for taking the exponential of a skew-Hermitian (anti-Hermitian) matrix in the standard library, ie:
expm(i*A)
whereA
is Hermitian or Symmetric?It can be much faster than
expm(complex.(0.0,A))
:If not feel free to close this issue.
The text was updated successfully, but these errors were encountered: