按照标题,当第一个参数是函数时,我正在寻找与MATLAB lsqr()等效的Python(可能在NumPy / SciPy中)。

简而言之,lsqr用数值方法为x解决以下问题:

argmin_x || A*x - b ||_2


其中xb是向量(可能具有不同的大小),而A是线性运算符。

我相信对于数字输入,等效值为numpy.linalg.lstsq()

函数scipy.optimize.least_squares()原则上可以用于解决argmin问题,但是似乎它在内部使用了不同的算法(并且速度较慢),这似乎不适合在相对较大的输入上进行优化。

我相信lsqr()在内部使用A*xA'*b,不需要明确表示A

那么,有没有等同于MATLAB的lsqr(第一个参数为函数)?

最佳答案

对于大而稀疏的输入(无论如何,这都是lsqr的用例),MATLAB的lsqr的Python / SciPy等效项是:

scipy.sparse.linalg.lsqr()


该函数的第一个参数可以是scipy.sparse.linalg.LinearOperator(),它是线性运算符的代理,其中必须提供A*xA'*b'是转置运算符)作为与matvec和(分别)。

最终可以将其用于计算rmatvec,其中lsqr未被明确知道。

例如:

def Ax(x):
    """Returns A*x"""
    ...

def Atb(b):
    """Returns A'*b"""
    ...

A = scipy.sparse.linalg.LinearOperator((m,n), matvec=Ax, rmatvec=Atb)
result = scipy.sparse.linalg.lsqr(A, b)


请注意,AMATLABPython文档均指示计算了lsqr(在Python中更精确地为A'*x,但含义相同),但这不是(也不能)正确。

Python和MATLAB实现之间存在一个重要区别:


MATLAB:A^T x的第一个参数似乎是afun,与是否调用xafun(x,'notransp')无关,并且必须以不同的方式获取afun(x,'transp')
Python:第一个参数是bx,这取决于分别调用了b还是A.matvec()


(这是基于来自@AnderBiguri和A.rmatvec() source code的非常有用的答案)。

09-26 15:04