суммирование внешнего произведения нескольких векторов в einsum

Я прочитал руководство по einsum и базовое введение ajcr

У меня есть нулевой опыт с суммированием эйнштейнов в некодирующем контексте, хотя я пытался исправить это с помощью некоторых интернет-исследований (предоставил бы ссылки, но пока не получил репутацию более двух). Я также пробовал экспериментировать с python с einsum, чтобы узнать, могу ли я лучше разбираться в вещах.

И все же я до сих пор неясно, можно ли и эффективно делать так:

на двух массивах массивов (a и b) равной длины (3) и высоты (n), строка за строкой производит внешний продукт (строка i: a на b) плюс внешний продукт (строка i: b на ), а затем суммируем все внешние матрицы продуктов для вывода одной конечной матрицы.

Я знаю, что «i, j-> ij» производит внешнее произведение одного вектора на другом – это следующие шаги, которые потеряли меня. ('ijk, jik-> ij' определенно не так)

другой доступной опцией является цикл через массив и вызов основных функций (двойной внешний продукт и добавление матрицы) из функций, которые я написал на языке cython (использование numpy, встроенного в функцию external и sum, не является вариантом, оно слишком медленно). Скорее всего, я тоже вернусь к цитону.

так:

  1. как я могу выразить в первую очередь процедуру, описанную выше?

  2. будет ли он предлагать реальные выгоды, чем делать все на cython? или есть другие альтернативы, о которых я не знаю? (включая возможность того, что я использовал numpy менее эффективно, чем мог бы быть …)

Благодарю.


отредактировать с примером:

A=np.zeros((3,3)) arrays_1=np.array([[1,0,0],[1,2,3],[0,1,0],[3,2,1]]) arrays_2=np.array([[1,2,3],[0,1,0],[1,0,0],[3,2,1]]) for i in range(len(arrays_1)): A=A+(np.outer(arrays_1[i], arrays_2[i])+np.outer(arrays_2[i],arrays_1[i])) 

(обратите внимание, однако, что на практике мы имеем дело с массивами гораздо большей длины (т. е. длиной 3 для каждого внутреннего члена, но до нескольких тысяч таких членов), и этот раздел кода получает (неизбежно) много раз)

в случае, если это вообще полезно, вот cython для суммирования двух внешних продуктов:

 def outer_product_sum(np.ndarray[DTYPE_t, ndim=1] a_in, np.ndarray[DTYPE_t, ndim=1] b_in): cdef double *a = <double *>a_in.data cdef double *b = <double *>b_in.data return np.array([ [a[0]*b[0]+a[0]*b[0], a[0]*b[1]+a[1]*b[0], a[0] * b[2]+a[2] * b[0]], [a[1]*b[0]+a[0]*b[1], a[1]*b[1]+a[1]*b[1], a[1] * b[2]+a[2] * b[1]], [a[2]*b[0]+a[0]*b[2], a[2]*b[1]+a[1]*b[2], a[2] * b[2]+a[2] * b[2]]]) 

который, прямо сейчас, вызываю из цикла «i in range (len (array)), как показано выше.

2 Solutions collect form web for “суммирование внешнего произведения нескольких векторов в einsum”

Суммирование Эйнштейна может быть использовано только для мультипликативной части вопроса (т. Е. Внешнего произведения). К счастью, суммирование не обязательно должно выполняться по элементам, но вы можете сделать это на матрицах уменьшения. Использование массивов из вашего примера:

 arrays_1 = np.array([[1,0,0],[1,2,3],[0,1,0],[3,2,1]]) arrays_2 = np.array([[1,2,3],[0,1,0],[1,0,0],[3,2,1]]) A = np.einsum('ki,kj->ij', arrays_1, arrays_2) + np.einsum('ki,kj->ij', arrays_2, arrays_1) 

Входные массивы имеют форму (4,3), суммирование происходит по первому индексу (с именем 'k' ). Если суммирование должно происходить по второму индексу, измените строку индексов на 'ik,jk->ij' .

Независимо от того, что вы можете сделать с np.einsum , вы обычно можете делать быстрее, используя np.dot . В этом случае A является суммой двух точечных произведений:

 arrays_1 = np.array([[1,0,0],[1,2,3],[0,1,0],[3,2,1]]) arrays_2 = np.array([[1,2,3],[0,1,0],[1,0,0],[3,2,1]]) A1 = (np.einsum('ki,kj->ij', arrays_1, arrays_2) + np.einsum('ki,kj->ij', arrays_2, arrays_1)) A2 = arrays_1.T.dot(arrays_2) + arrays_2.T.dot(arrays_1) print(np.allclose(A1, A2)) # True %timeit (np.einsum('ki,kj->ij', arrays_1, arrays_2) + np.einsum('ki,kj->ij', arrays_2, arrays_1)) # 100000 loops, best of 3: 7.51 µs per loop %timeit arrays_1.T.dot(arrays_2) + arrays_2.T.dot(arrays_1) # 100000 loops, best of 3: 4.51 µs per loop 
Python - лучший язык программирования в мире.