Имейте в виду, что для numpy
эти 4 и 5d-массивы - это просто не трехмерные массивы, содержащие 2-мерные матрицы и т. Д.
Давайте попробуем записать ваш расчет таким образом, чтобы уточнить размеры:
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