import math
f = lambda x: 2 * math.log(x) - x ** 2 + 5 # уравнение f(x) = 0
SEGMENTS = [(0.01, 0.1), (2, 3)] # отрезки изоляции корней (по графику)
ROOTS_COUNT = 2 # сколько корней найти
EPSILON = 0.0001 # точность
PARTS = 1000 # на сколько частей делим отрезок (для min и max)
H = 0.0001 # шаг для численной производной
if ROOTS_COUNT > len(SEGMENTS): # ошибка, если корней запрошено больше, чем есть
raise ValueError(f"В уравнении корней: {len(SEGMENTS)}, а запрошено {ROOTS_COUNT}")
def derivative(g): # принимает функцию, возвращает её производную
def d(x): # вложенная функция: g'(x) = (g(x+H) - g(x-H)) / 2H
return (g(x + H) - g(x - H)) / (2 * H)
return d
PHI = [lambda x: math.exp((x ** 2 - 5) / 2), # x = phi(x) для корня на [0.01; 0.1]
lambda x: math.sqrt(2 * math.log(x) + 5)] # x = phi(x) для корня на [2; 3]
for i in range(ROOTS_COUNT): # по одному отрезку на каждый корень
A, B = SEGMENTS[i] # границы отрезка
phi = PHI[i] # phi(x) для этого корня
phi1 = derivative(phi) # производная phi'(x)
points = [A + (B - A) * k / PARTS for k in range(PARTS + 1)] # точки разбиения отрезка
q = max(abs(phi1(p)) for p in points) # q = max |phi'(x)|
if q >= 1: # при q >= 1 метод не сходится
print(f"Корень {i + 1}: q = {q:.4f} >= 1, метод не сходится")
continue
x_prev = (A + B) / 2 # начальное приближение
iterations = 0 # счётчик итераций
while True:
x_new = phi(x_prev) # x(n) = phi(x(n-1))
iterations += 1
if q / (1 - q) * abs(x_new - x_prev) < EPSILON: # q/(1-q) * |x(n) - x(n-1)| < eps
break
x_prev = x_new # запоминаем для следующего шага
print(f"Корень {i + 1}: {x_new:.8f}, итераций: {iterations}, q = {q:.4f}")