summaryrefslogtreecommitdiff
path: root/ep_run/eig_traj2.py
blob: bae22b73aaf940b7ca0986c2691fa5ca8da0efa5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
"""E1b: ARPACK gold-standard re-measurement of the redx trajectory at 6 key ckpts (lead_rho's cold 2-D
iteration under-reads near-unity clusters by ~0.02-0.03, so absolute mu from eig_traj.py is suspect).
Top-3 |lam| of the forward map M = I + eps*J_F at the 400-step deep state, same seed-42 batch."""
import numpy as np, torch, scipy.sparse.linalg as sla
from torch.autograd.functional import jvp
import lt_ep_train as L

EPS, B, C = 0.1, 6, 1.0
KEY = [1000, 1400, 2000, 2400, 2800, 3200]

for s in KEY:
    torch.manual_seed(0)
    blk = L.EQBlock(512, 16, 256, 256, c=C, attn_mode='thick'); blk.qknorm = True
    ck = torch.load(f'runs/redx_traj/s{s}.pt', map_location=L.dev)
    with torch.no_grad():
        for p, w in zip(blk.allp, ck['allp']):
            p.copy_(w.to(L.dev))
    torch.manual_seed(42)
    idx, _ = L.get_batch('train', B, 256)
    xin = blk.embed(idx).detach()
    z = L.relax(blk, xin.clone(), xin, 400, EPS)
    sh, n = z.shape, z.numel()
    kk = 1.0 - EPS * (1.0 + C)

    def mv(x, z=z, sh=sh):
        v = torch.from_numpy(np.asarray(x, dtype=np.float32)).to(L.dev).view(sh)
        with torch.no_grad():
            Mv = kk * v + EPS * jvp(blk.nc_force, z, v)[1]
        return Mv.reshape(-1).double().cpu().numpy()

    A = sla.LinearOperator((n, n), matvec=mv, dtype=np.float64)
    try:
        vals = sorted(sla.eigs(A, k=3, which='LM', return_eigenvectors=False, maxiter=2000, tol=1e-4),
                      key=lambda x: -abs(x))
        out = "  ".join(f"|l|={abs(l):.5f}(mu={(l.real-1)/EPS:+.4f}{l.imag/EPS:+.3f}j)" for l in vals)
    except Exception as e:
        out = f"ARPACK-fail {type(e).__name__}"
    print(f"s{s:<5} {out}", flush=True)
print("EIG_TRAJ2_DONE", flush=True)