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}