【问题标题】:Efficient solution of linear system Ax= b when only one of the constant term changes线性系统 Ax= b 当只有一个常数项改变时的有效解
【发布时间】:2012-11-01 14:17:52
【问题描述】:

当只有少数常数项发生变化时,如何有效地求解大型线性方程组。例如:

我目前有系统 Ax=b。我计算 A 的逆一次,将其存储在矩阵中,每次 b 中的任何条目更新执行矩阵向量乘法 A^-1(b) 以重新计算 x。

这是低效的,因为只有几个条目会在 b 中更新。当 A-1 保持不变但 b 中特定的已知值发生变化时,是否有更有效的方法来解决这个系统?

我使用 uBlas 和 Eigen,但不知道可以解决选择性重新计算这个问题的解决方案。感谢您的任何指导。

【问题讨论】:

    标签: c++ linear-algebra blas eigen ublas


    【解决方案1】:

    计算A^-1。如果b_ib 的第i 个分量,则检查d/db_i A^-1 b(A^-1 相对于b 的第i 个分量的导数)——它等于A^-1 的列(特别是,第 i 列)。并且线性函数的导数在其域上是常数。因此,如果您有bb',并且它们仅在第i 个组件上有所不同,那么A^-1 b - A^-1 b' = [d/db_i A^-1] * (b-b')_i。对于多个组件,只需将它们相加即可(因为A^-1 是线性的)。

    或者,简而言之,您可以对为零的输入组件进行一些优化来计算A^-1 (b'-b)(如果只有一些组件发生变化,则将是大部分组件)。 A^-1 b' = A^-1 (b'-b) + A^-1 (b)。如果您知道只有某些组件会发生变化,您可以复制A^-1 的相应列,然后将其乘以 b 的该组件的变化。

    【讨论】:

      【解决方案2】:

      你可以利用问题的线性:

      x0 = A_(-1)*b0 
      x = A_(-1)*b = x0 + A_(-1)*db
      

      其中 db 是 bb0 之间的差异矩阵,应该用零填充:您可以将其压缩为稀疏矩阵。

      Eigen lib 有很多很酷的稀疏矩阵函数(乘法、逆矩阵、...)。

      【讨论】:

        【解决方案3】:

        首先,不要执行矩阵求逆,而是使用求解器库。其次,将您的初始 x 作为初步猜测传递给库

        该库将执行某种类似于 LU 的分解,并使用它来计算 x。如果您选择迭代求解器,那么它已经在执行您描述的解决方案的大部分内容;它将从一个更差的猜测开始并产生一个更好的猜测,任何好的例程都需要一个初步的猜测来加速这个过程。在许多情况下,无论如何您都对结果有一个很好的了解,因此利用它是有意义的。

        如果新的b 靠近旧的b,那么新的x 应该靠近旧的x,这将作为一个很好的初步猜测。

        【讨论】:

          【解决方案4】:

          首先,不要计算逆矩阵,而是使用 LU 分解或 QR 分解(比 LU 慢但更稳定)。这种分解在矩阵大小方面比反演性能更好,并且通常更稳定(尤其是 QR)。

          如果 A 发生轻微变化(例如,通过一级矩阵),有一些方法可以更新 QR 分解,但如果 B 发生变化,您必须使用新的 b 再次求解——您无法逃避这一点,这是O(n^2)。

          但是,如果右手边 B 只改变一个固定元素,即。 B' = B + dB 事先知道 dB,你可以一劳永逸地解决 A dx = dB,现在 Ax' = B' 的解决方案 x' 是 x + dX。

          如果事先不知道dB,但总是几个dB_i向量的线性组合,你可以解出A dx_i = dB_i,但是如果你有很多这样的dB_i,你最终会得到一个n^2过程(这在事实上相当于计算逆)...

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2016-06-15
            • 1970-01-01
            • 2016-11-24
            • 2013-06-18
            • 2019-08-14
            • 1970-01-01
            • 2012-10-01
            相关资源
            最近更新 更多