Системы уравнений в Python: от простых до сложных

Раздел: Научные вычисления -> Математические вычисления

Основной метод: решение линейных систем с помощью NumPy

Для систем линейных уравнений вида Ax = b самым быстрым и надёжным способом является вызов numpy.linalg.solve. Матрица коэффициентов A должна быть квадратной и невырожденной. Пример системы:

import numpy as np
A = np.array([[2.0, 1.0], [1.0, -3.0]])
b = np.array([7.0, 1.0])
x = np.linalg.solve(A, b)
print(x)  # [ 3. -1.]

Python решение примера (решение примера на python)

Как решить систему линейных уравнений с квадратной матрицей?

Функция solve использует разложение LU и решает систему за O(n³). Если матрица вырождена (детерминант равен нулю), возникает ошибка LinAlgError.

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

  • Матрица A или вектор b имеют неправильные размеры. Решение: проверить shape, использовать reshape.
  • Матрица плохо обусловлена. Результат может быть неточным. Рекомендуется нормировка или использование numpy.linalg.lstsq.
  • Перепутаны строки и столбцы при формировании A.

Как решить переопределённую систему (метод наименьших квадратов)?

Когда уравнений больше, чем неизвестных, точного решения нет. Используется numpy.linalg.lstsq, который минимизирует ||Ax - b||₂.

A = np.array([[1, 1], [1, 2], [1, 3]])
b = np.array([2, 3, 5])
x, residuals, rank, s = np.linalg.lstsq(A, b, rcond=None)
print(x)  # [1.1667 1.1667]

Python вычисление значения выражений (вычисление значения выражений в python)

Вектор x даёт наилучшее приближение. Параметр rcond=None автоматически выбирает порог для отбрасывания малых сингулярных чисел.

Проблема: при очень плохой обусловленности решение может быть неустойчивым. Рекомендуется регуляризация (например, scipy.linalg.lstsq с параметром lapack_driver='gelsy').

Как решить систему нелинейных уравнений с помощью SciPy?

Для нелинейных систем используется scipy.optimize.fsolve. Систему нужно записать в виде F(x) = 0. Пример:

from scipy.optimize import fsolve

def equations(vars):
    x, y = vars
    eq1 = x**2 + y**2 - 1
    eq2 = x - y
    return [eq1, eq2]

x0 = [0.5, 0.5]
solution = fsolve(equations, x0)
print(solution)  # [0.7071 0.7071]

вычисление функции в python (вычисление значения функции в python)

Как найти корни нелинейной системы с несколькими неизвестными?

Функция fsolve требует начальное приближение x0. Результат сильно зависит от начальной догадки. Если система имеет несколько решений, можно перебирать разные x0.

Ошибки: fsolve может сходиться к локальному минимуму, а не к корню. Рекомендуется проверять невязку в найденной точке. Если fsolve выдает ошибку 'The iteration is not making good progress', следует изменить начальное приближение или уменьшить xtol.

Как получить аналитическое (символьное) решение с помощью SymPy?

Библиотека SymPy позволяет решать системы символьно. Пример:

import sympy as sp
x, y = sp.symbols('x y')
eq1 = sp.Eq(x**2 + y**2, 1)
eq2 = sp.Eq(x - y, 0)
sol = sp.solve((eq1, eq2), (x, y))
print(sol)  # [(-sqrt(2)/2, -sqrt(2)/2), (sqrt(2)/2, sqrt(2)/2)]

Python вычисление корня (вычисление квадратного корня в python)

Для линейных систем можно использовать sp.linsolve. Символьное решение даёт точные выражения, но для больших систем может быть медленным.

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

Как решить большую разреженную систему итерационными методами?

Для матриц большой размерности и разреженной структуры эффективны итерационные методы из scipy.sparse.linalg, например cg (сопряжённые градиенты) для симметричных положительно определённых матриц.

from scipy.sparse import csr_matrix
from scipy.sparse.linalg import cg

A = csr_matrix([[4, 1], [1, 3]])
b = np.array([1, 2])
x, info = cg(A, b)
print(x)  # [0.0909 0.6364]

Параметр info равен 0 при успешной сходимости. Итерационные методы экономят память, но требуют предобуславливания для ускорения сходимости.

