В алгоритме Python получаю нули функции вместо значений

Рейтинг: 0Ответов: 1Опубликовано: 24.02.2023

Реализовал алгоритм нахождения корня методом дихотомии. Есть три функции: f() содержит уравнение, чьи корни ищем, print_dichotomy декоратор для вывода в консоль результатов расчета и dichotomy() - скрипт по методу дихотомии.

Однако строка print('Значения функции составляют:\n', func) выводит нули. Почему?

Код:

import numpy as np

def print_dichotomy(dichotomy):
    def wrapper(a,b,eps):
        res = list(dichotomy(a,b, eps))
        func = ', '.join(map(lambda x: f'{f(x):.4f}', res))
        print('Корни по методу дихотомии находятся в точках:')
        print(', '.join(map(lambda x: f'{x:.4f}', res)))
        print('Значения функции составляют:\n', func)
    return wrapper

def f(x):
    return 1.2-np.log(x)-4*np.cos(2*x) 

@print_dichotomy
def dichotomy(a, b, eps):  
    """
    Функция отделения и уточнения корня.
    Передаются параметры: отрезок от a до b делим на n частей (отдельный запрос), погрешность по функции eps
    """
      
    # 2. определим ограничения на границы отрезка 
    assert a != 0, 'a равно 0'
    assert b != 0, 'b равно 0'

    # 3. запросим количество частей n, на которые будет дробиться отрезок 
    n = int( input('Введите параметр n (целое число): ') )
    
    # 4. отделим корни
    # 4.1. разделим заданный отрезок на n частей 
    grid = np.linspace(a, b, n)
    # 4.2. уточним наличие корней на каждом отрезке 
    for x, y in zip(grid, grid[1:]):
        # если на отрезке нет корня, смотрим следующий отрезок
        if f(x) * f(y) > 0:  
            continue
        root = None
        # 5. уточним корни
        # пока отрезок больше заданной погрешности по функции, выполняем нижестоящие операции:
        while abs(f(y) - f(x)) > eps or ((y - x)/2) > eps:
            if y != x:
            # получаем середину отрезка
                mid = (y + x) / 2
            # если функция в середине отрезка равну нулю или меньше погрешности:
                if f(mid) == 0 or abs(f(mid)) < eps:
                # корень равень серединному значению:
                    root = mid  
                    break
            # иначе если произведение функции в середине отрезка на функцию в т. а <0:
                elif (f(mid) * f(x)) <= 0:
                    # серединой становится точка b:
                    y = mid  
                else:
                    # в другом случае — точка а:
                    x = mid  
        if root:
            yield root

dichotomy(0.0001, 50, 0.000001)

Ответы

▲ 1Принят

Да, строка выводит нули или числа близкие к нулю так как это приближенные значения функции в корнях. Так и должно быть:

$ python temp.py
Введите параметр n (целое число): 10
Корни по методу дихотомии находятся в точках:
2.3970, 7.1653, 14.7317, 32.5048, 39.7206
Значения функции составляют:
 0.0000, 0.0000, -0.0000, -0.0000, -0.0000

Поменяйте точность с четырёх на десять:

<        func = ', '.join(map(lambda x: f'{f(x):.4f}', res))
-----------
>        func = ', '.join(map(lambda x: f'{f(x):.10f}', res))
$ python temp.py
Введите параметр n (целое число): 10
Корни по методу дихотомии находятся в точках:
2.3970, 7.1653, 14.7317, 32.5048, 39.7206
Значения функции составляют:
 0.0000005723, 0.0000001953, -0.0000007381, -0.0000009070, -0.0000007247