скалярное произведение по нескольким осям

Учитывая два массива numpy, где первые d измерения равны по размеру

import numpy

d = 3
a = numpy.random.rand(2, 2, 2, 12, 3)
b = numpy.random.rand(2, 2, 2, 5)

Я хотел бы вычислить точечный продукт по этим первым измерениям. Этот

a2 = a.reshape(-1, *a.shape[d:])
b2 = b.reshape(-1, *b.shape[d:])
out = numpy.dot(numpy.moveaxis(a2, 0, -1), numpy.moveaxis(b2, 0, -2))

работает, но только если b не имеет формы (2, 2, 2). Возиться с reshape и moveaxis также кажется более сложным, чем необходимо.

Есть ли более изящные решения? (Возможно, с tensordot?)


person Nico Schlömer    schedule 28.07.2017    source источник
comment
tensordot изменяет форму и ось перемещается до тех пор, пока не сможет дать задание dot. А потом обратно перестраивается.   -  person hpaulj    schedule 28.07.2017


Ответы (2)


Снова используйте np.einsum.

np.einsum('ijklm,ijkn->lmn',a,b)
person Jürg Merlin Spaak    schedule 28.07.2017
comment
Я предполагаю, что это потребует адаптации для d, отличного от 3, или количества дополнительных измерений. - person Nico Schlömer; 28.07.2017
comment
Да, вы должны. np.einsum допускает многоточие, но я думаю, что лучшее, что вы можете получить, это что-то вроде np.einsum('ijklm,ijk...->lm...',a,b). В частности, вы не можете суммировать по неопределенному количеству осей. - person Jürg Merlin Spaak; 28.07.2017
comment
Я полагаю, по крайней мере, часть lm тоже можно заменить? Для ijk можно построить строку до тех пор, пока не закончится алфавит. - person Nico Schlömer; 28.07.2017
comment
Мне тоже не удалось избавиться от части lm, но, возможно, есть способ - person Jürg Merlin Spaak; 28.07.2017
comment
Как и в случае с tensordot, изменение формы может уменьшить количество осей до управляемого. Я думаю, что максимальное ndim равно 32. Вероятно, вы сначала столкнетесь с ошибкой памяти. - person hpaulj; 28.07.2017

Оказывается, tensordot является полезно в конце концов. Этот

numpy.tensordot(a, b, axes=(range(3), range(3)))

делает свое дело.

person Nico Schlömer    schedule 28.07.2017
comment
Видимо, лучшее решение, к сожалению, мне очень нравится np.einsum - person Jürg Merlin Spaak; 28.07.2017
comment
Я тоже, на самом деле. Как только вы освоите синтаксис, вы сможете делать практически все. Почти. - person Nico Schlömer; 28.07.2017