Перейти к содержимому

Линейные уравнения и матрицы. Нелинейные уравнения. SymPy.

Линейные уравнения и матрицы. Нелинейные уравнения. SymPy.

В этом уроке вы разберетесь, как в SymPy создавать матрицы, выполнять с ними операции и решать системы линейных уравнений. Затем мы сравним линейные и нелинейные уравнения и посмотрим, как SymPy их решает. В конце есть практика с решениями и чек-лист.

Примечание: Meta Platforms Inc. признана экстремистской, ее продукты запрещены на территории РФ.

Главная мысль: матрицы в SymPy -- это объект для линейной алгебры, который умеет выполнять операции (сложение, умножение, транспонирование, поиск обратной матрицы и определителя). Для уравнений важно выбирать правильную функцию: linsolve для линейных систем, solve для символьного решения, nsolve для численного решения.

Содержание

1. Цели урока

  • Понимать базовые термины: матрица, вектор-столбец, размер (shape), линейное и нелинейное уравнение.
  • Создавать матрицы разными способами: Matrix, zeros, ones, eye, diag.
  • Выполнять операции: сложение, умножение, транспонирование (T), обратная матрица (inv), определитель (det).
  • Решать системы линейных уравнений через linsolve и через матричную форму \(A x = b\).
  • Решать простые нелинейные уравнения символически (solve) и численно (nsolve).
  • Выводить результаты в специальном формате: LaTeX-строка и ASCII pretty-печать.
Что особенно важно запомнить: матричное умножение -- это "строка на столбец", а не поэлементное умножение. Умножение \(A B\) возможно только при согласованных размерах.
^ К оглавлению

2. Контекст: матрицы и уравнения в SymPy

Новые термины и определения

  • SymPy -- библиотека Python для символьной математики: выражения хранятся как объекты, их можно упрощать и преобразовывать.
  • символьное выражение -- объект SymPy, который представляет формулу (например \(x^2 - 2\)), а не конкретное число.
  • матрица -- прямоугольная таблица элементов (чисел или выражений).
  • вектор-столбец -- матрица размера \(n \times 1\).
  • строка матрицы -- горизонтальный набор элементов матрицы.
  • столбец матрицы -- вертикальный набор элементов матрицы.
  • размер (shape) -- пара \((m, n)\), где \(m\) -- число строк, \(n\) -- число столбцов.
  • линейное уравнение -- уравнение, где неизвестные входят только в 1 степени и не перемножаются (пример: \(2x + 3y = 5\)).
  • система уравнений -- несколько уравнений, которые решаются вместе для одних и тех же неизвестных.
  • нелинейное уравнение -- уравнение, где неизвестные входят в степени, корни, знаменатели, тригонометрию и т.д. (пример: \(x^2 - 2 = 0\)).
  • корень уравнения -- значение неизвестной, при котором уравнение становится верным.
Практический вывод: SymPy полезен, когда вы хотите получить ответ как формулу (например \(\sqrt{2}\)) или аккуратно работать с матрицами и системами.
import sympy as sp

x = sp.Symbol("x")
expr = x**2 - 2

print(expr)
# x**2 - 2
Python

Частая путаница

Запомните: выражение x**2 - 2 само по себе не является уравнением. Уравнение появляется, когда вы задаете равенство, например \(x^2 - 2 = 0\), или создаете объект Eq.
Определение: Eq -- объект SymPy, который хранит уравнение в виде "левая часть равна правой части".
import sympy as sp

x = sp.Symbol("x")
eq = sp.Eq(x**2 - 2, 0)

print(eq)
# Eq(x**2 - 2, 0)
Python
^ К оглавлению

3. Создание матриц в SymPy

Matrix из list и list of lists

Определение: list (список) -- тип данных Python для хранения последовательности значений. Пример: [1, 2, 3].

Конструктор Matrix превращает список в матрицу. Если передать обычный список [1, 2, 3], SymPy создаст вектор-столбец (матрицу \(n \times 1\)).

from sympy import Matrix

col = Matrix([1, 2, 3])
print(col)
# Matrix([[1], [2], [3]])
Python

Если передать двумерный список (list of lists), получится прямоугольная матрица.

from sympy import Matrix

A = Matrix([[1, 2, 3],
            [4, 5, 6]])
print(A)
# Matrix([[1, 2, 3], [4, 5, 6]])
Python
Определение: итерируемый объект (iterable) -- объект, по которому можно пройти циклом for (например list, tuple, range).
from sympy import Matrix

v = Matrix(range(1, 5))
print(v)
# Matrix([[1], [2], [3], [4]])
Python

