Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions src/qr.jl
Original file line number Diff line number Diff line change
Expand Up @@ -535,6 +535,28 @@ function ldiv!(A::QRCompactWY{T}, B::AbstractMatrix{T}) where {T}
return B
end

"""
rank(A::QRPivoted{<:Any, T}; atol::Real=0, rtol::Real=min(n,m)*ϵ) where {T}

Compute the numerical rank of the QR factorization `A` by counting how many diagonal entries of
`A.factors` are greater than `max(atol, rtol*Δ₁)` where `Δ₁` is the largest calculated such entry.
This is similar to the [`rank(::AbstractMatrix)`](@ref) method insofar as it counts the number of
(numerically) nonzero coefficients from a matrix factorization, although the default method uses an
SVD instead of a QR factorization. Like [`rank(::SVD)`](@ref), this method also re-uses an existing
matrix factorization.

Using a QR factorization to compute rank should typically produce the same result as using SVD,
although it may be more prone to overestimating the rank in pathological cases where the matrix is
ill-conditioned. It is also worth noting that it is generally faster to compute a QR factorization
than it is to compute an SVD, so this method may be preferred when performance is a concern.

`atol` and `rtol` are the absolute and relative tolerances, respectively.
The default relative tolerance is `n*ϵ`, where `n` is the size of the smallest dimension of `A`
and `ϵ` is the [`eps`](@ref) of the element type of `A`.

!!! compat "Julia 1.12"
The `rank(::QRPivoted)` method requires at least Julia 1.12.
"""
function rank(A::QRPivoted; atol::Real=0, rtol::Real=min(size(A)...) * eps(real(float(eltype(A)))) * iszero(atol))
m = min(size(A)...)
m == 0 && return 0
Expand Down