爱因斯坦求和约定
爱因斯坦求和约定(Einstein summation convention)是一种标记的约定,在处理关于坐标的方程式时非常有用。
1 简介
爱因斯坦求和约定省去了求和符号,下面的点成公式
s
=
∑
i
v
i
w
i
s = \sum_{i} v_i w_is=i∑viwi
这个公式描述的是,两个向量对应元素相乘后求和,这种写法与我们而言,觉得很简单了,但是对于爱因斯坦而言,嫌它太麻烦,于是他发明了另一种标记符号。
s
=
v
i
w
i
s = v_iw^is=viwi
在爱因斯坦的标记体系中,下标表示行向量中的元素
[
v
1
,
v
2
,
v
3
,
.
.
.
v
k
]
\left[ v_1, v_2, v_3, ... v_k \right][v1,v2,v3,...vk]
上标表示列向量
[
w
1
w
2
.
.
.
w
k
]
⎡⎣⎢⎢⎢⎢w1w2...wk⎤⎦⎥⎥⎥⎥[w1w2...wk]⎣⎢⎢⎡w1w2...wk⎦⎥⎥⎤
上述向量中的w
1
,
w
2
w^1, w^2w1,w2 分别表示为列向量中的第1个, 第2个元素。那么类似的,
2 一般运算
矩阵A中的第m行,第n列元素,以前标记为A
m
n
A_{mn}Amn 现在标记为A
n
m
A^m_nAnm
(1) 内积
u
⃗
⋅
v
⃗
=
u
j
v
i
\vec{u} \cdot \vec{v} = u_jv^iu⋅v=ujvi
(2) 向量乘以矩阵,矩阵A和向量v的乘积是向量b
u
⃗
i
=
A
j
i
v
j
\vec{u}_i = A^i_jv^jui=Ajivj
(3) 矩阵乘法,矩阵A
i
×
j
A_{i×j}Ai×j和矩阵B
j
×
k
B_{j×k}Bj×k 两者的乘积
C
k
i
=
A
j
i
B
k
j
C_k^i = A_j^iB_k^jCki=AjiBkj
(4) 矩阵的迹,对于矩阵A,上标和下标相同,就可以得到矩阵的迹t
tt
t
=
A
i
i
t = A_i^it=Aii
(5) 外积,M维向量a和N维余向量b的外积是一个M×N的矩阵A
A
j
i
=
a
i
b
j
A_j^i = a^ib_jAji=aibj
3 Numpy中的einsum()方法
在矩阵运算中,einsum()求和约定能够实现求和,求内积,求外积, 矩阵乘法,矩阵转置,求迹。
在einsum()方法的第一个参数是格式字符串
不同的输入变量格式字符串之间要用逗号分隔开,且输入格式字符的数量和参与运算的变量数量匹配
输入格式字符串和输出格式字符串用箭头分隔开
输入格式字符串中字符串长度和张量的维数相对应。如 ‘ij’ 表示二维张量,'ijk’表示三维张量。
案例1: 降维
import numpy as np
# 1 一维向量求和
arr = np.arange(10)
sum1 = np.einsum('i->', arr)
# print(sum1)
# 2 二维数组按行和按列求和
arr2 = np.arange(20).reshape(4, 5)
sum_col = np.einsum('ij->j', arr2) # 按列求和
sum_row = np.einsum('ij->i', arr2) # 按行求和
# print(sum_col)
# print(sum_row)
# 3 三维到二维的约减操作
arr3 = np.arange(27).reshape(3, 3, 3)
# print(arr3)
ret = np.einsum('ijk->jk', arr3) # 三维将为二维
print(ret)
案例2: 矩阵乘法
import numpy as np
# 矩阵乘法dot实现和einsum实现
a = np.array([[1, 1, 1], [2, 2, 2], [3, 3, 3]])
b = np.array([[0, 1, 0], [1, 0, 1], [0, 1, 0]])
ret1 = np.dot(a, b) # 矩阵a*b
print(ret1)
ret2 = np.einsum('ij, jk->ik', a, b)
print(ret2)
案例3: 实现一般运算
import numpy as np
# 1.内积
a = np.arange(1, 10) # 1-9
b = np.arange(1, 10) # 1-9
ret_inner = np.einsum('i, i->', a, b)
# print(ret_inner)
# ret = np.dot(a, b) # 等价于上面的einsum()
# print(ret)
# 2 向量乘以矩阵
a = np.arange(1, 10).reshape((3, 3))
b = np.arange(1, 4)
vec_mul_mat = np.einsum('ij, j->i', a, b)
# print(vec_mul_mat)
# 3 矩阵的迹
a = np.arange(1, 10).reshape((3, 3))
ret_trace = np.einsum('ii->', a)
print(ret_trace)
# 4 外积
a = np.arange(1, 10) # 1-9
b = np.arange(1, 10) # 1-9
ret_outer = np.einsum('i, j ->ij', a, b)
print(ret_outer)
原文链接:https://blog.csdn.net/jiangyi_1612101_03/article/details/111668726