Skip to main content

A fast and robust root-finding library written in C for Python, using the Modified Anderson-Bjork method: Ganchovski, N.; Smith, O.; Rackauckas, C.; Tomov, L.; Traykov, A. Improvements to the Modified Anderson–Björck(modAB) Root-Finding Algorithm. Algorithms 2026, 19, 332. https://doi.org/10.3390/a19050332 It finds the root of a single nonlinear equation f(x) = 0 within the specified interval [x1, x2].

Installation

pip install pymodab

Usage

import math
from pymodab import find_root, get_evaluation_count

# Find the root of cos(x) - x = 0 in [0, 1]
root = find_root(lambda x: math.cos(x) - x, 0, 1, 1e-3, 1e-3, 10)
print(f"Root: {root}")  # 0.7390851332086904

# Get the number of function evaluations
print(f"Evaluations: {get_evaluation_count()}")
print(f"Error:       {math.cos(root) - root}")

# Using default tolerances
root = find_root(lambda x: x**2 - 2, 1, 2)
print(f"sqrt(2) = {root}")  # 1.414213562373095

# Get the number of function evaluations
print(f"Evaluations: {get_evaluation_count()}")
print(f"Error:       {root**2 - 2}")

API

find_root(f, x1, x2, atol=1e-14, rtol=1e-14, max_iter=200)

Find the root of f(x) = 0 within the interval [x1, x2].

Parameters:

  • f: A continuous function of one variable, or the address (int) of a compiled C function double f(double)
  • x1, x2: Bracket interval endpoints (must satisfy f(x1) * f(x2) < 0)
  • atol: Absolute tolerance (default: 1e-14)
  • rtol: Relative tolerance (default: 1e-14)
  • max_iter: Maximum iterations (default: 200)

Returns: The root, or NaN if not found. Exceptions raised by f are propagated to the caller.

Since version 1.0.6, find_root is a native CPython extension that calls f directly, which is about 2x faster than the previous ctypes wrapper. If the extension is not available for your platform, pymodab falls back to ctypes automatically; pymodab.NATIVE tells which one is used.

For maximum speed, pass a compiled function, e.g. from numba. It is then called from C with no Python overhead:

import math
from numba import cfunc
from pymodab import find_root

@cfunc("float64(float64)")
def f(x):
    return math.cos(x) - x

root = find_root(f.address, 0, 1)

get_evaluation_count()

Returns the number of function evaluations from the last root-finding call.

Algorithm

Modified Anderson-Björck's method is a new robust and efficient bracketing root-finding algorithm. It combines bisection with Anderson-Björk's method to achieve both fast performance and worst-case optimality.

References:

Ganchovski N.; Traykov A. Modified Anderson-Björck's method for solving non-linear equations in structural mechanics. IOP Conference Series: Materials Science and Engineering 2023, 1276 (1) 012010, IOP Publishing.
https://iopscience.iop.org/article/10.1088/1757-899X/1276/1/012010/pdf

Ganchovski, N.; Smith, O.; Rackauckas, C.; Tomov, L.; Traykov, A. Improvements to the Modified Anderson–Björck (modAB) Root-Finding Algorithm. Algorithms 2026, 19, 332. https://doi.org/10.3390/a19050332

License

MIT License

Benchmark results

The modAB algorithm is benchmarked against the available algorithms in Python/SciPy in respect to number of evaluations and execution times:

  • bisect- Bisection method
  • brentq - Brent’s method (van Wijngaarden–Dekker–Brent, 1973)
  • brenth - Brent–Dekker variant (hyperbolic extrapolation variant, 1975)
  • ridder - Ridder’s method (1979)
  • toms748 - Alefeld–Potra–Shi method (1995 - TOMS Algorithm 748)
  • chandr - Chandrupatla's method (1997) - scipy.optimize.elementwise.find_root
  • cybrentq - Cython implementation of brentq by Gledis Caushaj
  • modAB - Modified Anderson Bjork's method (Ganchovski & Traykov, 2023; improved 2026)
  • modAB_ct - the old version of pymodab 1.0.5 implemented with ctypes

