A from-scratch Python library for symbolic and numerical calculus operations
Project description
Calcus
A lightweight, dependency-free Python library for symbolic and numerical calculus operations.
Why Calcus?
- Zero dependencies — no SymPy, NumPy, or any external math library required
- Educational — transparent implementation of calculus algorithms you can study and modify
- Simple API — intuitive functions that do exactly what you expect
- Lightweight — no heavy symbolic engine overhead, fast imports, minimal footprint
- Both symbolic and numerical — get exact answers when possible, approximations when needed
Installation
From PyPI
pip install calcus
From source
git clone https://github.com/YOUR_USERNAME/calcus.git
cd calcus
pip install -e .
Development install (with pytest)
pip install -e ".[dev]"
Quick Start
from calcus import parse, differentiate, integrate, limit, pretty
# Parse an expression from a string
expr = parse("x^2 + sin(x)")
# Differentiate
diff_result = differentiate(expr, "x")
print(pretty(diff_result)) # 2 * x + cos(x)
# Integrate
int_result = integrate(expr, "x")
print(pretty(int_result)) # x ^ 3 / 3 - cos(x)
# Limits
lim = limit(parse("sin(x)/x"), "x", 0)
print(lim) # 1.0
CLI Usage
Calcus ships with a command-line interface:
# Symbolic differentiation
calcus --diff "x^2 + sin(x)" --var x
# Symbolic integration
calcus --integrate "sin(x)" --var x
# Limits
calcus --limit "sin(x)/x" --var x --point 0
# Taylor series
calcus --taylor "exp(x)" --var x --order 5
# Numerical integration
calcus --num-int "x^2" --var x --lower 0 --upper 1
# LaTeX output
calcus --diff "x^3" --var x --latex
# Interactive REPL
calcus --repl
API Reference
Parsing
from calcus import parse
expr = parse("x^2 + 2*x + 1") # Addition and multiplication
expr = parse("sin(x) * cos(x)") # Functions
expr = parse("exp(x) / x^2") # Division and powers
expr = parse("sqrt(x) + ln(x)") # Square root, natural log
expr = parse("atan(x^2)") # Inverse trig functions
Supported functions: sin, cos, tan, sec, csc, cot, asin/arcsin, acos/arccos, atan/arctan, exp, ln/log, sqrt, abs
Symbolic Differentiation
from calcus import parse, differentiate, gradient, hessian
# Basic derivatives
differentiate(parse("x^3"), "x") # 3 * x ^ 2
differentiate(parse("sin(x)"), "x") # cos(x)
differentiate(parse("exp(x)"), "x") # exp(x)
differentiate(parse("ln(x)"), "x") # 1 / x
# Higher-order derivatives
differentiate(parse("x^4"), "x", order=2) # 12 * x ^ 2
differentiate(parse("sin(x)"), "x", order=3) # -cos(x)
# Chain rule
differentiate(parse("sin(x^2)"), "x") # 2 * x * cos(x ^ 2)
# Product rule
differentiate(parse("x * sin(x)"), "x") # sin(x) + x * cos(x)
# Quotient rule
differentiate(parse("sin(x) / x"), "x") # (x * cos(x) - sin(x)) / x ^ 2
# Multivariable
expr = parse("x^2 * y + y^3")
gradient(expr, ["x", "y"]) # [2 * x * y, x ^ 2 + 3 * y ^ 2]
hessian(expr, ["x", "y"]) # [[2 * y, 2 * x], [2 * x, 6 * y]]
Symbolic Integration
from calcus import parse, integrate, definite_integral
# Basic antiderivatives
integrate(parse("x^2"), "x") # x ^ 3 / 3
integrate(parse("sin(x)"), "x") # -cos(x)
integrate(parse("cos(x)"), "x") # sin(x)
integrate(parse("exp(x)"), "x") # exp(x)
integrate(parse("1/x"), "x") # ln(x)
# Definite integrals
definite_integral(parse("x^2"), "x", 0, 1) # 0.33333...
definite_integral(parse("sin(x)"), "x", 0, 3.14159) # ~2.0
Limits
from calcus import parse, limit
# Direct substitution
limit(parse("x^2 + 1"), "x", 3) # 10.0
# 0/0 indeterminate form (L'Hôpital's rule)
limit(parse("sin(x)/x"), "x", 0) # 1.0
# Limits at infinity
limit(parse("1/x"), "x", "inf") # 0.0
limit(parse("1/x"), "x", "-inf") # 0.0
Numerical Differentiation
from calcus import parse, numerical_diff, numerical_diff2
expr = parse("x^2")
numerical_diff(expr, "x", 2) # ~4.0
numerical_diff2(expr, "x", 2) # ~2.0
# Choose method: 'forward', 'backward', 'central' (default)
numerical_diff(expr, "x", 2, method="central")
Numerical Integration
from calcus import parse, trapezoidal_rule, simpsons_rule, adaptive_quadrature, gaussian_quadrature
expr = parse("x^2")
trapezoidal_rule(expr, "x", 0, 1, n=1000) # ~0.333
simpsons_rule(expr, "x", 0, 1, n=100) # ~0.333
adaptive_quadrature(expr, "x", 0, 1) # ~0.333 (high precision)
gaussian_quadrature(expr, "x", 0, 1, n=3) # ~0.333
Taylor & Maclaurin Series
from calcus import parse, taylor_series, maclaurin_series, pretty
# Maclaurin series (Taylor at x=0)
series = maclaurin_series(parse("exp(x)"), "x", order=5)
print(pretty(series)) # 1 + x + x^2/2 + x^3/6 + x^4/24
series = maclaurin_series(parse("sin(x)"), "x", order=6)
print(pretty(series)) # x - x^3/6 + x^5/120
# Taylor series at arbitrary point
series = taylor_series(parse("ln(x)"), "x", point=1, order=4)
Vector Calculus
from calcus import parse, gradient, divergence, curl, laplacian
# Gradient of scalar field
f = parse("x^2 + y^2 + z^2")
gradient(f, ["x", "y", "z"]) # [2*x, 2*y, 2*z]
# Divergence of vector field
F = [parse("x^2"), parse("y^2"), parse("z^2")]
divergence(F, ["x", "y", "z"]) # 2*x + 2*y + 2*z
# Curl of vector field
curl(F, ["x", "y", "z"]) # [0, 0, 0]
# Laplacian
laplacian(f, ["x", "y", "z"]) # 6
ODE Solvers
from calcus import ODESolver
# dy/dx = y, y(0) = 1 (solution: y = e^x)
def f(x, y):
return y
result = ODESolver.runge_kutta_4(f, y0=1, x0=0, x_end=1, h=0.1)
for x, y in result:
print(f"y({x:.1f}) = {y:.6f}")
Pretty Printing
from calcus import parse, pretty, to_latex
expr = parse("x^2 + 2*x + 1")
print(pretty(expr)) # x ^ 2 + 2 * x + 1
print(to_latex(expr)) # x^{2} + 2 \cdot x + 1
Expression API
from calcus import parse, constant, symbol
# Create expressions programmatically
x = symbol("x")
expr = x ** 2 + 2 * x + 1
# Evaluate with variable bindings
expr = parse("x^2 + 3*x + 2")
expr.evaluate({"x": 2}) # 12.0
# Substitute variables
expr.substitute("x", constant(3)) # x^2 + 3*x + 2 with x=3
expr.substitute("x", parse("y+1")) # Replace x with (y+1)
# Get all variables in an expression
parse("x^2 + sin(y)").symbols() # {"x", "y"}
Complex Example
from calcus import parse, differentiate, integrate, maclaurin_series, pretty
# Differentiate a complex expression
expr = parse("exp(x) * sin(x^2) / (1 + x^2)")
deriv = differentiate(expr, "x")
print(pretty(deriv))
# Expand sin(x) as a Maclaurin series
series = maclaurin_series(parse("sin(x)"), "x", order=8)
print(pretty(series))
# x - x^3 / 6 + x^5 / 120 - x^7 / 5040
Project Structure
calcus/
├── calcus/
│ ├── __init__.py # Public API exports
│ ├── __main__.py # CLI entry point
│ ├── core/
│ │ ├── expression.py # Expression AST nodes
│ │ ├── parser.py # Recursive descent parser
│ │ ├── simplify.py # Expression simplification
│ │ └── pretty.py # ASCII and LaTeX formatting
│ ├── symbolic/
│ │ ├── differentiate.py # Symbolic differentiation
│ │ ├── integrate.py # Symbolic integration
│ │ └── limits.py # Limit computation
│ ├── numerical/
│ │ ├── differentiate.py # Numerical differentiation
│ │ └── integrate.py # Numerical integration
│ └── advanced/
│ ├── series.py # Taylor/Maclaurin series
│ ├── ode.py # ODE solvers
│ └── vector.py # Vector calculus
├── tests/
│ └── test_calculus.py # All tests
├── pyproject.toml
├── README.md
└── LICENSE
Limitations
- No implicit multiplication: Write
2*xnot2x - Integration is rule-based: Handles common cases but not a full CAS like SymPy. Complex integrals may raise
NotImplementedError - Simplification is basic: Does not apply trig identities, log rules, or polynomial factoring
- Single variable focus: Multivariable support exists for gradient/Hessian/divergence/curl but not for limits or integration
- No complex numbers: All operations are over real numbers
Running Tests
pip install -e ".[dev]"
pytest tests/ -v
pytest tests/ -v --cov=calcus
License
MIT
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 calcus-0.1.0.tar.gz.
File metadata
- Download URL: calcus-0.1.0.tar.gz
- Upload date:
- Size: 31.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8a247b8d6a0ab8389bcba56d4fbdbe44dd2fb59ad1b8aca96c78ea5298b10567
|
|
| MD5 |
7d401e4b74713be8a1c42616dc754cd8
|
|
| BLAKE2b-256 |
fe220736845e555ba3a56f61446451e7a3bca0b2d8e1f4da583ccb82f48d9cb8
|
File details
Details for the file calcus-0.1.0-py3-none-any.whl.
File metadata
- Download URL: calcus-0.1.0-py3-none-any.whl
- Upload date:
- Size: 31.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
751c8f4112a6371d4fb10edb36eb223ad0ca23fddb8ba13db75425dd8e71c73e
|
|
| MD5 |
0a3961bb22628a7846aec4d5816096a8
|
|
| BLAKE2b-256 |
eeed1d38eb582b7508500caa106716197539577445f82bc51e4675d81d4fc2db
|