Типичная ошибка: матрица не является положительно определённой (для CG). Решение: использовать gmres или bicgstab для несимметричных матриц.

- Python вычислить строку (вычисление выражения из строки в python)
- возвести в квадрат python (возведение числа в квадрат в python)
- площадь python (вычисление площади в python)

Расширенные примеры решения систем уравнений

Пример 1: Система с комплексными коэффициентами

Линейная система, где матрица A и вектор b содержат комплексные числа, решается теми же функциями NumPy.

Пример
import numpy as np
A = np.array([[1+2j, 3-1j], [4j, 2+0j]])
b = np.array([5+1j, 3-2j])
x = np.linalg.solve(A, b)
print(x)
# Результат:
[ 1.08333333-1.08333333j -0.58333333+0.08333333j]

Пример 2: Система нелинейных уравнений с несколькими корнями

Уравнения sin(x) = 0 и cos(y) = 0 имеют бесконечно много решений. Разные начальные приближения приводят к разным корням.

Пример
from scipy.optimize import fsolve
import numpy as np

def f(vars):
    x, y = vars
    return [np.sin(x), np.cos(y)]

for guess in [(0, 0), (3, 1), (6, 2)]:
    sol = fsolve(f, guess)
    print(f'Начальн. {guess}: решение {np.round(sol,3)}')
# Результат:
Начальн. (0, 0): решение [0.    1.571]
Начальн. (3, 1): решение [3.142 1.571]
Начальн. (6, 2): решение [6.283 1.571]

Как видно, fsolve находит корни, ближайшие к начальному приближению.

Пример 3: Решение параметрического семейства систем

Рассмотрим систему x + a*y = 1, a*x - y = 0 с параметром a. Для серии значений a можно вычислить решения в цикле.

Пример
import numpy as np
def solve_parametric(a):
    A = np.array([[1, a], [a, -1]])
    b = np.array([1, 0])
    return np.linalg.solve(A, b)

alphas = np.linspace(0, 2, 5)
solutions = [solve_parametric(a) for a in alphas]
for a, sol in zip(alphas, solutions):
    print(f'a={a:.1f}: x={sol[0]:.4f}, y={sol[1]:.4f}')
# Результат:
a=0.0: x=1.0000, y=0.0000
a=0.5: x=0.8000, y=0.4000
a=1.0: x=1.0000, y=1.0000
a=1.5: x=-0.8000, y=-1.2000
a=2.0: x=-0.3333, y=-0.6667

Пример 4: Использование автоматического вычисления Якобиана в fsolve

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

Пример
from scipy.optimize import fsolve
import numpy as np

def equations(vars):
    x, y = vars
    return [x**2 + y**2 - 2, np.exp(x) + y - 1]

def jacobian(vars):
    x, y = vars
    return [[2*x, 2*y], [np.exp(x), 1]]

sol = fsolve(equations, [0.5, 0.5], fprime=jacobian)
print(sol)  # [ 0.1553  1.4108]

Передача аналитического якобиана уменьшает число итераций. Если якобиан неизвестен, fsolve аппроксимирует его численно.

Пример 5: Решение системы дифференциальных уравнений (сведение к системе нелинейных)

Иногда требуется решить краевую задачу для системы ОДУ. Метод стрельбы сводит её к системе нелинейных уравнений. Пример для уравнения y'' = -y с граничными условиями y(0)=0, y(π/2)=1.

Пример
from scipy.optimize import fsolve
from scipy.integrate import solve_ivp
import numpy as np

def shoot(s0):
    # интегрирование с начальным y'(0)=s0
    def ode(t, y):
        return [y[1], -y[0]]
    sol = solve_ivp(ode, [0, np.pi/2], [0, s0], method='RK45', max_step=0.01)
    return sol.y[0, -1] - 1  # невязка в правой границе

s_guess = 1.0
s_root = fsolve(shoot, s_guess)[0]
print(f'Начальная производная: {s_root:.4f}')  # ~1.0
# Результат:
Начальная производная: 1.0000

Этим способом можно решать краевые задачи для систем ОДУ.

Решить систему уравнений в Python - comments

En
решение системы уравнений python (python)