import math
# ================== ЗДЕСЬ ЗАДАЁТСЯ УРАВНЕНИЕ ==================
def function(x):
return 2 * math.log(x) - x ** 2 + 5 # 2*ln(x) - x^2 + 5 = 0
# ==============================================================
A = 0.01 # левая граница (ln(x) определён только при x > 0, поэтому не 0)
B = 5 # правая граница
EPSILON = 0.0001 # требуемая точность
PARTS = 1000 # на сколько кусочков делим отрезок при поиске смены знака
def find_intervals(function, a, b, parts):
"""Отделение корней: ищет кусочки отрезка, где функция меняет знак.
Возвращает (список отрезков со сменой знака, список точных корней в узлах сетки)."""
step = (b - a) / parts
intervals = []
exact_roots = []
value_left = function(a)
for i in range(parts):
left = a + i * step
right = left + step
value_right = function(right)
if value_left == 0: # левый узел сам оказался корнем
exact_roots.append(left)
elif value_left * value_right < 0: # знак поменялся, значит внутри есть корень
intervals.append((left, right))
value_left = value_right # правая граница станет левой на следующем шаге
if value_left == 0: # последний узел (точка b) - корень
exact_roots.append(b)
return intervals, exact_roots
def bisection(function, left, right, epsilon):
"""Метод дихотомии на отрезке, где гарантирована смена знака.
Возвращает (корень, количество итераций, оценка погрешности)."""
value_left = function(left)
previous_x = None
iterations = 0
while True:
x = (left + right) / 2 # новое приближение x(n)
value_x = function(x)
iterations += 1
# Проверка 1: x - точный корень
if value_x == 0:
return x, iterations, 0.0
# Проверка 2: |x(n) - x(n-1)| < epsilon
if previous_x is not None:
difference = abs(x - previous_x)
if difference < epsilon:
return x, iterations, difference
# Выбираем ту половину, где знак меняется
if value_left * value_x < 0:
right = x
else:
left = x
value_left = value_x
previous_x = x
# ---------- основная программа ----------
intervals, exact_roots = find_intervals(function, A, B, PARTS)
for root in exact_roots:
print(f"Корень: {root:.8f} (точное попадание в узел сетки)")
for left, right in intervals:
root, iterations, error = bisection(function, left, right, EPSILON)
print(f"Корень: {root:.8f}, погрешность: {error:.2e}, итераций: {iterations}")
if not intervals and not exact_roots:
print("Корней со сменой знака на отрезке не найдено")