Python 相当于 MATLAB 的 lsqr(),第一个参数是一个函数
Python equivalent of MATLAB's lsqr() with first argument a function
根据标题,当第一个参数是函数时,我正在寻找与 MATLAB 的 lsqr()
(可能在 NumPy / SciPy 中)等效的 Python。
简而言之,lsqr
解决了 x
以下问题的数值:
argmin_x || A*x - b ||_2
其中 x
和 b
是向量(可能大小不同),A
是线性运算符。
我认为对于数字输入来说,等价于 numpy.linalg.lstsq()
。
函数scipy.optimize.least_squares()
原则上可以用于解决argmin问题,但它似乎在内部使用了不同的(而且慢得多)算法,这似乎不适合对相对较大的输入进行优化.
我相信 lsqr()
在内部使用 A*x
和 A'*b
并且不需要 A
.
的明确表示
那么,有没有等同于 MATLAB 的 lsqr
(第一个参数是一个函数)?
显然在 python 的 lsqr
A can also be a LinearOperator
中,这就是您要查找的内容。
函数本身是 scipy.sparse.linalg.LinearOperator,文档本身有很好的示例说明如何使用它。
本质上,您只需创建 2 个函数(我们称它们为 Ax()
和 Atb()
)并创建 A
为:
A = LinearOperator((m,n), matvec=Ax, rmatvec=Atb)
其中 m,n
是矩阵大小。
对于大而稀疏的输入(这将是 lsqr
的用例),Python / SciPy 等价于 MATLAB 的 lsqr
是:
scipy.sparse.linalg.lsqr()
此函数的第一个参数可以是 scipy.sparse.linalg.LinearOperator()
,它是线性运算符的代理,其中 A*x
和 A'*b
('
是转置运算符)必须作为对应于 matvec
和 rmatvec
(分别)的可调用对象提供。
这最终可用于计算 lsqr
,其中 A
未明确知道。
例如:
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)
请注意,lsqr
的两个 MATLAB and Python 文档都表明 A'*x
(在 Python 的情况下更准确地说是 A^T x
,但具有相同的含义) 被计算出来,但这不(也不可能)正确。
如果事实上他们都使用 x
作为静音变量(与 Ax = b
命名无关),但他们实际上都使用 b
.
Python 和 MATLAB 实现之间存在重要区别:
- MATLAB:提供了一个函数,它需要根据
afun
的第二个参数计算A*x
或A'*b
( afun(x,'notransp')
或 afun(x,'transp')
。
- Python:两个函数分别提供,第一个参数是
x
或b
,具体取决于是否调用 A.matvec()
或 A.rmatvec()
(分别)。
(这是基于@AnderBiguri 和 scipy.sparse.linalg.lsqr()
source code 提供的信息丰富的答案)。
根据标题,当第一个参数是函数时,我正在寻找与 MATLAB 的 lsqr()
(可能在 NumPy / SciPy 中)等效的 Python。
简而言之,lsqr
解决了 x
以下问题的数值:
argmin_x || A*x - b ||_2
其中 x
和 b
是向量(可能大小不同),A
是线性运算符。
我认为对于数字输入来说,等价于 numpy.linalg.lstsq()
。
函数scipy.optimize.least_squares()
原则上可以用于解决argmin问题,但它似乎在内部使用了不同的(而且慢得多)算法,这似乎不适合对相对较大的输入进行优化.
我相信 lsqr()
在内部使用 A*x
和 A'*b
并且不需要 A
.
那么,有没有等同于 MATLAB 的 lsqr
(第一个参数是一个函数)?
显然在 python 的 lsqr
A can also be a LinearOperator
中,这就是您要查找的内容。
函数本身是 scipy.sparse.linalg.LinearOperator,文档本身有很好的示例说明如何使用它。
本质上,您只需创建 2 个函数(我们称它们为 Ax()
和 Atb()
)并创建 A
为:
A = LinearOperator((m,n), matvec=Ax, rmatvec=Atb)
其中 m,n
是矩阵大小。
对于大而稀疏的输入(这将是 lsqr
的用例),Python / SciPy 等价于 MATLAB 的 lsqr
是:
scipy.sparse.linalg.lsqr()
此函数的第一个参数可以是 scipy.sparse.linalg.LinearOperator()
,它是线性运算符的代理,其中 A*x
和 A'*b
('
是转置运算符)必须作为对应于 matvec
和 rmatvec
(分别)的可调用对象提供。
这最终可用于计算 lsqr
,其中 A
未明确知道。
例如:
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)
请注意,lsqr
的两个 MATLAB and Python 文档都表明 A'*x
(在 Python 的情况下更准确地说是 A^T x
,但具有相同的含义) 被计算出来,但这不(也不可能)正确。
如果事实上他们都使用 x
作为静音变量(与 Ax = b
命名无关),但他们实际上都使用 b
.
Python 和 MATLAB 实现之间存在重要区别:
- MATLAB:提供了一个函数,它需要根据
afun
的第二个参数计算A*x
或A'*b
(afun(x,'notransp')
或afun(x,'transp')
。 - Python:两个函数分别提供,第一个参数是
x
或b
,具体取决于是否调用A.matvec()
或A.rmatvec()
(分别)。
(这是基于@AnderBiguri 和 scipy.sparse.linalg.lsqr()
source code 提供的信息丰富的答案)。