You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/src/changelog.md
-2Lines changed: 0 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -23,8 +23,6 @@ When releasing a new version, move the "Unreleased" changes to a new version sec
23
23
### Added
24
24
25
25
- New matrix functions `squareroot`, `logarithm` and `power` (with both integer and fractional exponents), supporting the `MatrixFunctionViaLA`, `MatrixFunctionViaEig`, `MatrixFunctionViaEigh` and `DiagonalAlgorithm` algorithms ([#261](https://github.com/QuantumKitHub/MatrixAlgebraKit.jl/pull/261)).
26
-
- The scalar type of the output of these matrix functions matches that of the input, and out-of-domain eigenvalues (e.g. on the negative real axis for a real input) throw a `DomainError`; eigenvalues that violate the domain within a tolerance `domain_atol` (defaulting to `default_domain_atol`) are treated as rounding artifacts and clamped to the domain boundary ([#261](https://github.com/QuantumKitHub/MatrixAlgebraKit.jl/pull/261)).
27
-
-`MatrixFunctionViaEig` and `MatrixFunctionViaEigh` accept a `domain_atol` keyword argument to control this tolerance ([#261](https://github.com/QuantumKitHub/MatrixAlgebraKit.jl/pull/261)).
The functions below ([`squareroot`](@ref), [`logarithm`](@ref) and [`power`](@ref) with fractional powers) are only defined for matrices whose eigenvalues avoid (part of) the negative real axis, and their principal values are complex whenever eigenvalues on that axis are present.
44
44
In MatrixAlgebraKit, we aim to keep type stability, and thus the scalar type of the output always matches that of the input.
45
45
As such, a real matrix with eigenvalues on the negative real axis leads to a `DomainError`.
46
46
You should pass a complex matrix instead to obtain the complex principal value.
47
-
To avoid spurious errors for eigenvalues that lie on the negative real axis only because of rounding errors (e.g. a positive semidefinite matrix with a tiny negative eigenvalue), eigenvalues within an absolute tolerance `domain_atol` of the domain boundary are clamped onto it.
48
-
This tolerance defaults to [`default_domain_atol`](@ref) and can be specified explicitly for the algorithms that support it, e.g. `MatrixFunctionViaEigh(eigh_alg; domain_atol=...)`.
47
+
To avoid spurious errors for eigenvalues that lie on the negative real axis only because of rounding errors (e.g. a positive semidefinite matrix with a tiny negative eigenvalue), an absolute tolerance `domain_atol` decides which eigenvalues are treated as rounding artifacts.
48
+
It can be specified for every algorithm, e.g. `MatrixFunctionViaEigh(eigh_alg; domain_atol=...)` or `squareroot(A; domain_atol=...)`, and defaults to [`default_domain_atol`](@ref).
49
+
50
+
### The tolerance has two opposite roles
51
+
52
+
Whether the boundary point `λ = 0` belongs to the domain differs per function, and this flips what raising `domain_atol` does.
53
+
54
+
| Function | Domain for a real result |`domain_atol` is | Raising it |
|[`squareroot`](@ref)|`λ ∉ ℝ₋`, boundary included | a clamping radius: eigenvalues within `domain_atol` of the negative real axis are moved onto it | accepts more matrices |
57
+
|[`power`](@ref), fractional `p > 0`| as `squareroot`, since `0^p = 0`| as `squareroot`| accepts more matrices |
58
+
|[`logarithm`](@ref)|`λ ∉ ℝ₋ ∪ {0}`, boundary excluded | a rejection radius: eigenvalues within `domain_atol` of the origin are `DomainError`s, since `log(0)` does not exist | rejects more matrices |
59
+
|[`power`](@ref), fractional `p < 0`| as `logarithm`, since `0^p` diverges | as `logarithm`| rejects more matrices |
60
+
|[`power`](@ref), integer `p < 0`| invertible matrices | a rejection radius around the origin | rejects more matrices |
So for `logarithm` and negative `power`, raising `domain_atol` never rescues a matrix that was rejected: there is no boundary point to clamp onto, and the tolerance only widens the neighbourhood of the origin that is rejected.
65
+
Raising it past a small negative eigenvalue merely turns a "negative eigenvalue" `DomainError` into a "numerically zero eigenvalue" one; *lowering* it is what admits an eigenvalue that is small but genuinely nonzero.
66
+
67
+
Clamping is backward stable, but only to the size of the eigenvalue that was discarded, and the forward error it incurs is *not* of that size.
68
+
For `squareroot`, clamping an eigenvalue at `-δ` perturbs the result by `O(√δ)`, so an accepted result computed at the default tolerance can differ from the exact principal value by considerably more than the tolerance itself.
69
+
70
+
### What the tolerance is measured on
71
+
72
+
For the eigenvalue-decomposition-based algorithms, `domain_atol` is the distance of an eigenvalue to the domain boundary, and its default reflects how accurately that algorithm obtains the spectrum.
73
+
74
+
| Algorithm |`domain_atol` measures | Default |
75
+
|:----------|:-----------------------|:--------|
76
+
|[`DiagonalAlgorithm`](@ref)| the eigenvalue itself, which is exact input here |`n * eps * maximum(abs, λ)`|
77
+
|[`MatrixFunctionViaEigh`](@ref)| the eigenvalue, accurate to the backward error of a stable hermitian eigensolver |`n * eps * maximum(abs, λ)`|
78
+
|[`MatrixFunctionViaEig`](@ref)| the eigenvalue, whose accuracy is additionally limited by the conditioning of the eigenvectors |`defaulttol(λ) * maximum(abs, λ)`|
79
+
|[`MatrixFunctionViaLA`](@ref)| the imaginary part of the *result*|`defaulttol * norm(f(A), Inf)`|
80
+
81
+
The first two use the same rule as `LinearAlgebra.sqrt(::Hermitian; rtol = eps(T) * size(A, 1))`, so for hermitian input MatrixAlgebraKit and `LinearAlgebra` accept and reject the same matrices.
82
+
`MatrixFunctionViaEig` is deliberately looser, since a defective eigenvalue of multiplicity `k` is only resolved to `eps^(1/k)`.
83
+
84
+
`MatrixFunctionViaLA` is the exception, because `LinearAlgebra` never exposes the spectrum: it decides internally whether a real result exists and returns a complex matrix when it does not.
85
+
The tolerance therefore bounds the imaginary part of the result instead, which is a different quantity on a different scale — for `squareroot`, an eigenvalue at `-δ` shows up as an imaginary part of order `√δ`.
86
+
Such a tolerance is not optional there: `LinearAlgebra` casts a fractional power back to a real matrix only when its imaginary part vanishes identically, so `A^p` of a real matrix with complex-conjugate eigenvalues is complex even when the spectrum stays well clear of the negative real axis.
87
+
88
+
!!! warning "`MatrixFunctionViaLA` cannot detect a singular matrix"
89
+
Because it inspects only the result, `MatrixFunctionViaLA` does not enforce the nonzero-eigenvalue condition of `logarithm` and of `power` with a negative exponent: `LinearAlgebra` treats a numerically zero eigenvalue as in-domain and returns a finite result whose entries are merely large.
90
+
Use [`MatrixFunctionViaEig`](@ref) or [`MatrixFunctionViaEigh`](@ref) if you need such input rejected.
0 commit comments