我有一个带有Mmax轨迹的随机过程。对于每个轨道,我必须取两个矩阵的点积,A和B,有一个循环,它工作得很好。
A=np.zeros((2,Mmax),dtype=np.complex64)
B=np.zeros((2,2,Mmax),dtype=np.complex64)
C=np.zeros((2,Mmax),dtype=np.complex64)
for m in range(Mmax):
C[:,m]=B[:,:,m].dot(A[:,m])(这里只有2x2矩阵来简化它,而实际上它们要大得多)然而,对于大量的轨迹,这个循环是缓慢的。我想通过矢量化来优化它,当我试图实现它时,我遇到了一些问题。
B[:,:,:].dot(A[:,:])它给出的错误‘形状(2,2, 10 )和(2,10)不对齐:10 (dim 2) != 2 (dim 0)',这是有意义的。但是,我确实需要将这个过程向量化,或者至少尽可能地优化它。
有办法弄到这个吗?
发布于 2022-05-09 16:15:27
如果你关心的是速度,有一种方法可以让乘法非矢量化,但速度却非常快--通常比这还要快得多。不过,它需要伦巴:
import numpy as np
import numba as nb
@nb.njit
def mat_mul(A, B):
n, Mmax = A.shape
C = np.zeros((n, Mmax))
for m in range(Mmax):
for j in range(n):
for i in range(n):
C[j, m] += B[j, i, m]*A[i, m]
return C
Mmax = 100
A = np.ones((2, Mmax))
B = np.ones((2, 2, Mmax))
C = mat_mul(A, B)发布于 2022-05-09 17:45:52
定义并非全部为零的示例数组。我们想要验证值以及形状。
In [82]: m = 5
In [83]: A = np.arange(2*m).reshape(2,m)
In [84]: B = np.arange(2*2*m).reshape(2,2,m)您的迭代:
In [85]: C = np.zeros((2,m))
In [86]: for i in range(m):
...: C[:,i]=B[:,:,i].dot(A[:,i])
...:
In [87]: C
Out[87]:
array([[ 25., 37., 53., 73., 97.],
[ 75., 107., 143., 183., 227.]])在einsum中很容易表达这一点
In [88]: np.einsum('ijk,jk->ik',B,A)
Out[88]:
array([[ 25, 37, 53, 73, 97],
[ 75, 107, 143, 183, 227]])matmul/@是np.dot的一个变种,它很好地处理“批处理”。但是批处理维度必须是第一个( 3)。您的批处理维度m是最后一个,因此我们必须进行一些转换以获得相同的结果:
In [90]: (np.matmul(B.transpose(2,0,1),A.transpose(1,0)[...,None])[...,0]).T
Out[90]:
array([[ 25, 37, 53, 73, 97],
[ 75, 107, 143, 183, 227]])https://stackoverflow.com/questions/72174818
复制相似问题