Загрузка данных


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()