Различия

Показаны различия между двумя версиями страницы.

Ссылка на это сравнение

Предыдущая версия справа и слева Предыдущая версия
Следующая версия
Предыдущая версия
calc:vector [2021/02/10 15:34]
root [Операции над матрицами]
calc:vector [2022/08/10 23:55] (текущий)
root
Строка 1: Строка 1:
-====== Основные операции линейной алгебры в numpy ======+<div slide>
  
-==== Операции над векторами ====+===== Функция на сетке =====
  
-Положим что одномерные массивы ''a'' и ''b'' являются векторами в трехмерном пространстве:+Важная особенность ''np.array'' — возможность обходиться при вычислении значения функции **без циклов**.
  
 <sxh python> <sxh python>
 import numpy as np import numpy as np
  
-= np.array([1,1,1]) +def f(x,y): 
-= np.array([2,-1,3])+    return x**2+2*x+6*y 
 + 
 += np.linspace(1,7,3) 
 +p = np.linspace(5,9,3) 
 + 
 +v = f (s,p) # Функция f была применена поэлементно  
 +# v == array([  33.  66. 117.]) 
 + 
 +S, P = np.meshgrid(s,p,indexing='ij'
 +v = f (S,P) # Функция f была применена для каждой пары из s и p 
 +array([[ 33. 45. 57.], 
 +#       [ 54.,  66.,  78.], 
 +#       [ 93., 105., 117.]])
 </sxh> </sxh>
  
-^ Операция ^ Запись ^ Результат ^ 
-| Длина вектора | ''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])'' | 
  
-==== Операции над матрицами ====+В случае простой подстановки ''f (s,p)'' будет массивы будут подставлены поэлементно. В случае подстановки с использованием ''meshgrid'' из массивов будет построена сетка, в узлах которой будут пары элементов и функция будет рассчитана для каждого элемента сетки.
  
-Положим, что ''a'' — вектор, а ''M'' — матрица в трехмерном пространстве.+</div><div slide> 
 + 
 +===== Дифференциальные операторы на сетке ===== 
 + 
 +Для расчетов производных на сетке будем использовать модуль ''findiff''<sup>pip</sup> ([[https://findiff.readthedocs.io|документация]]).
  
 <sxh python> <sxh python>
 import numpy as np import numpy as np
 +from findiff import FinDiff
  
-= np.array([1,1,1]) += np.linspace(010100) 
-= np.array([[1,0,1],[2,1,-1],[-1,0,-3]])+dx = x[1] - x[0] 
 += np.sin(x) 
 + 
 +d_dx = FinDiff(0, dx, 1
 +df_dx = d_dx(f)
 </sxh> </sxh>
  
-Операция ^ Запись ^ Результат +</div><div slide> 
-| Определитель | ''np.linalg.det(M)'' ''-2.0'' + 
-| След ''np.trace(M)'' ''-1'' +Объект ''FinDiff'' реализует дифференциальный оператор, аргументы: ''0'' — по первой оси, ''dx'' — размер шага, ''1'' — первая производная.  
-| Форма ''M.shape'' ''(3, 3)'' + 
-| Векторно-матричное умножение | ''np.matmul(a, M)'' |''array([ 2,  1, -3])'' | +''df_dx'' — массив ''np.array'' со значениями производной ''f'' в узлах сетки. Модуль ''findiff'' не изменяет размер массива т.к. на краях применяется схема дифференциирование вперед или назад соответственно, а по остальному объему массива используется центральная схема. 
-Матричное умножение | ''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]])%%'' +</div><div slide> 
-Собственные числа и собственные векторы ''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]])%%'' | +==== Дифференциальные операторы модуля findiff  ==== 
-| Нулевая матрица | ''%%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.]])%%'' |+^ Название ^ Значение ^ Запись ^ Вход ^ Выход ^ 
 +FinDiff дифференциал d/dx скалярное поле | скалярное поле | 
 +Gradient градиент | ∇f | скалярное поле | векторное поле | 
 +| Laplacian | оператор Лапласа | ∇<sup>2</sup>скалярное поле | векторное поле 
 +Divergence | дивергенция | ∇· f | векторное поле | скалярное поле | 
 +| Curl | ротор | ∇×f | векторное поле | векторное поле | 
 + 
 +</div><div slide> 
 + 
 +==== В 2D задаче  ==== 
 + 
 +<sxh python> 
 +import numpy as np 
 +from findiff import Gradient, Divergence, Laplacian 
 +import matplotlib.pyplot as plt 
 + 
 +#%% 
 + 
 +borders = [-2*np.pi2*np.pi, -2*np.pi2*np.pi] 
 + 
 +x = np.linspace(-2*np.pi2*np.pi30) 
 +dx = x[1]-x[0] 
 +y = np.linspace(-2*np.pi2*np.pi30) 
 +dy = y[1]-y[0
 + 
 +X, Y = np.meshgrid(xy, 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**2Y**2-X)) 
 + 
 +div = Divergence(h=[dxdy]) 
 +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() 
 + 
 +</sxh> 
 + 
 +== Скалярная функция f и ее изолинии == 
 + 
 +{{:calc:f_foo.png?400|Скалярная функция f и ее изолинии}} 
 + 
 +== Скалярная функция f и ее градиент == 
 + 
 +{{:calc:f_grad_foo.png?400|Скалярная функция f и ее градиент}} 
 + 
 +== Векторная функция u и ее дивергенция == 
 +{{:calc:f_div_foo.png?400|Векторная функция u и ее дивергенция}} 
 + 
 +</div><div slide> 
 + 
 +==== В 3D задаче  ==== 
 +<sxh python> 
 +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(010100) 
 +dz = z[1]-z[0
 + 
 +X, Y, Z = np.meshgrid(xy, z, indexing='ij'
 +f = np.sin(X) * np.cos(Y) * np.sin(Z) 
 + 
 +grad = Gradient(h=[dxdy, 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) 
 +</sxh>
  
 +</div>