I am trying to calculate the rank of a large (182 x 182) matrix. As a test, I put
from numpy import linalg as LA
# Some other code ...
# R is a 182 x 182 matrix
det = LA.det(R)
print('|R|:')
print(det) # Prints out 1.528938248893958e-29
tol = 10*det
rank = LA.matrix_rank(R, 10*det)
print('Rank of R:')
print(rank) # Prints out 182!
So this calculates the determinant of R, multiplies this by 10 (so it is obviously greater than the determinant) and passes this value as the tolerance to matrix_rank. However, this prints out 182 (the size of the matrix), which I do not understand. I am expecting matrix_rank to give the number of singularities greater than the tolerance. Since the determinate of the entire matrix (which is a singularity of the matrix) is smaller than this, I would expect to get less than 182.
Could anyone shed any light on this for me? Am I doing something wrong / misunderstood something or is this some kind of bug?
The matrix rank uses singular value decomposition, if you want to make sure your matrix will be considered with incomplete rank your tolerance should be calculated like this
_, s, _ = LA.svd(R)
tol = np.min(abs(s)) * 10;