from math import log
# коэффициенты Котеса для n = 1..6: (числители, знаменатель)
cotes = {
1: ([1, 1], 2),
2: ([1, 4, 1], 6),
3: ([1, 3, 3, 1], 8),
4: ([7, 32, 12, 32, 7], 90),
5: ([19, 75, 50, 50, 75, 19], 288),
6: ([41, 216, 27, 272, 27, 216, 41], 840),
}
# ввод
n = int(input("n (число разбиений): "))
a = float(input("a: "))
b = float(input("b: "))
p = int(input("числитель степени: "))
q = int(input("знаменатель степени: "))
exact = float(input("точное значение: "))
if n <= 0 or q == 0:
exit("Ошибка: n должно быть > 0, знаменатель не может быть 0")
if a < 1 or b <= a:
print("Предупреждение: нужно a >= 1 и b > a, результат может быть неверным")
# таблица значений
h = (b - a) / n
x = [a + i * h for i in range(n + 1)]
try:
y = [log(t) ** (p / q) for t in x]
except ValueError:
exit("Ошибка: функция не определена на этом отрезке")
if any(isinstance(v, complex) for v in y):
exit("Ошибка: функция не определена на этом отрезке")
print("\n i x_i f(x_i)")
for i in range(n + 1):
print(f"{i:2d} {x[i]:12.8f} {y[i]:14.8f}")
# методы
res = {}
if n in cotes:
c, d = cotes[n]
res["Ньютона-Котеса"] = (b - a) * sum(ci * yi for ci, yi in zip(c, y)) / d
else:
print("\nНьютона-Котеса: ошибка, коэффициенты есть только для n от 1 до 6")
res["Прямоугольников"] = h * sum(y[:-1])
res["Трапеций"] = h * ((y[0] + y[-1]) / 2 + sum(y[1:-1]))
res["Симпсона"] = h / 3 * (y[0] + y[-1] + 4 * sum(y[1:-1:2]) + 2 * sum(y[2:-1:2]))
# вывод
print(f"\nТочное значение: {exact:.15f}")
for name, val in res.items():
print(f"\nМетод {name}:")
if name == "Симпсона" and n % 2 != 0:
print(" Предупреждение: n нечётное, результат неточный!")
err = abs(exact - val)
print(f" интеграл: {val:.10f}")
print(f" абсолютная погрешность: {err:.10f}")
if exact != 0:
print(f" относительная погрешность: {err / abs(exact):.10f}")
else:
print(" относительная погрешность: не определена (точное значение = 0)")