Numpy非常适合通过矢量化来加速代码。但是,当进行诸如Gauss-Seidel method之类的隐式迭代方程求解方法时,则数组的元素n+1
依赖于n
的前几个元素,从而阻止了矢量化。
我已经像这样实现了高斯塞德尔:
def gaussSeidel(A, b, x0, tol = 1e-10):
n = len(A)
x = np.copy(x0)
k = 0
while (True):
print(k)
for i in range(n):
x[i] = (b[i] - np.delete(A[i], i) @ np.delete(x, i)) / A[i, i]
if max(abs(x - x0)) < tol:
return x
x0 = np.copy(x)
k += 1
这种方式比像Jacobi方法那样的显式版本慢
def jacobi(A, b, x0, tol = 1e-10):
n = len(A)
M = np.copy(A)
DInv = np.zeros((n, n))
k = 0
for i in range(n):
DInv[i, i] = 1 / M[i, i]
M[i, i] = 0
while (True):
x = DInv @ (b - M @ x0)
if max(abs(x - x0)) < tol:
return x
x0 = x
k += 1
print(max(abs(x - x0)))
据我所知,这里不可能消除for循环,但这是加快速度的一种方法吗?
答案 0 :(得分:0)
某些可能会有所帮助的方法是将if-test移到后续循环之外
s = b[i]
for j in range(n):
if i == j:
continue
s -= A[i, j] * x[j]
与
相同 s = b[i] + A[i, i] * x[i]
for j in range(n):
s -= A[i, j] * x[j]
这样就避免了n次if-tests。
另一种可以尝试的方法是numba软件包,该软件包可以即时编译您的代码,而无需外部编译步骤。