discrete dynamical systems · exact classification · Rust

Dynamics Engine

A universe is a small integer matrix. Its state moves by a velocity that depends only on the signs of its coordinates. This engine decides, exactly, where every one of the 387,420,489 three-element universes ends up.

0universes at N = 3
0for the full census
0possible fates
0runtime dependencies
§1

Live, from the zero state

Five fates

Every orbit ends in one of five ways. Each is proven, not guessed: spirals by running one lap with the size left as an unknown, which settles all but 192 of the 277,344 three-element spirals. Each card is a real three-element universe, simulated in your browser.

§2

Typical and rarest, by size

The explorer

Within each fate the census records a finer class: the period, or the step at which the fate was proven. Here are the most common class and the rarest ones, each shown by the universe with the smallest index.

§3

Exhaustive where possible, sampled where not

The census

Every universe started from zero, classified by its fate. Escape dominates and grows with size; the rare fates are where the structure lives.

0undecided universes at N = 3: every one of 387,420,489 receives a fate
0symmetry classes at N = 3, under signed permutations of the elements (order 2NN!)
0steps in the longest cycle at N = 3, reached from the zero state
0three-element spirals proven to grow forever, out of 277,344

Stable from every start?

The census follows one start. A universe is stable when every start in the whole lattice ends fixed or in a cycle. One escaping start proves it unstable. For two elements a far-field argument proves the rest bounded, so every one of them is decided.

At N = 2 the answer is a formula: stable exactly when no sign pattern's velocity keeps every sign, except the sign rotation d = (sgn v1, −sgn v0), which gains one step per axis crossing and spirals out (2-2800, from (−3, −3) in the CLI).

bounded from every startsome start escapesno escape found, no proof
N = 26,561 universes
856 bounded (13.05 %, proven) · 5,705 unstable · 0 open
N = 3387,420,489 universes
97.54 % unstable (proven) · 2.46 % open

A cycle from the zero state often hides instability: 37 % of those three-element universes escape from some other start.

§4

Pick any universe

Try your number

Every universe has an index: its drift tables read as one number in base 3. Type any index, and your browser decodes it, runs it from zero and decides its fate with the same proofs the engine uses.

universe
pick a number

§5

The same engine, on your machine

Run it yourself

This page is a demo. The engine itself is a command-line tool written in Rust, with no dependencies. Install it with Cargo and any universe here, or the whole census, is one command away. Ids match: #u=2-613 on this page is show 2-613 in the terminal.

  1. Get RustInstall the stable toolchain from rustup.rs, or skip steps 1–2 with a prebuilt binary for Linux, macOS or Windows.
  2. Install the engine
    cargo install --git https://github.com/mukos/dynamics-engine
  3. Ask about one universe
    dynamics-engine show 2-613
  4. Or about all of them
    dynamics-engine exact --size 3
$ dynamics-engine show 2-613
reduced universe 613 (multiplicity 8, canonical: true):
  element 0: pos = [  -1   -1 ]  neg = [   0    1 ]
  element 1: pos = [   1    0 ]  neg = [  -1    0 ]
events:
  step      1  v = [  -1    0 ]  drift = [   0    1 ]
  step      2  v = [  -1    1 ]  drift = [   1    1 ]
  …
  step     16  v = [   1    0 ]  drift = [  -1   -1 ]
fate: cycle of period 10, repeating from step 6

$ dynamics-engine exact --size 3
model sign, size 3: 387420489 reduced universes in 9.39s on 8 threads
fate          reduced universes
  cycle             3687240   0.952%
  fixed            27800807   7.176%
  helix             5025024   1.297%
  ray             350630074  90.504%
  spiral             277344   0.072%
spirals proven to grow forever: 277152 of 277344
§6

How it is built

The engineering

A dependency-free Rust codebase that turns an exponential search into seconds: reduce the space, prove instead of simulate, and keep the hot loop out of the allocator's way.

exact, not simulated

Event-driven certificates

The analyser jumps from one sign change to the next instead of stepping, and stops at a certificate: a checkable proof of the fate. A repeated state proves a cycle; a quadrant the velocity cannot leave proves a ray; a replayed segment v(t+T) = v(t) + D proves a helix; one lap run with the size as an unknown, x ↦ ax + b, proves a spiral.

symmetry

Canonical forms

Fates are invariant under the hyperoctahedral group of signed permutations. Burnside's lemma counts the orbits: 873 classes at N = 2, 8,093,160 at N = 3.

reduction

From bits to ternary rows

Only differences between paired channels matter, so 24N² bit matrices collapse to 32N² universes, each carrying a multiplicity of 2zeros.

performance

Out of the allocator's way

Static musl builds serialise threads on malloc. Reusing one workspace per thread and walking indices with an odometer removed every allocation from the hot loop. Size-3 census on 8 cores:

first Rust version527 s
allocation-free loop9.4 s
80× faster, same answers
verified

Tests that pin the maths

The proofs are checked against brute-force simulation, the index odometer against decoding, and the original TypeScript histogram is kept as a regression test.

§7

The mathematics

The rule and its theory

Locally the system is trivial: a straight line. Globally it is as hard as computation itself. The interesting mathematics is in between, on the loops.

around one loop of quadrants, the return map is affine: x ↦ Ax + b
A = I, b = 0the state comes back exactly: a cycle
A = I, b ≠ 0it comes back shifted by the same vector: a helix
ρ(A) > 1each return is larger, like x ↦ 2x + 12: a spiral
no loop at alla quadrant it never leaves: a ray; zero velocity: fixed
Piecewise-constant derivativesThe continuous cousin: reachability is decidable in two dimensions and undecidable from three, which is why a few spirals still resist proof.Asarin, Maler, Pnueli (1995)
Glass networksGene-regulation models whose vector field depends only on which side of thresholds each variable lies.Glass, Kauffman (1973)
Karp–Miller coverabilityThe helix proof is its deterministic analogue: a repeated pattern whose gain keeps every sign repeats forever.Karp, Miller (1969)
Basins of attractionStarted away from zero, basins form sectors (55 %), stripes from conserved functionals (40 %) and parity checkerboards (1 %).computed by this engine