繁体   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