user112495
user112495

Reputation: 254

Pseudo-inverse not producing correct output

I have a number of 2x2 matrices that I want to invert. When using pinv (either numpy pinv, scipy pinv, or scipy pinv2), for some of them I get an answer with elements of the order -30, which is much smaller than they should be. The matrix has a large (so non-zero) determinant, so it is invertible. If I use scipy.linalg.inv, it works fine. The matrices are all fairly similar, and the majority of them work fine with pinv.

Does anyone know what could be happening here?

Edit: Sorry, forgot to include an example. If I take

A = [[1e2, -1.6e9], [-1.6e9, 3e16]]

then using np.linalg.inv gives [6.81e-2, 3.63e-9; 3.63e-9, 2.27e-16], while np.linalg.pinv gives [9.48e-32, -1.77e-24; -1.77e-24, 3.33e-17].

import numpy as np
A = np.matrix([[1e2, -1.6e9], [-1.6e9, 3e16]])
print(np.linalg.pinv(A))
print(np.linalg.inv(A))

Upvotes: 0

Views: 697

Answers (1)

Bob
Bob

Reputation: 14654

The problem is that the matrix has very different singular values

np.linalg.svd(A)[1]
[3.00000000e+16, 1.46666666e+01]

And pinv has a rcond=1e-15 by default, that decides decides if a singular value must or must not be included. You could simply increase the rcond

np.linalg.pinv(A, rcond=1e-20) @ A
matrix([[ 9.99999996e-01,  2.06089933e-01],
        [-1.93556853e-16,  1.00000001e+00]])

That solves your immediate problem, but you may have to check how these ill-conditioned matrices will impact the final result.

Upvotes: 3

Related Questions