Skip to content

Commit f64463d

Browse files
LilithHafnerfredrikekrestevengj
authored
Document numerical error in rank (#48127)
Co-authored-by: Daniel Karrasch <@dkarrasch> Co-authored-by: Fredrik Ekre <[email protected]> Co-authored-by: Steven G. Johnson <[email protected]>
1 parent 12d329b commit f64463d

File tree

1 file changed

+13
-4
lines changed

1 file changed

+13
-4
lines changed

stdlib/LinearAlgebra/src/generic.jl

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -947,13 +947,22 @@ dot(x::AbstractVector, transA::Transpose{<:Real}, y::AbstractVector) = adjoint(d
947947
rank(A::AbstractMatrix; atol::Real=0, rtol::Real=atol>0 ? 0 : n*ϵ)
948948
rank(A::AbstractMatrix, rtol::Real)
949949
950-
Compute the rank of a matrix by counting how many singular
951-
values of `A` have magnitude greater than `max(atol, rtol*σ₁)` where `σ₁` is
952-
`A`'s largest singular value. `atol` and `rtol` are the absolute and relative
950+
Compute the numerical rank of a matrix by counting how many outputs of
951+
`svdvals(A)` are greater than `max(atol, rtol*σ₁)` where `σ₁` is `A`'s largest
952+
calculated singular value. `atol` and `rtol` are the absolute and relative
953953
tolerances, respectively. The default relative tolerance is `n*ϵ`, where `n`
954954
is the size of the smallest dimension of `A`, and `ϵ` is the [`eps`](@ref) of
955955
the element type of `A`.
956956
957+
!!! note
958+
Numerical rank can be a sensitive and imprecise characterization of
959+
ill-conditioned matrices with singular values that are close to the threshold
960+
tolerance `max(atol, rtol*σ₁)`. In such cases, slight perturbations to the
961+
singular-value computation or to the matrix can change the result of `rank`
962+
by pushing one or more singular values across the threshold. These variations
963+
can even occur due to changes in floating-point errors between different Julia
964+
versions, architectures, compilers, or operating systems.
965+
957966
!!! compat "Julia 1.1"
958967
The `atol` and `rtol` keyword arguments requires at least Julia 1.1.
959968
In Julia 1.0 `rtol` is available as a positional argument, but this
@@ -981,7 +990,7 @@ function rank(A::AbstractMatrix; atol::Real = 0.0, rtol::Real = (min(size(A)...)
981990
isempty(A) && return 0 # 0-dimensional case
982991
s = svdvals(A)
983992
tol = max(atol, rtol*s[1])
984-
count(x -> x > tol, s)
993+
count(>(tol), s)
985994
end
986995
rank(x::Union{Number,AbstractVector}) = iszero(x) ? 0 : 1
987996

0 commit comments

Comments
 (0)