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


import math
import matplotlib.pyplot as plt

x0, y0, b = 1, 2, 1.8
eps = 1e-2

def f(x, y):
    return (3*x*x+y) /2*x

def exact(x):
    return x**2 + 0.8 * math.sqrt(x)

def euler(h):
    n = round((b-x0)/h)
    x = [x0 + k*h for k in range(n+1)]
    y = [y0]
    for k in range(n):
        y.append(y[k] + h*f(x[k], y[k]))
    return x, y

def euler_cauchy(h, tol=eps):
    n = round((b-x0)/h)
    x = [x0 + k*h for k in range(n+1)]
    y = [y0]

    for k in range(n):
        # Нулевое приближение
        y_prev = y[k] + h*f(x[k], y[k])

        # Итерационное уточнение
        while True:
            y_new = y[k] + h/2 * (
                f(x[k], y[k]) + f(x[k+1], y_prev)
            )
            if abs(y_new - y_prev) <= tol:
                break
            y_prev = y_new

        y.append(y_new)

    return x, y

def max_common_difference(y_coarse, y_fine):
    return max(abs(y_coarse[k] - y_fine[2*k])
               for k in range(len(y_coarse)))

#  Метод Эйлера 
# Начинаем с h=0.1 (h^2 <= eps), 
_, y01 = euler(0.1)
_, y005 = euler(0.05)
_, y0025 = euler(0.025)
_, y00125 = euler(0.0125)

d1 = max_common_difference(y01, y005)
d2 = max_common_difference(y005, y0025)
d3 = max_common_difference(y0025, y00125)

print("Проверка метода Эйлера:")
print(f"h=0.1000 -> сравнение с h=0.0500: {d1:.6f}")
print(f"h=0.0500 -> сравнение с h=0.0250: {d2:.6f}")
print(f"h=0.0250 -> сравнение с h=0.0125: {d3:.6f}")

# Так как d3 < eps, принимаем h=0.025
h_euler = 0.025
xe, ye = euler(h_euler)

print(f"\nИтоговый шаг Эйлера: h={h_euler}")
print(f"y(1.5) = {ye[-1]:.8f}")

# Метод Эйлера-Коши 
h_ec = 0.1
xc, yc = euler_cauchy(h_ec)
_, yc05 = euler_cauchy(0.05)

ec_check = max_common_difference(yc, yc05)

print("\nМетод Эйлера-Коши:")
print(f"Проверка h=0.1 с h=0.05: {ec_check:.6f}")
print(f"y(1.5) = {yc[-1]:.8f}")

# Таблицы 
print("\nТаблица метода Эйлера:")
print(" k       x_k        y_k         y_точн      ошибка")
for k, (x, y) in enumerate(zip(xe, ye)):
    print(f"{k:2d}   {x:8.4f}   {y:10.8f}   "
          f"{exact(x):10.8f}   {abs(y-exact(x)):10.8f}")

print("\nТаблица метода Эйлера-Коши:")
print(" k       x_k        y_k         y_точн      ошибка")
for k, (x, y) in enumerate(zip(xc, yc)):
    print(f"{k:2d}   {x:8.4f}   {y:10.8f}   "
          f"{exact(x):10.8f}   {abs(y-exact(x)):10.8f}")

print(f"\nТочное y(1.5) = {exact(1.5):.8f}")

# ---------- График ----------
xx = [x0 + i*(b-x0)/500 for i in range(501)]
plt.plot(xx, [exact(x) for x in xx], label="Точное решение")
plt.plot(xe, ye, "o", markersize=3, label="Эйлер")
plt.plot(xc, yc, "s", label="Эйлер-Коши")
plt.xlabel("x")
plt.ylabel("y")
plt.grid(True)
plt.legend()
plt.show()