zeros, ones, eye, diag

Определение: конструктор (в контексте урока) -- функция, которая создает объект по заданным параметрам.
  • zeros(n, m) -- матрица \(n \times m\), заполненная нулями.
  • ones(n, m) -- матрица \(n \times m\), заполненная единицами.
  • eye(n) -- единичная матрица \(n \times n\) (единицы на главной диагонали, остальное нули).
  • diag(a, b, c) -- диагональная матрица, где значения стоят на диагонали.
from sympy import zeros, ones, eye, diag

Z = zeros(2, 3)
O = ones(3, 2)
I = eye(3)
D = diag(1, 2, 3)

print(Z)
# Matrix([[0, 0, 0], [0, 0, 0]])

print(O)
# Matrix([[1, 1], [1, 1], [1, 1]])

print(I)
# Matrix([[1, 0, 0], [0, 1, 0], [0, 0, 1]])

print(D)
# Matrix([[1, 0, 0], [0, 2, 0], [0, 0, 3]])
Python

Типичные ошибки

Ошибка 1: ожидали строку, а получили столбец

Обычный список дает столбец. Чтобы получить строку \(1 \times n\), передайте список списков.

from sympy import Matrix

row = Matrix([[1, 2, 3]])
print(row)
# Matrix([[1, 2, 3]])
Python

Ошибка 2: строки разной длины

Матрица должна быть прямоугольной: все строки одинаковой длины. Ниже показан безопасный способ увидеть ошибку и ее тип.

from sympy import Matrix

try:
    bad = Matrix([[1, 2, 3],
                  [4, 5]])  # строка короче
    print(bad)
except Exception as e:
    print("ERROR:", type(e).__name__)
# ERROR: ValueError
Python
^ К оглавлению

4. Операции с матрицами

Сложение

Определение: покомпонентно (поэлементно) -- "каждый элемент с элементом на той же позиции".

Сложение матриц выполняется покомпонентно и возможно только для матриц одинакового размера.

from sympy import Matrix, eye

A = Matrix([[1, 2],
            [3, 4]])
B = eye(2)

print(A + B)
# Matrix([[2, 2], [3, 5]])
Python

Умножение: "строка на столбец"

Определение: внутренний размер (для умножения \(A B\)) -- число столбцов матрицы \(A\), которое должно совпасть с числом строк матрицы \(B\).

Умножение матриц -- это операция "строка на столбец". Она НЕ является поэлементным умножением.

Правило размеров:

$$ (m, n)\cdot(n, p) = (m, p) $$

Определение: согласованные размеры -- это когда внутренние размеры совпали (в записи \((m, n)\cdot(n, p)\) совпадает число \(n\)).

Как считается один элемент результата:

$$ c_{ij}=\sum_{k=1}^{n} a_{ik} b_{kj} $$

То есть берется \(i\)-я строка матрицы \(A\) и \(j\)-й столбец матрицы \(B\), элементы перемножаются попарно и складываются.

from sympy import Matrix

A = Matrix([[1, 2],
            [3, 4]])

B = Matrix([[10, 20],
            [30, 40]])

C = A * B
print(C)
# Matrix([[70, 100], [150, 220]])
Python

Мини проверка "вручную" для C[0,0]

Элемент \(c_{11}\) равен \(1\cdot 10 + 2\cdot 30 = 70\).

print(1*10 + 2*30)
# 70
Python

Пример ошибки: размеры не согласованы

Покажем тип ошибки безопасно: через try/except.

from sympy import Matrix

A = Matrix([[1, 2],
            [3, 4]])     # shape (2, 2)

B = Matrix([[1],
            [2],
            [3]])        # shape (3, 1)

try:
    print(A * B)
except Exception as e:
    print("ERROR:", type(e).__name__)
# ERROR: ShapeError
Python
Определение: поэлементное умножение (также встречается термин "произведение Адамара") -- умножение элементов на одинаковых позициях. Оно возможно только для одинаковых размеров.
from sympy import Matrix

A = Matrix([[1, 2],
            [3, 4]])
B = Matrix([[10, 20],
            [30, 40]])

print(A.multiply_elementwise(B))
# Matrix([[10, 40], [90, 160]])
Python

T, inv, det

  • транспонирование -- операция, которая меняет местами строки и столбцы. В SymPy: M.T.
  • обратная матрица -- матрица \(A^{-1}\), такая что \(A\cdot A^{-1}=I\), где \(I\) -- единичная матрица. В SymPy: A.inv().
  • определитель -- число, которое вычисляется по квадратной матрице. Если \(\det(A)=0\), обратная матрица не существует. В SymPy: A.det().
