为什么numpy比纯python慢​​?

时间:2019-04-25 03:17:47

标签: python numpy math

我尝试在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

0 个答案:

没有答案