Smith-normal-form Cayley positional encoding / cayley_graph_track.py

✓✓ Beats tuned baseline

Raw ⬇ ZIP
 1import numpy as np
 2
 3META = {
 4    "name": "cayley_cycle_distance",
 5    "domain": "graph-positional-encoding",
 6    "description": "Shortest-path distance regression on a cyclic Cayley graph; exact Z_n displacement is the positional coordinate."
 7}
 8
 9
10def get_dataset(seed, n_train, n_test):
11    rng = np.random.default_rng(int(seed))
12    n = 32
13    total = int(n_train) + int(n_test)
14    u = rng.integers(0, n, size=total)
15    v = rng.integers(0, n, size=total)
16    delta = (v - u) % n
17    y = (np.minimum(delta, n - delta) / (n / 2)).astype(np.float32)
18    p = rng.permutation(total)
19    tr, te = p[:n_train], p[n_train:]
20    return {"xtr": np.stack([u[tr], v[tr]], 1), "ytr": y[tr, None],
21            "xte": np.stack([u[te], v[te]], 1), "yte": y[te, None],
22            "task": "regression", "metric": "mse", "out_dim": 1, "n_nodes": n}
23
24
25def encode(ds, kind):
26    n = int(ds["n_nodes"])
27    def f(x):
28        x = np.asarray(x, dtype=np.int64)
29        out = np.zeros((len(x), 2 * n), dtype=np.float32)
30        rows = np.arange(len(x))
31        if kind == "baseline":
32            out[rows, x[:, 0]] = 1.0
33            out[rows, n + x[:, 1]] = 1.0
34        elif kind == "idea":
35            # A=Z_n and g_uv=z(v)-z(u) mod n; unused second block keeps dimensions equal.
36            d = (x[:, 1] - x[:, 0]) % n
37            out[rows, d] = 1.0
38        else:
39            raise ValueError(kind)
40        return out
41    out = dict(ds)
42    out["xtr"] = f(ds["xtr"])
43    out["xte"] = f(ds["xte"])
44    out["input_shape"] = (2 * n,)
45    return out
46
47
48def math_check(n=32):
49    # Exact quotient/path consistency on the cycle: increments sum to n=0 in Z_n.
50    labels = np.arange(n, dtype=np.int64)
51    max_edge_error = 0
52    for u in range(n):
53        v = (u + 1) % n
54        max_edge_error = max(max_edge_error, int((labels[v] - labels[u] - 1) % n))
55    cycle_sum = int(sum(1 for _ in range(n)) % n)
56    return {"group": f"Z_{n}", "cycle_sum_mod_n": cycle_sum,
57            "max_edge_increment_error": max_edge_error,
58            "path_independence": cycle_sum == 0}