Quantum walks on Metatron’s Cube
Metatron’s Cube is the complete graph K₁₃ on the 13 centres of the Fruit of Life. This tutorial looks at its symmetry, at continuous-time quantum walks on it and on the Fruit-of-Life contact graph, and at spatial search.
import math
import matplotlib.pyplot as plt
import numpy as np
import metatron_qso as q
cube = q.Graph.metatron_cube()
fol = q.Graph.fruit_of_life()
Geometry and symmetry
for length, count in q.metatron_line_lengths():
print(f"line length {length:.4f}: {count} lines")
print("|Aut(Metatron's Cube)| =", cube.automorphism_group_order(), "= 13!")
print("|Aut(Fruit of Life)| =", fol.automorphism_group_order(), "(the dihedral group D6)")
print("orbits of the Fruit of Life:", fol.automorphism_orbits())
line length 1.0000: 18 lines
line length 1.7321: 18 lines
line length 2.0000: 15 lines
line length 2.6458: 12 lines
line length 3.0000: 6 lines
line length 3.4641: 6 lines
line length 4.0000: 3 lines
|Aut(Metatron's Cube)| = 6227020800 = 13!
|Aut(Fruit of Life)| = 12 (the dihedral group D6)
orbits of the Fruit of Life: [[0], [1, 2, 3, 4, 5, 6], [7, 8, 9, 10, 11, 12]]
pos = fol.positions
fig, axes = plt.subplots(1, 2, figsize=(7, 3.5))
for ax, g, title in [(axes[0], cube, "Metatron's Cube (K13)"), (axes[1], fol, "Fruit of Life contact graph")]:
p = g.positions
for u, v, _ in g.edges:
ax.plot([p[u, 0], p[v, 0]], [p[u, 1], p[v, 1]], "k-", lw=0.6)
ax.scatter(p[:, 0], p[:, 1], s=40, zorder=3)
ax.set_title(title)
ax.set_aspect("equal")
ax.axis("off")
plt.tight_layout()
plt.show()
A walk from the centre
On K₁₃ the Laplacian has eigenvalues 0 and 13 (twelve-fold), so the walk from the centre returns periodically. Its time average converges to 145/169: the limiting distribution keeps a large share at the start.
walk = q.ContinuousWalk(cube)
ts = np.linspace(0, 3, 301)
p_centre = [walk.probabilities(0, t)[0] for t in ts]
avg = np.cumsum(p_centre) / np.arange(1, len(ts) + 1)
print("limiting P(centre) =", walk.limiting_distribution(0)[0], " 145/169 =", 145 / 169)
fol_walk = q.ContinuousWalk(fol)
p_fol = [fol_walk.probabilities(0, t)[0] for t in ts]
p_classical = [q.classical_walk_probabilities(fol, 0, t)[0] for t in ts]
plt.figure(figsize=(6, 3))
plt.plot(ts, p_centre, label="K13, quantum")
plt.plot(ts, avg, label="K13, running time average")
plt.axhline(145 / 169, color="k", ls=":", lw=0.8)
plt.plot(ts, p_fol, label="Fruit of Life, quantum")
plt.plot(ts, p_classical, label="Fruit of Life, classical")
plt.xlabel("t")
plt.ylabel("P(centre)")
plt.legend(fontsize=8)
plt.tight_layout()
plt.show()
limiting P(centre) = 0.8579881656804739 145/169 = 0.8579881656804734
Spatial search
With the oracle −|w⟩⟨w| and γ = 1/N, the walk on the complete graph moves all amplitude to the marked node at t = π√N/2. A classical random walk on K₁₃ needs 12 steps on average.
search = q.SpatialSearch(cube, marked=[4], gamma=1 / 13)
ts = np.linspace(0, 12, 400)
success = [search.success_probability(t) for t in ts]
t_star = math.pi * math.sqrt(13) / 2
print(f"P(t = π√13/2 = {t_star:.4f}) = {search.success_probability(t_star):.12f}")
print("classical hitting time:", q.classical_hitting_times(cube, 4)[0])
best = q.SpatialSearch.optimize(fol, [0])
print("Fruit of Life, marked centre:", best)
plt.figure(figsize=(5, 3))
plt.plot(ts, success)
plt.axvline(t_star, color="k", ls=":", lw=0.8)
plt.xlabel("t")
plt.ylabel("P(marked)")
plt.tight_layout()
plt.show()
P(t = π√13/2 = 5.6636) = 1.000000000000
classical hitting time: 11.999999999999998
Fruit of Life, marked centre: {'gamma': 0.3147337510441124, 'time': 5.46332670498062, 'success_probability': 0.5117699808266946, 'expected_time': 10.675355940485922}
From quantum to classical
Dephasing at rate κ turns the walk into a classical random walk; for large κ the populations follow dp/dt = −(2γ²/κ)·L·p (quantum Zeno regime).
ts = np.linspace(0, 6, 121)
plt.figure(figsize=(6, 3))
for rate in [0.0, 0.5, 2.0, 8.0]:
walk = q.DephasingWalk(fol, rate=rate)
plt.plot(ts, [walk.populations(0, t)[0] for t in ts], label=f"κ = {rate}")
plt.plot(ts, [q.classical_walk_probabilities(fol, 0, t)[0] for t in ts], "k:", label="classical")
plt.xlabel("t")
plt.ylabel("P(centre)")
plt.legend(fontsize=8)
plt.tight_layout()
plt.show()