| """ |
| Mathematical constructions for low C1. |
| |
| Key insight: we need functions where the sumset A+A is uniformly distributed. |
| This is a problem in additive combinatorics. |
| |
| Constructions to try: |
| 1. Quadratic residue indicator functions |
| 2. Functions based on polynomial evaluation over finite fields |
| 3. B-spline wavelets |
| 4. Optimized step functions via DE at small K |
| 5. Functions that equalize the autoconvolution |
| """ |
| import numpy as np |
| from scipy.optimize import minimize, differential_evolution |
| from scipy.interpolate import interp1d |
| import time |
|
|
| def compute_c1_fft(f_values, dx): |
| f = np.maximum(f_values, 0.0) |
| N = len(f) |
| M = 2 * N |
| fft_f = np.fft.rfft(f, n=M) |
| conv = np.fft.irfft(fft_f * fft_f, n=M) * dx |
| integral_sq = (np.sum(f) * dx) ** 2 |
| if integral_sq < 1e-20: |
| return 1e10 |
| return float(np.max(conv) / integral_sq) |
|
|
| def compute_c1_smooth_and_grad(f, N, dx, alpha=200.0): |
| M = 2 * N |
| fft_f = np.fft.rfft(f, n=M) |
| conv = np.fft.irfft(fft_f * fft_f, n=M) * dx |
| integral = np.sum(f) * dx |
| if integral < 1e-15: |
| return 1e10, np.zeros(N) |
| integral_sq = integral ** 2 |
| max_val = np.max(conv) |
| shifted = conv - max_val |
| mask = shifted > -50.0 / alpha |
| weights = np.zeros_like(conv) |
| weights[mask] = np.exp(alpha * shifted[mask]) |
| sum_w = np.sum(weights) |
| if sum_w < 1e-30: |
| weights[np.argmax(conv)] = 1.0 |
| sum_w = 1.0 |
| smooth_max = max_val + np.log(sum_w) / alpha |
| softmax_w = weights / sum_w |
| c1 = smooth_max / integral_sq |
| fft_sw = np.fft.rfft(softmax_w, n=M) |
| fft_fp = np.fft.rfft(f, n=M) |
| corr = np.fft.irfft(fft_sw * np.conj(fft_fp), n=M) |
| grad_f = 2.0 * corr[:N] * dx / integral_sq - 2.0 * smooth_max * dx / (integral**3) |
| return c1, grad_f |
|
|
| def opt_pipeline(f_init, N, dx, maxiter=2000): |
| """Full optimization pipeline.""" |
| params = np.sqrt(np.maximum(f_init, 0.0) + 1e-12) |
| for alpha in [0.5, 5.0, 50.0, 500.0, 5000.0, 50000.0]: |
| def obj(p, a=alpha): |
| f = p ** 2 |
| c1, g = compute_c1_smooth_and_grad(f, N, dx, a) |
| return c1, g * 2 * p |
| result = minimize(obj, params, jac=True, method='L-BFGS-B', |
| options={'maxiter': maxiter, 'ftol': 1e-16, 'gtol': 1e-15}) |
| params = result.x |
| f_out = params ** 2 |
| return f_out, compute_c1_fft(f_out, dx) |
|
|
| def upscale(f, N_new): |
| N_old = len(f) |
| x_old = np.linspace(0, 1, N_old) |
| x_new = np.linspace(0, 1, N_new) |
| interp = interp1d(x_old, f, kind='linear', fill_value=0.0, bounds_error=False) |
| return np.maximum(interp(x_new), 0.0) |
|
|
| |
| |
| |
| print("=== DE on step functions ===") |
| t0 = time.time() |
|
|
| best_results = [] |
|
|
| for K in [10, 15, 20, 25, 30, 40, 50, 75, 100]: |
| N_k = K * 10 |
| dx_k = 0.5 / N_k |
| step_size = N_k // K |
|
|
| def obj_de(heights): |
| f = np.repeat(np.maximum(heights, 0.0), step_size)[:N_k] |
| return compute_c1_fft(f, dx_k) |
|
|
| bounds = [(0.0, 5.0)] * K |
| result = differential_evolution(obj_de, bounds, maxiter=500, seed=42, |
| popsize=20, tol=1e-12) |
| c1_raw = result.fun |
|
|
| |
| f_step = np.repeat(np.maximum(result.x, 0.0), step_size)[:N_k] |
| f_opt, c1_opt = opt_pipeline(f_step, N_k, dx_k, maxiter=1000) |
|
|
| best_results.append((K, c1_opt, f_opt, N_k, dx_k)) |
| elapsed = time.time() - t0 |
| print(f" K={K:3d}: DE C1={c1_raw:.8f}, opt C1={c1_opt:.8f} ({elapsed:.0f}s)") |
|
|
| |
| |
| |
| print("\n=== Finite field constructions ===") |
|
|
| |
| for p in [31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 127, 131]: |
| N_p = p * 10 |
| dx_p = 0.5 / N_p |
|
|
| |
| qr = set() |
| for a in range(p): |
| qr.add((a * a) % p) |
|
|
| f = np.zeros(N_p) |
| for r in qr: |
| block_start = int(r * N_p / p) |
| block_end = int((r + 1) * N_p / p) |
| f[block_start:block_end] = 1.0 |
|
|
| f_opt, c1 = opt_pipeline(f, N_p, dx_p, maxiter=1000) |
| if c1 < 1.515: |
| best_results.append(('QR', c1, f_opt, N_p, dx_p)) |
| print(f" p={p}: C1 = {c1:.8f} ***") |
|
|
| |
| |
| |
| |
| print("\n=== Autoconvolution equalization ===") |
|
|
| for N_eq in [200, 500]: |
| dx_eq = 0.5 / N_eq |
|
|
| |
| for seed in range(20): |
| np.random.seed(seed + 3000) |
| f = np.random.exponential(1.0, N_eq) + 0.1 |
|
|
| |
| for iteration in range(50): |
| f_nn = np.maximum(f, 0.0) |
| M = 2 * N_eq |
| fft_f = np.fft.rfft(f_nn, n=M) |
| conv = np.fft.irfft(fft_f * fft_f, n=M) * dx_eq |
|
|
| |
| max_val = np.max(conv) |
| threshold = max_val * 0.99 |
| high_mask = conv > threshold |
|
|
| |
| |
| |
|
|
| |
| |
| power_spectrum = np.abs(fft_f) ** 2 |
| |
| cutoff = len(power_spectrum) // 2 |
| damping = np.ones(len(power_spectrum)) |
| top_freqs = np.argsort(power_spectrum[1:cutoff])[::-1][:10] + 1 |
| damping[top_freqs] *= 0.95 |
| fft_mod = fft_f * damping |
| f = np.fft.irfft(fft_mod, n=M)[:N_eq] |
| f = np.maximum(f, 0.0) + 0.001 |
|
|
| f_opt, c1 = opt_pipeline(f, N_eq, dx_eq, maxiter=1000) |
| if c1 < 1.515: |
| best_results.append(('EQ', c1, f_opt, N_eq, dx_eq)) |
| print(f" N={N_eq}, seed={seed}: C1 = {c1:.8f}") |
|
|
| |
| |
| |
| print("\n=== B-spline basis ===") |
|
|
| for n_knots in [5, 10, 15, 20, 30]: |
| N_bs = 500 |
| dx_bs = 0.5 / N_bs |
| x = np.linspace(0, 0.5, N_bs, endpoint=False) |
|
|
| |
| knots = np.linspace(0, 0.5, n_knots + 2) |
| basis = np.zeros((N_bs, n_knots)) |
| for i in range(n_knots): |
| |
| center = knots[i + 1] |
| width = knots[i + 2] - knots[i] |
| basis[:, i] = np.maximum(1 - np.abs(x - center) / (width/2), 0) |
|
|
| def obj_bs(coeffs): |
| f = np.maximum(basis @ coeffs, 0.0) |
| return compute_c1_fft(f, dx_bs) |
|
|
| for seed in range(20): |
| np.random.seed(seed + 4000) |
| c0 = np.random.exponential(1.0, n_knots) |
|
|
| result = minimize(obj_bs, c0, method='Nelder-Mead', |
| options={'maxiter': 10000, 'xatol': 1e-10, 'fatol': 1e-10}) |
| c1 = result.fun |
| if c1 < 1.515: |
| f_bs = np.maximum(basis @ result.x, 0.0) |
| f_opt, c1_opt = opt_pipeline(f_bs, N_bs, dx_bs, maxiter=1000) |
| best_results.append(('BS', c1_opt, f_opt, N_bs, dx_bs)) |
| print(f" n_knots={n_knots}, seed={seed}: C1 = {c1:.4f} → {c1_opt:.8f}") |
|
|
| |
| |
| |
| |
| valid = [(r[1], r[2], r[3], r[4]) for r in best_results if isinstance(r[0], (int, str))] |
| valid.sort(key=lambda x: x[0]) |
|
|
| print(f"\n=== Top 5 results ===") |
| for i, (c1, f, N_r, dx_r) in enumerate(valid[:5]): |
| print(f" #{i+1}: C1 = {c1:.10f} at N={N_r}") |
|
|
| if valid: |
| best_c1, best_f, best_N, best_dx = valid[0] |
|
|
| |
| print(f"\nUpscaling best (C1={best_c1:.10f}) to N=5000...") |
| N_final = 5000 |
| dx_final = 0.5 / N_final |
| f_up = upscale(best_f, N_final) |
| f_final, c1_final = opt_pipeline(f_up, N_final, dx_final, maxiter=5000) |
|
|
| |
| params = np.sqrt(np.maximum(f_final, 0.0) + 1e-12) |
| for cycle in range(5): |
| for alpha in [0.5, 2.0, 10.0]: |
| def obj(p, a=alpha): |
| f = p ** 2 |
| c1, g = compute_c1_smooth_and_grad(f, N_final, dx_final, a) |
| return c1, g * 2 * p |
| result = minimize(obj, params, jac=True, method='L-BFGS-B', |
| options={'maxiter': 500, 'ftol': 1e-16, 'gtol': 1e-15}) |
| params = result.x |
| for alpha in [100.0, 1000.0, 10000.0, 100000.0]: |
| def obj(p, a=alpha): |
| f = p ** 2 |
| c1, g = compute_c1_smooth_and_grad(f, N_final, dx_final, a) |
| return c1, g * 2 * p |
| result = minimize(obj, params, jac=True, method='L-BFGS-B', |
| options={'maxiter': 2000, 'ftol': 1e-16, 'gtol': 1e-15}) |
| params = result.x |
| f_out = params ** 2 |
| c1 = compute_c1_fft(f_out, dx_final) |
| if c1 < c1_final: |
| c1_final = c1 |
| f_final = f_out.copy() |
|
|
| print(f"Final at N=5000: C1 = {c1_final:.10f}") |
| print(f"Score: {1.5052939684401607 / c1_final:.10f}") |
|
|
| |
| try: |
| f_existing = np.load('/workspace/best_f_5000.npy') |
| c1_existing = compute_c1_fft(f_existing, 0.5/len(f_existing)) |
| print(f"Existing best: C1 = {c1_existing:.10f}") |
| if c1_final < c1_existing: |
| np.save('/workspace/best_f_5000_math.npy', f_final) |
| print("NEW BEST! Saved to best_f_5000_math.npy") |
| except: |
| pass |
|
|
| print(f"\nTotal time: {time.time()-t0:.0f}s") |
|
|