【发布时间】:2016-11-21 12:24:48
【问题描述】:
我似乎无法从 scipy 的 CG 和稀疏矩阵算法中获益。
当我尝试求解这个带状矩阵方程时
import time
import scipy.sparse.linalg as ssla
import scipy.sparse as ss
import numpy as np
size = 3000
x = np.ones(size)
A = ss.diags([1, -2, 1], [-1, 0, 1], shape=[size, size]).toarray()
print 'cond. nr.:{}'.format(np.linalg.cond(A))
b = np.dot(A, x)
start_time = time.clock()
sol = np.linalg.solve(A, b)
elapsed_time = time.clock() - start_time
error = np.sum(np.abs(sol - x))
print 'LU time, error:', elapsed_time, error
start_time = time.clock()
sol, info = ssla.bicg(A, b, tol=1e-12)
elapsed_time = time.clock() - start_time
error = np.sum(np.abs(sol - x))
print 'CG time, ret code, error:', elapsed_time, info, error
它所花费的时间大约是 LU 求解器的 20 倍。据我了解,CG 并不比 LU 贵多少,即使它必须使用所有 N 次迭代才能达到结果。所以我预计它至少会一样快,但实际上要快得多,因为先验知识是关于带状的。是不是跟条件数这么差有关系?
在密集矩阵的情况下
import time
import scipy.sparse.linalg as ssla
import numpy as np
import matplotlib.pyplot as plt
size = 1000
x = np.ones(size)
np.random.seed(1)
A = np.random.random_integers(-size, size,
size=(size, size))
print 'cond. nr.:{}'.format(np.linalg.cond(A))
b = np.dot(A, x)
start_time = time.clock()
sol = np.linalg.solve(A, b)
elapsed_time = time.clock() - start_time
error = np.sum(np.abs(sol - x))
print 'LU time, error:', elapsed_time, error
start_time = time.clock()
sol, info = ssla.bicg(A, b, tol=1e-12)
elapsed_time = time.clock() - start_time
error = np.sum(np.abs(sol - x))
print 'CG time, ret code, error:', elapsed_time, info, error
我根本没有收敛。在这种情况下,A的条件数似乎并没有那么大,但是我对这种事情没有太多经验。
【问题讨论】:
-
收敛还取决于您选择的初始猜测。如果您碰巧选择了正确的答案作为起点,您将在一次迭代中收敛;做出一个糟糕的选择,你可能需要更多的迭代。这不仅仅是关于矩阵及其条件。
-
(1000, 1000)矩阵非常小。尝试更大更稀疏的东西。 -
在我的第二个示例中将 x0=x 添加到 bicg 调用并不能解决问题。将大小减小到 10 时,我使用 bicg 得到一个有效结果,而无需开始猜测。添加 x0=x 给我一个错误的解决方案。我做错了什么?
标签: scipy sparse-matrix