Мне нужен тензорный режим n product. Определение продукта tenosr mode n можно увидеть здесь. https://www.alexejgossmann.com/tensor_decomposition_tucker/
Я нашел код Python. Я хотел бы преобразовать этот код в julia.
def mode_n_product(x, m, mode):
x = np.asarray(x)
m = np.asarray(m)
if mode <= 0 or mode % 1 != 0:
raise ValueError('`mode` must be a positive interger')
if x.ndim < mode:
raise ValueError('Invalid shape of X for mode = {}: {}'.format(mode, x.shape))
if m.ndim != 2:
raise ValueError('Invalid shape of M: {}'.format(m.shape))
return np.swapaxes(np.swapaxes(x, mode - 1, -1).dot(m.T), mode - 1, -1)
Я нашел другой ответ, используя Tensortoolbox.jl
using TensorToolbox
X=rand(5,4,3);
A=rand(2,5);
ttm(X,A,n) #X times A[1] by mode n
Один из способов:
using TensorOperations
@tensor y[i1, i2, i3, out, i5] := x[i1, i2, i3, s, i5] * a[out, s]
Это буквально формула, указанная по вашей ссылке, чтобы определить это, за исключением того, что я изменил имя суммированного индекса на s
; вы можете использовать любые индексные имена, которые вам нравятся, это всего лишь маркеры. Сумма неявна, потому что s
не появляется слева.
Нет ничего особенного в том, чтобы вернуть индекс out
на то же место. Как и ваш код на Python, @tensor
переставляет размеры x
, чтобы использовать обычное матричное умножение, а затем снова переставляет, чтобы задать y
запрошенный порядок. Чем меньше нужно перестановок, тем быстрее это будет.
В качестве альтернативы вы можете попробовать using LoopVectorization, Tullio; @tullio y[i1, i2, ...
с теми же обозначениями. Вместо перестановки для вызова библиотечной функции умножения матриц он записывает чистую версию Джулии, которая работает с массивом по мере его поступления.