bisection.bisection_find_roots.bisection_find_roots

bisection.bisection_find_roots.bisection_find_roots(
    f,
    xmin,
    xmax,
    tol=1e-06,
    max_iter=100,
    N=100,
)

Find multiple roots of a scalar function using the bisection method.

The interval [xmin, xmax] is split into N-1 subintervals, and each subinterval is checked for a sign change indicating a root.

Parameters

Name Type Description Default
f callable Function whose root is sought. Must accept a single scalar argument. required
xmin float Lower bound of the initial interval. required
xmax float Upper bound of the initial interval. required
tol float Absolute convergence tolerance for the bisection method. The method converges when \|xmax - xmin\| < tol. Default is 1e-6. 1e-06
max_iter int Maximum number of iterations allowed. Default is 100. 100
N int Number of subintervals. Default is 100 (99 intervals). 100

Returns

Name Type Description
roots numpy.ndarray Estimated roots of the function f.

Raises

Name Type Description
RuntimeError If the algorithm fails to converge within max_iter iterations.
TypeError If the inputs are not of the expected types.
ValueError If xmax <= xmin.

Notes

The bisection method requires that a root be enclosed within an interval [a, b] such that f(a) * f(b) < 0.

Convergence is achieved when:

:math:|x_{\max} - x_{\min}| < \mathrm{tol}

When searching for multiple roots, this method:

  • Is not guaranteed to find all roots
  • Cannot detect roots with multiplicity greater than one (e.g. x**2)
  • May return duplicate roots

Examples

Find two simple roots:

>>> roots = bisection_find_roots(lambda x: x**2 - 4, -3, 3, N=100)
>>> roots
array([-2.,  2.])

Bisection may fail with large intervals:

>>> roots = bisection_find_roots(lambda x: x**2 - 0.0001, -3, 3,
...                              tol=1e-9, max_iter=1000, N=100)
>>> roots
array([])

Smaller intervals recover the roots:

>>> roots = bisection_find_roots(lambda x: x**2 - 0.0001, -3, 3,
...                              tol=1e-9, max_iter=1000, N=1000)
>>> roots
array([-0.01,  0.01])

Duplicate roots may be returned:

>>> roots = bisection_find_roots(lambda x: x**2 - 1, -3, 3,
...                              tol=1e-9, N=100)
>>> roots
array([-1., -1.,  1.,  1.])