sigalg
Measure-Theoretic Probability in Python
SigAlg is a Python library for measure-theoretic probability: build probability spaces from sample spaces, \(\sigma\)-algebras, and probability measures, define random variables and stochastic processes, and compute derived objects (e.g., conditional expectations, checks for martingales).
Unlike most probabilistic computing libraries that treat probabilities primarily as arrays of numbers, SigAlg exposes the richer structures of measure-theoretic probability as manipulable, inspectable objects. The goal is to reduce friction when translating from mathematics to working code.
Key Features:
- Core probabilistic objects — Sample spaces, \(\sigma\)-algebras, and probability measures modeled close to their definitions.
- Filtrations of \(\sigma\)-algebras — Support for time-evolving information structures used in stochastic processes.
- Random variables and vectors — Algebraic operations and transformations, including conditional expectation and variance.
- \(L^2\) spaces of random variables — Inner products, norms, orthogonal projections, Fourier expansions, measure-theoretic regression.
- Stochastic processes — Adapted and predictable processes, stopping times and stopped processes, discrete Itô integrals, and a growing library of built-in processes.
- Exact and Monte Carlo — Support for Monte Carlo simulation, discrete approximations to continuous-time objects, and exhaustive exact enumeration.
- Integration with scientific Python — NumPy/Pandas interoperability; visualization via Matplotlib/Plotly; probability distributions via SciPy.
All the above is implemented according to SigAlg's core design philosophy of a focus on mathematical fidelity and accuracy, not just black-box simulation and speed. SigAlg is meant to be a different kind of library—an interface between abstract mathematics and concrete code that complements the rest of the Python ecosystem. Get Started →
"""Demo SigAlg API by creating a random walk from scratch."""
import pandas as pd
from scipy.stats import bernoulli
from sigalg.core import Time
from sigalg.processes import IIDProcess
T = Time.discrete(start=1, stop=4) # (1)!
B = IIDProcess(
distribution=bernoulli(p=0.7),
support=[0, 1],
time=T,
).from_enumeration() # (2)!
Y = 2 * B - 1 # (3)!
X = Y.cumsum(name="X") # (4)!
X.insert_rv(state=0, time=0, in_place=True) # (5)!
F = X.natural_filtration # (6)!
expectation = X[4].expectation(sigma_algebra=F[3]) # (7)!
print(pd.concat([X.data, expectation.data], axis=1)) # (8)!
print("\nIs X a submartingale?", X.is_submartingale()) # (9)!
- Create a time index \(T = \{1,2,3,4\}\).
- Create a discrete-time IID Bernoulli process \(B = \{B_t\}_{t=1}^4\), and enumerate all \(2^4 = 16\) possible trajectories. A value of \(B_t=1\) means step right, and \(B_t=0\) means step left.
- Create the process \(Y=2B-1\), which will serve as the increments of our random walk. A value of \(Y_t=1\) means step right, and \(Y_t=-1\) means step left.
- Create the random walk process \(X\) by taking the cumulative sum of the increment process \(Y\), so that \(X_t = \sum_{s=1}^t Y_s\).
- Add the initial state \(X_0=0\) to the process \(X\).
- Get the natural filtration \(\mathcal{F}\) of \(X\), where \(\mathcal{F}_t = \sigma(X_1,X_2,\ldots,X_t)\).
- Compute the conditional expectation \(E(X_4 \mid \mathcal{F}_3)\).
- Print the trajectories of \(X\), along with the computed conditional expectation.
- Our random walk has positive drift, so it should be a submartingale.
0 1 2 3 4 E(X_4|3)
trajectory
0 0 -1 -2 -3 -4 -2.6
1 0 -1 -2 -3 -2 -2.6
2 0 -1 -2 -1 -2 -0.6
3 0 -1 -2 -1 0 -0.6
4 0 -1 0 -1 -2 -0.6
5 0 -1 0 -1 0 -0.6
6 0 -1 0 1 0 1.4
7 0 -1 0 1 2 1.4
8 0 1 0 -1 -2 -0.6
9 0 1 0 -1 0 -0.6
10 0 1 0 1 0 1.4
11 0 1 0 1 2 1.4
12 0 1 2 1 0 1.4
13 0 1 2 1 2 1.4
14 0 1 2 3 2 3.4
15 0 1 2 3 4 3.4
Is X a submartingale? True