Although the question has a great answer, here's
a rule of thumb for small singular values, with a plot.
If a singular value is nonzero but very small,
you should define its reciprocal to be zero,
since its apparent value is probably an artifact of roundoff error, not a meaningful number.
A plausible answer to the question "how small is small ?"
is to edit in this fashion all singular values whose ratio to the largest
is less than $N$ times the machine precision $\epsilon$ .
$\qquad$ — Numerical Recipes p. 795
Added: the following couple of lines calculate this rule-of-thumb.
#!/usr/bin/env python2
from __future__ import division
import numpy as np
from scipy.sparse.linalg import svds # sparse, dense or LinOp
#...............................................................................
def howsmall( A, singmax=None ):
""" singular values < N float_eps sing_max may be iffy, questionable
"How small is small ?"
[Numerical Recipes p. 795](http://apps.nrbook.com/empanel/index.html?pg=795)
"""
# print "%d singular values are small, iffy" % (sing < howsmall(A)).sum()
# small |eigenvalues| too ?
if singmax is None:
singmax = svds( A, 1, return_singular_vectors=False )[0] # v0=random
return max( A.shape ) * np.finfo( A.dtype ).eps * singmax
The Hilbert matrix seems to be widely used as a test case for roundoff error:

Here low-order bits in the mantissas of the Hilbert matrix are zeroed,
A.astype(np.float__).astype(np.float64)
,
then np.linalg.svd
is run in float64
.
(Results with svd
all float32
are about the same.)
Simply truncating to float32
might even be useful for denoising high-dimensional data,
e.g. for train / test classification.
Real test cases would be welcome.