Series-reversion polynomial solver with bootstrap and deflation
Project description
geodepoly — Series-Reversion Polynomial Solver (MVP)
geodepoly is a small Python package that finds all roots of a complex polynomial
using a shift–recenter + truncated series reversion with optional bootstrap
iterations, and only falls back to classical iterations when strictly necessary.
This implements the impact-first MVP discussed:
- Compositional inverse (via Lagrange inversion in coefficient form) around a local recentering point to obtain an analytic series for a nearby root.
- Bootstrap: update the center by the series estimate and re-expand (typically a few steps).
- Deflation: synthetic division to peel off roots one-by-one.
- Safe fallbacks: Halley or Durand–Kerner if series degenerates (multiple root / tiny derivative).
Note: This is a minimal working scaffold you can publish and iterate on. It is self-contained (numpy optional), tested, and provides a SymPy hook.
Install (editable)
pip install -e .
Install (PyPI)
pip install geodepoly==0.1.4
Quickstart
from geodepoly import series_solve_all
# Coefficients lowest-degree first: a0 + a1 x + ... + aN x^N
coeffs = [1, 0, -7, 6] # 1 + 0 x - 7 x^2 + 6 x^3 = 0 (roots near 1, 2, 3 after rescale)
roots = series_solve_all(coeffs, verbose=True)
print(roots)
CLI
python -m geodepoly.scripts.benchmark --deg 8 --seed 123 --trials 100
Examples
- SymPy comparison:
python examples/sympy_vs_nroots.py - JSON bridge round‑trip:
python examples/json_bridge_roundtrip.py - Multiple root demo:
python examples/multiple_root_demo.py
API
series_solve_all(coeffs, max_order=32, boots=3, tol=1e-12, max_deflation=None, verbose=False)series_one_root(coeffs, center=None, max_order=32, boots=3, tol=1e-14)sympy_solve(poly)— lightweight SymPy integration (if SymPy is installed).solve_eigs(A)— eigenvalues via characteristic polynomial (Faddeev–LeVerrier).
How it works (short)
Let p(x) be a degree-n polynomial. We recenter around x = μ and expand
q(y) = p(μ + y) = a0 + a1 y + a2 y^2 + .... If a1 ≠ 0, solve q(y)=0 by
compositional inversion of F(y) = y + β2 y^2 + β3 y^3 + ... with βk = ak/a1.
Lagrange inversion gives the inverse coefficients {g_m} of F, and the nearby
root is y ≈ Σ_{m≥1} g_m t^m, with t = -a0/a1. Update μ ← μ + y (bootstrap)
and repeat a few times; then deflate and continue.
This repo implements the coefficient formula
g_m = (1/m) * [y^{m-1}] (1 / F'(y))^m using truncated series arithmetic.
No derivatives of p beyond a1 = q'(0) are used.
Caveats
- Multiple or nearly-multiple roots are ill-conditioned for any method.
We switch to a guarded Durand–Kerner step when
|a1|is tiny. - Convergence radius depends on the local analytic structure; bootstrap helps.
License
MIT
New in this build
Friendlier API
from geodepoly import solve_poly, solve_all, solve_one
roots = solve_poly(coeffs, method="hybrid", resum="pade")
Methods: hybrid (series seeds + Aberth), aberth, dk, numpy (companion).
Resummation: None, "pade", "borel", "borel-pade".
SymPy integration
from geodepoly.sympy_plugin import sympy_solve
roots = sympy_solve(x**8 - 3*x + 1, method="hybrid", resum="pade")
Mathematica / Maple bridge (JSON CLI)
python bridges/geodepoly_cli.py <<'JSON'
{"coeffs":[-6,11,-6,1],"kwargs":{"method":"hybrid","resum":"pade"}}
JSON
In Mathematica:
payload = ExportString[<|"coeffs"->{-6,11,-6,1},"kwargs"-><|"method"->"hybrid","resum"->"pade"|>|>,"JSON"];
res = RunProcess[{"python","bridges/geodepoly_cli.py"}, "StandardInput"->payload, "StandardOutput"];
ImportString[res, "JSON"]
Benchmarks
python -m geodepoly.scripts.bench_compare --deg 8 --trials 50 --out bench_deg8.csv
Aggregate and plot (see docs/assets/):
python scripts/bench_compare.py --degrees 3,5,8,12 --methods hybrid,aberth,dk --trials 10 --out docs/assets/bench.csv --agg_out docs/assets/bench_agg.csv --resum auto
python scripts/plot_bench.py --in docs/assets/bench_agg.csv --out docs/assets
Previews:
Paper skeleton
See paper/GeodePoly_MVP.md.
Bench dataset & GPU roadmap
- GeodeBench spec:
bench/geodebench_spec.md, generator:bench/generate_slices.py - GPU roadmap:
docs/geode_gpu_spec.md
Hyper-Catalan API (S[t2,t3,...])
Utilities based on the paper's multivariate series:
from geodepoly import evaluate_hyper_catalan, evaluate_quadratic_slice, catalan_number
# Quadratic slice (Catalan series)
t2 = 0.05
alpha_approx = evaluate_quadratic_slice(t2, max_weight=20)
catalan_series = sum(catalan_number(n) * (t2**n) for n in range(12))
# Multivariate evaluation (truncated by weighted degree)
alpha_multi = evaluate_hyper_catalan({2: 0.05, 3: 0.01}, max_weight=12)
See docs/paper_guide.md for how the paper maps onto the codebase.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file geodepoly-0.1.5.tar.gz.
File metadata
- Download URL: geodepoly-0.1.5.tar.gz
- Upload date:
- Size: 22.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.11.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
df4d3f0799776cf26bca79cb36defac55c762f899cbbb704ee5c4b2b79872c8d
|
|
| MD5 |
b1c6a0e0155c57bfe52c434376e45e1f
|
|
| BLAKE2b-256 |
93414414764b01d18042992ba1b5e16d29df33faf65e6a1644efb8bb0ead0cf8
|
File details
Details for the file geodepoly-0.1.5-py3-none-any.whl.
File metadata
- Download URL: geodepoly-0.1.5-py3-none-any.whl
- Upload date:
- Size: 21.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.11.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7f6b69d05595b30b099d30cd95387c692d00b9624d85d7cf02cf96dca255d101
|
|
| MD5 |
08f00a8b63cc21568dce01ef640074bf
|
|
| BLAKE2b-256 |
73ebfbacb1a055efef77232ae192a6c13fc689fe08e170c90e324554bb6553a3
|