scipy.sparse.linalg: splu 和 factorized 有什么区别?

scipy.sparse.linalg: what's the difference between splu and factorized?

使用有什么区别

 scipy.sparse.linalg.factorized(A)

 scipy.sparse.linalg.splu(A)

他们两个 return 对象都具有 .solve(rhs) 方法,并且在文档中说他们使用 LU 分解。我想知道两者在性能上的差异。

更具体地说,我正在编写一个实现动态 FEM 模型的 python/numpy/scipy 应用程序。我需要在每个时间步上求解方程 Au = f。 A 稀疏且相当大,但不依赖于时间步长,所以我想事先投入一些时间来加快迭代速度(可能有数千次)。我尝试使用 scipy.sparse.linalg.inv(A),但是当矩阵的大小很大时它会抛出内存异常。直到最近,我在每个步骤上都使用 scipy.linalg.spsolve,现在我正在考虑使用某种分解来获得更好的性能。所以如果你有除了LU之外的其他建议,欢迎提出!

假设 A 不随每个时间步而改变,它们应该都能很好地解决您的问题。

scipy.sparse.linalg.inv(A) 将 return 一个与 A 大小相同的密集矩阵,因此它会抛出内存异常也就不足为奇了。

scipy.linalg.solve也是一个密集的线性求解器,这不是你想要的。

假设 A 是稀疏的,求解 Au=f 而你只想求解一次 Au=f,你可以使用 scipy.sparse.linalg.spsolve。例如

u = spsolve(A, f)

如果您想大大加快后续求解的速度,您可以使用 scipy.sparse.linalg.factorizedscipy.sparse.linalg.splu。例如

A_inv = splu(A)
for t in range(iterations):
    u_t = A_inv.solve(f_t)

A_solve = factorized(A)
for t in range(iterations):
    u_t = A_solve(f_t)

它们的速度应该相当,并且比以前的选项快得多。

正如@sascha 所说,您需要深入研究文档以了解 splu 和 factorize 之间的区别。但是,如果您已正确安装和设置,则可以使用 'umfpack' 而不是默认值 'superLU'。我认为 umfpack 在大多数情况下会更快。请记住,如果您的矩阵 A 太大或有太多非零值,则 LU 分解/直接求解器可能会在您的系统上占用太多内存。在这种情况下,您可能无法使用迭代求解器,例如 this。不幸的是,您将无法在每个时间步重用 A 的求解,但您可以为 A 找到一个好的预条件子(近似于 inv(A))来提供求解器以加快速度。