广播-系数的3D字段到给定矩阵基础的矩阵的3D字段

时间:2018-06-25 18:47:54

标签: python numpy matrix

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

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

并且矩阵字段M[x,y,z,a,b]是位置(3,3)上的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.multiplynp.sum导致广播错误,因为所需产品的歧义是3x3矩阵的字段。

1 个答案:

答案 0 :(得分:0)

请记住,对于numpy来说,这4d和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]是一个系数,对不对?那么MT_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)

我编写此代码时未经测试,因此可能会有错误,但是我认为基本概述是正确的。

如果我可以将dot维度放在一个参数的末尾,并将第二维度放在另一个参数的末尾,也可以将其写为n。或使用tensordot。但是对其他维度的广播的控制较少。

对于测试计算,您还可以调整这些数组的形状,以便将x,y,z滚动为一个,并将a,b滚动为另一个,例如

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