Skip to main content

ER2 — Mathematical Python

CI Status: early development Python 3.12 | 3.13 | 3.14 License: MIT Code style: PEP 8 Ruff PARI/GP SymPy Jupyter Quarto Cite Contributions welcome

ER2 is Python with mathematics built in: symbolic syntax, exact arithmetic by default, and computational number theory powered by PARI/GP.

It is named after the Hungarian mathematician Paul Erdős. In Spanish, "Erdős" sounds like "ER-dos", which is where ER2 comes from.

Why ER2?

  • Write mathematics as mathematics. x^2 is a power, 1/3 is exactly one third, and sym x declares a symbol. There are no imports and no Rational(1, 3).
  • Two engines, one language. ER2 sends each computation to the right backend: SymPy for symbolic algebra and PARI/GP, one of the fastest number theory systems, for integers, primes and modular arithmetic.
  • It is still Python. All Python syntax works, every library imports as usual, and ER2 runs in Jupyter and Quarto with LaTeX output.

Quick start

ER2 is not on PyPI yet. You need Python ≥ 3.12 and uv; PARI comes inside the cypari2 wheel, so there is nothing else to install.

git clone https://github.com/oeistools/ER2.git && cd ER2
uv sync
uv run er2 examples/hello.er2
Hello from ER2
1024 1/2
x^3 + 3*x^2 + 3*x + 1
True

Then try the REPL (uv run er2), write your own program.er2, or open a notebook: see Jupyter and Quarto. uv run er2 --show-python program.er2 shows the Python that ER2 generates.

A taste of ER2

import numpy as np            # any Python library, imported as usual

sym x                         # declare a symbol
f = x^2 + 2*x + 1             # ^ means power

print(factor(f))              # (x + 1)^2
print(diff(f, x))             # 2*x + 2
print(latex(f))               # x^{2} + 2 x + 1  (any expression → LaTeX)

print(1/3)                    # 1/3, exact and not 0.333...
print(isprime(2^521 - 1))     # True  (PARI)
print(phi(123456789))         # 82260072
print(factor(2^127 - 1))      # 2^127 - 1 is prime
print(factor(360))            # 2^3 * 3^2 * 5

for k in range(1, 20):        # ordinary Python
    if isprime(k):
        print(k)

np.zeros(2^3)                 # ER2 numbers pass straight into libraries

Examples

Each program runs with uv run er2 examples/<name>.er2, and its expected output is checked by the test suite.

Example What it shows
hello.er2 The smallest tour: power, exact division, algebra, a primality test
syntax.er2 Every ER2 syntax difference from Python: ^, ^^, exact literals, sym, 5r
factorization.er2 One factor for integers, rationals and polynomials; partial factorizations
mvp.er2 The MVP program: CAS and number theory together
demo.qmd A Quarto tour with rendered math, including the OEIS (make render)
mvp.ipynb The MVP as a Jupyter notebook

Documentation

The documentation site is at https://oeistools.github.io/ER2/, built by Quarto and executed by ER2 itself.

If you want to… Read
Use ER2 This README, the examples, and docs/PARI_FUNCTIONS.md (every PARI function and its ER2 name)
Know exactly what the language is docs/LANGUAGE.md: the normative specification — the differences from Python, precedence, the number model, and what is stable before 1.0
Understand the design ARCHITECTURE.md: the compatibility contract, the components, and the design decisions D1–D17
Follow the project PLAN.md (milestones and acceptance criteria), CHANGELOG.md (releases and versioning policy), docs/BENCHMARKS.md
Contribute CONTRIBUTING.md: setup, tests, rules for each part of the code, good first contributions

The rules for AI-assisted development are in CLAUDE.md.

Algebra (0.5)

sym x, y

det(Matrix([[2, 1], [1, 3]]))        # 5, computed by PARI
kernel(Matrix([[1, 2], [2, 4]]))     # [Matrix([[1], [-1/2]])]
smith_form(Matrix([[2, 4], [6, 8]])) # Matrix([[2, 0], [0, 4]]), as SymPy's

factor(x^8 - x, modulus=2)           # x*(x + 1)*(x^3 + x + 1)*(x^3 + x^2 + 1)
isirreducible(x^2 + x + 1, modulus=2)   # True

a = GF(9).gen()                      # the finite field with 9 elements
a^4, a.order(), minpoly(a)           # 2, 8, x^2 + x + 2

resultant(x^2 + 1, x^3 - 2, x)       # 5
discriminant(x^3 + x + 1)            # -31

G = groebner([x^2 + y^2 - 1, x - y], x, y)
list(G)                              # [x - y, 2*y^2 - 1]
reduce(x^2 + y^2, G)                 # 1, the normal form

K = NumberField(x^2 + 5)             # Q(sqrt(-5))
K.discriminant, K.class_number()     # -20, 2
K.factor(2)                          # [((2, x + 1), 2)]: 2 ramifies
K.factor(3)                          # 3 splits into two primes

resultant follows the standard sign convention, which is PARI's, so resultant(f, g) and resultant(g, f) differ in sign when both degrees are odd (ARCHITECTURE.md §6, D16). A class number is only as good as the GRH unless you ask for certify=True.

Python compatibility

ER2 is a superset of Python and follows the same model as SageMath:

  • All Python syntax works: classes, decorators, generators, async, match, f-strings, type hints, and the rest.

  • The whole ecosystem is available through normal import: NumPy, SciPy, pandas, Matplotlib, and so on.

  • Only .er2 sources are translated. Your .py modules and installed libraries run as ordinary Python and are never modified.

  • Inside .er2 files there are only a few deliberate differences:

    Construct Python ER2
    a ^ b XOR power
    a ^^ b syntax error XOR
    1/3 0.333… exact rational 1/3
    sym x, y syntax error declares symbols x, y
    5r syntax error the plain Python int 5

