rankMM.RdCompute 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)a numerical matrix, maybe non-square. When sv is
specified, only dim(A) is made use of.
numerical tolerance (compared to singular values). By
default, when NULL, the tolerance is determined from the
maximal value of sv and the computer epsilon.
vector of non-increasing singular values of A, (to be
passed if already known).
There are more sophisticated proposals for computing the rank of a
matrix; for a couple of those, see rankMatrix in the
Matrix package.
an integer from the set 0:min(dim(A)).
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