Ătonnamment, dans le segment russe d'Internet, il n'y a presque aucun Ă©lĂ©ment qui explique l'accord de sommation d'Einstein dans un langage comprĂ©hensible . Il n'est pas moins surprenant qu'il y ait encore moins de matĂ©riaux pour comprendre le fonctionnement de la fonction einsum sur Internet russophone. En anglais, il y a une rĂ©ponse assez dĂ©taillĂ©e sur le travail d'einsum sur le dĂ©bordement de pile, et en russe, seuls quelques sites fournissent une traduction de courbe de cette mĂȘme rĂ©ponse. Je veux rĂ©soudre ce problĂšme par manque de matĂ©riel et j'invite tous ceux qui sont intĂ©ressĂ©s Ă le lire!
Discuter de l'Accord d'Einstein
Tout d'abord, je voudrais noter que l'accord d'Einstein est le plus souvent utilisé dans l'analyse des tenseurs et ses applications, par conséquent, plus loin dans l'article, il y aura plusieurs références aux tenseurs.
Lorsque vous commencez tout juste Ă travailler avec des tenseurs, vous pouvez ĂȘtre confus qu'en plus des indices habituels, des exposants sont Ă©galement utilisĂ©s, ce qui au dĂ©but peut gĂ©nĂ©ralement ĂȘtre pris pour l'exponentiation. Exemple:
"a avec exposant i" sera écrit comme , et "a dans un carré avec exposant i" sera écrit
. Cela peut ĂȘtre dĂ©routant et inconfortable au dĂ©but, mais vous pouvez vous y habituer avec le temps.
Accord: plus loin dans l'article, des objets du type ou
je les appellerai des termes .
Sur quoi porte l'accord d'Einstein?
L'accord d'Einstein est conçu pour réduire le nombre de signes de sommation dans une expression. Il existe trois rÚgles simples qui déterminent dans quelle mesure une expression est écrite dans la notation d'Einstein.
RĂšgle n ° 1: la sommation est effectuĂ©e sur tous les indices qui sont rĂ©pĂ©tĂ©s deux fois dans un mĂȘme terme.
Exemple: considérez une expression comme celle-ci:
En utilisant la convention d'Einstein, cette expression peut ĂȘtre réécrite comme ceci:
Ainsi, nous nous débarrassons du signe somme et écrivons juste un seul terme. Notons que dans ce terme l'indice i est répété deux fois, ce qui signifie que, conformément à la premiÚre rÚgle, on comprend que la sommation est effectuée sur l'indice i, ou plutÎt sur toutes les valeurs possibles que prend cet indice.
:
.
. :
:
, i , j , , j.
1. , , .
2. , .
, , ,
.
, .
, Python:
for i in range(M):
for j in range(N):
b[i] += A[i, j] * v[j]
â 2. .
, ,
, , .
:
â i , .. ;
â i , j â ;
â i, j ;
â i, j ;
â ( i );
, , , . :
, , . , , , i 3 , j, , , ( ), , .
â 3. , .
:
â , i , ;
â . : k j , , , i , , . k , i â , , k â , i â . i , , . : i , , 3 .
, :
â i , i j;
â j, i. ;
â i, i, j;
:
â . , :
, ,
. â . , .
, , ,
. , , , , . ,
,
. , , . :
, !
einsum
einsum , Python (NumPy, TensorFlow, PyTorch). , , ( , ), , einsum . NumPy. einsum . , , , , .
: ,
â , .
, , :
. , :
M = np.zeros((3, 2))
for i in range(3):
for j in range(2):
for k in range(5):
M[i, j] += A[i, k] * B[k, j]
, einsum :
M = np.einsum("ik,kj->ij", A, B)
, . einsum : , . :
"{, },{, }->{, }"
einsum :
( ), ;
, ;
3 ;
, einsum , , , . , , , , einsum . , einsum.
, einsum:
einsum,
1. :
vector = np.array([1, 2, 3, 4, 5])
result = np.einsum("i->", vector)
print(result)
Output
15
2. :
matrix = np.array([[1, 2], [3, 4], [5, 6]])
result = np.einsum("ij->", matrix)
print(result)
Output
21
3. :
matrix = np.array([[1, 2], [3, 4], [5, 6]])
result = np.einsum("ij->j", matrix)
print(result)
Output
[9, 12]
4. :
matrix = np.array([[1, 2], [3, 4], [5, 6]])
result = np.einsum("ij->i", matrix)
print(result)
Output
[3, 7, 11]
5. ( , , , ):
matrix = np.array([[1, 2], [3, 4], [5, 6]])
result = np.einsum("ij->ji", matrix)
print(result)
Output
[[1, 3, 5], [2, 4, 6]]
6. :
matrix = np.array([[1, 2], [3, 4], [5, 6]])
vector = np.array([[1, 2]])
result = np.einsum("ij,kj->ik", matrix, vector)
print(result)
, , , . einsum , , , .
Output
[[5], [11], [17]]
7. :
matrix1 = np.array([[1, 2], [3, 4], [5, 6]])
matrix2 = np.array([[1, 0], [0, 1]])
result = np.einsum("ik,kj->ij", matrix1, matrix2)
print(result)
Output
[[1, 2], [3, 4], [5, 6]]
8. :
vector1 = np.array([[1, 2, 3]])
vector2 = np.array([[1, 1, 1]])
result = np.einsum("ik,jk->", vector1, vector2)
print(result)
Output
6
9. :
matrix1 = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
result = np.einsum("ii->", matrix1)
print(result)
Output
15
10. () :
matrix1 = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
matrix2 = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]])
result = np.einsum("ij,ij->ij", matrix1, matrix2)
print(result)
, , : , einsum â :
result = np.zeros(matrix1.shape, dtype="int32")
for i in range(result.shape[0]):
for j in range(result.shape[1]):
result[i, j] += matrix1[i, j] * matrix2[i, j]
print(result)
Output
[[1, 0, 0], [0, 5, 0], [0, 0, 9]]
11. () :
vector1 = np.array([1, 2, 3])
vector2 = np.array([1, 0, 0])
result = np.einsum("i,j->ij", vector1, vector2)
print(result)
Output
[[1, 0, 0], [2, 0, 0], [3, 0, 0]]
12. :
A = np.array([[[0, 1], [1, 2], [2, 3]], [[1, 2], [2, 3], [3, 4]], [[2, 3], [3, 4], [4, 5]]])
result = np.einsum("ijk->jki", A)
print(result)
Output
[[[0, 1, 2], [1, 2, 3]], [[1, 2, 3], [2, 3, 4]], [[2, 3, 4], [3, 4, 5]]]
13. :
A = np.array([[[0, 1], [1, 2], [2, 3]], [[1, 2], [2, 3], [3, 4]], [[2, 3], [3, 4], [4, 5]]])
U = np.array([[1, 2], [2, 3]])
result = np.einsum("ijk,nk->ijn", A, U)
print(result)
Output
[[[2, 3], [5, 8], [8, 13]], [[5, 8], [8, 13], [11. 18]], [[8, 13], [11, 18], [14, 23]]]
, einsum . , (np.dot, np.outer, np.tensordot, np.transpose, np.cumsum ..), einsum. , , , , , .
Accord d'Einstein (base)
Accord d'Einstein (partie avancée)