48

假设你有 n 个方阵 A1,...,An。反正有没有以一种简洁的方式将这些矩阵相乘?据我所知,numpy 中的 dot 只接受两个参数。一种明显的方法是定义一个函数来调用自身并获取结果。有没有更好的方法来完成它?

4

5 回答 5

78

这可能是一个相对较新的功能,但我喜欢:

A.dot(B).dot(C)

或者如果你有一条长链,你可以这样做:

reduce(numpy.dot, [A1, A2, ..., An])

更新:

这里有关于 reduce 的更多信息这是一个可能有帮助的例子。

>>> A = [np.random.random((5, 5)) for i in xrange(4)]
>>> product1 = A[0].dot(A[1]).dot(A[2]).dot(A[3])
>>> product2 = reduce(numpy.dot, A)
>>> numpy.all(product1 == product2)
True

2016 年更新:从 python 3.5 开始,有一个新的 matrix_multiply 符号@

R = A @ B @ C
于 2012-08-07T05:12:31.673 回答
42

用更新复活一个老问题:

截至2014 年 11 月 13 日,现在有一个np.linalg.multi_dot功能可以完全满足您的需求。它还具有优化呼叫顺序的好处,尽管在您的情况下这不是必需的。

请注意,这从 numpy 版本 1.10 开始可用。

于 2014-11-18T16:58:32.670 回答
4

如果您先验地计算所有矩阵,那么您应该使用矩阵链乘法的优化方案。请参阅此维基百科文章

于 2012-08-07T02:05:48.733 回答
4

实现此目的的另一种方法是使用einsum,它为 NumPy 实现了爱因斯坦求和约定

为了非常简要地解释关于这个问题的这个约定:当你把你的多矩阵乘积写成一个很大的乘积时,你会得到类似的东西:

P_im = sum_j sum_k sum_l A1_ij A2_jk A3_kl A4_lm

其中P是您的产品的结果A1A2A3、 和A4是输入矩阵。请注意,您将准确地对在加法中出现两次的那些索引进行求和,即jkl。由于具有此属性的总和经常出现在物理学、矢量微积分以及可能的其他一些领域中,因此有一个 NumPy 工具可以解决它,即einsum.

在上面的示例中,您可以使用它来计算矩阵乘积,如下所示:

P = np.einsum( "ij,jk,kl,lm", A1, A2, A3, A4 )

在这里,第一个参数告诉函数将哪些索引应用于参数矩阵,然后将所有双重出现的索引相加,产生所需的结果。

请注意,计算效率取决于几个因素(因此您最好只测试它):

于 2016-10-03T07:14:18.740 回答
2
A_list = [np.random.randn(100, 100) for i in xrange(10)]
B = np.eye(A_list[0].shape[0])
for A in A_list:
    B = np.dot(B, A)

C = reduce(np.dot, A_list)

assert(B == C)
于 2012-08-07T08:07:16.857 回答