Skip to main content

wanderwalk

wanderwalk

Brownian motion on Riemannian manifolds

version 0.2.0 Python 3.9 and newer MIT license Documentation

This project simulates Brownian motion on Riemannian manifolds. It pairs a small, testable Python library for running these simulations with an interactive Streamlit app for watching the diffusion unfold in real time.

pip install wanderwalk
import numpy as np
import wanderwalk as ww

np.random.seed(0)
trajectory = ww.sphere_simulator(T=200, N=500, dt=0.01, noise_type="isotropic")
final_positions = trajectory[-1]        # (500, 3), every point on the sphere

Full documentation, including six tutorials and a generated API reference, is at jeanjacquesstleroux.github.io/wanderwalk.

What This Project Is About

Brownian motion is the random, erratic motion first observed in pollen grains suspended in water and later given a rigorous mathematical treatment by Einstein and Wiener. It underlies fields ranging from statistical physics to quantitative finance, and, more recently, the diffusion models behind modern generative AI.

The question this project explores is what happens to that random motion when the space it lives in is curved. A particle wandering on the surface of a sphere behaves differently from one wandering on a flat plane or on the surface of a donut (a torus): the curvature of the space bends and constrains the motion. This project builds simulations of that behavior and visualizes it directly.

For the full motivation, mathematical background, and the theory connecting this project to diffusion models and quantitative finance, see ONBOARDING.md.

Surfaces Implemented

  • Sphere (S²): positively curved, particle paths are recurrent, and the particle distribution converges to uniform over the surface.
  • Torus (T²): zero average curvature but non-trivial global topology; particles wrap around the surface rather than escaping it.
  • Hyperbolic plane (H²): represented via the Poincaré disk model. Its constant negative curvature makes random paths transient -- rather than equilibrating to a uniform distribution, particle paths converge almost surely to a random point on the boundary circle (the Poisson boundary). See docs/writeups/2-poincare-disk-derivation.md for the full derivation of the governing SDE from this project's own conventions, and notebooks/Notebook-05.ipynb for its validation.

How the Simulation Works

Each manifold is represented by a small class (src/wanderwalk/manifolds/sphere.py, src/wanderwalk/manifolds/torus.py, src/wanderwalk/manifolds/hyperbolic.py) implementing a shared interface (src/wanderwalk/manifolds/base.py):

  • sample_tangent_noise: generates a random vector constrained to the tangent plane at a point, so a step never points off the surface.
  • euler_maruyama_step: advances a point one time step using the Euler-Maruyama method, the standard numerical scheme for stochastic differential equations.
  • project_to_manifold: pulls a point back onto the surface after a step, correcting for the small numerical drift introduced by moving in a straight line through the ambient space.

For the Sphere and Torus, this is the projection method: propose a step in the tangent plane, take it, then project back onto the surface -- both are embedded in R³, so ambient Euclidean lengths agree with the surface's own metric. The Poincaré disk has no such embedding (Hilbert's theorem), so it is handled intrinsically instead: points are 2D vectors in the open unit disk, sample_tangent_noise rescales an isotropic Gaussian by the disk's own conformal factor rather than projecting an ambient vector, and project_to_manifold is a numerical safety clamp rather than an exact geometric projection (see the derivation doc for why).

Running this update for many particles at once (vectorized with NumPy) is handled by src/wanderwalk/simulation/simulator.py, and the resulting particle distributions are visualized with a kernel density estimate in src/wanderwalk/visualization/kde.py (sphere) and src/wanderwalk/visualization/hyperbolic_kde.py (Poincaré disk, using the exact hyperbolic geodesic distance as the kernel). The geometry, the simulation loop, and the visualization are kept in separate modules, so adding a new surface mostly requires implementing its geometry, without changes to the simulator's vectorized-loop pattern.

Installation

The core library depends only on NumPy:

pip install wanderwalk

The Streamlit app is optional, since it pulls in Streamlit and Plotly:

pip install wanderwalk[app]

Requires Python 3.9 or newer.

Library Usage

The three simulators each return a trajectory array of shape (T, N, d), holding the positions of all N particles at each of the T time steps. The sphere and torus live in R^3 so d is 3; the Poincaré disk is intrinsically two-dimensional so d is 2.

The library is conventionally imported under the alias ww, the way NumPy is imported as np. Every example in the documentation uses that convention.

import numpy as np
import wanderwalk as ww

np.random.seed(0)                                     # for a repeatable run

on_sphere = ww.sphere_simulator(T=200, N=500, dt=0.01, noise_type="isotropic")
on_torus = ww.torus_simulator(T=200, N=500, dt=0.01, R=3.0, r=1.0)
in_disk = ww.hyperbolic_simulator(T=200, N=500, dt=0.01)

