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("|| top-16 block (rows=V index, cols=T index):") print(X[:16,:16]) print("\ndiagonal || 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}")