Skip to main content

A from-scratch Python library for symbolic and numerical calculus operations

Project description

Calcus

PyPI version Python versions License: MIT Tests

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*x not 2x
  • 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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

calcus-0.1.0.tar.gz (31.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

calcus-0.1.0-py3-none-any.whl (31.7 kB view details)

Uploaded Python 3

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

Hashes for calcus-0.1.0.tar.gz
Algorithm Hash digest
SHA256 8a247b8d6a0ab8389bcba56d4fbdbe44dd2fb59ad1b8aca96c78ea5298b10567
MD5 7d401e4b74713be8a1c42616dc754cd8
BLAKE2b-256 fe220736845e555ba3a56f61446451e7a3bca0b2d8e1f4da583ccb82f48d9cb8

See more details on using hashes here.

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

Hashes for calcus-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 751c8f4112a6371d4fb10edb36eb223ad0ca23fddb8ba13db75425dd8e71c73e
MD5 0a3961bb22628a7846aec4d5816096a8
BLAKE2b-256 eeed1d38eb582b7508500caa106716197539577445f82bc51e4675d81d4fc2db

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page