簡體   English   中英

省略號廣播在numpy.einsum

[英]Ellipsis broadcasting in numpy.einsum

我有一個問題,理解為什么以下不起作用:

我有一個可以是三維或六維的陣列前因子 我有一個有四個維度的陣列偶極子 偶極子的前三個維度與前因子的最后三個維度相匹配。

由於我不知道前因子的形狀,我使用省略號來說明前因子中的三個可選維度:

numpy.einsum('...lmn,lmno->...o', prefactor, dipoles)

(在這里的示例中,prefactor.shape是(1,1,1,160,160,128),dipoles.shape是(160,160,128,3)。執行時,我得到錯誤:

操作數1沒有足夠的尺寸來匹配廣播,並且無法擴展,因為在開頭和結尾都指定了愛因斯坦和下標

但是,當我向第二個術語添加省略號時,它確實有效:

numpy.einsum('...lmn,...lmno->...o', prefactor, dipoles)

只是我不明白為什么,因為那里不應該有省略號。 有人知道這里發生了什么嗎?

http://comments.gmane.org/gmane.comp.python.numeric.general/53705上也提出了同樣的問題,但還沒有令人滿意的答案。

這個問題有一個github問題:

https://github.com/numpy/numpy/issues/2455 einsum中索引表示法的改進(Trac#18​​62)

錯誤案例:

einsum('ij...,j->ij...',A,B)

當前的解決方法需要(空)省略號:

einsum( 'IJ ...,J ...-> IJ ...',A,B)

它看起來像einsum循環遍歷字符串參數和操作數次,識別索引和廣播類型(右,左,中,無)和操作維度。 有了它,它構造了一個numpy.nditer 在為edum構造op_axeseinsum會引發此錯誤。 我不知道測試標准是否太緊( ibroadcast >= ndim ),或者是否需要采取額外的步驟來為此參數構造正確的op_axes

https://github.com/numpy/numpy/issues/2619顯示了如何使用nditer來復制einsum行為。 通過這種方式,我可以復制你的計算:

prefactor = np.random.random((1, 1, 1, 160, 160, 128))
dipoles = np.random.random((160, 160, 128, 3))
x = numpy.einsum('...lmn,...lmno->...o', prefactor, dipoles)
#numpy.einsum('...lmn,lmno->...o', prefactor, dipoles)  # not work

op_axes = [[0,1,2,3,4,5,-1], [-1,-1,-1,0,1,2,3], [0,1,2,-1,-1,-1,3]]
flags = ['reduce_ok','buffered', 'external_loop', 'delay_bufalloc', 'grow_inner']
op_flags = [['readonly']]*nops + [['allocate','readwrite']]
it = np.nditer([prefactor,dipoles,None], flags, op_flags, op_axes=op_axes)
it.operands[nops][...] = 0
it.reset()
#it.debug_print()
for (x,y,w) in it:
    w[...] += x*y
print "\nnditer usage:"
print it.operands[nops] # == x
print it.operands[nops].shape # (1, 1, 1, 3)

op_axes行表示einsum'...lmn,...lmno->...o'推斷出'...lmn,...lmno->...o'


我正在https://github.com/hpaulj/numpy-einsum上探討這個問題。

我有一個einsum_py.py ,用Python代碼模擬np.einsum 與此問題相關的部分是parse_subscripts() ,特別是prepare_op_axes() 看起來只需要BROADCAST_RIGHT迭代(從結尾開始)來正確創建op_axes ,無論下標中的省略號是什么。 它還會刪除此問題核心的錯誤消息。

該存儲庫上的einsum.c.src文件具有此更改,並使用當前主分發正確編譯(只需替換文件和構建)。 它對test_einsum.py以及此問題的示例進行了測試。

我已經提交了此次更改的拉取請求。

暫無
暫無

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

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