Две части:
Название | Абстрактный язык | Язык чисел (базис) | Язык матриц |
---|---|---|---|
Базис | $$\vec{e_0}, \vec{e_1}$$ | $$\epsilon=\left\{\vec{e_0}, \vec{e_1}\right\}$$ | |
Элемент | $$\vec{x}$$ | $$\vec{x}=\sum_{i=0}^{n-1} x_i \vec{e_i}$$ | $$\vec{x}=\epsilon X$$$$\vec{x}=\left\{\vec{e_0}, \vec{e_1}\right\}\begin{bmatrix}x_0\\ x_1\end{bmatrix}$$ |
Линейная функция (форма) | $$f(\vec{x})$$ | $$f(\vec{x})=\sum_{i=0}^{n-1} x_i f(\vec{e_i})=\sum_{i=0}^{n-1} x_i f_i = (\vec{x},\vec{f})$$ | $$f(\vec{x})=X^T F$$$$f(\vec{x})=\begin{bmatrix}x_0 & x_1\end{bmatrix}\begin{bmatrix}f_0\\ f_1\end{bmatrix}$$ |
Билинейная форма | $$b(\vec{x},\vec{y})$$ | $$b(\vec{x},\vec{y})=\sum_{i,j=0}^{n-1} x_i y_j b(\vec{e_i},\vec{e_j})=\sum_{i,j=0}^{n-1} x_i y_j b_{ij}$$ | $$b(\vec{x},\vec{y})=X^T B Y$$$$b(\vec{x},\vec{y})=\begin{bmatrix}x_0 & x_1\end{bmatrix}\begin{bmatrix}b_{00} & b_{01}\\ b_{10} & b_{11}\end{bmatrix}\begin{bmatrix}y_0\\ y_1\end{bmatrix}$$ |
Оператор | $$\vec{y} = \hat A \vec{x}$$ | $$\hat A \vec{x}=\sum_{i=0}^{n-1} x_i \hat A\vec{e_i}=\sum_{i=0}^{n-1} x_i \sum_{j=0}^{n-1} a_{ji}\vec{e_j}$$ | $$Y=AX$$$$Y=\begin{bmatrix}a_{00} & a_{01}\\ a_{10} & a_{11}\end{bmatrix}\begin{bmatrix}x_0\\ x_1\end{bmatrix}$$ |
Название | В базисе $\epsilon$ | Переход $\epsilon \to\phi$ | Обратный переход $\phi \to\epsilon$ | Вместе с базисом |
---|---|---|---|---|
Базис | $$\epsilon=\left\{\vec{e_0}, \vec{e_1}\right\}$$ | $$\phi = \epsilon T $$ | $$\epsilon = \phi T^{-1} $$ | + |
Элемент | $$\vec{x}=\epsilon X_\epsilon$$ |
$$X_\phi=T^{-1}X_\epsilon$$ | $$X_\epsilon=T X_\phi$$ | - |
Линейная функция (форма) | $$f(\vec{x})=X_\epsilon^T F_\epsilon$$ | $$F_\phi=T^{T}F_\epsilon$$ | $$F_\epsilon=(T^{-1})^TF_\phi$$ | + |
Билинейная форма | $$b(\vec{x},\vec{y})=X_\epsilon^T B_\epsilon Y_\epsilon$$ | $$B_\phi = T^T B_\epsilon T$$ | $$B_\epsilon = (T^{-1})^T B_\phi T^{-1}$$ | +/- |
Оператор | $$Y_\epsilon=A_\epsilon X_\epsilon$$ | $$A_\phi = T^{-1} A_\epsilon T$$ | $$A_\epsilon = T A_\phi T^{-1}$$ | +/- |
Название | Переход $\epsilon \to\phi$ | Преобразование компоненты | Преобразование компоненты в нотации Эйнштейна |
---|---|---|---|
Базис | $$\phi = \epsilon T $$ | $$\vec{f}_j=[T]_{ij}\vec{e}_i$$ | $$\vec{f}_j=[T]^i_j\vec{e}_i$$ |
Элемент | $$X_\phi=T^{-1}X_\epsilon$$ | $$[x_\phi]_i=\sum_{j=0}^{n-1}[T^{-1}]_{ij} [x_\epsilon]_j$$ | $$\underset{\phi}{x^j} = [T^{-1}]^j_i \underset{\epsilon}{x^i}$$ |
Линейная функция (форма) | $$F_\phi=T^{T}F_\epsilon$$ | $$[f_\phi]_i = \sum_{j=0}^{n-1}[T]_{ji} [f_\epsilon]_j$$ | $$\underset{\phi}{f_j}=[T]^i_j \underset{\epsilon}{f_i}$$ |
Билинейная форма | $$B_\phi = T^T B_\epsilon T$$ | $$[B_\phi]_{ij}=\sum_{p=0}^{n-1}\sum_{k=0}^{n-1}[T]_{ip} [T]_{kj} [B_\epsilon]_{pk}$$ | $$\underset{\phi}{B_{ij}}=[T]^p_i [T]^k_j \underset{\epsilon}{B_{pk}} $$ |
Оператор | $$A_\phi = T^{-1} A_\epsilon T$$ | $$[A_\phi]_{ij}=\sum_{p=0}^{n-1}\sum_{k=0}^{n-1} [T^{-1}]_{jp} [T]_{ik} [A_\epsilon]_{pk} $$ | $$\underset{\phi}{A^j_i}=[T^{-1}]^j_p [T]^k_i \underset{\epsilon}{A^p_k} $$ |
$$ \underset{\phi}{a^{p_1p_2 \ldots p_m}_{s_1s_2 \ldots s_l}} = [T^{-1}]^{p_1}_{i_1} \ldots [T^{-1}]^{p_m}_{i_m} [T]^{j_1}_{s_1} \ldots [T]^{j_l}_{s_l} \underset{\epsilon}{a^{i_1i_2 \ldots i_m}_{j_1j_2 \ldots j_l}} $$
$$ b_i = \sum_{i=0}^{n-1} A_{ij} v_j $$
for i in range(n): # свободный
for j in range(n): # немой
b[i] += A[i, j] * v[j]
$$ b^i = \sum_{i=0}^{n-1} A^i_j v^j = A^i_j v^j $$
import numpy as np
from numpyarray_to_latex.jupyter import to_jup
индексы первого тензора, индексы второго тензора, индексы третьего тензора, ... -> индексы результата
Создадим тензор
a = np.arange(6).reshape(2, 3)
to_jup(a)
to_jup(np.einsum('ij->ji', a))
a = np.arange(9).reshape(3, 3)
to_jup(a)
np.einsum('ii->', a)
12
np.trace(a)
12
Бонус: диагональ
np.einsum('ii->i', a)
array([0, 4, 8])
Всех
np.einsum('ij->', a)
15
По столбцам
to_jup(np.einsum('ij->j', a))
По строкам
to_jup(np.einsum('ij->i', a))
Понижение размерности на 2
a = np.arange(6).reshape(2, 3)
b = np.arange(15).reshape(3, 5)
to_jup(a)
to_jup(b)
to_jup(np.einsum('pq,qt->pt', a, b))
a = np.arange(66).reshape(2, 3, 11)
b = np.arange(210).reshape(3, 5, 2, 7)
np.einsum('pqr,qtsi->prtsi', a, b).shape
(2, 11, 5, 2, 7)
a = np.arange(6).reshape(2, 3)
b = np.arange(3)
to_jup(a)
to_jup(b)
to_jup(np.einsum('ik,k->i', a, b))
a = np.arange(6).reshape(2, 3)
b = np.arange(15).reshape(3, 5)
to_jup(a)
to_jup(b)
to_jup(np.einsum('ik,kj->ij', a, b))
a = np.arange(2*6).reshape(2, 2, 3)
b = np.arange(2*15).reshape(2, 3, 5)
np.einsum('bik,bkj->bij', a, b).shape
(2, 2, 5)
a = np.arange(6).reshape(2, 3)
b = np.arange(6,12).reshape(2, 3)
to_jup(a)
to_jup(b)
to_jup(np.einsum('ij,ij->ij', a, b))
a = np.arange(3)
b = np.arange(3,6)
to_jup(a)
to_jup(b)
np.einsum('i,i->', a, b)
14
a = np.arange(6).reshape(2, 3)
b = np.arange(6,12).reshape(2, 3)
to_jup(a)
to_jup(b)
np.einsum('ij,ij->', a, b)
145
aka Кронокерово произведение
a = np.arange(3)
b = np.arange(3,7)
to_jup(a)
to_jup(b)
to_jup(np.einsum('i,j->ij', a, b))
Не надо выдумывать имена для всех индексов
a = np.arange(2*3*4*5*6*7).reshape(2, 3, 4, 5, 6, 7)
a.shape
(2, 3, 4, 5, 6, 7)
np.einsum('...ij->...ji', a).shape
(2, 3, 4, 5, 7, 6)
a = np.ones(300, dtype=np.int8)
np.einsum('i->', a) # должно быть 300
44
a = np.arange(6).reshape(2, 3)
to_jup(a)
np.trace(a)
4
np.einsum('ii->', a)
--------------------------------------------------------------------------- ValueError Traceback (most recent call last) Cell In[149], line 1 ----> 1 np.einsum('ii->', a) File ~/miniconda3/envs/python-bar-review/lib/python3.11/site-packages/numpy/core/einsumfunc.py:1371, in einsum(out, optimize, *operands, **kwargs) 1369 if specified_out: 1370 kwargs['out'] = out -> 1371 return c_einsum(*operands, **kwargs) 1373 # Check the kwargs to avoid a more cryptic error later, without having to 1374 # repeat default values here 1375 valid_einsum_kwargs = ['dtype', 'order', 'casting'] ValueError: dimensions in operand 0 for collapsing index 'i' don't match (2 != 3)
a = np.arange(6)
a
array([0, 1, 2, 3, 4, 5])
np.einsum('i', a)
array([0, 1, 2, 3, 4, 5])
np.einsum('i', a).__array_interface__
{'data': (105553164518192, False), 'strides': None, 'descr': [('', '<i8')], 'typestr': '<i8', 'shape': (6,), 'version': 3}
a.__array_interface__
{'data': (105553164518192, False), 'strides': None, 'descr': [('', '<i8')], 'typestr': '<i8', 'shape': (6,), 'version': 3}
def calc():
a = np.ones(64).reshape(2,4,8)
for iteration in range(500):
_ = np.einsum('ijk,ilm,njm,nlk,abc->',a,a,a,a,a)
%time calc()
CPU times: user 778 ms, sys: 4.11 ms, total: 782 ms Wall time: 784 ms
def calc():
a = np.ones(64).reshape(2,4,8)
for iteration in range(500):
_ = np.einsum('ijk,ilm,njm,nlk,abc->',a,a,a,a,a, optimize='optimal')
%time calc()
CPU times: user 150 ms, sys: 4.81 ms, total: 155 ms Wall time: 153 ms
def calc():
a = np.ones(64).reshape(2,4,8)
for iteration in range(500):
_ = np.einsum('ijk,ilm,njm,nlk,abc->',a,a,a,a,a, optimize='greedy')
%time calc()
CPU times: user 55.8 ms, sys: 4.15 ms, total: 60 ms Wall time: 57.4 ms
def calc():
a = np.ones(64).reshape(2,4,8)
path = np.einsum_path('ijk,ilm,njm,nlk,abc->',a,a,a,a,a, optimize='optimal')[0]
for iteration in range(500):
_ = np.einsum('ijk,ilm,njm,nlk,abc->',a,a,a,a,a, optimize=path)
%time calc()
CPU times: user 41.5 ms, sys: 2.49 ms, total: 44 ms Wall time: 43.1 ms
from einops import rearrange, reduce, repeat
a = np.arange(2*2*3).reshape(2, 2, 3)
a
array([[[ 0, 1, 2], [ 3, 4, 5]], [[ 6, 7, 8], [ 9, 10, 11]]])
rearrange(a, 'b h w -> b (h w)')
array([[ 0, 1, 2, 3, 4, 5], [ 6, 7, 8, 9, 10, 11]])
a = np.arange(2*2*2*3).reshape(2, 2, 6)
rearrange(a, 'b q (h d) -> b q h d', d=2).shape
(2, 2, 3, 2)
a = np.arange(2*2*2*3, dtype=np.float32).reshape(2, 2, 3, 2)
reduce(a, 'b q h d -> b q h', 'mean')
array([[[ 0.5, 2.5, 4.5], [ 6.5, 8.5, 10.5]], [[12.5, 14.5, 16.5], [18.5, 20.5, 22.5]]], dtype=float32)
a = np.arange(1*2*3).reshape(1, 2, 3)
repeat(a, 'b h d -> b 2 h d')
array([[[[0, 1, 2], [3, 4, 5]], [[0, 1, 2], [3, 4, 5]]]])
%load_ext watermark
%watermark -d -u -v -iv
The watermark extension is already loaded. To reload it, use: %reload_ext watermark Last updated: 2023-12-29 Python implementation: CPython Python version : 3.11.4 IPython version : 8.14.0 numpy : 1.25.1 einops: 0.7.0