[英]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.