Не получается достигнуть указанной точности по функции

Никак не получается доработать программу так, чтобы достигались обе указанные точности: и по функции и по аргументу. Причем если вы посмотрите, можете сказать, что точности достигаются. Но когда я выбираю интервал [-15;15] (например, чтобы вошли все корни), то точности для 4 корня оказываются не достигнуты... Не понимаю в чем проблема.

def main(np):
    import time

    # Определение функции
    def f(x):
        return 8 * np.cos(x) - x - 6

    # Метод дихотомии
    def dichotomy(f, a, b, eps1, eps2):
        # Начальные значения функции в точках a и b
        fa = f(a)
        fb = f(b)
        if fa * fb >= 0:
            raise ValueError("Функция должна иметь разные знаки на концах интервала [a, b].")
        
        iter_col = 0
        func_eval_col = 2  # Так как функцию уже вычислили дважды выше
        x_prev = a
        x_curr = b
        x_next = (a + b) / 2.0
        
        # Список для хранения предыдущих значений корней
        x_vals = [x_prev, x_curr]
        
        while (abs(b - a) / 2.0 >= eps1) or ((abs(f(x_next))) >= eps2):
            iter_col += 1
            x_next = (a + b) / 2.0  # Середина интервала
            fc = f(x_next)
            func_eval_col += 1  # Увеличение количества вычислений функции
            
            # Изменение границ интервала
            if fa * fc < 0:
                b = x_next
                fb = fc
            else:
                a = x_next
                fa = fc
            
            x_vals.append(x_next)  # Добавление текущего значения в список
        
        # Вычисление параметра сходимости
        if len(x_vals) >= 3:
            alpha = abs((x_vals[-1] - x_vals[-2]) / (x_vals[-2] - x_vals[-3]))
        else:
            alpha = None
        
        root = (a + b) / 2.0  # Корень - середина интервала
        
        # Погрешность
        error = abs(b - a) / 2.0
        func_error = abs(f(root))  # Абсолютное значение функции в корне
        
        return {
            "root": root,
            "f(root)": f(root),
            "iterations": iter_col,
            "function_evaluations_dichotomy": func_eval_col,  # Количество вычислений функции в методе дихотомии
            "convergence_param": alpha,
            "error": error,
            "func_error": func_error 
        }

    # Поиск всех корней на интервале [a, b]
    def find_all_roots(f, a, b, eps1, eps2, step):
        start_time = time.time()  # Время начала выполнения программы
        roots = []
        total_iterations = 0
        total_func_evals_dichotomy = 0  # Количество вычислений функции в методе дихотомии
        func_eval_separation = 0  # Счетчик вычислений функции при отделении корней
        
        x = a
        fx = f(x)  # Первоначальное вычисление функции
        func_eval_separation += 1
        
        while x < b:
            next_x = x + step
            next_fx = f(next_x)
            func_eval_separation += 1
            
            if fx * next_fx < 0:  # Проверка смены знака функции на интервале
                try:
                    root_data = dichotomy(f, x, next_x, eps1, eps2)
                    roots.append(root_data)
                    total_iterations += root_data['iterations']
                    total_func_evals_dichotomy += root_data['function_evaluations_dichotomy']
                except ValueError:
                    pass  # Пропуск интервала, если нет смены знака
            
            x = next_x
            fx = next_fx
        
        total_time_end = time.time() - start_time  # Общее время выполнения программы
        
        return {
            "roots": roots,
            "total_iterations": total_iterations,
            "total_func_evals_dichotomy": total_func_evals_dichotomy,
            "func_eval_separation": func_eval_separation,
            "total_time_elapsed": total_time_end
        }

    # Ввод данных
    a = float(input("Введите начало интервала a: "))
    b = float(input("Введите конец интервала b: "))
    eps1 = float(input("Введите точность по аргументу через точку: "))
    eps2 = float(input("Введите точность по функции через точку: "))
    step = 1.47

    # Поиск корней
    results = find_all_roots(f, a, b, eps1, eps2, step)

    # Вывод результатов
    if results["roots"]:
        for i, root_data in enumerate(results["roots"], 1):
            print(f"Корень {i}: ξ = {root_data['root']:.5f}")
            print(f"Значение функции f(ξ): {root_data['f(root)']:.5f}")
            print(f"Погрешность по аргументу: {root_data['error']:.{len(str(root_data['error']).replace('.', '').replace('-', ''))}e}")
            print(f"Погрешность по функции: {root_data['func_error']:.{len(str(root_data['func_error']).replace('.', '').replace('-', ''))}e}")  # Вывод ошибки по функции
            print(f"Параметр сходимости α: {root_data['convergence_param']:.2f}")
            print()

        print(f"Общее количество итераций n: {results['total_iterations']}")
        print(f"Количество вычислений функции при отделении корней: {results['func_eval_separation']}")
        print(f"Количество вычислений функции в методе дихотомии: {results['total_func_evals_dichotomy']}")
        print(f"Общее количество вычислений функции f(x): {results['func_eval_separation'] + results['total_func_evals_dichotomy']}")
        print(f"Общее время счета: {results['total_time_elapsed']:.10f} секунд")
    else:
        print("На данном интервале корней нет.")

    input("Нажмите любую клавишу для завершения программы")

Ответы (0 шт):