code wiki / _hdl_build / nx_timeseries_gate.nx

nx_timeseries_gate.nx source

↩ module page · 104 lines · 5430 B

1// nx_timeseries_gate.nx -- GATE for time-series analytics (nx_timeseries). Known-answer: an exact rising 2// ramp -> slope=+1000 (1.0/step) intercept=base; a falling ramp -> negative; a flat series -> ~0 + FLAT 3// class; rolling mean smooths + endpoints correct; growth% exact. expect_exit: 0 license_tier: ORIGINAL 4import "nx_syscalls.nx" 5import "_hdl_build/nx_timeseries.nx" 6 7func tp(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 8func tn(v: i64) -> i64 { var m: i64=v; if m<0{tp("-" as *u8);m=0-m} let t:*u8=sys_mmap(24); 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} let o:*u8=sys_mmap(24); var i:i64=0; while i<k{o[i]=t[k-1-i];i=i+1} sys_write(1,o,k); return 0 } 9func tstreq(a: *u8, b: *u8) -> i64 { var i: i64=0; while a[i]!=(0 as u8){ if a[i]!=b[i] { return 0 } i=i+1 } if b[i]!=(0 as u8){return 0} return 1 } 10 11func main() -> i64 { 12 tp("=== nx_timeseries_gate ===\n" as *u8) 13 var pass: i64 = 0 14 var fail: i64 = 0 15 let n: i64 = 50 16 let sm: *i64 = sys_mmap(8) as *i64 17 let ic: *i64 = sys_mmap(8) as *i64 18 19 // C1 rising ramp: y = 100 + 3*i -> slope 3.0 (=3000 milli), intercept 100 20 let rise: *i64 = sys_mmap(n * 8) as *i64 21 var i: i64 = 0 22 while i < n { rise[i] = 100 + 3 * i; i = i + 1 } 23 ts_linear_trend(rise, n, sm, ic) 24 tp("rising slope_milli=" as *u8); tn(sm[0]); tp(" intercept=" as *u8); tn(ic[0]); tp("\n" as *u8) 25 var t1: i64 = 1 26 if sm[0] != 3000 { t1 = 0 } 27 if ic[0] != 100 { t1 = 0 } 28 if ts_trend_class(sm[0], 100) != TS_RISING { t1 = 0 } 29 if tstreq(ts_class_str(ts_trend_class(sm[0], 100)), "rising" as *u8) == 0 { t1 = 0 } 30 if t1 == 1 { pass = pass + 1 } else { fail = fail + 1; tp("C1 FAIL rising trend\n" as *u8) } 31 32 // C2 falling ramp: y = 500 - 2*i -> slope -2000, FALLING 33 let fall: *i64 = sys_mmap(n * 8) as *i64 34 i = 0 35 while i < n { fall[i] = 500 - 2 * i; i = i + 1 } 36 ts_linear_trend(fall, n, sm, ic) 37 tp("falling slope_milli=" as *u8); tn(sm[0]); tp("\n" as *u8) 38 var t2: i64 = 1 39 if sm[0] != (0 - 2000) { t2 = 0 } 40 if ts_trend_class(sm[0], 100) != TS_FALLING { t2 = 0 } 41 if t2 == 1 { pass = pass + 1 } else { fail = fail + 1; tp("C2 FAIL falling trend\n" as *u8) } 42 43 // C3 flat: constant 42 -> slope 0, FLAT 44 let flat: *i64 = sys_mmap(n * 8) as *i64 45 i = 0 46 while i < n { flat[i] = 42; i = i + 1 } 47 ts_linear_trend(flat, n, sm, ic) 48 var t3: i64 = 1 49 if sm[0] != 0 { t3 = 0 } 50 if ts_trend_class(sm[0], 100) != TS_FLAT { t3 = 0 } 51 if tstreq(ts_class_str(TS_FLAT), "flat" as *u8) == 0 { t3 = 0 } 52 if t3 == 1 { pass = pass + 1 } else { fail = fail + 1; tp("C3 FAIL flat trend\n" as *u8) } 53 54 // C4 rolling mean window=3 on [0,3,6,9,...]: out[0]=0, out[1]=(0+3)/2=1, out[2]=(0+3+6)/3=3, out[3]=(3+6+9)/3=6 55 let rm: *i64 = sys_mmap(n * 8) as *i64 56 ts_rolling_mean(rise, n, 3, rm) // rise=100+3i; trailing window smooths but tracks up 57 var t4: i64 = 1 58 // window=3 trailing mean of a linear series lags by ~1 step-mean; verify monotonic increasing + endpoint 59 if rm[0] != rise[0] { t4 = 0 } // first element = itself (window of 1) 60 if rm[n - 1] >= rise[n - 1] { t4 = 0 } // trailing mean of rising series < current value 61 var mono: i64 = 1 62 var k: i64 = 1 63 while k < n { if rm[k] < rm[k - 1] { mono = 0 } k = k + 1 } 64 if mono == 0 { t4 = 0 } 65 // exact check on a simple ramp y=i (window 3): out[3] = (1+2+3)/3 = 2 66 let ramp: *i64 = sys_mmap(n * 8) as *i64 67 i = 0 68 while i < n { ramp[i] = i; i = i + 1 } 69 ts_rolling_mean(ramp, n, 3, rm) 70 if rm[3] != 2 { t4 = 0 } 71 if rm[2] != 1 { t4 = 0 } 72 if t4 == 1 { pass = pass + 1 } else { fail = fail + 1; tp("C4 FAIL rolling mean\n" as *u8) } 73 74 // C5 growth permil: first=100 last=100+3*49=247 -> (247-100)*1000/100 = 1470 permil 75 let g: i64 = ts_growth_permil(rise, n) 76 tp("growth_permil=" as *u8); tn(g); tp("\n" as *u8) 77 var t5: i64 = 1 78 if g != 1470 { t5 = 0 } 79 if ts_growth_permil(fall, n) >= 0 { t5 = 0 } // falling -> negative growth 80 if t5 == 1 { pass = pass + 1 } else { fail = fail + 1; tp("C5 FAIL growth\n" as *u8) } 81 82 // C6 degenerate/empty safety 83 var t6: i64 = 1 84 let one: *i64 = sys_mmap(8) as *i64 85 one[0] = 5 86 if ts_linear_trend(one, 1, sm, ic) != (0 - 1) { t6 = 0 } 87 if ts_growth_permil(one, 1) != 0 { t6 = 0 } 88 if t6 == 1 { pass = pass + 1 } else { fail = fail + 1; tp("C6 FAIL degenerate safety\n" as *u8) } 89 90 tp("pass=" as *u8); tn(pass); tp(" fail=" as *u8); tn(fail); tp("\n" as *u8) 91 let log: *u8 = sys_mmap(128) 92 var lo: i64 = 0 93 let pre: *u8 = "TIMESERIES authored=organ verdict=" as *u8 94 var pi: i64 = 0 95 while pre[pi] != (0 as u8) { log[lo] = pre[pi]; lo = lo + 1; pi = pi + 1 } 96 if fail == 0 { let gg: *u8 = "GREEN\n" as *u8; var gi: i64 = 0; while gg[gi] != (0 as u8) { log[lo] = gg[gi]; lo = lo + 1; gi = gi + 1 } } else { let rr: *u8 = "RED\n" as *u8; var ri: i64 = 0; while rr[ri] != (0 as u8) { log[lo] = rr[ri]; lo = lo + 1; ri = ri + 1 } } 97 let fd: i64 = sys_openat_wr("knowledge/status/timeseries.log" as *u8, 0x1A4) 98 if fd >= 0 { sys_write(fd, log, lo); sys_close(fd) } 99 100 if fail == 0 { tp("=== TIMESERIES-GATE verdict=GREEN ===\n" as *u8); sys_exit(0); return 0 } 101 tp("=== TIMESERIES-GATE verdict=RED ===\n" as *u8) 102 sys_exit(1) 103 return 1 104}