是否可以加快 NumPy 中的小協方差計算?函式“diff_cov_ridge”在我的程式中被呼叫了數百萬次。
“theta”是標量,“tx”、“ty”、“img1”、“ix1”、“iy1”、“x1”、“y1”、“img2”、“ix2”、“iy2”、“x2” ", "y2" 是長度為 n 的向量。
def cov(a, b):
return np.cov(a, b)[0, 1]
def diff_cov_ridge(theta, tx, ty, img1, ix1, iy1, x1, y1, img2, ix2, iy2, x2, y2):
ct = np.cos(theta)
st = np.sin(theta)
eq1 = cov(img1, ix2*x2)
eq2 = cov(img1, ix2*y2)
eq3 = cov(img1, iy2*x2)
eq4 = cov(img1, iy2*y2)
eq5 = cov(img2, ix1*x1)
eq6 = cov(img2, ix1*y1)
eq7 = cov(img2, iy1*x1)
eq8 = cov(img2, iy1*y1)
eq9 = cov(ix2, ix1*tx*x1)
eq10 = cov(ix1, ix2*tx*x2)
eq11 = cov(ix1*y1, ix2*tx)
eq12 = cov(ix1, ix2*tx*y2)
eq13 = cov(ix1*x1, ix2*x2)
eq14 = cov(ix1*x1, ix2*y2)
eq15 = cov(ix1*y1, ix2*x2)
eq16 = cov(ix1*y1, ix2*y2)
eq17 = cov(ix1, iy2*tx*x2)
eq18 = cov(ix1, iy2*tx*y2)
eq19 = cov(ix1*x1, iy2*ty)
eq20 = cov(ix1*y1, iy2*ty)
eq21 = cov(ix1*x1, iy2*x2)
eq22 = cov(ix1*x1, iy2*y2)
eq23 = cov(ix1*y1, iy2*x2)
eq24 = cov(ix1*y1, iy2*y2)
eq25 = cov(ix2, iy1*tx*x1)
eq26 = cov(ix2, iy1*tx*y1)
eq27 = cov(iy1, ix2*ty*x2)
eq28 = cov(iy1, ix2*ty*y2)
eq29 = cov(ix2*x2, iy1*x1)
eq30 = cov(ix2*y2, iy1*x1)
eq31 = cov(ix2*x2, iy1*y1)
eq32 = cov(ix2*y2, iy1*y1)
eq33 = cov(iy1*x1, iy2*ty)
eq34 = cov(iy1, iy2*ty*x2)
eq35 = cov(iy1*y1, iy2*ty)
eq36 = cov(iy1, iy2*ty*y2)
eq37 = cov(iy1*x1, iy2*x2)
eq38 = cov(iy1*x1, iy2*y2)
eq39 = cov(iy1*y1, iy2*x2)
eq40 = cov(iy1*y1, iy2*y2)
uj5u.com熱心網友回復:
的定義np.cov(a, b)[0, 1]很簡單
np.sum((a - np.mean(a)) * (b - np.mean(b))) / (a.size - 1)
因此,您可以避免對角元素的計算和對 2x2 矩陣的索引,這將使您的計算速度提高 1.5 倍到 3 倍之間的某個因素。稍微快一點的公式是
np.dot(a - a.mean(), b - b.mean()) / (a.size - 1)
這是對非常小的 ( a.size == 10) 陣列進行的非正式計時測驗,顯示了差異:
%timeit np.cov(a, b)[0, 1]
39.3 μs ± 751 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
%timeit np.sum((a - np.mean(a)) * (b - np.mean(b))) / (a.size - 1)
23.7 μs ± 370 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
%timeit np.dot(a - a.mean(), b - b.mean()) / (a.size - 1)
18 μs ± 83.8 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
我強烈懷疑使用上述公式,您可以預先計算一些您需要避免呼叫cov這么多次的數量。
您可以按照與方差相同的方式分解協方差的計算:
((a * b).sum() - a.sum() * b.sum() / a.size) / (a.size - 1)
這提供了 2 倍以上加速的額外因素:
%timeit ((a * b).sum() - a.sum() * b.sum() / a.size) / (a.size - 1)
8.03 μs ± 41.1 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
這里的額外優勢是您可以預先計算許多總和。例如,img1出現在您的 4 個方程中,但您只需img1.sum()為所有這些方程計算一次。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/335995.html
上一篇:如何制作Blazor頁面互斥鎖
