code wiki / (root) / sketch_moments_test.nx

sketch_moments_test.nx source

↩ module page · 124 lines · 3762 B

1// sketch_moments_test.nx -- streaming skewness + kurtosis verification. 2 3import "syscalls.nx" 4import "sketch_moments.nx" 5import "sketch_types.nx" 6 7func iabs(x: i64) -> i64 { 8 if x < 0 { return -x } 9 return x 10} 11 12func main() -> i64 { 13 // ---- alloc + empty ---- 14 let m: *Moments = nx_mom_alloc() 15 if m == (0 as *Moments) { return __syscall(93, 5, 0, 0, 0, 0, 0) } 16 if m.count != 0 { return __syscall(93, 6, 0, 0, 0, 0, 0) } 17 if nx_mom_skewness_ppm(m) != 0 { return __syscall(93, 7, 0, 0, 0, 0, 0) } 18 if nx_mom_kurtosis_ppm(m) != 0 { return __syscall(93, 8, 0, 0, 0, 0, 0) } 19 20 // ---- symmetric data: skewness near 0 ---- 21 // [-3, -1, 1, 3]: mean=0, symmetric -> skewness exactly 0. 22 nx_mom_add(m, -3) 23 nx_mom_add(m, -1) 24 nx_mom_add(m, 1) 25 nx_mom_add(m, 3) 26 if nx_mom_mean(m) != 0 { return __syscall(93, 10, 0, 0, 0, 0, 0) } 27 // variance = (9+1+1+9)/4 = 5. 28 if nx_mom_variance(m) != 5 { 29 return __syscall(93, 11, 0, 0, 0, 0, 0) 30 } 31 // Symmetric -> skewness = 0. 32 if iabs(nx_mom_skewness_ppm(m)) > 100000 { // < 10% in ppm 33 return __syscall(93, 12, 0, 0, 0, 0, 0) 34 } 35 36 // ---- positive skew: right tail dominates ---- 37 // [1, 1, 1, 1, 1, 100]: mostly low, one big. Skewness > 0. 38 let m2: *Moments = nx_mom_alloc() 39 nx_mom_add(m2, 1) 40 nx_mom_add(m2, 1) 41 nx_mom_add(m2, 1) 42 nx_mom_add(m2, 1) 43 nx_mom_add(m2, 1) 44 nx_mom_add(m2, 100) 45 let s: i64 = nx_mom_skewness_ppm(m2) 46 if s <= 0 { 47 return __syscall(93, 20, 0, 0, 0, 0, 0) 48 } 49 // Should be significantly positive. 50 if s < 1000000 { // > 1.0 expected for this skewed sample 51 return __syscall(93, 21, 0, 0, 0, 0, 0) 52 } 53 54 // ---- negative skew ---- 55 let m3: *Moments = nx_mom_alloc() 56 nx_mom_add(m3, 100) 57 nx_mom_add(m3, 100) 58 nx_mom_add(m3, 100) 59 nx_mom_add(m3, 100) 60 nx_mom_add(m3, 100) 61 nx_mom_add(m3, 1) 62 let s3: i64 = nx_mom_skewness_ppm(m3) 63 if s3 >= 0 { 64 return __syscall(93, 30, 0, 0, 0, 0, 0) 65 } 66 if s3 > -1000000 { 67 return __syscall(93, 31, 0, 0, 0, 0, 0) 68 } 69 70 // ---- merge ---- 71 let ma: *Moments = nx_mom_alloc() 72 let mb: *Moments = nx_mom_alloc() 73 var i: i64 = 0 74 while i < 50 { 75 nx_mom_add(ma, i + 1) 76 i = i + 1 77 } 78 i = 51 79 while i <= 100 { 80 nx_mom_add(mb, i) 81 i = i + 1 82 } 83 let merged: *Moments = nx_mom_merge(ma, mb) 84 if merged.count != 100 { 85 return __syscall(93, 40, 0, 0, 0, 0, 0) 86 } 87 // Mean of 1..100 = 50.5 -> integer 50. 88 if iabs(nx_mom_mean(merged) - 50) > 1 { 89 return __syscall(93, 41, 0, 0, 0, 0, 0) 90 } 91 92 // ---- overflow guard ---- 93 if nx_mom_safe_p(2048) != 0 { 94 return __syscall(93, 50, 0, 0, 0, 0, 0) 95 } 96 if nx_mom_safe_p(2000) != 1 { 97 return __syscall(93, 51, 0, 0, 0, 0, 0) 98 } 99 if nx_mom_safe_p(-2048) != 0 { 100 return __syscall(93, 52, 0, 0, 0, 0, 0) 101 } 102 let mo: *Moments = nx_mom_alloc() 103 if nx_mom_add(mo, 2048) != -1 { 104 return __syscall(93, 53, 0, 0, 0, 0, 0) 105 } 106 if mo.count != 0 { // failed add must not mutate 107 return __syscall(93, 54, 0, 0, 0, 0, 0) 108 } 109 110 // ---- typed envelope ---- 111 let q: *ApproxI64 = nx_mom_query_skewness(merged) 112 if q.envelope_kind != NX_ENV_REL_STDDEV { 113 return __syscall(93, 60, 0, 0, 0, 0, 0) 114 } 115 // n=100 -> stderr_ppb = 1e9 / 10 = 1e8. 116 if q.param_a != 100000000 { 117 return __syscall(93, 61, 0, 0, 0, 0, 0) 118 } 119 if q.maturity != NX_MATURITY_REFERENCE_IMPL { 120 return __syscall(93, 62, 0, 0, 0, 0, 0) 121 } 122 123 return 0 124}