numpy.linalg.tensordot#
- linalg.tensordot(x1, x2, /, *, оси=2)[источник]#
Вычисляет тензорное скалярное произведение вдоль указанных осей.
Даны два тензора, a и b, и объект array_like, содержащий два объекта array_like,
(a_axes, b_axes), суммировать произведения aи bэлементов (компонентов) по осям, указаннымa_axesиb_axes. Третий аргумент может быть одним неотрицательным скаляром, подобным целому числу,N; если это так, то последнийNразмерности a и первыйNизмерения b суммируются.- Параметры:
- a, barray_like
Тензоры для «скалярного произведения».
- осиint или (2,) array_like
integer_like Если int N, суммирование по последним N осям a и первые N осей b по порядку. Размеры соответствующих осей должны совпадать.
(2,) array_like Или список осей для суммирования, первая последовательность применяется к a, второй до b. Оба элемента array_like должны быть одинаковой длины.
- Возвращает:
- выводndarray
Тензорное скалярное произведение входных данных.
Примечания
- Три распространенных случая использования:
axes = 0: тензорное произведение \(a\otimes b\)axes = 1: тензорное скалярное произведение \(a\cdot b\)axes = 2: (по умолчанию) двойное свёртывание тензора \(a:b\)
Когда оси является integer_like, последовательность осей для вычисления будет: от -N-й оси до -1-й оси в a, и от 0-й оси до (N-1)-й оси в b. Например,
axes = 2равноaxes = [[-2, -1], [0, 1]]. Когда N-1 меньше 0 или когда -N больше -1, элемент a и b определяются как оси.Когда есть более одной оси для суммирования — и они не являются последними (первыми) осями a (b) — аргумент оси должны состоять из двух последовательностей одинаковой длины, причем первая ось для суммирования указывается первой в обеих последовательностях, вторая ось - второй и так далее. Вычисление может быть обозначено как
numpy.einsum.Форма результата состоит из неконтрактированных осей первого тензора, за которыми следуют неконтрактированные оси второго.
Примеры
Пример на integer_like:
>>> a_0 = np.array([[1, 2], [3, 4]]) >>> b_0 = np.array([[5, 6], [7, 8]]) >>> c_0 = np.tensordot(a_0, b_0, axes=0) >>> c_0.shape (2, 2, 2, 2) >>> c_0 array([[[[ 5, 6], [ 7, 8]], [[10, 12], [14, 16]]], [[[15, 18], [21, 24]], [[20, 24], [28, 32]]]])
Пример на array_like:
>>> a = np.arange(60.).reshape(3,4,5) >>> b = np.arange(24.).reshape(4,3,2) >>> c = np.tensordot(a,b, axes=([1,0],[0,1])) >>> c.shape (5, 2) >>> c array([[4400., 4730.], [4532., 4874.], [4664., 5018.], [4796., 5162.], [4928., 5306.]])
Более медленный, но эквивалентный способ вычисления того же…
>>> d = np.zeros((5,2)) >>> for i in range(5): ... for j in range(2): ... for k in range(3): ... for n in range(4): ... d[i,j] += a[k,n,i] * b[n,k,j] >>> c == d array([[ True, True], [ True, True], [ True, True], [ True, True], [ True, True]])
Расширенный пример, использующий перегрузку + и *:
>>> a = np.array(range(1, 9)).reshape((2, 2, 2)) >>> A = np.array(('a', 'b', 'c', 'd'), dtype=object) >>> A = A.reshape((2, 2)) >>> a; A array([[[1, 2], [3, 4]], [[5, 6], [7, 8]]]) array([['a', 'b'], ['c', 'd']], dtype=object)
>>> np.tensordot(a, A) # third argument default is 2 for double-contraction array(['abbcccdddd', 'aaaaabbbbbbcccccccdddddddd'], dtype=object)
>>> np.tensordot(a, A, 1) array([[['acc', 'bdd'], ['aaacccc', 'bbbdddd']], [['aaaaacccccc', 'bbbbbdddddd'], ['aaaaaaacccccccc', 'bbbbbbbdddddddd']]], dtype=object)
>>> np.tensordot(a, A, 0) # tensor product (result too long to incl.) array([[[[['a', 'b'], ['c', 'd']], ...
>>> np.tensordot(a, A, (0, 1)) array([[['abbbbb', 'cddddd'], ['aabbbbbb', 'ccdddddd']], [['aaabbbbbbb', 'cccddddddd'], ['aaaabbbbbbbb', 'ccccdddddddd']]], dtype=object)
>>> np.tensordot(a, A, (2, 1)) array([[['abb', 'cdd'], ['aaabbbb', 'cccdddd']], [['aaaaabbbbbb', 'cccccdddddd'], ['aaaaaaabbbbbbbb', 'cccccccdddddddd']]], dtype=object)
>>> np.tensordot(a, A, ((0, 1), (0, 1))) array(['abbbcccccddddddd', 'aabbbbccccccdddddddd'], dtype=object)
>>> np.tensordot(a, A, ((2, 1), (1, 0))) array(['acccbbdddd', 'aaaaacccccccbbbbbbdddddddd'], dtype=object)