Это старая версия документа!


Основные операции линейной алгебры в 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)

Функция на сетке

Важная особенность 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 из массивов будет построена сетка, в узлах которой будут пары элементов и функция будет рассчитана для каждого элемента сетки.

Дифференциальные операторы на сетке

Для расчетов производных на сетке будем использовать модуль findiffpip (документация).

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 векторное поле векторное поле
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)