Skip to content

Commit 9f527af

Browse files
committed
tolerance in Float64
1 parent 4849584 commit 9f527af

2 files changed

Lines changed: 15 additions & 20 deletions

File tree

src/implementations/matrixfunctions.jl

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -71,29 +71,26 @@ end
7171
)
7272
end
7373

74+
_clamp_domain_eigenvalues!(D::Diagonal, atol::Real) =
75+
_clamp_domain_eigenvalues!(diagview(D), atol)
76+
7477
# Clamp real eigenvalues that are negative within `atol` (rounding artifacts) to zero,
7578
# and throw a `DomainError` for eigenvalues that are genuinely negative, since then the
7679
# result cannot be expressed with the same (real) scalar type.
7780
function _clamp_domain_eigenvalues!::AbstractVector{<:Real}, atol::Real)
7881
λmin = minimum(λ; init = zero(eltype(λ)))
82+
atol = atol < 0 ? default_domain_atol(λ) : oftype(λmin, atol)
7983
λmin < -atol && throw_negative_eigenvalue(λmin, atol, "a negative real eigenvalue")
8084
λ .= max.(λ, zero(eltype(λ)))
8185
return λ
8286
end
8387

84-
# Convenience method for the eigenvalues of a decomposition, deriving the default
85-
# tolerance from the eigenvalues themselves when `domain_atol` is `nothing`.
86-
function _clamp_domain_eigenvalues!(D::Diagonal, domain_atol::Union{Nothing, Real})
87-
λ = diagview(D)
88-
atol = something(domain_atol, default_domain_atol(λ))
89-
return _clamp_domain_eigenvalues!(λ, atol)
90-
end
91-
9288
# Complex eigenvalues of a real matrix: only eigenvalues (numerically) on the negative
9389
# real axis obstruct a real result; complex-conjugate pairs do not.
9490
function _clamp_domain_eigenvalues!::AbstractVector{<:Complex}, atol::Real)
9591
onaxis = x -> abs(imag(x)) <= atol && real(x) < 0
9692
λmin = mapreduce(x -> onaxis(x) ? real(x) : zero(real(x)), min, λ; init = zero(real(eltype(λ))))
93+
atol = atol < 0 ? default_domain_atol(λ) : oftype(λmin, atol)
9794
λmin < -atol && throw_negative_eigenvalue(λmin, atol, "an eigenvalue on the negative real axis")
9895
λ .= ifelse.(onaxis.(λ), zero(eltype(λ)), λ)
9996
return λ

src/interface/matrixfunctions.jl

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -38,17 +38,16 @@ For matrix functions with a restricted domain (e.g. [`squareroot`](@ref) and [`l
3838
as rounding artifacts and clamped to the domain boundary, with `nothing` denoting the default
3939
tolerance [`default_domain_atol`](@ref).
4040
"""
41-
struct MatrixFunctionViaEigh{A <: AbstractAlgorithm, T <: Union{Nothing, Real}} <: AbstractAlgorithm
41+
struct MatrixFunctionViaEigh{A <: AbstractAlgorithm} <: AbstractAlgorithm
4242
eigh_alg::A
43-
domain_atol::T
44-
end
45-
function MatrixFunctionViaEigh(eigh_alg::AbstractAlgorithm; domain_atol::Union{Nothing, Real} = nothing)
46-
return MatrixFunctionViaEigh(eigh_alg, domain_atol)
43+
domain_atol::Float64 # negative value for runtime defaults
4744
end
45+
MatrixFunctionViaEigh(eigh_alg::AbstractAlgorithm; domain_atol::Real = -1.0) =
46+
MatrixFunctionViaEigh(eigh_alg, Float64(domain_atol))
4847
function Base.show(io::IO, alg::MatrixFunctionViaEigh)
4948
print(io, "MatrixFunctionViaEigh(")
5049
_show_alg(io, alg.eigh_alg)
51-
isnothing(alg.domain_atol) || print(io, "; domain_atol=", alg.domain_atol)
50+
alg.domain_atol < 0 || print(io, "; domain_atol=", alg.domain_atol)
5251
return print(io, ")")
5352
end
5453

@@ -62,16 +61,15 @@ For matrix functions with a restricted domain (e.g. [`squareroot`](@ref) and [`l
6261
as rounding artifacts and clamped to the domain boundary, with `nothing` denoting the default
6362
tolerance [`default_domain_atol`](@ref).
6463
"""
65-
struct MatrixFunctionViaEig{A <: AbstractAlgorithm, T <: Union{Nothing, Real}} <: AbstractAlgorithm
64+
struct MatrixFunctionViaEig{A <: AbstractAlgorithm} <: AbstractAlgorithm
6665
eig_alg::A
67-
domain_atol::T
68-
end
69-
function MatrixFunctionViaEig(eig_alg::AbstractAlgorithm; domain_atol::Union{Nothing, Real} = nothing)
70-
return MatrixFunctionViaEig(eig_alg, domain_atol)
66+
domain_atol::Float64 # negative value for runtime defaults
7167
end
68+
MatrixFunctionViaEig(eig_alg::AbstractAlgorithm; domain_atol::Real = -1.0) =
69+
MatrixFunctionViaEig(eig_alg, Float64(domain_atol))
7270
function Base.show(io::IO, alg::MatrixFunctionViaEig)
7371
print(io, "MatrixFunctionViaEig(")
7472
_show_alg(io, alg.eig_alg)
75-
isnothing(alg.domain_atol) || print(io, "; domain_atol=", alg.domain_atol)
73+
alg.domain_atol < 0 || print(io, "; domain_atol=", alg.domain_atol)
7674
return print(io, ")")
7775
end

0 commit comments

Comments
 (0)