Function evaluations

Func bisect brentq brenth ridder chandr cybrentq modAB_ct modAB
SUM 4464 2571 2534 3177 1891 2571 1746 1746
AVG 48 28 27 34 20 28 19 19
MEDIAN 49 12 12 16 12 12 12 12
MIN 3 4 4 3 3 4 3 3
MAX 53 102 102 202 58 102 55 55
FACTOR 2.557x 1.473x 1.451x 1.820x 1.083x 1.473x 1.000x 1.000x

Execution times (ms per problem, 100 iterations)

Func bisect brentq brenth ridder chandr cybrentq modAB_ct modAB
SUM 1359.38 946.80 795.71 928.54 50164.55 103.09 145.35 75.77
Func bisect brentq brenth ridder chandr cybrentq modAB_ct modAB
AVG 14.6170 10.1806 8.5561 9.9843 539.4037 1.1085 1.5629 0.8147
MEDIAN 14.1612 4.7324 4.5651 5.9825 307.2908 0.5875 1.2580 0.6201
MIN 2.1026 2.5171 1.7910 1.4065 84.3124 0.2047 0.5414 0.1632
MAX 55.4387 78.7136 32.4967 52.4362 1574.8965 5.4855 4.2678 2.8956
FACTOR 17.941x 12.496x 10.502x 12.255x 662.085x 1.361x 1.918x 1.000x

Notes:

Last Run on: 18.09.2026
Intel(R) Core(TM) i7-1065G7 CPU @ 1.30GHz (1.50 GHz) with 16.0 GB RAM
Windows 11 Home
Python Version: 3.14.7
numpy Version: 2.4.6
scipy Version: 1.18.0
cybrentq Version: 0.1.5 - by Gledis Caushaj (https://github.com/gledi-ai/cybrentq)
modAB_ct: pymodab version 1.0.5 - the previous implementation with ctypes
modAB: pymodab version 1.0.6 - the latest implementation as native C extension

Release files for pymodab 1.0.6

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pymodab 1.0.6
File Size Uploaded
pymodab-1.0.6.tar.gz 113.7 kB Details

Built distributions (wheels)

Table of built distributions (wheels) for pymodab 1.0.6
File Interpreter ABI Platform
pymodab-1.0.6-py3-none-any.whl Python 3 none any Details
pymodab-1.0.6-cp38-abi3-win_amd64.whl CPython 3.8 abi3 Windows x86-64 Details

Total release size: 343.8 kB

Release files / pymodab-1.0.6.tar.gz

Download URL pymodab-1.0.6.tar.gz
Size 113.7 kB
Tags Source
SHA-256 checksum
How to use checksums
b0c2925e6a2d9e9504ab10545440421135bb2210b0b58cf445ca20cddef1c843
BLAKE2b-256 checksum
How to use checksums
b9371f3d0055eaaf4f362ee4563b6bdad3eaf5d6143715b685f0602c7059f8f6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.7

Release files / pymodab-1.0.6-py3-none-any.whl

Download URL pymodab-1.0.6-py3-none-any.whl
Size 110.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
149fd72650f71b5240f15f3d04709435e0b61b2e6632de0bcb1239305e95233f
BLAKE2b-256 checksum
How to use checksums
029270147577038dd669c50082c752313fad30b8fc903f01370b52d3daa07cbe
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.7

Release files / pymodab-1.0.6-cp38-abi3-win_amd64.whl

Download URL pymodab-1.0.6-cp38-abi3-win_amd64.whl
Size 119.2 kB
Tags CPython 3.8 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
3bb00774517ba9c1caa667e65e5e2020f0c81a62032f4e5c3332e079ef7eb814
BLAKE2b-256 checksum
How to use checksums
11d6b58673d4f3b79ea684a5fc858e4555e9da8aaa9c2fde154eb11d8df2aa3e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.7

Release history Release notifications | RSS feed

1.0.7

8 release files

This release

1.0.6 This release

3 release files

1.0.5

2 release files

1.0.4

2 release files

1.0.3

2 release files

1.0.2

2 release files

1.0.1

2 release files

1.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page