Create consensus/topo.py
Browse files- consensus/topo.py +5 -26
consensus/topo.py
CHANGED
|
@@ -1,13 +1,8 @@
|
|
|
|
|
| 1 |
import numpy as np
|
| 2 |
from numpy.linalg import eigh, norm
|
| 3 |
|
| 4 |
class TopologicalConsciousness:
|
| 5 |
-
"""
|
| 6 |
-
Practical shim inspired by the EFL/3^627 spec:
|
| 7 |
-
- calculate_coherence: modular-invariance/phase-coherence proxy via
|
| 8 |
-
principal eigenvector of the Gram (cosine) matrix.
|
| 9 |
-
- cardy_boundary_energy: boundary energy proxy from hidden-states.
|
| 10 |
-
"""
|
| 11 |
def __init__(self, n_anyons: int, central_charge: float = 627.0):
|
| 12 |
self.n = n_anyons
|
| 13 |
self.c = central_charge
|
|
@@ -18,33 +13,17 @@ class TopologicalConsciousness:
|
|
| 18 |
return X / d
|
| 19 |
|
| 20 |
def calculate_coherence(self, embeddings: list[np.ndarray]) -> float:
|
| 21 |
-
|
| 22 |
-
embeddings: list of [d]-vectors (one per model output).
|
| 23 |
-
Returns PC in [0,1] using principal-eigenvector mass concentration.
|
| 24 |
-
"""
|
| 25 |
-
E = np.stack(embeddings, axis=0) # (M, d)
|
| 26 |
E = self._normalize_rows(E)
|
| 27 |
-
K = E @ E.T
|
| 28 |
-
# symmetrize for safety
|
| 29 |
-
K = 0.5 * (K + K.T)
|
| 30 |
-
# principal eigenvector (largest eigenvalue)
|
| 31 |
vals, vecs = eigh(K)
|
| 32 |
-
w = np.abs(vecs[:, -1])
|
| 33 |
-
w = w / (w.sum() + 1e-12)
|
| 34 |
M = len(embeddings)
|
| 35 |
pc = (w.max() - 1.0/M) / (1.0 - 1.0/M)
|
| 36 |
return float(np.clip(pc, 0.0, 1.0))
|
| 37 |
|
| 38 |
def cardy_boundary_energy(self, hidden: np.ndarray) -> float:
|
| 39 |
-
"""
|
| 40 |
-
Proxy for boundary energy: encourages smoothness and low-norm at
|
| 41 |
-
the 'boundary'. Use total variation + L2. Scale by central charge.
|
| 42 |
-
hidden: [T, D] or [D]
|
| 43 |
-
"""
|
| 44 |
h = np.atleast_2d(hidden)
|
| 45 |
-
# temporal variation (if T>1)
|
| 46 |
tv = np.abs(np.diff(h, axis=0)).mean() if h.shape[0] > 1 else 0.0
|
| 47 |
l2 = norm(h) / np.sqrt(h.size)
|
| 48 |
-
|
| 49 |
-
energy = (0.5 * l2 + 0.5 * tv) * np.log1p(self.c)
|
| 50 |
-
return float(energy)
|
|
|
|
| 1 |
+
# consensus/topo.py
|
| 2 |
import numpy as np
|
| 3 |
from numpy.linalg import eigh, norm
|
| 4 |
|
| 5 |
class TopologicalConsciousness:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 6 |
def __init__(self, n_anyons: int, central_charge: float = 627.0):
|
| 7 |
self.n = n_anyons
|
| 8 |
self.c = central_charge
|
|
|
|
| 13 |
return X / d
|
| 14 |
|
| 15 |
def calculate_coherence(self, embeddings: list[np.ndarray]) -> float:
|
| 16 |
+
E = np.stack(embeddings, axis=0)
|
|
|
|
|
|
|
|
|
|
|
|
|
| 17 |
E = self._normalize_rows(E)
|
| 18 |
+
K = 0.5 * ((E @ E.T) + (E @ E.T).T) # cosine Gram, symmetrized
|
|
|
|
|
|
|
|
|
|
| 19 |
vals, vecs = eigh(K)
|
| 20 |
+
w = np.abs(vecs[:, -1]); w = w / (w.sum() + 1e-12)
|
|
|
|
| 21 |
M = len(embeddings)
|
| 22 |
pc = (w.max() - 1.0/M) / (1.0 - 1.0/M)
|
| 23 |
return float(np.clip(pc, 0.0, 1.0))
|
| 24 |
|
| 25 |
def cardy_boundary_energy(self, hidden: np.ndarray) -> float:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 26 |
h = np.atleast_2d(hidden)
|
|
|
|
| 27 |
tv = np.abs(np.diff(h, axis=0)).mean() if h.shape[0] > 1 else 0.0
|
| 28 |
l2 = norm(h) / np.sqrt(h.size)
|
| 29 |
+
return float((0.5*l2 + 0.5*tv) * np.log1p(self.c))
|
|
|
|
|
|