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