Eigencube — the Rubik's cube as linear algebra

A port of eigencube. Each cubelet is its home vector c ∈ {-1,0,1}³ and a rotation matrix R: it sits at Rc, its stickers face the columns of R·diag(c), and it is solved when R·diag(c) = diag(c). A move on the face with axis v turns every cubelet with v·(Rc) > 0: R ← M·R. Every frame below is drawn from those matrices. Click a cubelet to see its own.

State

Solved

Keys

UDFBLR turn that face clockwise (as seen facing it) Shift + facecounter-clockwise (prime) Spacescramble (25 moves from the seed); during playback, play / pause Entersolve from here Esccancel the solver ←→step through the solution (hold to run) padthe coloured squares under the cube turn faces too (touch screens) mouse / touchdrag to orbit, wheel or pinch to zoom, click or tap a cubelet to inspect

Cubelet

Click a cubelet.

How it works — the cube as linear algebra

Most solvers track 54 stickers in flat arrays and permutation tables. Eigencube places the cube in 3D space with its centre at the origin (x = front, y = right, z = top) and lets vectors and rotation matrices do the bookkeeping. Its author walks through the idea in this video.

The model at a glance

cubeletits home vector c ∈ {-1,0,1}³, seen from the fixed core; 26 of them
type‖c‖₁ = |x|+|y|+|z| = number of stickers: centre 1, edge 2, corner 3
coloursthe six unit vectors ±e: a sticker's colour is the direction it faces when solved
stickersthe non-zero columns of diag(c)
stateone rotation matrix R per cubelet, I when solved
positionp = R·c
sticker directionsthe columns of R·diag(c)
moveevery cubelet with v·(R·c) > 0 turns: R ← M·R (v the face's axis)
solvedR·diag(c) = diag(c) for every cubelet

Why "eigen"

A turn about the axis v leaves v where it is: M·v = v, so v is an eigenvector of M with eigenvalue 1. The centre cubelet on that face is exactly c = v, so it never moves and its sticker keeps facing v. That is why the six centres can serve as the colours.

One formula for every rotation

M(v, θ) = I + sin θ·[v]ₓ + (1 − cos θ)·[v]ₓ²

This is Rodrigues' rotation formula; [v]ₓ is the cross-product matrix of v. At θ = −90° it is the clockwise quarter turn as seen from the face, an integer matrix. At the angles in between it is the animation frame, so the slice you see turning is M(v, θ)·R, frame by frame. Every reachable R is one of the 24 rotations of a cube: each column is some ±e and det R = 1.

Deriving every turn from v and θ also corrects a slip in the Python original. Its quarter turn ignores the sign of v, so each face shares its opposite face's matrix, and its "clockwise" right, bottom and back turns are really R′, D′ and B′.

Where the algebra stops and the search starts

The algebra replaces the bookkeeping, not the search. Solving is five rounds of A*, each aiming at a goal stated in matrices:

  1. top layer, one more solved cubelet per search;
  2. middle layer, the same, up to 17 cubelets;
  3. bottom cross: first the edges' yellow faces down (R·(0,0,−1) = (0,0,−1)), then solved;
  4. bottom corners into place (R·c = c, twist ignored);
  5. corner twists with the fixed sequence (L′ U′ L U)×2, turning D between corners.

The A* distance estimate asks of each cubelet: how many quarter turns would bring it home if it were alone? That is itself a tiny search over the 24 rotations, cached. The search keeps no pattern tables, and when it stalls it restarts with a 1.5× move budget and freshly randomized weights. Expect solutions of 100–160 moves, far from optimal.

See it live

Click any cubelet: the panel shows its c, its position R·c, its R, and R·diag(c). Turn a face and watch those matrices change, and only for the cubelets with v·(R·c) > 0.