Это старая версия документа!
Основные операции линейной алгебры в numpy
Операции над векторами
Положим что одномерные массивы a
и b
являются векторами в трехмерном пространстве:
import numpy as np
a = np.array([1,1,1])
b = np.array([2,-1,3])
Операция | Запись | Результат |
---|---|---|
Длина вектора | np.linalg.norm(a) | 1.7320508075688772 |
Произведение вектора на скаляр | 2*a | array([2, 2, 2]) |
Сумма векторов | a + b | array([3, 0, 4]) |
Скалярное произведение | np.dot(a,b) | 4 |
Векторное произведение | np.cross(a,b) | array([ 4, -1, -3]) |
Операции над матрицами
Положим, что a
— вектор, а M
— матрица в трехмерном пространстве.
import numpy as np
a = np.array([1,1,1])
M = np.array([[1,0,1],[2,1,-1],[-1,0,-3]])
Операция | Запись | Результат |
---|---|---|
Определитель | np.linalg.det(M) | -2.0 |
След | np.trace(M) | -1 |
Форма | M.shape | (3, 3) |
Векторно-матричное умножение | np.matmul(a, M) | array([ 2, 1, -3]) |
Матричное умножение | np.matmul(M,M) | array([[ 0, 0, -2], [ 5, 1, 4], [ 2, 0, 8]]) |
Обратная матрица | np.linalg.inv(M) | array([[ 1.5, 0. , 0.5], [-3.5, 1. , -1.5], [-0.5, 0. , -0.5]]) |
Собственные числа и собственные векторы | np.linalg.eig(M) | (array([ 1. , 0.73205081, -2.73205081]), array([[ 0. , 0.11727205, -0.2405126 ], [ 1. , -0.99260257, 0.36940291], [ 0. , -0.03142295, 0.89760524]])) |
Транспонирование | M.T | array([[ 1, 2, -1], [ 0, 1, 0], [ 1, -1, -3]]) |
Нулевая матрица | np.zeros((3,3)) | array([[0., 0., 0.], [0., 0., 0.], [0., 0., 0.]]) |
Единичная матрица | np.eye(3) | array([[1., 0., 0.], [0., 1., 0.], [0., 0., 1.]]) |
Вращение координат
Вращение координат удобно задавать в виде матрицы поворота с помощью модуля scipy.spatial.transform
from scipy.spatial.transform import Rotation
#Вращение на 90 градусов вокруг оси X
MRot = Rotation.from_euler('x', [np.pi/2]).as_dcm()
#Для новых версий:
MRot = Rotation.from_euler('x', [np.pi/2]).as_matrix()
a = np.array([1,1,1])
rot_a = np.matmul(a, MRot)
Сопобы задания вращения
Способ задания | Описание | Пример |
---|---|---|
Углы Эйлера | Последовательность вращений вокруг осей координат | Rotation.from_euler('xy', [np.pi/2, -np.pi/6]) |
Матрица поворота | Матрица направляющих косинусов | Rotation.from_matrix(0,0,0],[0,0,0],[0,0,1) |
Вращение вокруг ветора | Вращение вокруг ветора единичной длинны на данный угол | Rotation.from_rotvec(np.pi/2 * np.array([0, 0, 1])) |
Функция на сетке
Важная особенность np.array
— возможность обходиться при вычислении значения функции без циклов.
import numpy as np
def f(x,y):
return x**2+2*x+6*y
s = np.linspace(1,7,3)
p = np.linspace(5,9,3)
v = f (s,p)
# v == array([ 33., 66., 117.])
S, P = np.meshgrid(s,p,indexing='ij')
v = f (S,P)
# array([[ 33., 45., 57.],
# [ 54., 66., 78.],
# [ 93., 105., 117.]])
В случае простой подстановки f (s,p)
будет массивы будут подставлены поэлементно. В случае подстановки с использованием meshgrid
из массивов будет построена сетка, в узлах которой будут пары элементов и функция будет рассчитана для каждого элемента сетки.
Дифференциальные операторы на сетке
Для расчетов производных на сетке будем использовать модуль findiff
pip (документация).
import numpy as np
from findiff import FinDiff
x = np.linspace(0, 10, 100)
dx = x[1] - x[0]
f = np.sin(x)
d_dx = FinDiff(0, dx, 1)
df_dx = d_dx(f)
Объект FinDiff
реализует дифференциальный оператор, аргументы: 0
— по первой оси, dx
— размер шага, 1
— первая производная.
df_dx
— массив np.array
со значениями производной f
в узлах сетки.
Дифференциальные операторы модуля findiff
Название | Значение | Запись | Вход | Выход |
---|---|---|---|---|
FinDiff | дифференциал | d/dx | скалярное поле | скалярное поле |
Gradient | градиент | ∇f | скалярное поле | векторное поле |
Laplacian | оператор Лапласа | ∇2 f | скалярное поле | векторное поле |
Divergence | дивергенция | ∇· f | векторное поле | скалярное поле |
Curl | ротор | ∇×f | векторное поле | векторное поле |
В 2D задаче
import numpy as np
from findiff import Gradient, Divergence, Laplacian
import matplotlib.pyplot as plt
#%%
borders = [-2*np.pi, 2*np.pi, -2*np.pi, 2*np.pi]
x = np.linspace(-2*np.pi, 2*np.pi, 30)
dx = x[1]-x[0]
y = np.linspace(-2*np.pi, 2*np.pi, 30)
dy = y[1]-y[0]
X, Y = np.meshgrid(x, y, indexing='ij')
f = Y*np.sin(X) + np.cos(Y)
#%%
plt.imshow(f.T, origin='lower', extent=borders)
contours = plt.contour(X, Y, f, origin='lower', colors = 'r')
plt.clabel(contours, colors = 'r')
plt.show()
#%%
grad = Gradient(h=[dx, dy])
grad_f = grad(f)
plt.imshow(f.T , origin='lower', extent=borders)
plt.colorbar()
plt.quiver(X,Y,grad_f[0],grad_f[1])
plt.show()
#%%
u = np.array((X**2-Y**2, Y**2-X))
div = Divergence(h=[dx, dy])
div_u = div(u)
plt.imshow(div_u.T,origin='lower', extent=borders)
plt.colorbar()
plt.quiver(X,Y,u[0],u[1])
plt.show()
Скалярная функция f и ее изолинии
Скалярная функция f и ее градиент
Векторная функция u и ее дивергенция
В 3D задаче
import numpy as np
from findiff import Gradient, Divergence, Laplacian, Curl
x = np.linspace(0, 10, 100)
dx = x[1]-x[0]
y = np.linspace(0, 10, 100)
dy = y[1]-y[0]
z = np.linspace(0, 10, 100)
dz = z[1]-z[0]
X, Y, Z = np.meshgrid(x, y, z, indexing='ij')
f = np.sin(X) * np.cos(Y) * np.sin(Z)
grad = Gradient(h=[dx, dy, dz])
grad_f = grad(f)
laplace = Laplacian(h=[dx, dy, dz])
laplace_f = laplace(f)
g = np.array([f, 2*f, 3*f])
div = Divergence(h=[dx, dy, dz])
div_g = div(g)
curl = Curl(h=[dx, dy, dz])
curl_g = curl(g)