Compute the rank of a matrix A in simple way, based on the SVD, svd(), and “the same as Matlab”.

rankMM(A, tol = NULL, sv = svd(A, 0, 0)$d)

Arguments

A

a numerical matrix, maybe non-square. When sv is specified, only dim(A) is made use of.

tol

numerical tolerance (compared to singular values). By default, when NULL, the tolerance is determined from the maximal value of sv and the computer epsilon.

sv

vector of non-increasing singular values of A, (to be passed if already known).

See also

There are more sophisticated proposals for computing the rank of a matrix; for a couple of those, see rankMatrix in the Matrix package.

Value

an integer from the set 0:min(dim(A)).

Author

Martin Maechler, Date: 7 Apr 2007

Examples

rankMM # - note the simple function definition
#> function (A, tol = NULL, sv = svd(A, 0, 0)$d) 
#> {
#>     d <- dim(A)
#>     stopifnot(length(d) == 2, length(sv) == min(d), min(d) >= 
#>         1L, all(diff(sv) <= 0))
#>     if (is.null(tol)) 
#>         tol <- max(d) * .Machine$double.eps * abs(sv[1L])
#>     else stopifnot(is.numeric(tol), tol >= 0)
#>     sum(sv >= tol)
#> }
#> <bytecode: 0x5654ff7ec8f8>
#> <environment: namespace:robustbase>

hilbert <- function(n) { i <- seq_len(n); 1/outer(i - 1L, i, "+") }
hilbert(4)
#>           [,1]      [,2]      [,3]      [,4]
#> [1,] 1.0000000 0.5000000 0.3333333 0.2500000
#> [2,] 0.5000000 0.3333333 0.2500000 0.2000000
#> [3,] 0.3333333 0.2500000 0.2000000 0.1666667
#> [4,] 0.2500000 0.2000000 0.1666667 0.1428571
H12 <- hilbert(12)
rankMM(H12)        # 11 - numerically more realistic
#> [1] 11
rankMM(H12, tol=0) # -> 12
#> [1] 12
## explanation :
round(log10(svd(H12, 0,0)$d), 1)
#>  [1]   0.3  -0.4  -1.3  -2.4  -3.6  -5.0  -6.4  -7.9  -9.6 -11.5 -13.6 -16.0