当A是条带化矩阵时,如何使用scipy.linalg.solve_banded求解Ax = b?

时间:2018-10-01 06:04:11

标签: python scipy linear-algebra

求解线性方程组

Ax=b

其中A是类似的条纹矩阵

image

有5个非零对角线。

但是不同于带状矩阵,A具有三个非零对角线,其偏移量分别为0,-1和1,两个非零对角线的偏移量分别为-m和m。

我尝试直接用

解决
diagonals = [Ap, As, An, Aw, Ae]
A = diags(diagonals, [0, -1, 1, -m, m]).toarray()
x = linalg.solve(A, b)

此方法创建了整个A。但是A是多余的,因此该方法浪费了太多内存来保存零元素。

所以我尝试使用solve_banded

A = np.zeros((2 * m + 1, len(initial)))
A[0] = Ae
A[m - 1] = An
A[m] = Ap
A[m + 1] = As
A[2 * m] = Aw
x = linalg.solve_banded((m, m), A, b)

此方法比以前的方法花费更少的内存,但仍然浪费了(2m-4)个零向量。有没有更聪明的方法只使用五个非零向量?

1 个答案:

答案 0 :(得分:1)

嘿,我可以部分回答这个问题。为了减少内存存储,您可以通过保留to.array()命令来保持稀疏矩阵形式,而不必将其变成大矩阵:

A = diags(diagonals, [0, -1, 1, -m, m])

现在稀疏矩阵具有自己的spsolve方法,因此scipy.sparse.linalg.spsolve(A,b)将起作用。

要进一步提高性能,您可以sparse.linalg.splu(A).solve(b)通过LU分解转换A,然后SuperLU对象再次具有solve方法。 (如我所测试的,此方法比直接使用spsolve的方法略快一些,solve_banded也使用类似LU的分解。例如,请参见here。)

这里唯一的问题是在LU分解过程中,由于分解,内存使用量也会很大。

我还想知道是否有任何方法可以用稀疏矩阵来合成time.clock()方法,因为没有固有的方法。