code wiki / _hdl_build / nx_intfp_log_gate.nx
nx_intfp_log_gate.nx source
↩ module page · 54 lines · 3336 B
1// nx_intfp_log_gate.nx -- integer natural LOG (fp_log) in Q20, completing the sovereign transcendental set
2// (exp, rsqrt, log all integer, no float). log(x) = log2(x)*ln2 ; log2(x) = e + log2(m) where x=2^e*m, m in [1,2),
3// and log2(1+u) via a quartic minimax poly. Enables: true in-stack cross-entropy/perplexity VALUES (not just
4// gradients), DPO softplus, eval loss. Verified vs known ln() values; then a cross-entropy-value demo. license_tier: ORIGINAL
5import "nx_syscalls.nx"
6
7func w(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 }
8func wsi(v: i64) -> i64 { if v<0 { sys_write(1,"-" as *u8,1); v=0-v } var m: i64=v; if m==0 { sys_write(1,"0" as *u8,1); return 0 } let t: *u8=sys_mmap(24); var k: i64=0; while m>0{t[k]=(48+(m%10)) as u8;m=m/10;k=k+1} let o: *u8=sys_mmap(24); var q: i64=k-1; var i: i64=0; while q>=0{o[i]=t[q];i=i+1;q=q-1} sys_write(1,o,i); return 0 }
9
10const S: i64 = 1048576 // Q20
11
12// natural log of a Q20 value (x>0) -> Q20 (signed). ln(m)=2*atanh((m-1)/(m+1)), s<=1/3 => FAST-converging (a
13// Taylor log2(1+u) poly is 16pct WRONG at u->1 / mantissa->2; atanh is accurate across the whole [1,2) mantissa).
14func fp_log(xq: i64) -> i64 {
15 if xq<=0 { return 0-2000000000 }
16 var e: i64=0; var t: i64=xq
17 while t >= 2*S { t=t/2; e=e+1 }
18 while t < S { t=t*2; e=e-1 }
19 let s: i64=((t-S)*S)/(t+S) // (m-1)/(m+1), Q20 ; m=t/S in [1,2), s in [0,1/3)
20 let s2: i64=(s*s)/S
21 let poly: i64=S + s2/3 + ((s2*s2)/S)/5 // 1 + s^2/3 + s^4/5
22 let logm: i64=(2*s*poly)/S // 2*atanh(s) = ln(m)
23 return e*726817 + logm // e*ln2 + ln(m)
24}
25
26func showln(name: *u8, xq: i64, want_milli: i64) -> i64 {
27 let r: i64=fp_log(xq); let milli: i64=(r*1000)/S
28 w(" ln("); w(name); w(") = "); wsi(milli); w("m (want "); wsi(want_milli); w("m)\n" as *u8); return 0
29}
30
31func main() -> i64 {
32 w("=== nx_intfp_log: integer natural LOG (Q20) -- completes the sovereign transcendental set (exp/rsqrt/LOG) ===\n\n" as *u8)
33 showln("1" as *u8, S, 0)
34 showln("2" as *u8, 2*S, 693)
35 showln("e" as *u8, (S*271828)/100000, 1000)
36 showln("10" as *u8, 10*S, 2303)
37 showln("0.5" as *u8, S/2, 0-693)
38 showln("100" as *u8, 100*S, 4605)
39 showln("1.99" as *u8, (S*199)/100, 688) // mantissa near 2 -- the region the old Taylor poly got WRONG (was ~0.58)
40 showln("1.9" as *u8, (S*19)/10, 642)
41 // cross-entropy VALUE demo: probs p=[0.1,0.2,0.6,0.1] (Q20), target=2 -> CE=-ln(p[2])=-ln(0.6)=0.511
42 w("\n cross-entropy VALUE (in-stack, no float): p=[0.1,0.2,0.6,0.1] target=2\n" as *u8)
43 let p2: i64=(S*6)/10
44 let ce: i64=0-fp_log(p2); let ce_m: i64=(ce*1000)/S
45 w(" CE = -ln(0.6) = "); wsi(ce_m); w("m (want 511m) ; perplexity = e^CE ~ 1.82\n" as *u8)
46 // verdict: all within ~2% of truth
47 let l2: i64=(fp_log(2*S)*1000)/S; let le: i64=(fp_log((S*271828)/100000)*1000)/S
48 w("NX-INTFP-LOG verdict=" as *u8)
49 var ok: i64=1
50 if l2<680 { ok=0 } if l2>706 { ok=0 } if le<980 { ok=0 } if le>1020 { ok=0 } if ce_m<500 { ok=0 } if ce_m>522 { ok=0 }
51 if ok==1 { w("GREEN -- integer natural log correct (ln2/ln e/CE within ~2pct). exp+rsqrt+LOG all integer now. Unlocks in-stack CE/ppl VALUES + DPO softplus + eval loss.\n" as *u8) }
52 else { w("RED -- log poly off\n" as *u8) }
53 return 0
54}