code wiki / (root) / sketch_correlation_test.nx

sketch_correlation_test.nx source

↩ module page · 158 lines · 4838 B

1// sketch_correlation_test.nx -- streaming Pearson + regression verification. 2 3import "syscalls.nx" 4import "sketch_correlation.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 c: *Correlation = nx_corr_alloc() 15 if c == (0 as *Correlation) { return __syscall(93, 5, 0, 0, 0, 0, 0) } 16 if c.n != 0 { return __syscall(93, 6, 0, 0, 0, 0, 0) } 17 // Single point -> n<2 -> returns 0. 18 nx_corr_add(c, 5, 10) 19 if nx_corr_r_ppm(c) != 0 { 20 return __syscall(93, 10, 0, 0, 0, 0, 0) 21 } 22 23 // ---- perfect positive correlation: r = +1.0 ---- 24 // y = 2x for x in 1..20. r should be exactly 1.0 (PPM = 1_000_000). 25 let c1: *Correlation = nx_corr_alloc() 26 var i: i64 = 1 27 while i <= 20 { 28 nx_corr_add(c1, i, 2 * i) 29 i = i + 1 30 } 31 let r1: i64 = nx_corr_r_ppm(c1) 32 if iabs(r1 - 1000000) > 10000 { 33 return __syscall(93, 20, 0, 0, 0, 0, 0) 34 } 35 // Slope should be 2.0 (PPM = 2_000_000). 36 let s1: i64 = nx_corr_slope_ppm(c1) 37 if iabs(s1 - 2000000) > 10000 { 38 return __syscall(93, 21, 0, 0, 0, 0, 0) 39 } 40 // Intercept should be 0. 41 let b1: i64 = nx_corr_intercept(c1) 42 if iabs(b1) > 2 { 43 return __syscall(93, 22, 0, 0, 0, 0, 0) 44 } 45 46 // ---- perfect negative correlation: r = -1.0 ---- 47 let c2: *Correlation = nx_corr_alloc() 48 i = 1 49 while i <= 20 { 50 nx_corr_add(c2, i, 100 - i) 51 i = i + 1 52 } 53 let r2: i64 = nx_corr_r_ppm(c2) 54 if iabs(r2 - (-1000000)) > 10000 { 55 return __syscall(93, 30, 0, 0, 0, 0, 0) 56 } 57 let s2: i64 = nx_corr_slope_ppm(c2) 58 // slope = -1.0 (PPM = -1_000_000). 59 if iabs(s2 - (-1000000)) > 10000 { 60 return __syscall(93, 31, 0, 0, 0, 0, 0) 61 } 62 // intercept = 100. 63 let b2: i64 = nx_corr_intercept(c2) 64 if iabs(b2 - 100) > 2 { 65 return __syscall(93, 32, 0, 0, 0, 0, 0) 66 } 67 68 // ---- zero correlation (degenerate symmetric x) ---- 69 // For y = x², the correlation r is positive but slope is approximately 70 // mean(x). Skip this exact test -- variance and mean both nonzero. 71 // Instead test: constant y, varying x -> r=0, slope=0. 72 let c3: *Correlation = nx_corr_alloc() 73 i = 1 74 while i <= 20 { 75 nx_corr_add(c3, i, 50) // y constant 76 i = i + 1 77 } 78 // var_y = 0 -> r = 0 (by guard). slope = 0 (cov_xy = 0). 79 if nx_corr_r_ppm(c3) != 0 { 80 return __syscall(93, 40, 0, 0, 0, 0, 0) 81 } 82 if nx_corr_slope_ppm(c3) != 0 { 83 return __syscall(93, 41, 0, 0, 0, 0, 0) 84 } 85 86 // ---- linear with offset: y = 3x + 5 ---- 87 let c4: *Correlation = nx_corr_alloc() 88 i = 1 89 while i <= 20 { 90 nx_corr_add(c4, i, 3 * i + 5) 91 i = i + 1 92 } 93 // slope=3 (PPM=3_000_000), intercept=5, r=1.0. 94 let r4: i64 = nx_corr_r_ppm(c4) 95 if iabs(r4 - 1000000) > 10000 { 96 return __syscall(93, 50, 0, 0, 0, 0, 0) 97 } 98 let s4: i64 = nx_corr_slope_ppm(c4) 99 if iabs(s4 - 3000000) > 10000 { 100 return __syscall(93, 51, 0, 0, 0, 0, 0) 101 } 102 let b4: i64 = nx_corr_intercept(c4) 103 if iabs(b4 - 5) > 2 { 104 return __syscall(93, 52, 0, 0, 0, 0, 0) 105 } 106 107 // ---- typed envelope ---- 108 let q: *ApproxI64 = nx_corr_query_r(c1) 109 if q.envelope_kind != NX_ENV_ABS { 110 return __syscall(93, 60, 0, 0, 0, 0, 0) 111 } 112 if q.maturity != NX_MATURITY_PRODUCTION { 113 return __syscall(93, 61, 0, 0, 0, 0, 0) 114 } 115 116 // ---- overflow guard ---- 117 if nx_corr_safe_p(32768, 0) != 0 { 118 return __syscall(93, 70, 0, 0, 0, 0, 0) 119 } 120 if nx_corr_safe_p(0, 32768) != 0 { 121 return __syscall(93, 71, 0, 0, 0, 0, 0) 122 } 123 if nx_corr_safe_p(1000, 1000) != 1 { 124 return __syscall(93, 72, 0, 0, 0, 0, 0) 125 } 126 let co: *Correlation = nx_corr_alloc() 127 if nx_corr_add(co, 32768, 0) != -1 { 128 return __syscall(93, 73, 0, 0, 0, 0, 0) 129 } 130 if co.n != 0 { 131 return __syscall(93, 74, 0, 0, 0, 0, 0) 132 } 133 134 // ---- merge ---- 135 let m_a: *Correlation = nx_corr_alloc() 136 let m_b: *Correlation = nx_corr_alloc() 137 i = 1 138 while i <= 10 { 139 nx_corr_add(m_a, i, 2 * i) 140 i = i + 1 141 } 142 i = 11 143 while i <= 20 { 144 nx_corr_add(m_b, i, 2 * i) 145 i = i + 1 146 } 147 let merged: *Correlation = nx_corr_merge(m_a, m_b) 148 if nx_corr_count(merged) != 20 { 149 return __syscall(93, 80, 0, 0, 0, 0, 0) 150 } 151 // Merged is equivalent to c1 (same data). r=1.0, slope=2.0. 152 let r_m: i64 = nx_corr_r_ppm(merged) 153 if iabs(r_m - 1000000) > 10000 { 154 return __syscall(93, 81, 0, 0, 0, 0, 0) 155 } 156 157 return 0 158}