summaryrefslogtreecommitdiff
path: root/artifacts/spectral_frontier_probe/diag3.py
diff options
context:
space:
mode:
Diffstat (limited to 'artifacts/spectral_frontier_probe/diag3.py')
-rw-r--r--artifacts/spectral_frontier_probe/diag3.py21
1 files changed, 21 insertions, 0 deletions
diff --git a/artifacts/spectral_frontier_probe/diag3.py b/artifacts/spectral_frontier_probe/diag3.py
new file mode 100644
index 0000000..45a1430
--- /dev/null
+++ b/artifacts/spectral_frontier_probe/diag3.py
@@ -0,0 +1,21 @@
+import torch, numpy as np
+np.set_printoptions(precision=3, suppress=True, linewidth=200)
+def standardise(M):
+ M=np.asarray(M,dtype=np.float64); mask=~np.eye(len(M),dtype=bool); v=M[mask]
+ out=(M-v.mean())/v.std(); np.fill_diagonal(out,0.0); return out
+d=torch.load('artifacts/synth_v1/omit_size.pt',map_location='cpu')
+V=standardise(d['visual_field']); T=standardise(d['text_field']); N=len(V)
+
+wV,UV=np.linalg.eigh(V); wV=wV[::-1]; UV=UV[:,::-1]
+wT,UT=np.linalg.eigh(T); wT=wT[::-1]; UT=UT[:,::-1]
+K=24
+X=np.abs(UV[:,:K].T@UT[:,:K])
+print("|<u_k(V), u_l(T)>| top-16 block (rows=V index, cols=T index):")
+print(X[:16,:16])
+print("\ndiagonal |<u_k(V),u_k(T)>| k=0..23:", np.diag(X))
+print("row-max of |overlap| (best T partner for each V eigvec):", X.max(1))
+print("argmax:", X.argmax(1))
+# subspace alignment: principal angles between top-r spaces
+for r in (4,6,8,10,12,16,20,24,32,48):
+ s=np.linalg.svd(UV[:,:r].T@UT[:,:r],compute_uv=False)
+ print(f"r={r:3d} mean cos principal angle {s.mean():.3f} captured energy {np.sum(s**2)/r:.3f} min {s.min():.3f}")