Visualize flows on the space of lattices
- Horocycle flow: Demonstrates quantitative non-divergence
- Geodesic flow: Visualizes Diophantine approximation via the Dani correspondence
Python 3.8+ is required. Install if needed:
- macOS:
brew install python(or download from python.org) - Windows: Download from python.org
- Linux: Usually pre-installed, or
sudo apt install python3
uv (recommended) — fast Python package installer:
curl -LsSf https://astral.sh/uv/install.sh | shOr see uv installation docs.
uv tool install git+https://github.com/ericceg/cuspian.gitThen run from anywhere:
cuspianpip install git+https://github.com/ericceg/cuspian.gitgit clone https://github.com/ericceg/cuspian.git
cd cuspian
uv tool install .
# or: pip install .# Horocycle flow (default)
cuspian --flow horocycle
# Save as GIF
cuspian --alpha "sqrt(2)" --save output.gif
# Analysis mode
cuspian --alpha "pi" --analyze
# Geodesic analysis with continued-fraction convergents
cuspian --flow geodesic --alpha pi --analyze --cf-terms 10
# Fading trail in moduli space (fades after 6 seconds)
cuspian --flow horocycle --slope pi --trail 6
# Infinite trail (never fades)
cuspian --flow horocycle --slope pi --trail infcuspian --flow geodesic --alpha pi --theme light --speed 5Deep excursions into the cusp correspond to good rational approximations of π.
cuspian --flow horocycle --slope "1/3" --theme light --speed 5Rational slope creates a periodic orbit that eventually closes.
cuspian --flow horocycle --slope pi --theme light --speed 5Irrational slope creates a dense orbit that fills the fundamental domain.
The visualization window supports keyboard shortcuts:
| Key | Action |
|---|---|
Space |
Pause/Resume animation |
↑ |
Increase speed (1.5x) |
↓ |
Decrease speed (1.5x) |
R |
Reset animation and trail |
Q |
Quit |
| Option | Description | Default |
|---|---|---|
--flow |
horocycle or geodesic |
horocycle |
--slope |
Slope to tilt standard lattice (e.g., "1/2", "sqrt(2)") |
1/√2 |
--alpha |
Number to approximate (e.g., "pi", "3/7", "sqrt(2)") |
None |
--duration |
Animation duration (seconds) | 10 |
--speed |
Speed multiplier | 1.0 |
--theme |
dark, light, or system |
system |
--save |
Save to file (.mp4 or .gif) |
None |
--analyze |
Generate statistics and plots | False |
--cf-terms |
Continued-fraction terms/convergents to show in geodesic analysis | 8 |
--div-limit |
Divergence threshold (shortest vector) | 1e-3 |
--trail |
Trail in moduli space: inf=infinite, number=fade after N seconds, 0=off |
inf |
- Left: Physical lattice points evolving under the flow
- Right: Trajectory in the moduli space fundamental domain
- Bottom: Cusp height (inverse shortest vector length) over time
For rational α, the geodesic diverges into the cusp (visualization freezes when shortest vector < div-limit).
A lattice in
We visualize lattices in two ways:
-
Physical Space: The actual lattice points
$\Lambda_t = g_t \Lambda_0$ in$\mathbb{R}^2$ -
Moduli Space: Each lattice shape corresponds to a point
$\tau \in \mathbb{H}$ in the upper half-plane, reduced to the fundamental domain$\mathcal{F} = {z \in \mathbb{H} : |z| \ge 1, |\text{Re}(z)| \le 1/2}$
Horocycle Flow:
Shears the lattice horizontally. The slope parameter determines the initial lattice orientation:
- Rational slope (e.g.,
--slope 1/3): Creates a periodic orbit - Irrational slope (e.g.,
--slope pi): Creates a dense orbit that fills the fundamental domain (quantitative non-divergence)
Geodesic Flow:
Expands one direction and contracts the other. The alpha parameter determines which number to approximate.
Starting lattice:
- Rational α (e.g.,
--alpha 3/7): Trajectory diverges into the cusp - Badly approximable α (e.g.,
--alpha sqrt(2)): Trajectory stays bounded - Well approximable α (e.g.,
--alpha pi): Deep cusp excursions at continued fraction convergents
The cusp height (inverse shortest vector length
- Large cusp height ⟺ Good rational approximation
$p/q \approx \alpha$ - Cusp excursion depth ⟺ Quality of approximation (Dani correspondence)
This visualizes why rational numbers have infinitely good approximations (diverge to infinity) while algebraic irrationals like
When using --analyze with geodesic flow, Cuspian now also prints the continued-fraction expansion of α and a table of convergents (p/q), including approximation error
# Run tests
uv run pytest
# Type checking
uv run mypy cuspian/
# Format code
uv run ruff format cuspian/See AGENTS.md for:
- Detailed mathematical background
- Architecture and code structure
- Development workflows
- Advanced usage examples


