Нахождение корня уравнения методом бисекции с Python
Математика говорит нам о том, что для непрерывной функции на отрезке a,b, таком что знаки функции на его концах разные, найдется точка: f(x)=0.
Соответственно, один из подходов нахождения решения заключается в делении отрезка пополам с сохранением условий разных знаков, пока не найдется точка или отрезок не станет, настолько мал, что в качестве решения сойдет любая его граница. Рассмотрим пример:
import numpy as np import matplotlib.pyplot as plt x = np.linspace(-10, 10) def f(x): return 2*x**2 - 10 plt.plot(x, f(x)) plt.hlines(0,-10, 10)
У этом параболы есть два решения. Найдем одно из них задав интервал:
def solve_eq(f, a, b, thres=0.001): y_a = f(a) y_b = f(b) direction = f(b) - f(a) if not y_a*y_b<0: print("нарушены условия разных знаков точек") return None dif = b-a while dif>thres: # import pdb; pdb.set_trace() c = a+(b-a)/2 y = f(c) if y==0: return c if y*direction > 0: b=c else: a = c dif = b-a return b solve_eq(f,0, 5)
Функция в цикле, пока величина интервала не стала меньше некого предела (thres), берет середину отрезка и в зависимости от знака функции в ней и знаков функции на границах (direction) заменяет либо b (знаки совпадают) либо a (знаки разные).
Проверим работу метода на примере других функций:
def f1(x): return x def f2(x): return x**3 - 10 display(solve_eq(f1, -5, 5)) display(solve_eq(f2, 1, 4, 0.000001))