import math
import matplotlib.pyplot as plt
# --- 1. ФУНКЦИИ ---
# Вариант 2: f(x,y) = (3x^2 + y) / (2x)
def f(x, y):
return (3 * x * x + y) / (2 * x)
# Точное решение: y = x^2 + sqrt(x)
def exact(x):
return x**2 + math.sqrt(x)
# Метод Эйлера
def euler(x, y, h):
return y + h * f(x, y)
# Метод Рунге-Кутты 4-го порядка
def rk4(x, y, h):
k1 = f(x, y)
k2 = f(x + h/2, y + h*k1/2)
k3 = f(x + h/2, y + h*k2/2)
k4 = f(x + h, y + h*k3)
return y + h * (k1 + 2*k2 + 2*k3 + k4) / 6
# --- 2. ПАРАМЕТРЫ ЗАДАЧИ ---
h = 0.1
x0 = 1.0
y0 = 2.0
b = 1.8
# Количество шагов (от 1.0 до 1.8 с шагом 0.1)
n_steps = int((b - x0) / h) + 1
x = [x0 + i * h for i in range(n_steps)]
# Инициализация массивов
y_rk = [y0]
y_euler = [y0]
# --- 3. ВЫЧИСЛЕНИЯ ---
# Этап 1: Разгон (4 шага для получения начальных точек метода Адамса)
# Заполняем точки с 0 по 4 (всего 5 точек: x0, x1, x2, x3, x4)
for i in range(4):
y_rk.append(rk4(x[i], y_rk[i], h))
y_euler.append(euler(x[i], y_euler[i], h))
# Этап 2: Метод Адамса 4-го порядка
# Начинаем с i=4, так как у нас уже есть значения для x[0]..x[4]
for i in range(4, n_steps - 1):
# Для Рунге-Кутты
y_new_rk = y_rk[i] + h / 24 * (
55 * f(x[i], y_rk[i])
- 59 * f(x[i-1], y_rk[i-1])
+ 37 * f(x[i-2], y_rk[i-2])
- 9 * f(x[i-3], y_rk[i-3])
)
y_rk.append(y_new_rk)
# Для Эйлера
y_new_euler = y_euler[i] + h / 24 * (
55 * f(x[i], y_euler[i])
- 59 * f(x[i-1], y_euler[i-1])
+ 37 * f(x[i-2], y_euler[i-2])
- 9 * f(x[i-3], y_euler[i-3])
)
y_euler.append(y_new_euler)
# Точное решение
y_exact = [exact(xi) for xi in x]
# Погрешности
error_rk = [abs(y_rk[i] - y_exact[i]) for i in range(len(x))]
error_euler = [abs(y_euler[i] - y_exact[i]) for i in range(len(x))]
# --- 4. ВЫВОД ТАБЛИЦЫ ---
print("=" * 80)
print("k x Адамс+РК Адамс+Эйлер точное y ошибка РК ошибка Эйлера")
print("=" * 80)
for i in range(len(x)):
print(
i,
round(x[i], 1),
round(y_rk[i], 6),
round(y_euler[i], 6),
round(y_exact[i], 6),
round(error_rk[i], 8),
round(error_euler[i], 8)
)
# --- 5. ГРАФИКИ ---
# График 1: Сравнение решений
plt.figure(figsize=(10, 5))
plt.plot(x, y_rk, "o-", label="Адамс + Рунге-Кутта")
plt.plot(x, y_euler, "o-", label="Адамс + Эйлер")
plt.plot(x, y_exact, "s--", label="Точное решение")
plt.xlabel("x")
plt.ylabel("y")
plt.title("Сравнение методов (Вариант 2)")
plt.grid(True)
plt.legend()
plt.show()
# График 2: Сравнение погрешностей (ЛОГАРИФМИЧЕСКАЯ ШКАЛА)
plt.figure(figsize=(10, 5))
plt.plot(x, error_rk, "o-", label="Ошибка: Рунге-Кутта")
plt.plot(x, error_euler, "o-", label="Ошибка: Эйлер")
plt.xlabel("x")
plt.ylabel("Погрешность")
plt.title("Сравнение погрешностей (логарифмическая шкала)")
plt.yscale('log') # <--- ВОТ ЭТА СТРОКА ПОЗВОЛИТ УВИДЕТЬ СИНЮЮ ЛИНИЮ
plt.grid(True, which="both", ls="--")
plt.legend()
plt.show()