from sympy import Matrix

M = Matrix([[1, 2, 3],
            [4, 5, 6]])

print(M.T)
# Matrix([[1, 4], [2, 5], [3, 6]])
Python
Определение: квадратная матрица -- матрица, у которой число строк равно числу столбцов (размер \(n \times n\)).
from sympy import diag

A = diag(1, 2, 3, 4)
A_inv = A.inv()

print(A_inv)
# Matrix([[1, 0, 0, 0], [0, 1/2, 0, 0], [0, 0, 1/3, 0], [0, 0, 0, 1/4]])

print(A * A_inv)
# Matrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]])

print(A_inv.det())
# 1/24
Python

Типичные ошибки

Ошибка 1: попытка сложить матрицы разных размеров

Сложение требует одинакового shape. Поймаем тип ошибки безопасно.

from sympy import Matrix

A = Matrix([[1, 2],
            [3, 4]])
B = Matrix([[1, 2, 3],
            [4, 5, 6]])

try:
    print(A + B)
except Exception as e:
    print("ERROR:", type(e).__name__)
# ERROR: ShapeError
Python

Ошибка 2: попытка взять inv() у матрицы с det == 0

Определение: вырожденная матрица -- квадратная матрица с определителем 0. У нее нет обратной матрицы.
from sympy import Matrix

S = Matrix([[1, 2],
            [2, 4]])

print(S.det())
# 0

try:
    print(S.inv())
except Exception as e:
    print("ERROR:", type(e).__name__)
# ERROR: NonInvertibleMatrixError
Python
^ К оглавлению

5. Системы линейных уравнений

Что такое линейная система

Систему линейных уравнений удобно записывать в матричном виде:

$$ A x = b $$

Определения:
  • матрица коэффициентов A -- матрица чисел перед неизвестными.
  • вектор неизвестных x -- столбец переменных (то, что мы ищем).
  • вектор правых частей b -- столбец чисел справа от знака равенства.
  • коэффициент -- число перед неизвестной (в \(3x\) коэффициент равен 3).
from sympy import Matrix, symbols

x, y = symbols("x y")

A = Matrix([[2, 1],
            [5, 3]])
vec = Matrix([x, y])
b = Matrix([1, 2])

print(A)
# Matrix([[2, 1], [5, 3]])

print(vec)
# Matrix([[x], [y]])

print(b)
# Matrix([[1], [2]])
Python

Решение через linsolve

Определение: linsolve -- функция SymPy, которая решает системы линейных уравнений и возвращает множество решений.
Определение: кортеж (tuple) -- неизменяемая последовательность в Python, записывается как (a, b, c).

Пример системы с единственным решением:

$$ \begin{cases} x + 2y + 3z = 3 \\ 4x + 5y + 6z = 6 \\ 7x + 8y + 10z = 9 \end{cases} $$

from sympy import Matrix, linsolve, symbols

x, y, z = symbols("x y z")

A = Matrix([[1, 2, 3],
            [4, 5, 6],
            [7, 8, 10]])
b = Matrix([3, 6, 9])

sol = linsolve((A, b), (x, y, z))
print(sol)
# {(-1, 2, 0)}
Python
Определения:
  • бесконечно много решений -- когда можно выбирать одну или несколько переменных свободно, и все равно получаются решения.
  • параметр -- специальный символ (tau0, tau1 и т.д.), который означает "можно взять любое значение".
  • параметрическое решение -- решение, записанное через параметры.

Пример зависимой системы (бесконечно много решений):

$$ \begin{cases} x + y + z = 3 \\ 2x + 2y + 2z = 6 \end{cases} $$

from sympy import linsolve, symbols

x, y, z = symbols("x y z")

sol = linsolve([x + y + z - 3,
                2*x + 2*y + 2*z - 6], (x, y, z))

print(sol)
# {(3 - tau0 - tau1, tau0, tau1)}
Python

Матричная форма и LUsolve

Определение: LUsolve -- метод матрицы SymPy, который решает систему \(A x = b\) с помощью LU-разложения.
Определения:
  • LU-разложение -- представление матрицы \(A\) как произведения \(L\cdot U\).
  • нижнетреугольная матрица L -- матрица, где элементы выше главной диагонали равны нулю.
  • верхнетреугольная матрица U -- матрица, где элементы ниже главной диагонали равны нулю.
from sympy import Matrix

A = Matrix([[2, 1],
            [5, 3]])
b = Matrix([1, 2])

x = A.LUsolve(b)
print(x)
# Matrix([[1], [-1]])
Python

Типичные ошибки

