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


import math
from prettytable import PrettyTable

a = -2
b = -1


# Перевод числа в строку
def toFixed(numObj, digits=0):
    return f"{numObj:.{digits}f}"


# Правая часть дифференциального уравнения:
# y' = x^3 * y
def Uravnenie(xx, yy):
    return xx**3 * yy


# Точное решение задачи Коши:
# y(-2) = 2
# y = 2e^((x^4)/4 - 4)
def ExactSolution(x):
    return 2 * math.exp((x**4) / 4 - 4)


def Diffur(n):
    mytable = PrettyTable()

    mytable.title = f"Приближённое решение дифференциального уравнения при n = {n}"

    mytable.field_names = [
        "i",
        "xi",
        "y(xi)",
        "yi(Э)",
        "|y-yi(Э)|",
        "yi(Р-К)",
        "|y-yi(Р-К)|",
        "yi(А)",
        "|y-yi(А)|"
    ]

    data = []

    h = (b - a) / n

    # Начальные условия
    x = [a]

    y0 = ExactSolution(a)

    yk = [y0]   # точное решение
    ye = [y0]   # метод Эйлера
    yr = [y0]   # метод Рунге-Кутты
    ya = [y0]   # метод Адамса

    # Начальная строка таблицы
    data.append([
        0,
        toFixed(x[0], 4),
        toFixed(yk[0], 9),
        toFixed(ye[0], 9),
        toFixed(abs(yk[0] - ye[0]), 9),
        toFixed(yr[0], 9),
        toFixed(abs(yk[0] - yr[0]), 9),
        toFixed(ya[0], 9),
        toFixed(abs(yk[0] - ya[0]), 9)
    ])

    for i in range(n):

        # Следующее значение x
        xi = x[i] + h
        x.append(xi)

        # Точное решение
        exact = ExactSolution(xi)
        yk.append(exact)

        # Метод Эйлера
        ye_next = ye[i] + h * Uravnenie(x[i], ye[i])
        ye.append(ye_next)

        # Метод Рунге-Кутты 4 порядка
        k1 = h * Uravnenie(x[i], yr[i])

        k2 = h * Uravnenie(
            x[i] + h / 2,
            yr[i] + k1 / 2
        )

        k3 = h * Uravnenie(
            x[i] + h / 2,
            yr[i] + k2 / 2
        )

        k4 = h * Uravnenie(
            x[i] + h,
            yr[i] + k3
        )

        yr_next = yr[i] + (k1 + 2 * k2 + 2 * k3 + k4) / 6
        yr.append(yr_next)

        # Метод Адамса 4 порядка
        if i < 3:
            # Первые точки берём из Рунге-Кутты
            ya_next = yr_next
        else:
            ya_next = ya[i] + (h / 24) * (
                55 * Uravnenie(x[i], ya[i])
                - 59 * Uravnenie(x[i - 1], ya[i - 1])
                + 37 * Uravnenie(x[i - 2], ya[i - 2])
                - 9 * Uravnenie(x[i - 3], ya[i - 3])
            )

        ya.append(ya_next)

        # Добавление строки в таблицу
        data.append([
            i + 1,
            toFixed(xi, 4),
            toFixed(exact, 9),
            toFixed(ye_next, 9),
            toFixed(abs(exact - ye_next), 9),
            toFixed(yr_next, 9),
            toFixed(abs(exact - yr_next), 11),
            toFixed(ya_next, 9),
            toFixed(abs(exact - ya_next), 11)
        ])

    mytable.add_rows(data)

    print(mytable)


# Таблицы для n = 10 и n = 20
Diffur(10)
Diffur(20)