on_sphere.shape, in_disk.shape                        # ((200, 500, 3), (200, 500, 2))

The manifold classes can also be driven directly, one step at a time:

sphere = ww.Sphere()
point = np.array([1.0, 0.0, 0.0])
for _ in range(100):
    point = sphere.euler_maruyama_step(point, dt=0.01)   # stays on the sphere

disk = ww.PoincareDisk()
disk.geodesic_distance_from_origin(np.array([0.6, 0.0]))  # hyperbolic distance

And the density estimators turn final positions into a heatmap:

density = ww.disk_kde(in_disk[-1], x_mesh, y_mesh, N=500)
counts, edges = ww.boundary_angle_histogram(in_disk[-1], radius_threshold=0.9)

One module sits outside the alias. wanderwalk.heat_kernel needs SciPy, which the numpy-only core install does not pull in, so it is not re-exported at the top level and ww.heat_kernel will not resolve. Import it by path:

from wanderwalk.heat_kernel import estimate_heat_kernel

Project Layout

src/wanderwalk/manifolds/       Sphere, torus, and Poincare disk geometry (tangent
                                 projection/noise, stepping)
src/wanderwalk/simulation/      Vectorized Euler-Maruyama simulators
src/wanderwalk/visualization/   Kernel density estimation for particle distributions
src/wanderwalk/app/             Streamlit application and its launcher
tests/                          Test suite
notebooks/                      Jupyter notebooks (also exported to HTML for viewing
                                 without running code)
docs/writeups/                  Mathematical background, the differential geometry
                                 curriculum, and the Poincare disk SDE derivation
ONBOARDING.md                   Motivation, theory, and project background

Development

git clone https://github.com/jeanjacquesstleroux/wanderwalk.git
cd wanderwalk
pip install -r requirements.txt     # editable install with all extras
pytest

Starting the App

Once the app extra is installed, launch it with the bundled console script:

wanderwalk-app

This opens the app in your browser. From the sidebar you can:

  • Choose the manifold (sphere, torus, or Poincaré disk).
  • Set the number of particles, number of time steps, and the size of each time step.
  • Choose isotropic noise (motion in all tangent directions) or, for the sphere and the torus, anisotropic noise (motion constrained to a single tangent direction).
  • Set the starting point (latitude and longitude for the sphere, the toroidal and poloidal angles for the torus, or the radius and angle for the Poincaré disk) and, for the torus, its major and minor radius.

Click "Run Simulation" to generate an animated trajectory, the final particle distribution, and a density heatmap of where the particles ended up.

Notebooks

The notebooks/ directory contains the exploratory work behind the library, each one also exported to HTML in the same folder so it can be read without running any code. To run them yourself, install the notebook extra:

pip install wanderwalk[notebooks]
jupyter lab notebooks/

Authors

  • Jean-Jacques St. Leroux
  • Danielle Prilepskiy

License

Released under the MIT License. See LICENSE.

Download files

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

Source Distribution

wanderwalk-0.2.0.tar.gz (2.4 MB view details)

Uploaded Source

Built Distribution

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

wanderwalk-0.2.0-py3-none-any.whl (34.7 kB view details)

Uploaded Python 3

File details

Details for the file wanderwalk-0.2.0.tar.gz.

File metadata

  • Download URL: wanderwalk-0.2.0.tar.gz
  • Upload date:
  • Size: 2.4 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for wanderwalk-0.2.0.tar.gz
Algorithm Hash digest
SHA256 265ca2e0b2a5d728918a3cd5f6dfe6a52091706eda079a0ce545578cdfdf9004
MD5 e7f1ee9bb3eb434db0549f8da7294a9d
BLAKE2b-256 50947acb6e370629662c8f64a40a345d9024e3ea28c8000a52ffc191ba06503d

See more details on using hashes here.

Provenance

The following attestation bundles were made for wanderwalk-0.2.0.tar.gz:

Publisher: release.yml on jeanjacquesstleroux/wanderwalk

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file wanderwalk-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: wanderwalk-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 34.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for wanderwalk-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 fd59b0b34e30fd2bd4aa9c744053b9ebd79b43e492a1d3cb13ce2f6d6485a732
MD5 50efbaa9c9113c785829fdd0fa11a65b
BLAKE2b-256 9bf7748e1d07a7d7613737104c5baa17c0fda3220215a33908b6b7fd8a0ed629

See more details on using hashes here.

Provenance

The following attestation bundles were made for wanderwalk-0.2.0-py3-none-any.whl:

Publisher: release.yml on jeanjacquesstleroux/wanderwalk

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

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