在NumPy或SciPy中有左逆吗?

15

我正在尝试使用numpy或scipy在Python中获取非方阵矩阵的左逆。如何将以下Matlab代码翻译成Python?

>> A = [0,1; 0,1; 1,0]

A =

     0     1
     0     1
     1     0

>> y = [2;2;1]

y =

     2
     2
     1

>> A\y

ans =

    1.0000
    2.0000

是否有numpy或scipy中类似于Matlab左逆运算符\的等价物?


你可能会发现这个链接有用:http://mathesaurus.sourceforge.net/matlab-numpy.html但我不确定它是否能回答这个具体的问题。 - SapphireSun
7个回答

11

由于A不是方阵,因此请使用linalg.lstsq(A,y)。有关详细信息,请参见此处。如果A是方阵,则可以使用linalg.solve(A,y),但在您的情况下不适用。


我正在使用scipy.sparse模块,A是一个稀疏矩阵。如果A是稀疏的,linalg.lstsq(A,y)能正常工作吗? - D R
你可以使用 scipy.linalg.lstsq(A.todense(),y.todense()),但由于速度或内存的原因,这可能不是一个选项。我不确定是否可以直接在稀疏矩阵上使用 lstsq。这个帖子可能会引起你的兴趣:http://mail.scipy.org/pipermail/scipy-user/2008-November/018793.html - Ramashalanka

2

对于那些想要解决大规模稀疏最小二乘问题的人:

我已经将LSQR算法添加到SciPy中。在下一个版本中,您将能够做到以下操作:

from scipy.sparse import csr_matrix
from scipy.sparse.linalg import lsqr
import numpy as np

A = csr_matrix([[0., 1], [0, 1], [1, 0]])
b = np.array([[2.], [2.], [1.]])

lsqr(A, b)

这个代码会返回答案[1, 2]

如果你想使用这个新的功能,但不想升级SciPy,你可以从以下代码库下载lsqr.py

http://projects.scipy.org/scipy/browser/trunk/scipy/sparse/linalg/isolve/lsqr.py


2
这里有一种适用于稀疏矩阵(根据您的评论,这是您想要的)的方法,它使用了来自optimize包的leastsq函数。
from numpy import *
from scipy.sparse import csr_matrix
from scipy.optimize import leastsq
from numpy.random import rand

A=csr_matrix([[0.,1.],[0.,1.],[1.,0.]])
b=array([[2.],[2.],[1.]])

def myfunc(x):
    x.shape = (2,1)
    return (A*x - b)[:,0]

print leastsq(myfunc,rand(2))[0]

生成

[ 1.  2.]

因为我必须根据leastsq要求的方式进行形状匹配,所以这种情况有点丑陋。也许其他人知道如何使其更加整洁。

我还尝试过使用scipy.sparse.linalg中的函数并使用LinearOperators,但没有成功。问题在于所有这些函数都是针对方阵而设计的。如果有人发现了这种方法,请告诉我。


2
您也可以在numpy/scipy中寻找伪逆函数的等效函数pinv,作为其他答案的替代方案。

1
您可以使用矩阵计算来计算左逆:
import numpy as np

linv_A = np.linalg.solve(A.T.dot(A), A.T)

为什么?因为:

enter image description here

)

测试:

np.set_printoptions(suppress=True, precision=3)
np.random.seed(123)

A = np.random.randn(3, 2)
print('A\n', A)

A_linv = np.linalg.solve(A.T.dot(A), A.T)
print('A_linv.dot(A)\n', A_linv.dot(A))

结果:

A
 [[-1.086  0.997]
 [ 0.283 -1.506]
 [-0.579  1.651]]
A_linv.dot(A)
 [[ 1. -0.]
 [ 0.  1.]]

在“因为”的基础上添加:np.linalg.solve()函数可以找到x,使得A.T.dot(A).dot(x)= A.T;将其代入解释中的第二个A.T,则有:inverse(A.T.dot(A)).dot(A.T.dot(A).dot(x)).dot(A)=I;由此可得x.dot(A)=I,即x=inverse(A)。 - Dusch

0

我还没有测试过,但根据这个网页,它是:

linalg.solve(A,y)

2
这正是我所想的,但在Matlab中,只有当A是一个方阵时,\才会这样做。在这种情况下,你必须像Ramashalanka所说的那样使用linalg.lstsq。 - Daniel G

0

你可以使用scipy.sparse.linalg中的lsqr来解决最小二乘稀疏矩阵系统。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接