Skip to content

closedform/deriver

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

75 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

symderive

A Standalone Symbolic Engine for AI Agents and Mathematical Computing

PyPI version Python 3.12+ License: MIT

Y

Features

  • 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

Agent-Native Architecture

symderive is built for stateless, functional composition -- the ideal paradigm for LLM agents that need to chain mathematical operations without tracking mutable state.

The Pipe Framework

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 1

Each Pipe stage is a pure function: input in, output out, no side effects.

Lisp-Style Functional Primitives

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.

Ergonomics

Wolfram-Style CamelCase Syntax

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 expansion

No need to learn a new API. If you know Mathematica or standard mathematical notation, you know symderive.

Smart Number Handling

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.

Installation

From PyPI

pip install symderive
import symderive as sd

From Source

git 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 dependencies

A requirements.txt is also provided for environments that prefer it.

Advanced Installation (uv)

For faster dependency resolution, use uv:

git clone git@github.com:closedform/deriver.git
cd deriver
uv sync

Optional Dependencies (uv)

Some 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 dependencies

Quick Start

import 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")

Differential Geometry

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_ab

Pattern Matching

import 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)  # 10

Custom Types

from 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 product

Variational Calculus

import 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 = 0

Compact Models (FDTD to Symbolic)

from 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()

Agentic Math and Physics

symderive ships with agent personas -- pre-prompted contexts that transform general-purpose LLMs into domain experts in mathematical and physical reasoning.

Using Agent Personas

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 text

Then 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 Roster

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

Orchestrator Integration

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:

  1. Load AGENTS.yaml to understand available capabilities
  2. Match user intent to category, then select within category
  3. Load full .agent.md only when delegating to that agent

Use load_agents_index() for the complete roster and routing hints.

Documentation

See the docs/ directory for detailed documentation on:

Example Notebooks

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.

Interactive Notebooks

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.py

Replace 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.

Running Tests

uv run pytest tests/

Project Philosophy

And I helped!
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

License

MIT License

Acknowledgements

Thanks to the open-source libraries symderive is built on:

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.

Official Logo

The Derive Mascots: Der and Ive

About

A powerful symbolic mathematics library for Python.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 4

  •  
  •  
  •  
  •