# Performance of Hermitian eigensolvers

**URL:** <https://discourse.julialang.org/t/performance-of-hermitian-eigensolvers/23142>\
**Category:** Performance\
**Created:** [April 14, 2019, 4:07pm UTC](https://discourse.julialang.org/t/performance-of-hermitian-eigensolvers/23142 "2019-04-14T16:07:19Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![Invarianz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/invarianz/32/7825_2.png) [@Invarianz](https://discourse.julialang.org/u/Invarianz)\
**Post date:** [April 14, 2019, 4:07pm UTC](https://discourse.julialang.org/t/performance-of-hermitian-eigensolvers/23142/1 "2019-04-14T16:07:20Z")

</div>

I usually work with full diagonalisation of Hermitian matrices. After some research I realised that there are two options to retrieve the eigenvalues and eigenvectors of such a matrix.  
`LinearAlgebra.LAPACK.syev!()` and `eigen!()`. From the source code of `eigen!()` it seems that it is calling a general eigensolver routine called `ggevx()`.

The `LinearAlgebra.LAPACK.syev!()` routine required some digging into the source code to figure out that it is also intended for Hermitian matrices ([docs.julialang.org](http://docs.julialang.org) only talks about symmetric matrices). I realised that it is calling specialised Hermitian routines in LAPACK.

Now after building up a 2000x2000 Hermitian matrix I called both routines the following way and timed their peformance:

```julia
H = weyl(10, 10, 10)
Ht = deepcopy(H)

@time eigsys = LAPACK.syev!('V', 'U', H)
@time eigsyst = eigen!(Hermitian(Ht))

```

To my surprise the `eigen!` routine is quite a bit faster:

```julia
  8.998029 seconds (6 allocations: 1.068 MiB)
  6.128692 seconds (16 allocations: 123.658 MiB, 1.71% gc time)

```

To me this is quite counterintuitive behaviour. I would have guessed that the specialised routines should work faster.

---

<div class="post-metadata">

**Author:** ![Ralph\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ralph_smith/32/10344_2.png) [@Ralph\_Smith](https://discourse.julialang.org/u/Ralph_Smith)\
**Post date:** [April 14, 2019, 4:42pm UTC](https://discourse.julialang.org/t/performance-of-hermitian-eigensolvers/23142/2 "2019-04-14T16:42:56Z")

</div>

If you look more closely at `LinearAlgebra/src/symmetric.jl` you find that `eigen!(::Hermitian)` calls the `syevr` routines from LAPACK (note the trailing `r`). For full diagonalization these use Dhillon and Parlett’s “Relatively Robust Representations” which are more efficient than the traditional `syev` scheme.

---

<div class="post-metadata">

**Author:** ![Ralph\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ralph_smith/32/10344_2.png) [@Ralph\_Smith](https://discourse.julialang.org/u/Ralph_Smith)\
**Post date:** [April 26, 2025, 3:01am UTC](https://discourse.julialang.org/t/performance-of-hermitian-eigensolvers/23142/3 "2025-04-26T03:01:49Z")

</div>

As of v1.12, the default scheme for full diagonalization of Hermitian matrices is divide-and-conquer (which is faster and more accurate than RRR in many cases), and the algorithm can be changed with the keyword `alg`. RRR is still used when a subset of eigenpairs is requested.