Jupyter and Quarto

ER2 runs in notebooks and in Quarto documents:

  • ER2 kernel: run er2 kernel install, then pick "ER2" in Jupyter. In Quarto, set jupyter: er2 in the front matter. If Quarto or your editor reports Jupyter kernel 'er2' not found, it is only looking inside the project's virtual environment: run er2 kernel install --sys-prefix as well. In VS Code, the Quarto Preview button uses the system Python unless QUARTO_PYTHON is set. Add "terminal.integrated.env.linux": {"QUARTO_PYTHON": "${workspaceFolder}/.venv/bin/python"} to .vscode/settings.json.
  • Any Python kernel: add %load_ext er2 in the first cell.
  • LaTeX everywhere: expressions render as math. show(f) displays one, and `{python} latex(f)` puts inline math in Quarto text.
---
title: "Mersenne primes"
jupyter: er2
---

```{python}
[p for p in range(2, 130) if isprime(2^p - 1)]
```

How it works

ER2 does not introduce a new interpreter. It has three parts:

.er2 source ──► preparser ──► plain Python ──► CPython
                                                  │
                                    ER2 runtime (types, printing, dispatch)
                                          │                 │
                                        SymPy          cypari2 → PARI
                                    (symbolic math)   (number theory)
  1. Preparser. A token-level, source-to-source translation from .er2 to Python.
  2. Runtime. The er2 package provides the mathematical types and the functions (factor, diff, phi, …).
  3. Backends. SymPy handles symbolic computation, and PARI is accessed through cypari2. ER2 chooses the backend automatically, so factor works on both polynomials and integers.

Status and roadmap

Version 0.7.0, early development. Milestones M1–M7 are done (M3 was the MVP). Algebra (matrices, finite fields, F_p, resultants, Gröbner bases, NumberField), series (power, Dirichlet, Euler products) and the language specification are all in. docs/LANGUAGE.md now defines the language normatively, and CHANGELOG.md says what is stable, what is still experimental, and what has changed. What remains before 1.0 is the documentation site and the stability policy.

Version Focus Status
0.1 Preparser: sym, ^, _x, exact integers and rationals; Jupyter kernel, %load_ext er2, Quarto ✅
0.2 CAS on SymPy: expand, factor, simplify, diff, integrate, limit, solve, series ✅
0.3 Number theory on PARI: primality, factorization, phi, sigma, mu, … (the MVP) ✅
0.4 Automatic backend selection, PARI types (Mod, Qfb, series), benchmarks, the OEIS ✅
0.5 Algebra: matrices, finite fields, resultants, Gröbner bases, number fields ✅
0.6 Series: power, Dirichlet, Euler products ✅
0.7 The language specification, docs/LANGUAGE.md; first PyPI release ✅
1.0 Frozen syntax and public API: documentation site, stability policy in progress

Beyond the table, every PARI function is available as pari.<name>, and PARI's sums and integrals take Python functions (pari.sum(lambda n: 1/n^2, 1, 10)). Deeper CPython integration comes only after the syntax is stable.

Development

make install                    # uv sync + the ER2 kernel inside .venv
make test-fast                  # the tests without Jupyter and Quarto
make check                      # ruff + all tests, as in CI
make install-global             # the `er2` command for your user, editable (uv tool)
make preview FILE=my_doc.qmd    # live Quarto preview with the ER2 kernel

make lists every target. make install-global puts er2 in ~/.local/bin. It is an editable install, so it follows changes to the code, and it registers the ER2 kernel for your user.

We keep dependencies deliberately minimal: sympy and cypari2 at runtime, plus ipykernel and oeis-tools as the optional er2[jupyter] and er2[oeis] extras. Development uses pytest and ruff. The code follows PEP 8.

Contributing

ER2 is maintained by Enrique Pérez Herrero (energycode.org@gmail.com).

Contributions are welcome, from a bug report with a three-line example to a new feature. CONTRIBUTING.md explains how to set up, what a pull request needs, and where to start if you are new to the project.

Citation

If you use ER2 in your work, please cite it. The metadata is in CITATION.cff, and GitHub shows it through "Cite this repository". Please also cite PARI/GP and SymPy, which ER2 builds on.

License

MIT

Release files for er2 0.7.0

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

Source distribution (sdist)

Source distribution for er2 0.7.0
File Size Uploaded
er2-0.7.0.tar.gz 97.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for er2 0.7.0
File Interpreter ABI Platform
er2-0.7.0-py3-none-any.whl Python 3 none any Details

Total release size: 206.4 kB

Release files / er2-0.7.0.tar.gz

Download URL er2-0.7.0.tar.gz
Size 97.8 kB
Tags Source
SHA-256 checksum
How to use checksums
0b0b4b0acd4d2665f3144fc2a050cc37721722d710bdc6aaf6c5ffa69b3fab21
BLAKE2b-256 checksum
How to use checksums
085a33cfcf3596babc4923fb284ea4ceef98bba2ab23315578fa8187b4c2e5b1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 26, 2026.

Transparency log

Release files / er2-0.7.0-py3-none-any.whl

Download URL er2-0.7.0-py3-none-any.whl
Size 108.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
541e2e7cc344e38a4db06eaa8b2bfe373541238dffa52e68a600dd6cbc01b08e
BLAKE2b-256 checksum
How to use checksums
138b8cdb9e866104ad7e391a952d8fb95071686bc0ce38bef181d267878d08d1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 26, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.7.0 This release

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