Ошибка 1: использовать linsolve для нелинейной задачи

linsolve предназначен для линейных систем. Если в уравнении есть \(x^2\), \(\sin(x)\), \(1/x\) и т.д., это уже нелинейность. Ниже мы не "угадываем" текст ошибки, а надежно выводим тип исключения.

from sympy import linsolve, symbols

x = symbols("x")

try:
    sol = linsolve([x**2 - 1], (x,))
    print(sol)
except Exception as e:
    print("ERROR:", type(e).__name__)
# ERROR: NonlinearError
Python

Ошибка 2: не передать список неизвестных

Тогда SymPy может вернуть ответ через параметр tau0. Это не "плохо", но студенту сложнее читать ответ без объяснения.

from sympy import Matrix, linsolve

A = Matrix([[1, 1],
            [2, 2]])
b = Matrix([3, 6])

print(linsolve((A, b)))
# {(tau0, 3 - tau0)}
Python
^ К оглавлению

6. Нелинейные уравнения и формат вывода

Что такое нелинейное уравнение

Нелинейное уравнение -- это уравнение, где неизвестная входит не линейно: в квадрате, в степени, в знаменателе, под корнем, внутри функций (\(\sin\), \(\cos\), \(\exp\) и т.д.).

Примеры:

$$ x^2 - 2 = 0 $$

$$ \frac{1}{x} - 3 = 0 $$

import sympy as sp

x = sp.Symbol("x")

print(sp.Eq(x**2 - 2, 0))
# Eq(x**2 - 2, 0)

print(sp.Eq(1/x - 3, 0))
# Eq(1/x - 3, 0)
Python

solve и nsolve

Определения:
  • solve -- функция SymPy, которая пытается найти символьное (точное) решение.
  • nsolve -- функция SymPy для численного решения (приближенный корень).
  • начальная догадка -- число, с которого численный метод начинает поиск корня.
  • сходимость -- ситуация, когда численный метод приближается к решению и заканчивает работу успешно.

Символьное решение (точно) для \(x^2 - 2 = 0\):

from sympy import symbols, solve

x = symbols("x")

sol = solve(x**2 - 2, x)
print(sol)
# [-sqrt(2), sqrt(2)]
Python

Численное решение (приближенно) для \(x^2 - 2 = 0\):

from sympy import Symbol, nsolve

x = Symbol("x")

root = nsolve(x**2 - 2, 1)  # начальная догадка 1
print(root)
# 1.41421356237310
Python

Один запуск nsolve обычно дает один корень

Чтобы найти другой корень, меняют начальную догадку.

from sympy import Symbol, nsolve

x = Symbol("x")

r1 = nsolve(x**2 - 2, 1)
r2 = nsolve(x**2 - 2, -1)

print(r1)
# 1.41421356237310

print(r2)
# -1.41421356237310
Python

Специальный вывод: LaTeX и ASCII pretty

Определения:
  • формат вывода -- способ превратить объект SymPy в текст, который можно показать пользователю.
  • LaTeX -- текстовый язык для записи математических формул.
  • pretty-печать -- вывод в виде многострочной "псевдографики", чтобы дроби и степени выглядели наглядно.
  • ASCII -- базовый набор символов (латиница, цифры, знаки). Обычно безопасен для вставки в CMS.

1) LaTeX-строка для выражения \(\frac{(x+1)^2}{2}\) через latex().

from sympy import symbols
from sympy.printing.latex import latex

x = symbols("x")
expr = (x + 1)**2 / 2

print(latex(expr))
# \frac{\left(x + 1\right)^{2}}{2}
Python
Определение: LaTeX-строка -- обычная строка Python, внутри которой находятся команды LaTeX (например \frac, \sqrt).

2) ASCII pretty-печать (без Unicode) через pretty(..., use_unicode=False).

from sympy import symbols
from sympy.printing.pretty import pretty

x = symbols("x")
expr = (x + 1)**2 / 2

print(pretty(expr, use_unicode=False))
#        2
# (x + 1)
# --------
#    2
Python

Типичные ошибки

Ошибка 1: ожидать, что nsolve вернет все корни

nsolve обычно ищет один корень рядом с начальной догадкой. Это нормальное поведение.

from sympy import Symbol, nsolve

x = Symbol("x")

print(nsolve(x**2 - 2, 1))
# 1.41421356237310
Python

Ошибка 2: использовать Unicode pretty-печать и копировать вывод в CMS

Если у вас бывают проблемы с кодировками, используйте ASCII: use_unicode=False.

from sympy import symbols
from sympy.printing.pretty import pretty

