Нахождение корня уравнения методом бисекции с 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))