import json from pathlib import Path import numpy as np SEED = 1729 def sliced_w2_sq(a, b, n_proj=128, rng=None): rng = np.random.default_rng() if rng is None else rng d = a.shape[1] q = rng.normal(size=(n_proj, d)) q /= np.linalg.norm(q, axis=1, keepdims=True) pa = np.sort(a @ q.T, axis=0) pb = np.sort(b @ q.T, axis=0) return float(d * np.mean((pa - pb) ** 2)) def exact_translation_sweep(): """Verify W2^2 <= D dt Sigma for a distribution translated at velocity u. For p_t(x)=p_0(x-u t), v=u, so W2^2=||u||^2 dt^2 and D dt Sigma = D dt * (||u||^2/D)dt = ||u||^2 dt^2 exactly. This avoids confusing paired particle displacement with distribution W2. """ rng = np.random.default_rng(SEED) rows = [] for d in (1, 2, 8): for D in (0.05, 0.2, 0.8): for dt in (0.02, 0.08): for speed in (0.4, 1.2): n = 1024 x0 = rng.normal(size=(n, d)) u = np.full(d, speed / np.sqrt(d)) x1 = x0 + dt * u w2 = sliced_w2_sq(x0, x1, 128, rng) sigma = float(np.dot(u, u) / D) rhs = D * dt * sigma * dt predicted = float(np.dot(u, u) * dt * dt) rows.append({"d": d, "D": D, "dt": dt, "speed": speed, "w2": w2, "rhs": rhs, "predicted": predicted, "ratio": w2 / rhs, "w2_over_speed2_dt2": w2 / (speed * speed * dt * dt)}) ratios = np.array([r["ratio"] for r in rows]) scaling = np.array([r["w2_over_speed2_dt2"] for r in rows]) return rows, {"median_ratio": float(np.median(ratios)), "max_abs_ratio_error": float(np.max(np.abs(ratios - 1))), "median_speed_dt_scaling": float(np.median(scaling)), "speed_dt_scaling_range": [float(np.min(scaling)), float(np.max(scaling))]} def controller_update(eta, ratio, eta_min, eta_max, alpha=0.35, target=0.72): # Safety-oriented interpretation of the prose: r>target decreases eta; # r