numpy.linalg.tensordot#
- linalg.tensordot(x1, x2, /, *, axes=2)[source]#
沿指定的轴计算张量点积。
给定两个张量 a 和 b,以及一个包含两个类数组对象的类数组对象
(a_axes, b_axes)
,在由a_axes
和b_axes
指定的轴上对 a 和 b 的元素(分量)的乘积进行求和。第三个参数可以是单个非负整数类型的标量N
;如果是这样,则对 a 的最后N
个维度和 b 的前N
个维度进行求和。- 参数:
- a, barray_like
要进行“点积”的张量。
- axesint 或 (2,) array_like
整数类型 如果是整数 N,则按顺序对 a 的最后 N 个轴和 b 的前 N 个轴进行求和。对应轴的大小必须匹配。
(2,) array_like 或者,要进行求和的轴列表,第一个序列应用于 a,第二个序列应用于 b。两个类数组对象元素必须具有相同的长度。
- 返回值:
- outputndarray
输入的张量点积。
备注
- 三个常见的用例是
axes = 0
: 张量积 \(a\otimes b\)axes = 1
: 张量点积 \(a\cdot b\)axes = 2
: (默认)张量双重收缩 \(a:b\)
当 axes 是整数类型时,求值轴的序列将是:从 a 的第 -N 个轴到第 -1 个轴,以及从 b 的第 0 个轴到第 (N-1) 个轴。例如,
axes = 2
等于axes = [[−2,−1],[0,1]]
。当 N-1 小于 0 或 -N 大于 -1 时,a 和 b 的元素定义为 axes。当有多个轴需要求和时——并且它们不是 a(b)的最后一个(第一个)轴时——参数 axes 应包含两个长度相同的序列,其中第一个要求和的轴在两个序列中都排在第一位,第二个轴排在第二位,依此类推。计算可以参考
numpy.einsum
。结果的形状由第一个张量的非收缩轴组成,然后是第二个张量的非收缩轴。
示例
关于整数类型的示例
>>> 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]]]])
关于类数组对象的示例
>>> 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)) >>> a.shape = (2, 2, 2) >>> A = np.array(('a', 'b', 'c', 'd'), dtype=object) >>> A.shape = (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)