【发布时间】:2018-05-24 22:34:20
【问题描述】:
我需要对两个 4D 数组 (m & n) 执行矩阵乘法,m & n 的维度分别为 2x2x2x2 和 2x3x2x2,这应该会产生一个 2x3x2x2 数组。经过大量研究(主要是在这个网站上),这似乎可以通过 np.einsum 或 np.tensordot 有效地完成,但我无法复制答案我是从 Matlab 得到的(手工验证)。我了解这些方法(einsum 和 tensordot)在 2D 数组上执行矩阵乘法时的工作原理(清楚地解释了here),但我无法获得正确的 4D 数组的轴索引。显然我错过了一些东西!我的实际问题涉及两个 23x23x3x3 复数数组,但我的测试数组是:
a = np.array([[1, 7], [4, 3]])
b = np.array([[2, 9], [4, 5]])
c = np.array([[3, 6], [1, 0]])
d = np.array([[2, 8], [1, 2]])
e = np.array([[0, 0], [1, 2]])
f = np.array([[2, 8], [1, 0]])
m = np.array([[a, b], [c, d]]) # (2,2,2,2)
n = np.array([[e, f, a], [b, d, c]]) # (2,3,2,2)
我意识到复数可能会带来更多问题,但现在,我只是想了解 indexxing 如何与 einsum 和 tensordot 一起工作。我正在寻找的答案是这个 2x3x2x2 数组:
+----+-----------+-----------+-----------+
| | 0 | 1 | 2 |
+====+===========+===========+===========+
| 0 | [[47 77] | [[22 42] | [[44 40] |
| | [31 67]] | [27 74]] | [33 61]] |
+----+-----------+-----------+-----------+
| 1 | [[42 70] | [[24 56] | [[41 51] |
| | [10 19]] | [ 6 20]] | [ 6 13]] |
+----+-----------+-----------+-----------+
我最接近的尝试是使用 np.tensordot:
mn = np.tensordot(m,n, axes=([1,3],[0,2]))
这给了我一个 2x2x3x2 数组,其数字正确但顺序不正确:
+----+-----------+-----------+
| | 0 | 1 |
+====+===========+===========+
| 0 | [[47 77] | [[31 67] |
| | [22 42] | [24 74] |
| | [44 40]] | [33 61]] |
+----+-----------+-----------+
| 1 | [[42 70] | [[10 19] |
| | [24 56] | [ 6 20] |
| | [41 51]] | [ 6 13]] |
+----+-----------+-----------+
我也尝试实施here 的一些解决方案,但没有任何运气。
任何关于我如何改进的想法都将不胜感激,谢谢
【问题讨论】:
-
在 APL(一种编程语言)中,矩阵乘法运算符适用于高维对象。乘法/加法发生在左侧对象的最后一个维度和第二个对象的第一个维度上。在 2x2x2x2 +.x 2x3x2x2 的情况下,“内部”(...x2 ,2x...)尺寸被删除,结果将是一个 2x2x2x3x2x2 对象。我想知道 Matlab 是否遵循同样的规则。
标签: python arrays numpy matrix