Numerical rootfinding suite · Rn → {0}

Find every root in the box.
Prove there's nothing left out.

Yroots locates all real roots of smooth multivariate systems inside a compact search interval — no initial guess, no missed solutions, just the box and the functions. The same algorithm ships three ways: two Python editions and jroots, the Julia port.

Try yroots in your browser ↗ Opens the tutorial notebook on Google Colab. Single-threaded edition, nothing to install.
Figure 1
yroots.solve([f, g], a, b) searching interval…

Yroots isolates the real roots of a smooth system on a bounded interval [a, b]. Markers show the zero crossings it returns.

Algorithm

Chebyshev subdivision, not homotopy or elimination.

Rootfinders for this problem tend to fall into one of three families: homotopy continuation methods that track paths from a related system with known solutions, eigenvalue methods built on Möller–Stetter matrices, and resultant-based methods that eliminate variables one pair at a time. Yroots takes a fourth route — it builds a Chebyshev interpolant of each function, then repeatedly subdivides and shrinks the search box using properties specific to the Chebyshev basis. Near a simple zero, the interval is proven to shrink quadratically.

Method classRepresentative solverApproach
Homotopy continuationBertiniTrack paths from a related system with known roots
Eigenvalue-basedMöller–StetterRecast rootfinding as an eigenvalue problem
Resultant-basedChebfun2Eliminate variables one pair at a time
Chebyshev subdivisionyroots / jrootsSubdivide and shrink the box using Chebyshev basis properties
Real results

Benchmark.

Every solver runs on the same three families of systems. Dense systems are randomly generated with every coefficient populated up to a given degree, across dimensions 2–5. Sparse systems keep only a small, fixed number of nonzero terms per polynomial — that sparsity is what makes dimensions up to 8 tractable at all. Chebfun isn't randomly generated — it's a fixed set of hand-picked, harder bivariate systems (curves with cusps, near-tangencies, clustered roots), run specifically to compare against Chebfun2, which only handles two dimensions. Data pulled live from tylerjarvis/rootfinding_testing.

yroots jroots MTV Bertini NSolveValues Reduce Chebfun Croots Lambda variants
Three implementations, one algorithm

Pick the engine that fits your system.

All three solve the same problem — zeros of n smooth functions in n variables over a compact box. The two Python editions differ only in whether the subdivision runs across threads; jroots is the Julia port. The benchmark above is where yroots and jroots are run side by side against solvers like Bertini, Chebfun and NSolve.

Python · parallel

yroots

Uses Chebyshev polynomial approximation to subdivide the search box and isolate roots to machine precision. Guaranteed to find every root as long as the system is smooth, continuous, and has finitely many simple zeros in the interval. Subdivided regions are handed to a worker pool, which is why it wants the free-threaded build.

  • Requires Python 3.14t (free-threaded build), NumPy ≥2.4.4, Numba ≥0.65.1, SciPy ≥1.17.1, SymPy ≥1.12
  • Returns a NumPy array of root coordinates, one row per root
  • Parallelism max_cpu and parallel_depth on solve()
  • Funding NSF grant DMS-1564502
# install (with uv, recommended)
uv python install 3.14t
uv pip install git+https://github.com/tylerjarvis/RootFinding.git

# usage
import yroots as yr
f = lambda x, y: np.sin(x*y) + x*np.log(y + 3) - x**2
g = lambda x, y: np.cos(3*x*y) + np.exp(3*y/(x - 2)) - x
a, b = [-1, -2], [0, 1]
roots = yr.solve([f, g], a, b)
Python · serial

yroots-serial

The same subdivision solver with the parallel driver taken out: one thread, stock CPython. It is the reference the parallel fork is checked against, and the edition to reach for where a free-threaded interpreter isn't available. Same import, same call — without the two parallel arguments.

  • Requires Python ≥3.9, NumPy ≥1.21, Numba ≥0.57, SciPy ≥1.10, Matplotlib ≥3.7
  • Returns a NumPy array of root coordinates, one row per root
  • Differs solve() takes no max_cpu or parallel_depth
