Commit 116e2c2
fix: make
`MatrixFunctionViaEigh` built the real case as the symmetric product
`VexpD * transpose(VexpD)`, exact by construction, but the complex case as
a plain `VexpD * V'` with no closing projection, so the result was only
approximately hermitian. `squareroot`, `logarithm` and `power` are all
exact for both scalar types, leaving `exponential` the odd one out.
Since `eigh_full!` returns real eigenvalues, `exp(τD/2)` is self-adjoint
whenever `τ` is real, and `exp(τA) = (V exp(τD/2)) * (V exp(τD/2))'` is
then hermitian by construction. Route the complex case through
`_mul_herm!`, the same mechanism the other three use.
This needed a second change to take effect for `exponential(A)` itself:
the implicit scalar was `one(eltype(A))`, i.e. `1.0 + 0.0im` for a complex
matrix, which sent a plain `exp(A)` down the complex-`τ` branch even though
the scalar was real. Use `one(real(eltype(A)))` instead. The same edit for
`MatrixFunctionViaEig` is behaviour-neutral -- its branch condition already
excluded a complex `A` -- but avoids needless complex-scalar arithmetic.
A genuinely complex `τ` is still left unprojected, which is not an
oversight: `exp(τA)` of a hermitian `A` is hermitian only for real `τ`, and
projecting would silently return a different matrix.
Verified against `LinearAlgebra.exp(Hermitian(A))` for `Float32`,
`Float64`, `ComplexF32` and `ComplexF64` with both `QRIteration` and
`DivideAndConquer`, and for `Diagonal` with complex storage.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>exponential hermitian to the last bit for complex input1 parent 3bc2bb2 commit 116e2c2
2 files changed
Lines changed: 23 additions & 12 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
62 | 62 | | |
63 | 63 | | |
64 | 64 | | |
65 | | - | |
66 | | - | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
67 | 69 | | |
68 | 70 | | |
69 | 71 | | |
| |||
74 | 76 | | |
75 | 77 | | |
76 | 78 | | |
| 79 | + | |
| 80 | + | |
77 | 81 | | |
78 | 82 | | |
79 | 83 | | |
80 | 84 | | |
81 | 85 | | |
82 | 86 | | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
83 | 91 | | |
84 | | - | |
85 | | - | |
86 | | - | |
87 | | - | |
88 | | - | |
| 92 | + | |
| 93 | + | |
89 | 94 | | |
90 | 95 | | |
91 | 96 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
80 | 80 | | |
81 | 81 | | |
82 | 82 | | |
83 | | - | |
84 | | - | |
85 | | - | |
86 | | - | |
87 | | - | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
88 | 86 | | |
89 | 87 | | |
90 | 88 | | |
91 | 89 | | |
92 | 90 | | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
93 | 99 | | |
94 | 100 | | |
95 | 101 | | |
| |||
0 commit comments