code wiki / _hdl_build / nx_synth_fit.nx
nx_synth_fit.nx source
↩ module page · 59 lines · 3441 B
1// nx_synth_fit.nx -- shared synthesis-fit CORE (no main): the power-sum basis model + iterated-local-search
2// coefficient fit + keep-if-generalizes, used by the grammar-expansion / primitive-miner / NL-miner gates. NO
3// LLM. All identifiers sf_-prefixed so importers never collide. (DRY: extracted from nx_grammar_expand /
4// nx_primitive_miner; future migration of those two to import this is the clean follow-up.) license_tier: ORIGINAL
5import "nx_syscalls.nx"
6const K_MAGIC_1103515245: i64 = 1103515245
7const K_MAGIC_12345: i64 = 12345
8const K_MAGIC_2147483647: i64 = 2147483647
9const K_MAGIC_300000: i64 = 300000
10
11func sf_lcg(st: *i64) -> i64 { st[0]=((K_MAGIC_1103515245*st[0])+K_MAGIC_12345)&K_MAGIC_2147483647; return st[0] }
12func sf_rand_coef(st: *i64) -> i64 { return (0-9)+(sf_lcg(st)%19) } // coeff in [-9,9]
13func sf_pow_i(i: i64, k: i64) -> i64 { var r: i64=1; var c: i64=0; while c<k { r=r*i; c=c+1 } return r }
14func sf_powsum(k: i64, x: i64) -> i64 { var s: i64=0; var i: i64=1; while i<=x { s=s+sf_pow_i(i,k); i=i+1 } return s }
15// model: base {1, x, S1, S2} (+ c4*powsum(candk) if candk>0). candk=0 -> base grammar.
16func sf_model(c: *i64, candk: i64, x: i64) -> i64 {
17 var v: i64=(c[0])+(c[1]*x)+(c[2]*sf_powsum(1,x))+(c[3]*sf_powsum(2,x))
18 if candk>0 { v=v+(c[4]*sf_powsum(candk,x)) }
19 return v
20}
21func sf_merr(c: *i64, candk: i64, xs: *i64, ys: *i64, n: i64) -> i64 {
22 var e: i64=0; var i: i64=0
23 while i<n { var d: i64=sf_model(c,candk,xs[i])-ys[i]; if d<0 { d=0-d } e=e+d; i=i+1 }
24 return e
25}
26// iterated local search over the coefficients (no LLM; multi-gene + restart escapes local optima). candk=0 -> 4 coeffs.
27func sf_fit(candk: i64, xs: *i64, ys: *i64, n: i64, seed: i64, best: *i64) -> i64 {
28 var ng: i64=4; if candk>0 { ng=5 }
29 let st: *i64=sys_mmap(16) as *i64; st[0]=seed
30 let par: *i64=sys_mmap(64) as *i64; let ch: *i64=sys_mmap(64) as *i64; let bev: *i64=sys_mmap(64) as *i64
31 var gi: i64=0; while gi<ng { par[gi]=sf_rand_coef(st); gi=gi+1 }
32 var perr: i64=sf_merr(par,candk,xs,ys,n); var ec: i64=1
33 var ber: i64=perr; var zz: i64=0; while zz<ng { bev[zz]=par[zz]; zz=zz+1 }
34 var stag: i64=0; var stop: i64=0
35 while stop==0 {
36 var l: i64=0
37 while l<16 {
38 var c: i64=0; while c<ng { ch[c]=par[c]; c=c+1 }
39 ch[sf_lcg(st)%ng]=sf_rand_coef(st)
40 if (sf_lcg(st)%3)==0 { ch[sf_lcg(st)%ng]=sf_rand_coef(st) }
41 let ce: i64=sf_merr(ch,candk,xs,ys,n); ec=ec+1
42 if ce<perr { var c2: i64=0; while c2<ng { par[c2]=ch[c2]; c2=c2+1 } perr=ce }
43 if ce==0 { l=16 } else { l=l+1 }
44 }
45 if perr<ber { ber=perr; var b2: i64=0; while b2<ng { bev[b2]=par[b2]; b2=b2+1 } stag=0 } else { stag=stag+1 }
46 if stag>50 { var r: i64=0; while r<ng { par[r]=sf_rand_coef(st); r=r+1 } perr=sf_merr(par,candk,xs,ys,n); ec=ec+1; stag=0 }
47 if ber==0 { stop=1 }
48 if ec>=K_MAGIC_300000 { stop=1 }
49 }
50 var b: i64=0; while b<ng { best[b]=bev[b]; b=b+1 }
51 if ber==0 { return 1 }
52 return 0
53}
54// keep a candidate iff it fits the training AND generalizes on two held-out points (no-fake-green).
55func sf_keep(candk: i64, xs: *i64, ys: *i64, n: i64, hx0: i64, hy0: i64, hx1: i64, hy1: i64) -> i64 {
56 let bb: *i64=sys_mmap(64) as *i64
57 if sf_fit(candk,xs,ys,n,K_MAGIC_12345,bb)==1 { if sf_model(bb,candk,hx0)==hy0 { if sf_model(bb,candk,hx1)==hy1 { return 1 } } }
58 return 0
59}