You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

695 lines
178 KiB
Plaintext

{
"cells": [
{
"cell_type": "code",
"execution_count": 35,
"id": "cb0d4a44-e1b1-4b6c-a76a-20c30abce72c",
"metadata": {},
"outputs": [],
"source": [
"import numpy as np\n",
"import matplotlib as mpl\n",
"from numpy import float32, float64\n",
"import matplotlib.pyplot as plt\n",
"from functools import partial\n",
"import itertools\n",
"from collections import namedtuple"
]
},
{
"cell_type": "code",
"execution_count": 36,
"id": "f6800ffb-61d5-4fc7-99c8-414be78ffd56",
"metadata": {},
"outputs": [],
"source": [
"label_font = 12\n",
"markersize = 8"
]
},
{
"cell_type": "code",
"execution_count": 37,
"id": "b6ae5a80-7a8d-48c0-aa49-70d6d612c54f",
"metadata": {},
"outputs": [],
"source": [
"def get_a_ij(i: int, j: int, n: int):\n",
" if i == j:\n",
" return 2.0 + (float64(i) / float64(n)) ** 2.0\n",
" elif j == i - 1 or j == i + 1:\n",
" return -1.0\n",
" elif (i == 0 and j == n - 1) or (i == n - 1 and j == 0):\n",
" return -1.0\n",
" else:\n",
" return 0.0\n",
"\n",
"\n",
"def get_matrix_a(n: int) -> np.array:\n",
" a = np.zeros((n, n))\n",
" from_0_to_n = [i for i in range(n)]\n",
" for i, j in itertools.product(from_0_to_n, from_0_to_n):\n",
" a[i, j] = get_a_ij(i, j, n)\n",
" return a\n",
"\n",
"\n",
"def get_f(n: int) -> np.array:\n",
" def get_f_i(i):\n",
" return (1.0 + n**2.0 * np.sin(np.pi / n) ** 2.0) * np.sin(\n",
" (2.0 * np.pi * i) / float64(n)\n",
" )\n",
"\n",
" return np.array([get_f_i(i) for i in range(n)])"
]
},
{
"cell_type": "code",
"execution_count": 38,
"id": "ea07e9f0-f0cf-4d01-857f-96e8b50ee21c",
"metadata": {},
"outputs": [],
"source": [
"# Векторные и подчиненные им матричные нормы\n",
"def vec_norm_max(vector: np.array):\n",
" # |v|_1 = max(abs(v_i))\n",
" return np.abs(vector).max()\n",
"\n",
"\n",
"def vec_norm_sum(vector: np.array):\n",
" # |v|_2 = sum(abs(v_i))\n",
" return np.abs(vector).sum()\n",
"\n",
"def vec_norm_euclid(vector: np.array):\n",
" return np.sqrt((vector ** 2.0).sum())\n",
"\n",
"\n",
"def row_sum_norm(matrix: np.array):\n",
" # |A|_1 = max( sum(a_ij) for j ) over 1 <= i <= n\n",
" return np.sum(np.abs(matrix), axis=1).max()\n",
"\n",
"\n",
"def column_sum_norm(matrix: np.array):\n",
" # |A|_2 = max( sum(a_ij) for i ) over 1 <= j <= n\n",
" return np.sum(np.abs(matrix), axis=0).max()\n",
"\n",
"\n",
"def spectral_norm(matrix: np.array):\n",
" matrix_h = matrix.conj().T\n",
" eigenvalues = np.linalg.eigvals(np.matmul(matrix_h, matrix))\n",
" return np.sqrt(eigenvalues.max())\n",
"\n",
"\n",
"def mu(matrix_a: int, norm):\n",
" inv_matrix_a = np.linalg.inv(matrix_a)\n",
" norm_a = norm(matrix_a)\n",
" norm_inv_a = norm(inv_matrix_a)\n",
" return norm_a * norm_inv_a\n"
]
},
{
"cell_type": "code",
"execution_count": 39,
"id": "c9ae2bd0-1b87-46fc-96d7-c21a924bf72c",
"metadata": {},
"outputs": [],
"source": [
"EPS = 10e-8\n",
"\n",
"def lup(matrix):\n",
" if matrix.shape[0] != matrix.shape[1]:\n",
" raise AttributeError(\"Только квадратные матрицы подходят для LUP\")\n",
"\n",
" n = matrix.shape[0]\n",
" p = np.identity(n)\n",
" \n",
" for i in range(0, n - 1):\n",
"\n",
" max_idx = i\n",
" for k in range(i + 1, n):\n",
" # Найдем максимальный опорный элемент в столбце\n",
" if abs(matrix[k][i]) > abs(matrix[max_idx][i]):\n",
" max_idx = k\n",
" \n",
" if abs(matrix[max_idx][i]) <= EPS:\n",
" raise ArithmeticError(\"Опорный элемент равен нулю\")\n",
"\n",
" if max_idx != i:\n",
" matrix[[i, max_idx]] = matrix[[max_idx, i]]\n",
" p[[i, max_idx]] = p[[max_idx, i]]\n",
"\n",
" for j in range(i + 1, n):\n",
" matrix[j][i] /= matrix[i][i]\n",
" for k in range(i + 1, n):\n",
" matrix[j][k] -= matrix[j][i] * matrix[i][k]\n",
"\n",
" l = np.zeros(matrix.shape)\n",
" for i in range(n):\n",
" for j in range(n):\n",
" if j < i:\n",
" l[i][j] = matrix[i][j]\n",
" if j == i:\n",
" l[i][j] = 1\n",
"\n",
" u = np.zeros(matrix.shape)\n",
" for i in range(n):\n",
" for j in range(n):\n",
" if j >= i:\n",
" u[i][j] = matrix[i][j]\n",
" return l, u , p"
]
},
{
"cell_type": "code",
"execution_count": 40,
"id": "ffd52a5e-3bd9-4170-bcec-db917d5e7618",
"metadata": {},
"outputs": [],
"source": [
"def lower_solve(l: np.array, f: np.array):\n",
" assert l.ndim == 2 and l.shape[0] == l.shape[1]\n",
" dim = l.shape[0]\n",
"\n",
" x = np.zeros(dim)\n",
" for i in range(dim):\n",
" tmp = f[i]\n",
" for j in range(i):\n",
" tmp -= l[i, j] * x[j]\n",
" x[i] = tmp / l[i, i]\n",
"\n",
" return x\n",
"\n",
"\n",
"def upper_solve(u: np.array, f: np.array):\n",
" # Solve Ux = f, where U is upper triangular\n",
" assert u.ndim == 2 and u.shape[0] == u.shape[1]\n",
" dim = u.shape[0]\n",
"\n",
" x = np.zeros(dim)\n",
" for i in range(dim - 1, -1, -1):\n",
" tmp = f[i]\n",
" for j in range(i + 1, dim):\n",
" tmp -= u[i, j] * x[j]\n",
" x[i] = tmp / u[i, i]\n",
"\n",
" return x\n",
"\n",
"\n",
"def lu_solve(l, u, f):\n",
" # Ax = f, where A = LU\n",
" # L(Ux) = f, Ux = y <=> y = Ux\n",
" y = lower_solve(l, f)\n",
" x = upper_solve(u, y)\n",
" return x"
]
},
{
"cell_type": "code",
"execution_count": 41,
"id": "b10516d2-d020-4695-a6b3-65efb37333c3",
"metadata": {},
"outputs": [],
"source": [
"def lup_solve(a: np.array, f: np.array):\n",
" l, u, p = lup(a)\n",
" z = np.matmul(p, f)\n",
" x = lu_solve(l, u, z)\n",
" return x"
]
},
{
"cell_type": "code",
"execution_count": 42,
"id": "0d75a610-889b-4c85-8ed4-a03d2aa7a820",
"metadata": {},
"outputs": [],
"source": [
"def simple_iter(\n",
" a: np.array,\n",
" f: np.array,\n",
" tau: float64,\n",
" eps: float64,\n",
" norm = vec_norm_euclid,\n",
" max_iter: int = 1000000,\n",
") -> np.array:\n",
" assert a.ndim == 2\n",
" assert f.ndim == 1\n",
" assert a.shape[0] == a.shape[1]\n",
" assert a.shape[0] == f.shape[0]\n",
"\n",
" dim = a.shape[0]\n",
" tau_f = f * tau\n",
" cur = np.zeros(dim)\n",
" b = np.eye(dim) - tau * a\n",
" err_list = []\n",
"\n",
" for i in range(max_iter):\n",
" cur = np.matmul(b, cur) + tau_f\n",
" err = f - np.matmul(a, cur)\n",
" norm_err = norm(err)\n",
" err_list.append(norm_err)\n",
"\n",
" if norm_err < eps:\n",
" return (cur, err_list)\n",
"\n",
" raise RuntimeWarning(\"Простая итерация расходится\")"
]
},
{
"cell_type": "code",
"execution_count": 43,
"id": "8dab9094-becf-4acb-b1fa-b370bac2cb18",
"metadata": {},
"outputs": [],
"source": [
"Gershgorin = namedtuple(\"Gershgorin\", \"a r\")\n",
"\n",
"\n",
"def get_gershgorin(a: np.array):\n",
" assert a.ndim == 2\n",
" assert a.shape[0] == a.shape[1]\n",
"\n",
" circles = []\n",
" for i, row in enumerate(a):\n",
" a_ii = a[i, i]\n",
" r_i = np.abs(row).sum() - a_ii\n",
" circles.append(Gershgorin(a_ii, r_i))\n",
"\n",
" return circles"
]
},
{
"cell_type": "code",
"execution_count": 44,
"id": "631382d5-81ad-4963-b168-9916848eb4ca",
"metadata": {},
"outputs": [],
"source": [
" # Коэффициенты полинома\n",
"def compute_ch_poly(a: np.array, y0: np.array):\n",
" assert a.ndim == 2\n",
" assert y0.ndim == 1\n",
" assert a.shape[0] == a.shape[1]\n",
" assert a.shape[0] == y0.shape[0]\n",
"\n",
" dim = a.shape[0]\n",
" y_matrix = np.zeros((dim, dim))\n",
" y = y0\n",
"\n",
" for i in range(dim - 1, -1, -1):\n",
" y_matrix[:, i] = y\n",
" y = np.matmul(a, y)\n",
"\n",
" ps = lup_solve(y_matrix, y)\n",
"\n",
" return np.concatenate([np.ones(1), -1.0 * ps])"
]
},
{
"cell_type": "code",
"execution_count": 45,
"id": "d20a06fa-4757-4752-b7f3-ec831d788c15",
"metadata": {},
"outputs": [],
"source": [
"def plot_gershgorin(ax: plt.Axes, eigvals: np.array, circles: list, **kwargs):\n",
" # https://github.com/WenqiJiang/matplotlib-templates/blob/master/plot/plot.py\n",
"\n",
" max_x = 0.0\n",
" min_x = 0.0\n",
"\n",
" for a, r in circles:\n",
" circle = plt.Circle((a.real, 0.0), r, **kwargs)\n",
" ax.add_patch(circle)\n",
"\n",
" max_x = max(max_x, a.real + r)\n",
" min_x = min(min_x, a.real - r)\n",
"\n",
" max_dim = max(abs(max_x), abs(min_x))\n",
" ax.set_xlim((min_x, max_x))\n",
" ax.set_ylim((-max_dim, max_dim))\n",
"\n",
" ax.get_xaxis().set_visible(True)\n",
" ax.get_yaxis().set_visible(True)\n",
"\n",
" ax.grid(True, which=\"both\")\n",
" ax.set_xlabel(\"$Re(\\lambda)$\", fontsize=label_font)\n",
" ax.set_ylabel(\"$Im(\\lambda)$\", fontsize=label_font)\n",
"\n",
" plt.rcParams.update({\"figure.autolayout\": True})\n",
"\n",
" ys = np.zeros(eigvals.shape[0])\n",
" ax.scatter(eigvals, ys, color=\"red\")"
]
},
{
"cell_type": "code",
"execution_count": 46,
"id": "dad0efea-b922-47d8-8d1d-f4a1b710e960",
"metadata": {},
"outputs": [],
"source": [
"def plot_function(ax: plt.Axes, xs: np.array, ys: list, **kwargs):\n",
" # https://github.com/WenqiJiang/matplotlib-templates/blob/master/plot/plot.py\n",
"\n",
" plot = ax.plot(xs, ys, **kwargs)\n",
"\n",
" ax.get_xaxis().set_visible(True)\n",
" ax.get_yaxis().set_visible(True)\n",
"\n",
" ax.grid(True, which=\"both\")\n",
" ax.set_xlabel(\"$x$\", fontsize=label_font)\n",
" ax.set_ylabel(\"$y$\", fontsize=label_font)\n",
"\n",
" plt.rcParams.update({\"figure.autolayout\": True})\n",
" return plot"
]
},
{
"cell_type": "code",
"execution_count": 47,
"id": "17559b3b-9771-4f00-a157-c11dde9c9a69",
"metadata": {},
"outputs": [],
"source": [
"def newton_solve(x0, f, der, eps: float64, max_iter=1000000) -> np.array:\n",
" cur = x0\n",
"\n",
" for i in range(max_iter):\n",
" delta = f(cur) / der(cur)\n",
" cur -= delta\n",
"\n",
" if abs(delta) < eps:\n",
" return cur\n",
"\n",
" raise RuntimeWarning(\n",
" \"Метод Ньютона не сходится\")\n",
" "
]
},
{
"cell_type": "code",
"execution_count": 48,
"id": "9bc9ae73-4459-407b-b006-69d884826e4b",
"metadata": {},
"outputs": [],
"source": [
"def get_roots(coeffs: np.array, stpts: np.array, eps):\n",
" def f(x):\n",
" return np.polyval(coeffs, x)\n",
"\n",
" def der(x):\n",
" return np.polyval(np.polyder(coeffs), x)\n",
"\n",
" return np.array([newton_solve(st, f, der, eps=eps) for st in stpts])"
]
},
{
"cell_type": "code",
"execution_count": 49,
"id": "a8c79ed1-fc90-4cf3-bbf0-fbb3216ea6e5",
"metadata": {},
"outputs": [],
"source": [
" def print_sep():\n",
" print(\"\\n----\\n\")"
]
},
{
"cell_type": "code",
"execution_count": 50,
"id": "eb927b34-fe85-41f8-af0f-c3b7cab5e7f2",
"metadata": {},
"outputs": [],
"source": [
"def do_solve_with_tau(\n",
" a, f, eps, tau, comment=\"any\", norm = vec_norm_euclid\n",
"):\n",
" (solution, errs) = simple_iter(a, f, tau, eps)\n",
" exact_sol = np.linalg.solve(a, f)\n",
" delta = solution - exact_sol\n",
"\n",
" print_sep()\n",
" print(f\"Solution with tau = {tau} ({comment}):\")\n",
" print(solution)\n",
" print(f\"Norm of |exact - sol| = {norm(delta)}\")\n",
"\n",
" return errs"
]
},
{
"cell_type": "code",
"execution_count": 51,
"id": "acd33567-6f0c-4544-b46a-a99199122925",
"metadata": {},
"outputs": [],
"source": [
"n = 6 # size on system\n",
"a = get_matrix_a(n)\n",
"f = get_f(n)"
]
},
{
"cell_type": "code",
"execution_count": 52,
"id": "8dc8a48c-38bd-4d12-a74a-70280068234f",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"a = \n",
"[[ 2. -1. 0. 0. 0. -1. ]\n",
" [-1. 2.02777778 -1. 0. 0. 0. ]\n",
" [ 0. -1. 2.11111111 -1. 0. 0. ]\n",
" [ 0. 0. -1. 2.25 -1. 0. ]\n",
" [ 0. 0. 0. -1. 2.44444444 -1. ]\n",
" [-1. 0. 0. 0. -1. 2.69444444]]\n",
"f = \n",
"[ 0.00000000e+00 8.66025404e+00 8.66025404e+00 1.22464680e-15\n",
" -8.66025404e+00 -8.66025404e+00]\n"
]
}
],
"source": [
"print(f'a = \\n{a}')\n",
"print(f'f = \\n{f}')"
]
},
{
"cell_type": "code",
"execution_count": 53,
"id": "d84ffb6f-e4e6-4c0d-a581-29e0664bfc3c",
"metadata": {},
"outputs": [],
"source": [
"coeffs = compute_ch_poly(a, np.ones(n))"
]
},
{
"cell_type": "code",
"execution_count": 56,
"id": "50a89d66-c07a-4626-8976-b75a0d527a57",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(0.0, 4.694444444444445)"
]
},
"execution_count": 56,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 1170x830 with 2 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# Plot polynomial to find starting points for newton's method\n",
"fig, (ax_gersh, ax_poly) = plt.subplots(2, 1, figsize=(11.7, 8.3))\n",
"plot_gershgorin(ax_gersh, np.array([]), get_gershgorin(a), alpha=0.5)\n",
"left, right = ax_gersh.get_xlim()\n",
"xs = np.linspace(left, right, 1000)\n",
"plot_function(ax_poly, xs, np.polyval(coeffs, xs))\n",
"ax_poly.set_xlim(ax_gersh.get_xlim())"
]
},
{
"cell_type": "code",
"execution_count": 57,
"id": "18ff4e10-6a90-4a18-8988-41b72ae31d9d",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"|lambda_0' - 2.0| <= 2.0\n",
"|lambda_1' - 2.0277777777777777| <= 2.0\n",
"|lambda_2' - 2.111111111111111| <= 1.9999999999999996\n",
"|lambda_3' - 2.25| <= 2.0\n",
"|lambda_4' - 2.4444444444444446| <= 2.0\n",
"|lambda_5' - 2.6944444444444446| <= 2.0\n",
"\n",
"-- Собственные значения (Крылов) --\n",
"\n",
"lambda_0 = 0.21074228926813401\n",
"lambda_1 = 1.1723536556934515\n",
"lambda_2 = 1.3444997499925933\n",
"lambda_3 = 3.172098845043765\n",
"lambda_4 = 3.322122246700257\n",
"lambda_5 = 4.305960991079286\n",
"\n",
"-- Собственные значения (Numpy) --\n",
"\n",
"lambda_0 = 0.21074228926852\n",
"lambda_1 = 1.172353655693412\n",
"lambda_2 = 1.344499749992459\n",
"lambda_3 = 3.1720988450437133\n",
"lambda_4 = 3.3221222467005886\n",
"lambda_5 = 4.3059609910790835\n",
"\n",
"----\n",
"\n",
"tau_opt_numpy\t= 0.44280083854569274\n",
"tau_opt_krylov\t= 0.4428008385457108\n",
"\n",
"----\n",
"\n",
"Solution with tau = 0.2 (some value):\n",
"[ 5.3478266 12.93976584 12.23088945 4.22074719 -2.73420791 -2.24411219]\n",
"Norm of |exact - sol| = 4.551685315972811e-06\n",
"\n",
"----\n",
"\n",
"Solution with tau = 0.4428008385457108 (opt with krylov):\n",
"[ 5.34782662 12.93976583 12.23088947 4.22074718 -2.73420789 -2.24411221]\n",
"Norm of |exact - sol| = 4.540529116882713e-06\n",
"\n",
"----\n",
"\n",
"Solution with tau = 0.44280083854569274 (opt with numpy):\n",
"[ 5.34782662 12.93976583 12.23088947 4.22074718 -2.73420789 -2.24411221]\n",
"Norm of |exact - sol| = 4.540529119850784e-06\n"
]
}
],
"source": [
" eps = 1e-6\n",
"\n",
"# Шаг 2. Подсчет собственных значений\n",
"for i, (c, r) in enumerate(get_gershgorin(a)):\n",
" print(f\"|lambda_{i}' - {c}| <= {r}\")\n",
"\n",
"# Метод Крылова\n",
"krylov_eigvals = get_roots(coeffs, [0.0, 1.0, 1.5, 3.0, 3.5, 4.25], eps=eps)\n",
"exact_eigvals = np.linalg.eigvals(a)\n",
"krylov_eigvals.sort()\n",
"exact_eigvals.sort()\n",
"\n",
"print(\"\\n-- Собственные значения (Крылов) --\\n\")\n",
"for i, v in enumerate(krylov_eigvals):\n",
" print(f\"lambda_{i} = {v}\")\n",
"\n",
"print(\"\\n-- Собственные значения (Numpy) --\\n\")\n",
"for i, v in enumerate(exact_eigvals):\n",
" print(f\"lambda_{i} = {v}\")\n",
"\n",
"tau_any = 0.20\n",
"tau_opt_krylov = 2.0 / (krylov_eigvals.min() + krylov_eigvals.max())\n",
"tau_opt_numpy = 2.0 / (exact_eigvals.min() + exact_eigvals.max())\n",
"\n",
"print_sep()\n",
"print(f\"tau_opt_numpy\\t= {tau_opt_numpy}\")\n",
"print(f\"tau_opt_krylov\\t= {tau_opt_krylov}\")\n",
"\n",
"bound_solve = partial(do_solve_with_tau, a=a, f=f, eps=eps)\n",
"\n",
"errs_some = bound_solve(tau=tau_any, comment=\"some value\")\n",
"errs_krylov = bound_solve(tau=tau_opt_krylov, comment=\"opt with krylov\")\n",
"errs_numpy = bound_solve(tau=tau_opt_numpy, comment=\"opt with numpy\")"
]
},
{
"cell_type": "code",
"execution_count": 55,
"id": "f029039d-cc38-451d-b03b-512d9eab7829",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<matplotlib.legend.Legend at 0x7f66e303ab50>"
]
},
"execution_count": 55,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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qVKl8z5myZIldOzYMVfPv2PHDqpWrZqrYwcOHEhqairPPffcRY89evQo1atXP+f2mJiY7PutHAcwb948Ro4cyauvvsoTTzyRfXvjxo2pXbs2X375JXfccUeu3otVVnL6Cw2IRERERERERAqhtWvXEhMTc8HhEECLFi347bffcvWc5cuXz9Vxw4YN49NPP+Wtt96iRYsWuXrMhS61+ut9uT1u+PDh1KhRg0GDBp119lO1atUICwtj+/btOT7H4sWLcz0wW7VqVY6DICs5/YUGRCIiIiIiIlKkhbmcbHrhenw+HynuFCKjIm1fpDrMdfkLLa9duzZXW8xHRETkeiv6v18ylZORI0cyatQoRo8ezcMPP5yr5y1ZsmSOZ9UcO3YM+N+ZN7k97uDBg6xZswaAkJCQHF+zePHiOd5ep04d3nvvvVzlrly5co635zanP9GASERERERERIo0wzAIDw7C5/ORFewkPDjI9gHR5TJNkw0bNvDQQw9d9Ni8vMRs5MiRjBgxghEjRvDss8/mNi6NGjVi2rRpZGVlnTWEWr9+PQANGza0dNyZhbHHjRtHmzZtcnzNGjVq5Hh7uXLl6N+/f65y+3y+HLeSz21Of6IBkYiIiIiIiEghc+zYMU6dOkW1atUuemxeXWL24osvMmLECIYOHcrzzz+f66wAvXv35r333uPzzz/n1ltvzb79o48+onz58lx11VWWjjtzho5hGFxxxRWWsuSF3Ob0JxoQiYiIiIiIiBQyISEhuFwuEhISaNy4MU2aNCE6OjrHYyMjIy97iPL6668zfPhwbrjhBrp168Yvv/xy1v1XX3119v9esmQJnTp1Yvjw4QwfPhyALl26EBcXx0MPPYTb7aZmzZpMmzaNBQsW8Mknn+B0Oi0dV6NGDTp27MjQoUM5efIkV111FaZpcuDAAX744QfuueceOnTocFnv+UJymxPgm2++ITU1lZSUFAA2bdrErFmzAOjatSvh4eH5lvOvNCASERERERERKWQiIiJ45ZVXeO2112jfvj2bN28+74AoL8ydOxeABQsWsGDBgnPuN03zrP/t9Xrx+XxnHfPFF1/w3HPPMXz4cI4dO0bdunWZNm0at9122yUdN2fOHF5++WWmTJnCqFGjCAsLo3LlyrRr1y7Xay5djtzmfOihh9i1a1f2zzNnzmTmzJmAtV3jLpdh/vW3JOfldruJjo4mOTmZqKgou+NcEo/Hw/z58+natSsul8vuOBIA1BmxQn0Rq9QZsUqdEavUGclJeno6O3bsoFq1aoSGhp5135n1ZKKiogJ+DSIpGHZ35kJ9BmuzDDVeRERERERERKSI04BIRERERERERKSI04BIRERERERERKSI04BIRERERERERKSI0y5mRcSyLUeY8tNOgk8adLU7jIiIiIiIiIj4FQ2IiogjKRkk/HGYqhE6aUxEREREREREzqZpQRHRokoJAPakQobHa3MaEREREREREfEnGhAVEZVjwomNCMZrGmzY77Y7joiIiIiIiIj4EQ2IigjDMGhWqTgAq3afsDWLiIiIiIiIiPiXIjUg6t27NyVKlODmm2+2O4otWlQpDsAaDYhERERERERE5C+K1IDo0UcfZcqUKXbHsE3z/z+DaPWeE5imaW8YEREREREREfEbRWpA1LFjRyIjI+2OYZv65aM
"text/plain": [
"<Figure size 1170x830 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"fig, ax = plt.subplots(1, 1, figsize=(11.7, 8.3))\n",
"\n",
"ax.set_yscale('log')\n",
"plot_some = plot_function(ax, np.arange(0, len(errs_some)), errs_some)\n",
"plot_krylov = plot_function(ax, np.arange(0, len(errs_krylov)), errs_krylov)\n",
"plot_numpy = plot_function(ax, np.arange(0, len(errs_numpy)), errs_numpy)\n",
"\n",
"ax.legend([plot_some[0], plot_krylov[0], plot_numpy[0]],\n",
" [f'$\\\\tau = {tau_any:1.2e}$',\n",
" f'$\\\\tau = {tau_opt_krylov:1.2e}$',\n",
" f'$\\\\tau = {tau_opt_numpy:1.2e}$'],\n",
" loc='upper right', fontsize=label_font)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "6f2c3236-f444-4fcb-a8d4-0c97bc28b6d1",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.5"
}
},
"nbformat": 4,
"nbformat_minor": 5
}