Skip to main content
 首页 » 编程设计

python之无循环的 n 个矩阵的乘积运算符

2025年05月04日21www_RR

我得到了一个维度矩阵 (nx2x2),所以假设矩阵 M 为 (3x2x2):

[[[ 1.  5.] 
  [ 2.  4.]] 
 
 [[ 5. 25.] 
  [10. 20.]] 
 
 [[ 5. 25.] 
  [10. 20.]]] 

我想对每个 2x2 矩阵进行乘积运算(点积)。换句话说,我想执行以下操作:

其中 Mj 与 python 中的 M[j,:,:] 相同。最简单的方法是使用这样的 for 循环:

prod=np.identity(2) 
for temp in M: 
    prod=np.dot(prod,temp) 

但我不知道是否有矢量化的方式来做这件事(我确信这可能是一个重复的问题,但我无法通过谷歌找出正确的问题)

请您参考如下方法:

In [99]: X = np.array([1,5,2,4,5,25,10,20,5,25,10,20]).reshape(3,2,2) 
In [100]: X 
Out[100]:  
array([[[ 1,  5], 
        [ 2,  4]], 
 
       [[ 5, 25], 
        [10, 20]], 
 
       [[ 5, 25], 
        [10, 20]]]) 
In [101]: prod=np.identity(2) 
In [102]: for t in X: 
     ...:     prod=np.dot(prod,t) 
     ...:      
In [103]: prod 
Out[103]:  
array([[1525., 3875.], 
       [1550., 3850.]]) 

使用 mutmul 运算符:

In [104]: X[0]@X[1]@X[2] 
Out[104]:  
array([[1525, 3875], 
       [1550, 3850]]) 
In [105]:  

链式点函数:

In [106]: np.linalg.multi_dot(X) 
Out[106]:  
array([[1525, 3875], 
       [1550, 3850]]) 

检查它的文档和代码,看看它是如何尝试优化计算的。

How is numpy multi_dot slower than numpy.dot?

numpy large matrix multiplication optimize

Multiply together list of matrices in Numpy


如果我多次扩展X:

In [147]: X.shape 
Out[147]: (48, 2, 2) 

一个点积的成本:

In [148]: timeit X[0]@X[1] 
5.08 µs ± 14.2 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each) 

其中 48 个:

In [149]: 5*48 
Out[149]: 240 

将其与迭代评估链式点的成本进行比较:

In [150]: %%timeit 
     ...: Y = np.eye(X.shape[1]).astype(X.dtype) 
     ...: for i in X: 
     ...:     Y = Y@i 
     ...:      
227 µs ± 5.19 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each) 

因此,除了评估所有必需的点之外,链接不会花费任何东西。

我尝试了一个嵌套点的递归函数,但没有得到任何改进。

除非你能从数学上提出一种替代方法来依次评估点,否则我怀疑是否还有改进的余地。使用类似 cython 的东西来直接调用底层的 BLAS 函数可能是唯一的选择。它不会改进单个点,但可以减少一些调用开销。