我尝试在python中实现高斯消除。
我希望使用numpy比纯python更快。
因此,可以理解“向后淘汰”的结果。
当我在“ Forward Elimination”中使用100X100矩阵时,numpy比纯python更快。
但是,当我使用1000X1000矩阵时,“向前消除”没有意义。
为什么numpy比纯python慢?
这让我感到困惑。
实施
def foward_elimination(A, b):
A = A.copy().astype(np.float64); b = b.copy().astype(np.float64)
for i_pivot in range(len(A)-1):
for j_target in range(i_pivot+1, len(A)):
b[j_target] = b[j_target] - (A[j_target,i_pivot] / A[i_pivot,i_pivot] * b[i_pivot])
A[j_target] = A[j_target] - (A[j_target,i_pivot] / A[i_pivot,i_pivot] * A[i_pivot])
return A, b
def backward_elimination(A, b):
b = b.copy()
for i in range(len(A)-1, -1, -1):
for j in range(len(A)-1, i, -1):
b[i] -= A[i,j]*b[j]
b[i] = b[i] / A[i,i]
return b
def custom_foward_elimination(A, b):
A = A.copy().astype(np.float64); b = b.copy().astype(np.float64)
for i_pivot in range(len(A)-1):
b[i_pivot+1:] = b[i_pivot+1:] - (A[i_pivot+1:,i_pivot] / A[i_pivot,i_pivot] * b[i_pivot])
A[i_pivot+1:] = A[i_pivot+1:] - (A[i_pivot+1:,i_pivot].reshape(-1,1).repeat(len(A), axis=1) / A[i_pivot,i_pivot] * A[i_pivot])
return A, b
def custom_backward_elimination(A, b):
sol = np.ones(len(A))
for i in np.arange(len(A)-1, -1, -1):
sol[i] = (b[i] - (A[i]*sol)[i+1:].sum()) / A[i, i]
def gauss_solve(A, b):
A_foward, b_foward = foward_elimination(A, b)
sol = backward_elimination(A_foward, b_foward)
return sol
def custom_gauss_solve(A, b):
A_foward, b_foward = custom_foward_elimination(A, b)
sol = custom_backward_elimination(A_foward, b_foward)
return sol
测试(在Google colab中)
for n in [2,5,10,100,1000]:
A = np.random.rand(n,n)
b = np.random.rand(n)
print('=== {} Dimension ==='.format(n))
print('- Forward Elimination -')
%timeit -n 30 -r 1 forward_elimination(A, b)
print('- Forward Elimination (Using numpy) -')
%timeit -n 30 -r 1 custom_foward_elimination(A, b)
A_forward, b_forward = forward_elimination(A, b)
print('- Backward Elimination -')
%timeit -n 30 -r 1 backward_elimination(A_forward, b_forward)
print('- Backward Elimination (Using numpy) -')
%timeit -n 30 -r 1 custom_backward_elimination(A_forward, b_forward)
print()
结果
=== 2 Dimension ===
- Forward Elimination -
30 loops, best of 1: 14.2 µs per loop
- Forward Elimination (Using numpy) -
30 loops, best of 1: 37.5 µs per loop
- Backward Elimination -
30 loops, best of 1: 8.84 µs per loop
- Backward Elimination (Using numpy) -
30 loops, best of 1: 15.7 µs per loop
=== 5 Dimension ===
- Forward Elimination -
30 loops, best of 1: 58.6 µs per loop
- Forward Elimination (Using numpy) -
30 loops, best of 1: 52.6 µs per loop
- Backward Elimination -
30 loops, best of 1: 21.6 µs per loop
- Backward Elimination (Using numpy) -
30 loops, best of 1: 52 µs per loop
=== 10 Dimension ===
- Forward Elimination -
30 loops, best of 1: 178 µs per loop
- Forward Elimination (Using numpy) -
30 loops, best of 1: 109 µs per loop
- Backward Elimination -
30 loops, best of 1: 57.8 µs per loop
- Backward Elimination (Using numpy) -
30 loops, best of 1: 51.8 µs per loop
=== 100 Dimension ===
- Forward Elimination -
30 loops, best of 1: 18.3 ms per loop
- Forward Elimination (Using numpy) -
30 loops, best of 1: 4.05 ms per loop
- Backward Elimination -
30 loops, best of 1: 2.53 ms per loop
- Backward Elimination (Using numpy) -
30 loops, best of 1: 447 µs per loop
=== 1000 Dimension ===
- Forward Elimination -
30 loops, best of 1: 2.48 s per loop
- Forward Elimination (Using numpy) -
30 loops, best of 1: 4.42 s per loop ### ????
- Backward Elimination -
30 loops, best of 1: 257 ms per loop
- Backward Elimination (Using numpy) -
30 loops, best of 1: 5.51 ms per loop