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


mport sympy as sp

x = sp.symbols("x")
f_expr = 2 * sp.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)

if ROOTS_COUNT > len(SEGMENTS):                         # ошибка, если корней запрошено больше, чем есть
    raise ValueError(f"В уравнении корней: {len(SEGMENTS)}, а запрошено {ROOTS_COUNT}")

PHI_EXPRS = [sp.exp((x ** 2 - 5) / 2),                  # x = phi(x) для корня на [0.01; 0.1]
             sp.sqrt(2 * sp.log(x) + 5)]                # x = phi(x) для корня на [2; 3]

for i in range(ROOTS_COUNT):                            # по одному отрезку на каждый корень
    A, B = SEGMENTS[i]                                  # границы отрезка
    phi = sp.lambdify(x, PHI_EXPRS[i], "math")                          # phi(x)
    phi1 = sp.lambdify(x, sp.diff(PHI_EXPRS[i], x), "math")             # 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}")