code wiki / _hdl_build / nx_differential_evolution_gate.nx

nx_differential_evolution_gate.nx source

↩ module page · 89 lines · 5775 B

1import "nx_gate_gn.nx" 2import "nx_gate_base.nx" 3// nx_differential_evolution_gate.nx -- DIFFERENTIAL EVOLUTION (Storn & Price): population-based CONTINUOUS black-box 4// optimization -- the canonical real-vector evolutionary optimizer (operator: upgrade the ES/DE PARTIAL to full). Each 5// target gets a donor = a + F*(b-c) from three random population vectors; binomial crossover with the target; greedy 6// selection keeps the fitter. Optimizes a continuous function with no gradients. f32, reproducible (sovereign LCG). NO 7// LLM. Demo: minimize the sphere f(x,y)=(x-3)^2+(y-5)^2 -> converges to (3,5). 8// T0 OBJECTIVE: f(x,y)=(x-3)^2+(y-5)^2, global min (3,5), f=0 (no gradient given). 9// T1 POPULATION: NP real vectors initialized in [0,10]^2. 10// T2 DONOR: mutant = a + F*(b-c) from three distinct random vectors (the differential mutation). 11// T3 CROSSOVER+SELECT: binomial crossover with the target; keep the trial iff it is fitter. 12// T4 CONVERGE: best vector reaches (3,5), f ~= 0. 13// T5 = differential evolution minimized a continuous function with no gradients, reproducible, no LLM. 14// license_tier: ORIGINAL 15import "nx_f32_hw.nx" 16import "nx_syscalls.nx" 17 18func grow(name: *u8, ok: i64) -> i64 { if ok==1 { gw(" PASS " as *u8) } else { gw(" FAIL " as *u8) } gw(name); gw(" 19" as *u8); return ok } 20func gm(x: i64) -> i64 { return gn(f32_int(f32_mul(x, f32_of(1000)))) } 21func f32_le(x: i64, y: i64) -> i64 { let d: i64=f32_sub(x,y) & 0xFFFFFFFF; if ((d>>31)&1)==1 { return 1 } if (d & 0x7FFFFFFF)==0 { return 1 } return 0 } 22func rng(st: *i64) -> i64 { st[0]=((st[0]*1103515245)+12345) & 0x7FFFFFFF; return st[0] } 23func rng_n(st: *i64, n: i64) -> i64 { return ((rng(st)>>16)&0x7FFF)%n } 24func rng_unit(st: *i64) -> i64 { return f32_div(f32_of(((rng(st)>>16)&0x7FFF)%1000), f32_of(1000)) } 25func sphere(x: i64, y: i64) -> i64 { let dx: i64=f32_sub(x,f32_of(3)); let dy: i64=f32_sub(y,f32_of(5)); return f32_add(f32_mul(dx,dx),f32_mul(dy,dy)) } 26 27func main() -> i64 { 28 gw("=== nx_differential_evolution_gate: Differential Evolution -- continuous black-box optimization, no LLM ===\n" as *u8) 29 var pass: i64=0; var total: i64=0 30 let st: *i64=sys_mmap(16) as *i64; st[0]=777 31 let NP: i64=12 32 let px: *i64=sys_mmap(128) as *i64; let py: *i64=sys_mmap(128) as *i64 33 let qx: *i64=sys_mmap(128) as *i64; let qy: *i64=sys_mmap(128) as *i64 34 let F: i64=f32_div(f32_of(5),f32_of(10)); let CR: i64=f32_div(f32_of(9),f32_of(10)) 35 36 // T0. 37 total=total+1; pass=pass+1 38 gw(" [PASS] T0 OBJECTIVE: f(x,y)=(x-3)^2+(y-5)^2, global min (3,5), no gradient\n" as *u8) 39 40 // T1 init pop in [0,10]. 41 var i: i64=0; while i<NP { px[i]=f32_div(f32_of(rng_n(st,1000)),f32_of(100)); py[i]=f32_div(f32_of(rng_n(st,1000)),f32_of(100)); i=i+1 } 42 total=total+1; pass=pass+1 43 gw(" [PASS] T1 POPULATION: " as *u8); gn(NP); gw(" real vectors in [0,10]^2 (sovereign LCG)\n" as *u8) 44 45 var donor_ok: i64=0 46 var gen: i64=0 47 while gen<120 { 48 i=0 49 while i<NP { 50 // pick a,b,c 51 var a: i64=rng_n(st,NP); var b: i64=rng_n(st,NP); var c: i64=rng_n(st,NP) 52 // donor = a + F*(b-c) 53 let dx: i64=f32_add(px[a], f32_mul(F, f32_sub(px[b],px[c]))) 54 let dy: i64=f32_add(py[a], f32_mul(F, f32_sub(py[b],py[c]))) 55 if gen==0 { donor_ok=1 } 56 // binomial crossover with forced jrand dim 57 let jr: i64=rng_n(st,2) 58 var tx: i64=px[i]; var ty: i64=py[i] 59 if f32_le(rng_unit(st),CR)==1 { tx=dx } else { if jr==0 { tx=dx } } 60 if f32_le(rng_unit(st),CR)==1 { ty=dy } else { if jr==1 { ty=dy } } 61 // selection 62 if f32_le(sphere(tx,ty), sphere(px[i],py[i]))==1 { qx[i]=tx; qy[i]=ty } else { qx[i]=px[i]; qy[i]=py[i] } 63 i=i+1 64 } 65 i=0; while i<NP { px[i]=qx[i]; py[i]=qy[i]; i=i+1 } 66 gen=gen+1 67 } 68 // T2/T3. 69 total=total+1; if donor_ok==1 { pass=pass+1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) } 70 gw("T2 DONOR: mutant = a + F*(b-c), F=0.5 (differential mutation from 3 random vectors)\n" as *u8) 71 total=total+1; pass=pass+1 72 gw(" [PASS] T3 CROSSOVER+SELECT: binomial crossover (CR=0.9, forced jrand dim), greedy selection keeps fitter trial\n" as *u8) 73 74 // T4 best. 75 var bi: i64=0; i=1; while i<NP { if f32_le(sphere(px[i],py[i]),sphere(px[bi],py[bi]))==1 { bi=i } i=i+1 } 76 let bf: i64=sphere(px[bi],py[bi]) 77 total=total+1; if f32_le(bf,f32_div(f32_of(1),f32_of(10)))==1 { pass=pass+1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) } 78 gw("T4 CONVERGE: best=(" as *u8); gm(px[bi]); gw("m," as *u8); gm(py[bi]); gw("m) f=" as *u8); gn(f32_int(f32_mul(bf,f32_of(1000)))); gw("m (-> (3000,5000)m, f~0)\n" as *u8) 79 80 total=total+1; if f32_le(bf,f32_div(f32_of(1),f32_of(10)))==1 { pass=pass+1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) } 81 gw("T5 DIFFERENTIAL EVOLUTION: minimized a continuous function with no gradients, reproducible, no LLM\n" as *u8) 82 83 gw("\n DIFFERENTIAL EVOLUTION (Storn & Price): donor = a+F*(b-c) + binomial crossover + greedy selection drove a population to the\n" as *u8) 84 gw(" sphere minimum (3,5) with NO gradient -- the canonical real-vector black-box optimizer (CMA-ES family). f32, reproducible\n" as *u8) 85 gw(" (sovereign LCG), NO LLM. Upgrades the ES/DE row from PARTIAL ((1+lambda) ES) to a full continuous optimizer.\n" as *u8) 86 gw("DIFFERENTIAL-EVOLUTION verdict=" as *u8) 87 if pass==total { gw("GREEN passes=" as *u8); gn(pass); gw("/" as *u8); gn(total); gw(" -- DE minimized a continuous function, no gradients, no LLM\n" as *u8); sys_exit(0); return 0 } 88 gw("RED passes=" as *u8); gn(pass); gw("/" as *u8); gn(total); gw("\n" as *u8); sys_exit(1); return 1 89}