我得到了一个维度矩阵 (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 函数可能是唯一的选择。它不会改进单个点,但可以减少一些调用开销。
