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}