# install (stock CPython, 3.9 or newer)
pip install git+https://github.com/tylerjarvis/Rootfinding-serial.git

# usage -- same f, g and box as above
import yroots as yr
roots = yr.solve([f, g], a, b)

# the parallel edition adds, on top of this:
# roots = yr.solve([f, g], a, b, max_cpu=8)
Julia

jroots

A Julia port of the same Chebyshev subdivision algorithm, developed as Julia-Rootfinding. It's an active, in-progress translation of the Python codebase — internally the module is still named YRoots — with a separate FastSolve path for a more optimized solve.

  • Requires Julia · CSV, DataFrames, DelimitedFiles, FFTW, IterTools, Statistics
  • Returns an array of root coordinates, same convention as yroots
  • Status early-stage port (v0.1.0), not yet a registered package
# install (not yet registered — clone and include directly)
git clone https://github.com/tylerjarvis/Julia-Rootfinding.git
cd Julia-Rootfinding # then ] activate . && ] instantiate in Julia

# usage
include("src/CombinedSolver.jl")
f = (x,y) -> sin(30*x - y/30) + y
g = (x,y) -> cos(x/30 - 30*y) - x
a, b = [-1,-1], [1,1]
roots = solve([f, g], a, b; verbose=true)
About

Yroots and its variants are built and maintained by Tyler Jarvis' YRoots group at Brigham Young University. The underlying algorithm is described, and its properties proved, in the paper E. Parkinson, K. Wall, J. Slagle, D. Treuhaft, X. de la Bruere, S. Goldrup, T. Keith, P. Call, and T.J. Jarvis, Chebyshev subdivision and reduction methods for solving multivariable systems of equations, J. of Symbolic Computation 128 (2025) 102392. Some of the underlying ideas and design choices were influenced by our analysis of rootfinding algorithms in S. Parkinson, H. Ringer, K. Wall, E. Parkinson, L. Erekson, D. Christensen, and T.J. Jarvis, Analysis of normal-form algorithms for solving systems of polynomial equations, J. of Computational and Applied Mathematics 411 (September 2022), 114235.

Contributors

Peter Call· Xander de la Bruere· Lukas Erekson· Samuel Goldrup· Alex Hermosilla· Tyler J. Jarvis· David Kartchner· Timothy Keith· Catherine Kellar· Natalie Larsen· Hyun Lee· Nathan Longhurst· Jeremy Magland· Derek Miller· Tyler Moncur· Erik Parkinson· Hayden Ringer· Jane Slagle· Suzanna Stephenson· Zachary Taylor· Daniel Treuhaft· Kate Wall· Rowan Williams

Thanks also to Simon Telen and Alex Townsend for helpful feedback and suggestions.

This work has been supported in part by the College of Computing, Math, and Science at Brigham Young University; by two Mentoring Environment Grants from Brigham Young University; and by the National Science Foundation under grant DMS-1564502.

Reference

Cite this work.

The algorithm behind yroots is described and proven in Parkinson, Wall, Slagle, Treuhaft, de la Bruere, Goldrup, Keith, Call & Jarvis, Chebyshev Subdivision and Reduction Methods for Solving Multivariable Systems of Equations, Journal of Symbolic Computation (2024).

@article{parkinson2024chebyshev,
  title = {Chebyshev Subdivision and Reduction Methods for
    Solving Multivariable Systems of Equations},
  author = {Parkinson, Erik and Wall, Kate and Slagle, Jane
    and Treuhaft, Daniel and de la Bruere, Xander
    and Goldrup, Samuel and Keith, Timothy and Call, Peter
    and Jarvis, Tyler J.},
  journal = {Journal of Symbolic Computation},
  year = {2024},
  eprint = {2401.02114},
  archivePrefix = {arXiv}
}