我很难理解np.einsum()
的文档。subscripts
是如何解释的?
我正在尝试写np.einsum('a...c,b...c', Y, conj(Y))
,其中Y
是原始python上形状为C, F, T
的矩阵。此外,由于之前的实现差异,我的MATLABY
的大小为[F, T, C]
。
'a...c,b...c'
在每个组件中索引什么?我很困惑。
如何在MATLAB中编写相同的指令?
引用einsum
文档页面:
若要启用和控制广播,请使用省略号。默认NumPy风格的广播是通过在每个术语的左侧添加省略号来完成的,比如
np.einsum('...ii->...i', a)
。要沿着第一个和最后一个轴进行跟踪,可以执行np.einsum('i...i', a)
,或者要使用最左边的索引而不是最右边的索引进行矩阵矩阵乘积,可以执行np.einsum('ij...,jk...->ik...', a, b)
。
稍后给出一个示例:
>>> a = np.arange(25).reshape(5,5)
>>> np.einsum('...j->...', a)
array([ 10, 35, 60, 85, 110])
此示例的等效MATLAB代码为:
>> a = reshape(0:24, [5,5]).';
>> sum(a,2).'
ans =
10 35 60 85 110
需要注意的几点:
不应将省略号运算符(...
(理解为"范围",而应理解为"需要存在的任何内容"
.'
(。这是因为numpy数组以行为主,而MATLAB数组以列为主。实际上,虽然底层数据具有相同的顺序,但与MATLAB相比,numpy数组出现了的转置。进行换位是为了使阵列在中间阶段看起来相同这些文档中的另一个示例是:
>>> a = np.arange(6).reshape((3,2))
>>> b = np.arange(12).reshape((4,3))
>>> np.einsum('ki,jk->ij', a, b)
array([[10, 28, 46, 64],
[13, 40, 67, 94]])
>>> np.einsum('ki,...k->i...', a, b)
array([[10, 28, 46, 64],
[13, 40, 67, 94]])
>>> np.einsum('k...,jk', a, b)
array([[10, 28, 46, 64],
[13, 40, 67, 94]])
在MATLAB中可以写如下:
A = reshape(0:5, [2 3]).';
B = reshape(0:11, [3 4]).';
A.' * B.'
permute(sum( permute(A, [3 1 2]) .* B,2), [3 1 2])
shiftdim(sum( shiftdim(A, -1) .* B, 2), 2)
需要注意的几点:
- 从
np.einsum('ki,jk->ij', a, b)
到np.einsum('ki,...k->i...', a, b)
时,可以看到j
维度被...
替换。事实上,这两个例子都有一个->
,这意味着它处于显式模式 - 当从
np.einsum('ki,jk->ij', a, b)
转到np.einsum('k...,jk', a, b)
时,您可以看到现在第i
个维度被...
替换。->...j
的省略只是演示了隐式模式(其中输出维度按字母顺序排列(