Files
numethods/tutorials/tutorial2_linear_systems.ipynb
2025-09-17 13:28:33 +03:00

318 lines
40 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{
"cells": [
{
"cell_type": "markdown",
"id": "d3933270",
"metadata": {},
"source": [
"# Tutorial 2 - Solving Linear Systems\n",
"\n",
"In this notebook, we will study numerical methods for solving systems of linear equations:\n",
"\n",
"$$\n",
"A x = b, \\quad A \\in \\mathbb{R}^{n \\times n}, \\, x, b \\in \\mathbb{R}^n.\n",
"$$\n",
"## Motivation\n",
"Why we care about solving Ax=b? in numerical methods (e.g., arises in ODEs, PDEs, optimization, physics).\n",
"\n",
"Exact solution: $x = A^{-1}b$, but computing $A^{-1}$ explicitly is costly/unstable.\n",
"\n",
"Numerical algorithms instead use factorizations or iterative schemes.\n",
"\n",
"Such systems appear everywhere in scientific computing:\n",
"- discretization of differential equations (ODEs, PDEs),\n",
"- optimization problems,\n",
"- physical simulations,\n",
"- statistical models.\n",
"\n",
"We will study **direct methods** (exact in theory) and **iterative methods** (successive approximations)."
]
},
{
"cell_type": "markdown",
"id": "5fe78c6e",
"metadata": {},
"source": [
"## 1. Direct Methods\n",
"Introduce algorithms that give the solution in a finite number of steps (up to roundoff):\n",
"\n",
"- Gauss-Jordan elimination (concept, matrix reduction).\n",
"\n",
"- LU decomposition (and forward/backward substitution).\n",
"\n",
"- Cholesky decomposition (special case for symmetric positive definite matrices).\n",
"\n",
"### 1.1 Gauss-Jordan Elimination\n",
"We augment $A$ with $b$ and apply row operations until $A$ becomes the identity:\n",
"$$\n",
"[A | b] \\;\\longrightarrow\\; [I | x].\n",
"$$"
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "9bf371eb",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"GaussJordan solution: Vector([7.111111111111111, -3.2222222222222223])\n"
]
}
],
"source": [
"from numethods.linalg import Matrix, Vector\n",
"from numethods.solvers import GaussJordan\n",
"\n",
"A = Matrix([[2, 1], [5, 7]])\n",
"b = Vector([11, 13])\n",
"solver = GaussJordan(A)\n",
"x = solver.solve(b)\n",
"print(\"GaussJordan solution:\", x)"
]
},
{
"cell_type": "markdown",
"id": "a45de9c0",
"metadata": {},
"source": [
"### 1.2 LU Decomposition\n",
"\n",
"Factorization:\n",
"$$\n",
"A = L U,\n",
"$$\n",
"with $L$ lower-triangular, $U$ upper-triangular."
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "7211fd5a",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"LU solution: Vector([1.0, 2.0])\n"
]
}
],
"source": [
"from numethods.solvers import LUDecomposition\n",
"\n",
"A = Matrix([[3, 1], [6, 3]])\n",
"b = Vector([5, 12])\n",
"solver = LUDecomposition(A)\n",
"x = solver.solve(b)\n",
"print(\"LU solution:\", x)"
]
},
{
"cell_type": "markdown",
"id": "476368f3",
"metadata": {},
"source": [
"### 1.3 Cholesky Decomposition\n",
"\n",
"For symmetric positive-definite (SPD) matrices:\n",
"$$\n",
"A = L L^T.\n",
"$$"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "29c710f2",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Cholesky solution: Vector([1.1666666666666665, 0.6666666666666667])\n"
]
}
],
"source": [
"from numethods.solvers import Cholesky\n",
"\n",
"A = Matrix([[4, 2], [2, 4]])\n",
"b = Vector([6, 5])\n",
"solver = Cholesky(A)\n",
"x = solver.solve(b)\n",
"print(\"Cholesky solution:\", x)"
]
},
{
"cell_type": "markdown",
"id": "c8b85927",
"metadata": {},
"source": [
"## 2. Iterative Methods\n",
"\n",
"### 2.1 Jacobi Iteration\n",
"\n",
"Update:\n",
"$$\n",
"x_i^{(k+1)} = \\frac{1}{a_{ii}}\\Big(b_i - \\sum_{j\\ne i} a_{ij}x_j^{(k)}\\Big).\n",
"$$"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "ebd0b31c",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Jacobi solution: Vector([4.999999991891302, 4.999999985914916, 4.999999984848761, 4.999999987766864])\n"
]
}
],
"source": [
"from numethods.solvers import Jacobi\n",
"\n",
"A = Matrix([[4, -1, 0, 0],\n",
" [-1, 4, -1, 0],\n",
" [0, -1, 4, -1],\n",
" [0, 0, -1, 3]])\n",
"b = Vector([15, 10, 10, 10])\n",
"solver = Jacobi(A, b, tol=1e-8, max_iter=100)\n",
"x = solver.solve()\n",
"print(\"Jacobi solution:\", x)"
]
},
{
"cell_type": "markdown",
"id": "3e1bd09d",
"metadata": {},
"source": [
"### 2.2 Gauss-Seidel Iteration\n",
"\n",
"Update:\n",
"$$\n",
"x_i^{(k+1)} = \\frac{1}{a_{ii}}\\Big(b_i - \\sum_{j<i} a_{ij}x_j^{(k+1)} - \\sum_{j>i} a_{ij}x_j^{(k)}\\Big).\n",
"$$"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "5bea9ffe",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"GaussSeidel solution: Vector([4.999999973600783, 4.999999981068349, 4.999999991156471, 4.999999997052157])\n"
]
}
],
"source": [
"from numethods.solvers import GaussSeidel\n",
"\n",
"solver = GaussSeidel(A, b, tol=1e-8, max_iter=100)\n",
"x = solver.solve()\n",
"print(\"GaussSeidel solution:\", x)"
]
},
{
"cell_type": "markdown",
"id": "4f365016",
"metadata": {},
"source": [
"## 3. Convergence\n",
"\n",
"The residual is:\n",
"$$\n",
"r^{(k)} = b - A x^{(k)}.\n",
"$$\n",
"\n",
"A good stopping rule: $\\|r^{(k)}\\| < tol$."
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "993a9d44",
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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",
"text/plain": [
"<Figure size 640x480 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"import matplotlib.pyplot as plt\n",
"\n",
"solver_j = Jacobi(A, b, tol=1e-12, max_iter=50)\n",
"xj = solver_j.solve()\n",
"res_j = solver_j.history\n",
"\n",
"solver_gs = GaussSeidel(A, b, tol=1e-12, max_iter=50)\n",
"xgs = solver_gs.solve()\n",
"res_gs = solver_gs.history\n",
"\n",
"plt.semilogy(res_j, label=\"Jacobi\")\n",
"plt.semilogy(res_gs, label=\"GaussSeidel\")\n",
"plt.xlabel(\"Iteration\")\n",
"plt.ylabel(\"Residual norm\")\n",
"plt.legend()\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"id": "41a3c7a9",
"metadata": {},
"source": [
"## 4. Summary\n",
"\n",
"- Direct: Gauss-Jordan, LU, Cholesky.\n",
"- Iterative: Jacobi, GaussSeidel.\n",
"- Convergence depends on matrix properties (e.g., diagonal dominance, SPD).\n",
"- Direct methods better for small/moderate dense systems.\n",
"- Iterative methods essential for large, sparse systems (e.g., PDE discretizations).\n",
"- Conditioning of matrix affects stability."
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"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.13.7"
}
},
"nbformat": 4,
"nbformat_minor": 5
}