2016-09-20 57 views
1

鑑於這種......矢量化評估,廣播單元方式操作

enter image description here

我要解釋這個代碼做什麼,知道它執行F的量化評估,利用廣播,元素明智的操作理念......

def F(x_pos, alpha): 
    D = x_pos.reshape(1,-1) - x_pos.reshape(-1,1) 
    return (1./alpha) * (alpha.reshape(1,-1) * R(D)).sum(axis=1) 

我的解釋是:

函數F的第一行接收x_pos和alpha作爲參數(均爲numpy數組),在第二行中,通過廣播計算矩陣D(基本操作,如數組中的加法numpy是元素執行的,即元素但如果numpy可以將它們轉換成其他尺寸相同的其他尺寸,那麼也可以使用不同大小的arranys,這種轉換稱爲廣播),將Nx1的另一個序列減去1xN的序列,得到矩陣D的包含x_j - x_1,x_j - x_2等等的順序NxN作爲元素,最後,在最後一行中計算alpha的倒數(顯然是一種排列),其中每個元素乘以每個元素的R評估值之和矩陣D的單元格水平地乘以alpha_j(由於參數中的軸= 1)

問題:

  1. 考慮到我是新來的Python,我的解釋好嗎?
  2. 該代碼有錯誤或沒有?因爲我沒有看到每個數字中的「j必須與1,2,...,n不同」在代碼中被考慮到......並且如果它實際上是錯誤的......我該如何修復該代碼與圖像中所陳述的完全相同?

回答

0

這裏可以提出一些意見/改進/修復。

1]第一步可以只引入一個新的軸,並與自身相減,像這樣被交替做 -

D = x_pos[:,None] - x_pos 

在我看來,這是一個更清潔的選擇。性能優勢可能只是邊際。

2]在第二行中,我認爲需要修復,因爲我們需要避免計算R(D)的對角線元素。所以,如果我得到了正確,更正後的代碼會 -

vals = R(D) 
np.fill_diagonal(vals,0) 
out = (1./alpha) * (alpha.reshape(1,-1) * vals).sum(axis=1) 

現在,讓我們做一下代碼更地道/清潔劑。

在該行,我們可以寫:(alpha * vals)而不是alpha.reshape(1,-1) * vals。這是因爲,如下面的示意圖中的形狀已經對broadcasting對齊 -

alpha :  n 
vals : n x n 

因此,alpha將自動延長到2D與其元件沿着所述第一軸線爲vals然後的elementwise長度廣播乘法與它一起產生。再次,這意味着更清潔的代碼。

這裏還有一個進一步的性能改進,(alpha.reshape(1,-1) * vals).sum(axis=1)可以用matrix-multiplicatiion替換,使用​​作爲alpha.dot(vals)。這一步應該注意到性能的好處。

因此,第二步驟減小到 -

out = (1./alpha) * alpha.dot(vals) 
+0

'X_POS [:,無] - x_pos'幾乎肯定會慢一些,因爲它具有解析切片,而是僅由具有可忽略的恆定量,並且肯定是更地道 – Eric

+0

Divakar ...謝謝你,但我覺得你沒看過我的問題... – OiciTrap

+0

@Oici看看編輯的文本和代碼有意義嗎? – Divakar