Skip to content

Exponential of a skew Hermitian matrix #417

@jebej

Description

@jebej

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) where A is Hermitian or Symmetric?

function expim(A::Union{Symmetric,Hermitian})
    # First decompose A into U*Λ*Uᴴ
    (Λ,U) = eig(A)
    # U must be a complex matrix
    U = complex.(U,0.0)
    # Calculate the imaginary exponential of each eigenvalue and multiply
    # by U to obtain B = U*exp(iΛ)
    B = scale!(copy(U),complex.(cos.(Λ),sin.(Λ)))
    # Finally multiply B by Uᴴ to obtain U*exp(iΛ)*Uᴴ = exp(i*A)
    return B*U'
end

It can be much faster than expm(complex.(0.0,A)):

julia> A = Hermitian(rand(1000,1000));

julia> B = Hermitian(rand(100,100));

julia> C = Hermitian(rand(10,10));

julia> @benchmark expm(complex.(0.0,A))
BenchmarkTools.Trial:
  memory estimate:  686.67 MiB
  allocs estimate:  123
  --------------
  minimum time:     2.558 s (4.62% GC)
  median time:      2.654 s (6.86% GC)
  mean time:        2.654 s (6.86% GC)
  maximum time:     2.750 s (8.94% GC)
  --------------
  samples:          2
  evals/sample:     1
  time tolerance:   5.00%
  memory tolerance: 1.00%

julia> @benchmark expim(A)
BenchmarkTools.Trial:
  memory estimate:  69.04 MiB
  allocs estimate:  28
  --------------
  minimum time:     489.935 ms (1.02% GC)
  median time:      505.759 ms (0.99% GC)
  mean time:        512.661 ms (3.93% GC)
  maximum time:     566.183 ms (12.66% GC)
  --------------
  samples:          10
  evals/sample:     1
  time tolerance:   5.00%
  memory tolerance: 1.00%

julia> @benchmark expm(complex.(0.0,B))
BenchmarkTools.Trial:
  memory estimate:  6.42 MiB
  allocs estimate:  117
  --------------
  minimum time:     3.838 ms (0.00% GC)
  median time:      4.272 ms (0.00% GC)
  mean time:        5.037 ms (11.12% GC)
  maximum time:     13.668 ms (0.00% GC)
  --------------
  samples:          977
  evals/sample:     1
  time tolerance:   5.00%
  memory tolerance: 1.00%

julia> @benchmark expim(B)
BenchmarkTools.Trial:
  memory estimate:  743.11 KiB
  allocs estimate:  27
  --------------
  minimum time:     2.787 ms (0.00% GC)
  median time:      2.912 ms (0.00% GC)
  mean time:        3.015 ms (1.83% GC)
  maximum time:     7.143 ms (0.00% GC)
  --------------
  samples:          1641
  evals/sample:     1
  time tolerance:   5.00%
  memory tolerance: 1.00%

julia> @benchmark expm(complex.(0.0,C))
BenchmarkTools.Trial:
  memory estimate:  70.88 KiB
  allocs estimate:  72
  --------------
  minimum time:     66.639 μs (0.00% GC)
  median time:      67.809 μs (0.00% GC)
  mean time:        72.095 μs (3.05% GC)
  maximum time:     845.272 μs (85.55% GC)
  --------------
  samples:          10000
  evals/sample:     1
  time tolerance:   5.00%
  memory tolerance: 1.00%

julia> @benchmark expim(C)
BenchmarkTools.Trial:
  memory estimate:  12.73 KiB
  allocs estimate:  20
  --------------
  minimum time:     59.332 μs (0.00% GC)
  median time:      64.301 μs (0.00% GC)
  mean time:        65.727 μs (0.89% GC)
  maximum time:     1.089 ms (90.74% GC)
  --------------
  samples:          10000
  evals/sample:     1
  time tolerance:   5.00%
  memory tolerance: 1.00%

If not feel free to close this issue.

Metadata

Metadata

Assignees

No one assigned

    Labels

    speculativeWhether the change will be implemented is speculative

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions