-
-
Notifications
You must be signed in to change notification settings - Fork 5.4k
scipy.linalg.pinv gives wrong result while scipy.linalg.pinv2 works #8861
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
I don't know the reasons but probably they are historical artifacts. I will change the cutoff values and ask over the mailing list. Actually it is the pinv2 values that should be kept but pinv doesn't push the condition number to lstsq hence the factors are lost. |
Starting from scipy 1.7.0 ,
That means, import numpy as np
import scipy
arr = np.random.rand(1000, 2000)
res1 = np.linalg.pinv(arr)
res2 = scipy.linalg.pinv(arr)
res3 = scipy.linalg.pinv2(arr)
np.testing.assert_array_almost_equal(res1, res2, decimal=10)
np.testing.assert_array_almost_equal(res1, res3, decimal=10) |
For a student project with finite differences we use the pseudo inverse. Here, we noticed large differences in the accuracy of
scipy.linalg.pinv
andscipy.linalg.pinv2
: while the latter works just fine, the first produces useless pseudo inverses in this example, see the code below.As far as I understand,
pinv
usesscipy.linalg.lstsq
to minimize | e^i - A x^i |_2 for the i-th unit vector e^i in order to obtain the pseudo inverse X, whereaspinv
directly uses a truncated singular value decomposition.However, internally
lstsq
uses the LAPACK routinegelss
which solves the minimization also using a singular value decomposition, see e. g. http://www.netlib.org/lapack/lug/node27.html .The reason why
pinv
fails for the example below whilepinv2
doesn't results from the fact, that the standard cut-off threshold for the small singular values inpinv2
is set to1e6*eps
(for double), whereaspinv
useseps*max(n,m)
ifA
is ann
xm
matrix, which is much smaller for the matrix in our example.Now I wonder why
pinv
andpinv2
use different cut-off thresholds as standard values. If I use the standard value ofpinv2
forpinv
, see comment in example code, the results are about the same.Moreover, I wonder why the least squares solver is namend
pinv
and the classical method is calledpinv2
. In my opinion it might by better to switch them.Since in the end, both use a truncated singular value decomposition, I do not completely understand the fundamental need of both.
Reproducing code example:
Output:
Scipy/Numpy/Python version information:
The text was updated successfully, but these errors were encountered: