import json, math, random import numpy as np import torch from torch import nn SEED=2711 random.seed(SEED); np.random.seed(SEED); torch.manual_seed(SEED) torch.set_num_threads(4) device='cuda' if torch.cuda.is_available() else 'cpu' try: if device=='cuda': torch.cuda.empty_cache() except Exception: device='cpu' def true_x(u): return 0.2 + 0.8*u + 0.08*torch.sin(4*math.pi*u) def cost(x,u): return (x-0.72)**2 + 0.035*(u-0.15)**2 def grid_opt(xfun, n=20001): u=torch.linspace(0,1,n,device=device) with torch.no_grad(): j=cost(xfun(u),u); k=int(torch.argmin(j)) return float(u[k]), float(j[k]) def stability_sweep(): H=3.7; rows=[] for rho in np.linspace(.05,.7,14): e=1.0 for _ in range(80): e=(1-rho*H)*e rows.append({'rho':float(rho),'rhoH':float(rho*H),'error80':float(abs(e)), 'stable_observed':bool(abs(e)<1e-4), 'stable_predicted':bool(abs(1-rho*H)<1)}) return {'H':H,'predicted_rho_boundary_2_over_H':2/H,'rows':rows} def minima_count(eps,k=6*math.pi,n=20001): u=np.linspace(0,1,n); us=.63 j=(u-us)**2+eps*np.cos(k*u) idx=np.where((j[1:-1].025: distinct.append(z) k=int(np.argmin(j)); return {'grid_opt_u':float(us[k]),'grid_opt_j':float(j[k]),'displacement':abs(float(us[k])-ut), 'grid_local_minima':int(len(ids)),'multistart_distinct':len(distinct), 'multistart_solutions':distinct,'data_mse':float(((model(torch.tensor([[0.],[.22],[.48],[.76],[1.]],device=device))-true_x(torch.tensor([[0.],[.22],[.48],[.76],[1.]],device=device)))**2).mean().detach().cpu())} def main(): ut,jt=grid_opt(true_x) base,_a,_b=train(False); idea,_a,_b=train(True) out={'device':device,'true_optimum':{'u':ut,'j':jt},'math_stability':stability_sweep(),'math_extra_minima':minima_sweep(), 'baseline':assess(base,ut,jt),'decision_aware':assess(idea,ut,jt)} with open('results.json','w') as f: json.dump(out,f,indent=2) print(json.dumps(out,indent=2)) if __name__=='__main__': main()