x = symbols("x")
expr = 1 / (x + 1)

print(pretty(expr, use_unicode=False))
#   1
# -----
# x + 1
Python
^ К оглавлению

7. Практика: задачи (с решениями)

Блок 1: матрицы

Задача 1: создать матрицу 3 x 3

Создайте матрицу \(3 \times 3\) через Matrix и выведите ее в консоль.

from sympy import Matrix

A = Matrix([[1, 2, 3],
            [4, 5, 6],
            [7, 8, 9]])

print(A)
# Matrix([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
Python

Задача 2: прибавить единичную матрицу

Прибавьте \(I\) (единичную матрицу) к матрице \(A\) из задачи 1.

from sympy import Matrix, eye

A = Matrix([[1, 2, 3],
            [4, 5, 6],
            [7, 8, 9]])

print(A + eye(3))
# Matrix([[2, 2, 3], [4, 6, 6], [7, 8, 10]])
Python

Задача 3: умножить матрицы (строка на столбец)

Перемножьте матрицы и выведите результат.

from sympy import Matrix

A = Matrix([[1, 2],
            [3, 4]])

B = Matrix([[10, 20],
            [30, 40]])

print(A * B)
# Matrix([[70, 100], [150, 220]])
Python

Задача 4: найти определитель и сделать вывод об обратимости

Если \(\det(A)\neq 0\), матрица обратима (у нее есть \(A^{-1}\)).

from sympy import Matrix

A = Matrix([[2, 1],
            [5, 3]])

d = A.det()
print(d)
# 1

print(d != 0)
# True
Python

Блок 2: уравнения и вывод

Задача 5: решить систему линейных уравнений через linsolve

Решите систему:

$$ \begin{cases} 2x + y = 1 \\ 5x + 3y = 2 \end{cases} $$

from sympy import Matrix, linsolve, symbols

x, y = symbols("x y")

A = Matrix([[2, 1],
            [5, 3]])
b = Matrix([1, 2])

sol = linsolve((A, b), (x, y))
print(sol)
# {(1, -1)}
Python

Задача 6: решить нелинейное уравнение через solve

Найдите корни уравнения:

$$ x^2 - 2 = 0 $$

from sympy import symbols, solve

x = symbols("x")
print(solve(x**2 - 2, x))
# [-sqrt(2), sqrt(2)]
Python

Задача 7: получить ASCII pretty-печать

Выведите выражение \(\frac{(x+1)^2}{2}\) в виде многострочной ASCII-формулы.

from sympy import symbols
from sympy.printing.pretty import pretty

x = symbols("x")
expr = (x + 1)**2 / 2

print(pretty(expr, use_unicode=False))
#        2
# (x + 1)
# --------
#    2
Python

Задача 8: вывести выражение в LaTeX

Сформируйте LaTeX-строку для \(\frac{(x+1)^2}{2}\).

from sympy import symbols
from sympy.printing.latex import latex

x = symbols("x")
expr = (x + 1)**2 / 2

print(latex(expr))
# \frac{\left(x + 1\right)^{2}}{2}
Python
^ К оглавлению

8. Чек-лист самопроверки

Отметьте пункты, которые вы действительно понимаете и можете повторить без подсказок.

+/-НавыкПроверка
Понимаю, что такое матрица и ее shape Могу объяснить: строки, столбцы, размер \((m, n)\)
Создаю матрицу через Matrix Могу получить столбец из Matrix([1,2,3]) и матрицу из Matrix([[...],[...]])
Использую zeros/ones/eye/diag Могу создать матрицы \(n \times m\) и \(n \times n\) через конструкторы
Складываю матрицы правильно Понимаю, что нужны одинаковые размеры (shape совпадает)
Умножаю матрицы правильно Могу проверить внутренний размер и объяснить формулу \(c_{ij}=\sum a_{ik}b_{kj}\)
Отличаю матричное умножение от поэлементного Знаю разницу между A*B и A.multiply_elementwise(B)
Делаю транспонирование Могу получить M.T и объяснить, что строки стали столбцами
Понимаю det и обратимость Могу объяснить: если \(\det(A)=0\), то \(A^{-1}\) не существует
Решаю линейные системы Могу решить через linsolve и прочитать ответ как кортеж
Решаю нелинейные уравнения Понимаю разницу между solve (символьно) и nsolve (численно)
Делаю специальный вывод Могу получить LaTeX через latex() и ASCII pretty через pretty(..., use_unicode=False)
^ К оглавлению

Ссылки по теме

Воскресенье, 01 марта 2026
Линейные уравнения и матрицы. Нелинейные уравнения. SymPy.