【问题标题】:Python equivalent of MATLAB's lsqr() with first argument a functionPython 等效于 MATLAB 的 lsqr(),第一个参数是一个函数
【发布时间】:2018-07-15 05:46:24
【问题描述】:

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

简而言之,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 等效项(第一个参数是函数)?

【问题讨论】:

    标签: python matlab numpy scipy mathematical-optimization


    【解决方案1】:

    显然在 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 是矩阵大小。

    【讨论】:

    • 这看起来是朝着正确的方向发展,但我对如何准确地使用它有点困惑。我必须进行一些测试,然后我会报告结果。
    • @norok2 你有什么困惑?
    • 主要是 MATLAB 文档 de.mathworks.com/help/matlab/ref/lsqr.html :那里说 A 可以是 mxn,但随后要求函数返回 A*xA'*x,但这如果A 不是正方形,则不可能,除非x 意味着两个不同的东西——这让我很困惑。
    • @norok2 你对 MATLAB 的 fucntion 或 pythons 函数感到困惑吗?首先,LSQR 我不是方阵的一种方法,如果您的矩阵是方阵,请不要使用它。其次,MATLAB 需要一个可以称为afun(x,'notransp')afun(x,'transp') 的函数,因此它返回2 个不同的矩阵。与蟒蛇相同。很有可能,虽然从编程上讲你需要返回A'*x,但从数学上讲它是A'*b,它与x不一样A*x
    • 我喜欢mrpotato,这可能是文档的更好选择。关键是afunLinearOperator之间有一个重要的区别: (1)在MATLAB中,afun的第一个参数实际上总是x所以,最终b必须取自其他地方; (2)在Python中,LinearOperator.matvecLinearOperator.rmatvec的第一个参数实际上是不同的(matvecxrmatvecb!)。我认为这是值得注意的。除此之外,MATLAB 和 Python 中的文档都令人困惑。阿门。
    【解决方案2】:

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

    scipy.sparse.linalg.lsqr()
    

    此函数的第一个参数可以是scipy.sparse.linalg.LinearOperator(),它是线性运算符的代理,其中A*xA'*b'是转置运算符)必须作为与@987654331对应的可调用对象提供@ 和 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)
    

    请注意,lsqrMATLABPython 文档都表明 A'*x(更准确地说是 A^T x 在 Python 的情况下,但含义相同)被计算,但这不是(和不可能)正确。

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

    • MATLABafun 的第一个参数似乎是x,与调用afun(x,'notransp')afun(x,'transp') 无关,而且b 的获取方式必须不同。
    • Python:第一个参数是xb,取决于是调用A.matvec() 还是A.rmatvec()(分别)。

    (这是基于@AnderBiguri 和scipy.sparse.linalg.lsqr() source code 提供的非常丰富的答案。

    【讨论】:

      猜你喜欢
      • 2013-03-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-08
      • 2022-11-17
      • 1970-01-01
      • 2018-10-31
      相关资源
      最近更新 更多