簡體   English   中英

計數算術運算

[英]Counting arithmetic operations

有沒有辦法計算函數/表達式中的數字運算(+、-、/、*)的數量?

例如,讓我們考慮一個簡單的線性代數問題 ( Ax = b ):

A_data = np.array([[1, -4, 1],
                  [1, 6, -1],
                  [2, -1, 2]], dtype=float)

b_data = np.array([[7],
                  [13],
                  [5]], dtype=float)

接下來,讓我們應用高斯消元程序:

def gauss_elim(A, b):
    Ab = np.column_stack((A, b))
    for k, pivot_row in enumerate(Ab[:-1]):
        for row in Ab[k+1:]:
            if pivot_row[k] != 0:
                row[k:] = row[k:] - pivot_row[k:] * row[k]/pivot_row[k]
    return Ab

結果是:

array([[  1. ,  -4. ,   1. ,   7. ],
       [  0. ,  10. ,  -2. ,   6. ],
       [  0. ,   0. ,   1.4, -13.2]])

我如何計算操作數?

注意:我知道可以事先用數學方法評估運算次數(即對於高斯消去法,它是 O(n^3))。

我假設您正在嘗試降低此處的復雜性以提高性能。 這篇文章中列出了一種通過broadcasting殺死Gauss-elimination內循環的方法,為我們提供了一個部分矢量化的解決方案,就像這樣 -

# Concatenate A and b into a single 2D array
Ab = np.concatenate((A,b),axis=1)

for k, pivot_row in enumerate(Ab[:-1]):

    # Vectorized broadcasting magic happens here : 
    # Calculate offsets corresponding to "pivot_row[k:] * row[k]/pivot_row[k]" 
    offsets = (Ab[k+1:,k][:,None] * pivot_row[k:])/pivot_row[k]

    # Update each row
    Ab[k+1:,k:] -= offsets

運行時測試並驗證輸出 -

In [137]: def partvect_gauss_elim(A,b):
     ...:     Ab = np.concatenate((A,b),axis=1)
     ...:     for k, pivot_row in enumerate(Ab[:-1]):
     ...:         offsets = (Ab[k+1:,k][:,None] * pivot_row[k:])/pivot_row[k]
     ...:         Ab[k+1:,k:] -= offsets
     ...:     return Ab
     ...: 
     ...: def original_gauss_elim(A,b):
     ...:     Ab = np.concatenate((A,b),axis=1)
     ...:     for k, pivot_row in enumerate(Ab[:-1]):
     ...:         for row in Ab[k+1:]:
     ...:             if pivot_row[k] != 0:
     ...:                 row[k:] = row[k:] - pivot_row[k:] * row[k]/pivot_row[k]
     ...:     return Ab
     ...: 

In [138]: A = np.random.randint(0,9,(50,50))
     ...: b = np.random.randint(0,9,(50,1))
     ...: 

In [139]: np.allclose(original_gauss_elim(A,b),partvect_gauss_elim(A,b))
Out[139]: True

In [140]: %timeit original_gauss_elim(A,b)
100 loops, best of 3: 12.1 ms per loop

In [141]: %timeit partvect_gauss_elim(A,b)
100 loops, best of 3: 2.56 ms per loop

如果你能花一點時間,應該有一種方法:創建一個數字類並覆蓋基本的算術方法: __add____mul____sub____div__通過在其中嵌入一個計數器系統(例如與某些全局變量相關) )。 然后,您應該能夠通過使用dtype=object參數(在創建數組時)強制 Numpy 使用您的類型,以確保 Numpy 不會將您的數字轉換為任何其他類型。 我有時會為了更簡單的任務而這樣做; 我從來沒有用 Numpy 做過,但它應該可以工作。 希望它能有所幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM