A Standalone Symbolic Engine for AI Agents and Mathematical Computing
- Symbolic Computation: Work with mathematical expressions symbolically
- Calculus: Differentiation, integration, limits, series, variational derivatives
- Linear Algebra: Matrix operations, eigenvalues, determinants
- Differential Equations: Symbolic and numerical ODE solving
- Differential Geometry: Metrics, Christoffel symbols, curvature tensors, abstract indices
- Special Functions: Bessel, Gamma, error functions, and more
- Pattern Matching: Replace, ReplaceAll, custom function definitions
- Custom Types: Define your own types (Quaternion, Vector3D included)
- Probability: Distribution functions and statistics
- Optimization: Convex optimization via cvxpy (optional)
- Symbolic Regression: Discover formulas from data via PySR
- Compact Models: Extract symbolic models from FDTD simulation data with Kramers-Kronig causality enforcement
- Plotting: Publication-quality mathematical plots
- Composable API: Pipe operations and functional composition
symderive is built for stateless, functional composition -- the ideal paradigm for LLM agents that need to chain mathematical operations without tracking mutable state.
import symderive as sd
from symderive import Pipe, pipe, Sin, Cos
x = sd.Symbol('x')
# Stateless transformation pipeline
result = (
Pipe((x + 1)**3)
.then(sd.Expand)
.then(sd.Simplify)
.value
)
# Or use the functional form
result = pipe(Sin(x)**2 + Cos(x)**2, sd.Simplify) # Returns 1Each Pipe stage is a pure function: input in, output out, no side effects.
symderive includes functional programming constructs that let agents express complex mathematical workflows declaratively:
# Repeated function application
Nest(lambda x: x**2, 2, 3) # 256 (2 -> 4 -> 16 -> 256)
NestList(lambda x: 2*x, 1, 4) # [1, 2, 4, 8, 16]
# Convergence detection
FixedPoint(lambda x: (x + 2/x)/2, 1.0) # sqrt(2)
FixedPointList(lambda x: Cos(x), 1.0) # Full convergence path
# Fold operations for accumulation
FoldList(lambda acc, x: acc + x, 0, [1, 2, 3, 4]) # [0, 1, 3, 6, 10]These primitives let agents reason about iteration, convergence, and accumulation without writing explicit loops -- reducing the chance of off-by-one errors and infinite loops in generated code.
symderive uses standard mathematical notation that researchers and students already know:
import symderive as sd
from symderive import D, Integrate, Limit, Series, Sin, Cos, Exp, oo
x = sd.Symbol('x')
# Familiar mathematical syntax
D(Sin(x), x) # Differentiation
Integrate(Exp(-x**2), (x, -oo, oo)) # Gaussian integral
Limit(Sin(x)/x, x, 0) # L'Hopital
Series(Cos(x), (x, 0, 4)) # Taylor expansionNo need to learn a new API. If you know Mathematica or standard mathematical notation, you know symderive.
Floats automatically convert to exact rationals, preventing floating-point drift in symbolic computation:
0.5 * x # Becomes Rational(1, 2) * x, not 0.5 * x
1/3 + 1/6 # Exact: Rational(1, 2)Use exact() and numerical() context managers when you need explicit control.
pip install symderiveimport symderive as sdgit clone git@github.com:closedform/deriver.git
cd deriver
pip install -e .For optional dependencies:
pip install -e ".[notebooks]" # Marimo interactive notebooks
pip install -e ".[optimize]" # Convex optimization (cvxpy)
pip install -e ".[regression]" # Symbolic regression (pysr + Julia)
pip install -e ".[all]" # All optional dependenciesA requirements.txt is also provided for environments that prefer it.
For faster dependency resolution, use uv:
git clone git@github.com:closedform/deriver.git
cd deriver
uv syncSome features require optional dependencies:
uv sync --extra notebooks # Marimo interactive notebooks
uv sync --extra optimize # Convex optimization (cvxpy)
uv sync --extra regression # Symbolic regression (pysr + Julia)
uv sync --extra all # All optional dependenciesimport symderive as sd
from symderive import D, Integrate, Limit, Series, Sin, Cos, Exp, Eq, Pi
# Define symbols
x, y = sd.symbols('x y')
# Calculus
D(Sin(x), x) # Differentiation: Cos(x)
Integrate(x**2, x) # Integration: x**3/3
Limit(Sin(x)/x, x, 0) # Limits: 1
Series(Exp(x), (x, 0, 5)) # Taylor series
# Algebra
sd.Solve(Eq(x**2 - 4, 0), x) # Solve equations: [-2, 2]
sd.Factor(x**2 - 5*x + 6) # Factor: (x-2)(x-3)
sd.Simplify(Sin(x)**2 + Cos(x)**2) # Simplify: 1
# Linear Algebra
A = sd.Matrix([[1, 2], [3, 4]])
sd.Det(A) # Determinant: -2
sd.Eigenvalues(A) # Eigenvalues
sd.Inverse(A) # Matrix inverse
# Differential Equations
t = sd.Symbol('t')
y = sd.Function('y')
sd.DSolve(Eq(D(y(t), t), y(t)), y(t), t) # Solve dy/dt = y
# Plotting
sd.Plot(Sin(x), (x, 0, 2*Pi), PlotLabel="Sine Wave")import symderive as sd
from symderive import Sin
import symderive.diffgeo as dg
# Create a metric (2-sphere)
theta, phi = sd.symbols('theta phi', real=True)
sphere = dg.Metric(
coords=[theta, phi],
components=[
[1, 0],
[0, Sin(theta)**2]
]
)
# Compute geometric quantities
christoffel = sphere.christoffel_second_kind()
riemann = sphere.riemann_tensor()
ricci = sphere.ricci_tensor()
R = sphere.ricci_scalar()
# Abstract index notation (xAct-style)
spacetime = dg.IndexType('spacetime', 4, metric=dg.minkowski_metric())
a, b, c = spacetime.indices('a b c')
T = dg.AbstractTensor('T', rank=2, index_type=spacetime)
g = dg.AbstractTensor('g', rank=2, index_type=spacetime, symmetric=[(0, 1)])
F = dg.AbstractTensor('F', rank=2, index_type=spacetime, antisymmetric=[(0, 1)])
# Use sign convention: a = upper, -a = lower
T[a, -b] # T^a_b
T[-a, -b] # T_abimport symderive as sd
x, y, a = sd.Symbol('x'), sd.Symbol('y'), sd.Symbol('a')
# Pattern-based replacement
sd.Replace(x**2 + y**2, sd.Rule(x**2, a)) # a + y**2
# Replace all occurrences
sd.ReplaceAll(x + x**2 + x**3, sd.Rule(x, 2)) # 2 + 4 + 8
# Define custom functions
x_ = sd.Pattern_('x')
f = sd.DefineFunction('f')
f.define(x_, x_**2 + 1)
f(3) # 10from symderive.types import Quaternion, Vector3D
# Quaternions
q1 = Quaternion(1, 2, 3, 4)
q2 = Quaternion(5, 6, 7, 8)
q1 * q2 # Quaternion multiplication
# 3D Vectors
v1 = Vector3D(1, 2, 3)
v2 = Vector3D(4, 5, 6)
v1.cross(v2) # Cross product
v1.dot(v2) # Dot productimport symderive as sd
from symderive import D, Rational
from symderive.calculus import VariationalDerivative
# Klein-Gordon Lagrangian
x, t, m = sd.symbols('x t m')
phi = sd.Function('phi')(x, t)
L = Rational(1,2)*D(phi,t)**2 - Rational(1,2)*D(phi,x)**2 - Rational(1,2)*m**2*phi**2
# Compute Euler-Lagrange equation
eq = VariationalDerivative(L, phi, [x, t])
# Result: -m**2 * phi - d**2 phi/dt**2 + d**2 phi/dx**2 = 0from symderive.compact import (
LoadSParameters, FitRationalModel,
CheckCausality, RationalModel
)
# Load S-parameter data from Touchstone file
freq, S11, S21 = LoadSParameters("device.s2p")
# Fit a rational function model (vector fitting)
model = FitRationalModel(freq, S21, n_poles=4)
# Check Kramers-Kronig causality
is_causal = CheckCausality(model)
# Export pole-residue form for SPICE/Verilog-A
poles, residues = model.pole_residue_form()symderive ships with agent personas -- pre-prompted contexts that transform general-purpose LLMs into domain experts in mathematical and physical reasoning.
from symderive.agents import load_agent, list_agents
# See available agents
list_agents() # ['ed', 'steve', 'atiyah', 'grothendieck', ...]
# Load an agent's system prompt
prompt = load_agent("ed") # Returns full system prompt textThen paste into your LLM:
With Claude:
System: [output of load_agent("ed")]
User: Derive the Klein-Gordon equation from the scalar field Lagrangian.
With ChatGPT:
[Custom Instructions or System Message]
[output of load_agent("steve")]
User: What experimental signatures would distinguish this model from QCD?
This is a key differentiator from other math libraries: symderive ships with battle-tested prompts that transform general-purpose LLMs into domain experts.
| Agent | Expertise | Use When |
|---|---|---|
| Ed | Theoretical physicist (QFT, gravity, condensed matter, statistical mechanics). Analytical methods, scaling arguments, physical intuition. | You need derivations, physical insight, or theoretical analysis |
| Steve | Particle physicist and critical reviewer. Demands experimental grounding and calculational rigor. | You need to verify calculations or connect theory to experiment |
| Atiyah | Geometric bridge-builder (index theory, K-theory, topology). Elegant proofs and clear notation. | You need geometric/topological insight or elegant formulations |
| Grothendieck | Abstraction architect (category theory, schemes, universal properties). Patient exposition. | You want to reframe problems in more general settings |
| Bill Press | Numerical algorithms expert. Stability, conditioning, error analysis, diagnostics. | You have numerical instability or need robust algorithms |
| Jim Simons | Quantitative researcher. Statistical signals, backtesting, risk management. | You need to validate strategies or design robust experiments |
| Edward Tufte | Information design critic. Clarity, density, honest visual encoding. | You want feedback on visualizations or data presentation |
| Beavis | Fast sanity checker. Spots obvious bugs, keeps momentum. | You need a quick gut check or obvious failure modes |
| Butt-Head | Skeptical contrarian. Questions assumptions, demands clarity. | You need to stress-test reasoning or find weak claims |
The AGENTS.yaml index provides lightweight metadata for routing without loading full agent definitions:
# Read ~600 tokens instead of ~15,000
categories:
physics:
agents:
- id: ed
summary: "Theoretical physicist..."
tags: [physics, theory, analytical]
use_when: "User needs theoretical physics analysis..."Orchestrators can:
- Load
AGENTS.yamlto understand available capabilities - Match user intent to category, then select within category
- Load full
.agent.mdonly when delegating to that agent
Use load_agents_index() for the complete roster and routing hints.
See the docs/ directory for detailed documentation on:
- Calculus - Differentiation, integration, limits, series, transforms
- Special Functions - Bessel, Legendre, Hermite, elliptic integrals
- Differential Geometry - Metrics, Christoffel, curvature, tensors
- Plotting - Function plots, data visualization
The examples/ directory contains interactive Marimo notebooks demonstrating complex use cases:
| Notebook | Description | GitHub | Rendered |
|---|---|---|---|
derive_marimo.py |
Intro notebook for core calculus/plotting | IPYNB | HTML |
symbolic_regression.py |
Discover formulas from data with FindFormula/PySR | IPYNB | HTML |
classical_mechanics.py |
Lagrangian/Hamiltonian mechanics, Noether's theorem | IPYNB | HTML |
quantum_mechanics.py |
Harmonic oscillator, hydrogen atom, perturbation theory | IPYNB | HTML |
electromagnetism.py |
Maxwell equations, gauge theory, EM waves | IPYNB | HTML |
differential_geometry.py |
Manifolds, curvature tensors, connections | IPYNB | HTML |
linearized_gravity.py |
Metric perturbations and gravitational waves | IPYNB | HTML |
renormalization_group.py |
CLT as RG fixed point, universality, beta functions | IPYNB | HTML |
numerical_relativity_stencils.py |
Lagrangians to finite difference stencils, code generation | IPYNB | HTML |
compact_models.py |
FDTD to symbolic compact models, Kramers-Kronig | IPYNB | HTML |
The RG notebook demonstrates how the Central Limit Theorem emerges as a renormalization group fixed point, inspired by The Simplest Renormalization Group.
The numerical relativity stencils notebook demonstrates the pipeline from Lagrangians to numerical simulation code, based on arXiv:1608.04408.
The example notebooks are written for Marimo, a reactive Python notebook. Marimo is included as a dependency.
To launch an interactive session for any of the examples:
uv run marimo edit examples/quantum_mechanics.pyReplace examples/quantum_mechanics.py with the path to any other notebook in the examples/ directory.
Marimo notebooks are pure Python files that can also be imported as modules or run as scripts.
uv run pytest tests/
Built from vibes for your pleasure.
symderive started as an experiment: what if we designed a symbolic math library specifically for the way AI agents think and work? The result is a library that prioritizes:
- Composability over configuration: Chain operations, not configure objects
- Familiarity over novelty: Use notation that physicists and mathematicians already know
- Exactness over approximation: Keep things symbolic as long as possible
MIT License
Thanks to the open-source libraries symderive is built on:
- CVXPY (optional, for optimization features)
- Marimo
- Matplotlib
- mpmath
- NumPy
- Polars
- PySR (symbolic regression)
- Rich
- SciPy
- SymPy
Note: This project is the result of a collaboration between Brandon DiNunno, Tom Mainiero, Victor (Mingsy) Chua, and Claude Code. Any likeness to proprietary APIs is strictly coincidental.

