系数字段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.multiply
,np.sum
导致广播错误,因为所需产品的歧义是3x3矩阵的字段。
答案 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]
是一个系数,对不对?那么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)
我编写此代码时未经测试,因此可能会有错误,但是我认为基本概述是正确的。
如果我可以将dot
维度放在一个参数的末尾,并将第二维度放在另一个参数的末尾,也可以将其写为n
。或使用tensordot
。但是对其他维度的广播的控制较少。
对于测试计算,您还可以调整这些数组的形状,以便将x,y,z
滚动为一个,并将a,b
滚动为另一个,例如
M[xyz,:] = T_n[ab]*c[xyz,n] # etc