Python 广播-给定矩阵基的三维系数场到三维矩阵场

Python 广播-给定矩阵基的三维系数场到三维矩阵场,python,numpy,matrix,Python,Numpy,Matrix,我有一个(大的)4D数组,在给定的矩阵域的基础上由5个系数组成。给定5个基矩阵,我想有效地计算矩阵场 系数字段c[x,y,z,i]是位置x,y,z处的第i个系数的值 矩阵字段M[x,y,z,a,b]是位于x,y,z 基矩阵T_1,…T_5,即(3,3)基矩阵 我可以在空间中的每个位置上循环: M[x,y,z,:,:]=T_1[,:]*c[x,y,z,0]+T_2[,:]*c[x,y,z,1]…T_5[,:]*c[x,y,z,4] 但这是非常低效的。我尝试使用np.multiply,np.sum会

我有一个(大的)4D数组,在给定的矩阵域的基础上由5个系数组成。给定5个基矩阵,我想有效地计算矩阵场

系数字段
c[x,y,z,i]
是位置x,y,z处的第i个系数的值

矩阵字段
M[x,y,z,a,b]
是位于
x,y,z

基矩阵
T_1,…T_5
,即
(3,3)
基矩阵

我可以在空间中的每个位置上循环:

M[x,y,z,:,:]=T_1[,:]*c[x,y,z,0]+T_2[,:]*c[x,y,z,1]…T_5[,:]*c[x,y,z,4]


但这是非常低效的。我尝试使用
np.multiply
np.sum
会导致广播错误,因为所需的乘积是一个3x3矩阵的字段。

请记住,对于
numpy
,这些4维和5d数组就是这样,而不是包含2d矩阵的3d数组,等等

让我们试着以澄清维度的方式编写您的计算:

M[x,y,z] = T_1*c[x,y,z,0] + T_2*c[x,y,z,1]...T_5*c[x,y,z,4]

M[x,y,z,:,:] = T_1[:,:]*c[x,y,z,0] + T_2[:,:]*c[x,y,z,1]...T_5[:,:]*c[x,y,z,4]
c[x,y,z,i]
是一个系数,对吗?所以
M
T\n
数组的加权和吗

表达这一点的一种方式是:

T = np.stack([T_1, T_2, ...T_5], axis=0)   # 3d  (nab)
M = np.einsum('nab,xyzn->xyzab', T, c)
我们也可以将
T_i
堆叠在新的最后一个轴上

T = np.stack([T_1, T_2 ...T_5], axis=2)   # (abn)
M = np.einsum('abn,xyzn->xyzab', T, c)
或广播乘法加和:

M = (T[None,None,None,:,:,:] * c[:,:,:,None,None,:]).sum(axis=-1)
我在编写这段代码时没有进行测试,因此可能会有错误,但我认为基本大纲是正确的

如果我能在一个参数中把
n
维度放在最后一个,在另一个参数中放在第二到最后一个,那么它也可以写成
点。或使用
tensordot
。但对其他维度的广播控制较少

对于测试计算,您还可以重塑这些数组,以便将
x,y,z
卷成一个数组,将
a,b
卷成另一个数组,例如

 M[xyz,:] = T_n[ab]*c[xyz,n]   # etc

所以在你的文本中你提到了
M[x,y,z,a,b]
,然后当你计算它时
M[x,y,z]
哪个是维度?你能提供一个虚拟的例子吗?快速评论,当提供系数-->矩阵转换函数时,
np.apply\u沿轴()
似乎是一个解决方案。这是一种非常低效的附加问题的方法,因为你没有任何不能用张量完成的费力的函数。查看
einsum
,您可以将
T_i
打包成一个矩阵,然后使用张量表示法:是的,
M
只是基数组
T_n
的加权和。谢谢你的澄清说明。