Конкретный тензорный продукт в numpy

Я хочу вычислить следующую операцию над матрицей:

import numpy as np

x = np.arange(9).reshape((3,3))
result = np.zeros((3,3,3))
for i in range(3):
    for j in range(3):
        for k in range(3):
            result[i,j,k] = x[j,i] * x[j,k]

Который дает

array([[[  0.,   0.,   0.],
        [  9.,  12.,  15.],
        [ 36.,  42.,  48.]],

       [[  0.,   1.,   2.],
        [ 12.,  16.,  20.],
        [ 42.,  49.,  56.]],

       [[  0.,   2.,   4.],
        [ 15.,  20.,  25.],
        [ 48.,  56.,  64.]]])

Как и ожидалось.

Вопрос

Как я могу выполнить этот расчет с тензорными произведениями (без циклов) с помощью numpy?

Редактировать

Если элементы X являются векторами, операция вместо этого:

result[i,j,k] = np.dot(x[j,i] , x[j,k])

Каким будет подходящий оператор numpy для этого расчета?


person Toool    schedule 14.07.2017    source источник


Ответы (1)


Простой, использующий итераторы в виде строкового выражения с np.einsum будет -

np.einsum('ji,jk->ijk',x,x)

Другой с broadcasting и переключением осей -

(x[:,None,:]*x[:,:,None]).swapaxes(0,1)
person Divakar    schedule 14.07.2017
comment
Благодарю вас ! Я забыл упомянуть, что не ищу решения с np.einsum. Решение для вещания отличное! Но мне интересно, есть ли решение с использованием np.tensordot (поскольку истинная проблема подразумевает точечные произведения - см. Мое редактирование) или что-то подобное. На самом деле я реализую это в theano, что накладывает ограничения на вещание. - person Toool; 14.07.2017
comment
@Tool Итак, theano поддерживает вещание? Каковы ограничения? Поскольку нам нужно выровнять одну ось (в данном случае первую ось), numpy.dot или numpy.tensordot не будут работать без чрезмерного использования памяти. numpy.matmul может работать, но опять же хотелось бы знать, есть ли его эквивалент в theano. - person Divakar; 14.07.2017
comment
Я только что проверил, theano поддерживает вещание (так же, как numpy) :) Разве tensordot не должно использовать вещание? Что было бы эквивалентно вашему текущему ответу с точечным продуктом вместо обычного продукта? - person Toool; 14.07.2017
comment
@Tool См. here для объяснения примера и того, почему tensordot не будет работать/по крайней мере, без дополнительных обходных путей и без производительности польза. В вашем случае нет уменьшения суммы, все расширение. Таким образом, broadcasting был бы выходом. - person Divakar; 14.07.2017
comment
Продукт dot представляет собой сумму продуктов. tensordot сводит проблему к вызову dot, используя транспонирование и изменение формы. Но ты ничего не суммируешь. Это своего рода внешний продукт, с которым прекрасно справляется трансляция. Даже решение einsum не суммируется. - person hpaulj; 14.07.2017
comment
Спасибо за ваши Коментарии. Я выберу решение для вещания, так как оно самое эффективное! - person Toool; 14.07.2017