code wiki / _hdl_build / _f64_rootfind_gate.nx

_f64_rootfind_gate.nx source

↩ module page · 70 lines · 3556 B

1// _f64_rootfind_gate.nx -- self-validating gate for the GAMS-F bisection root-finder. 2// For each test function: find the root, assert |f(root)| ~ 0 (< 2^-40, the DEFINING 3// property -- a free oracle). For the two with closed-form roots (sqrt2, ln2) also assert 4// the root matches bit-tight (<= 4 ulp). Durable: ROOTFIND-GATE -> math_engine.log. 5// license_tier: ORIGINAL 6import "nx_syscalls.nx" 7import "nx_f64.nx" 8import "nx_f64_rootfind.nx" 9 10func rg_p(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 11func rg_f(fd: i64, s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(fd,s,n); return 0 } 12func rg_n(fd: i64, v: i64) -> i64 { let bb: *u8=sys_mmap(28); var m: i64=v; if m<0{m=0-m; sys_write(fd,"-" as *u8,1)}; let t: *u8=sys_mmap(28); var k: i64=0; if m==0{t[0]=48 as u8;k=1}; while m>0{t[k]=(48+(m%10)) as u8;m=m/10;k=k+1}; var i: i64=0; while i<k{bb[i]=t[k-1-i];i=i+1}; sys_write(fd,bb,k); return 0 } 13func rg_ulp(a: i64, b: i64) -> i64 { if a >= b { return a - b } return b - a } 14 15const RG_ONE: i64 = 0x3FF0000000000000 16const RG_TWO: i64 = 0x4000000000000000 17const RG_ZERO: i64 = 0 18 19func main() -> i64 { 20 rg_p("=== F64-ROOTFIND GATE: bisection root-finder, |f(root)|~0 + closed-form roots ===\n" as *u8) 21 let thr: i64 = 983 << 52 // 2^-40 22 var froot_bad: i64 = 0 23 var maxfr: i64 = 0 24 25 // fid 0: x^2-2 on [1,2] -> sqrt2 26 let r0: i64 = nx_f64_root_bisect(0, RG_ONE, RG_TWO) 27 let f0: i64 = rf_eval(0, r0) & 0x7FFFFFFFFFFFFFFF 28 if f0 > maxfr { maxfr = f0 } 29 if f0 >= thr { froot_bad = froot_bad + 1 } 30 // fid 1: cos(x)-x on [0,1] -> Dottie 31 let r1: i64 = nx_f64_root_bisect(1, RG_ZERO, RG_ONE) 32 let f1: i64 = rf_eval(1, r1) & 0x7FFFFFFFFFFFFFFF 33 if f1 > maxfr { maxfr = f1 } 34 if f1 >= thr { froot_bad = froot_bad + 1 } 35 // fid 2: exp(x)-2 on [0,1] -> ln2 36 let r2: i64 = nx_f64_root_bisect(2, RG_ZERO, RG_ONE) 37 let f2: i64 = rf_eval(2, r2) & 0x7FFFFFFFFFFFFFFF 38 if f2 > maxfr { maxfr = f2 } 39 if f2 >= thr { froot_bad = froot_bad + 1 } 40 // fid 3: x^3-x-2 on [1,2] 41 let r3: i64 = nx_f64_root_bisect(3, RG_ONE, RG_TWO) 42 let f3: i64 = rf_eval(3, r3) & 0x7FFFFFFFFFFFFFFF 43 if f3 > maxfr { maxfr = f3 } 44 if f3 >= thr { froot_bad = froot_bad + 1 } 45 46 // closed-form root matches 47 let u_sqrt2: i64 = rg_ulp(r0, 0x3FF6A09E667F3BCD) 48 let u_ln2: i64 = rg_ulp(r2, 0x3FE62E42FEFA39EF) 49 50 var ok: i64 = 0 51 if froot_bad == 0 { if u_sqrt2 <= 4 { if u_ln2 <= 4 { ok = 1 } } } 52 let lfd: i64 = sys_openat_append("knowledge/status/math_engine.log" as *u8, 0x1a4) 53 if lfd >= 0 { 54 rg_f(lfd, "ROOTFIND-GATE epoch=" as *u8); rg_n(lfd, sys_now_realtime_sec()) 55 rg_f(lfd, " fns=4 froot_bad=" as *u8); rg_n(lfd, froot_bad) 56 rg_f(lfd, " max_froot_bits=" as *u8); rg_n(lfd, maxfr) 57 rg_f(lfd, " ulp_sqrt2=" as *u8); rg_n(lfd, u_sqrt2) 58 rg_f(lfd, " ulp_ln2=" as *u8); rg_n(lfd, u_ln2) 59 rg_f(lfd, " method=bisection gams=F(nonlinear-solve)" as *u8) 60 if ok == 1 { rg_f(lfd, " verdict=GREEN\n" as *u8) } else { rg_f(lfd, " verdict=RED\n" as *u8) } 61 sys_close(lfd) 62 } 63 rg_p(" froot_bad=" as *u8); rg_n(1, froot_bad) 64 rg_p(" ulp_sqrt2=" as *u8); rg_n(1, u_sqrt2) 65 rg_p(" ulp_ln2=" as *u8); rg_n(1, u_ln2) 66 if ok == 1 { rg_p(" ROOTFIND-GATE: GREEN (GAMS-F nonlinear-solve class opened: bisection, |f(root)|~0 + sqrt2/ln2 tight)\n" as *u8); sys_exit(0); return 0 } 67 rg_p(" ROOTFIND-GATE: RED (measured gap named)\n" as *u8) 68 sys_exit(1) 69 return 1 70}