code wiki / _hdl_build / nx_dataframe_approx.nx

nx_dataframe_approx.nx source

↩ module page · 65 lines · 2686 B

1// nx_dataframe_approx.nx -- LIB: wire the DORMANT sketch primitives behind the aggregation front door 2// (nx_dataframe). The 07-10 audit found nx_sketch_hll (HLL++) and nx_sketch_tdigest (Dunning) genuinely 3// real but ORPHANED -- and their accuracy claims UNMEASURED (headers: ReferenceImpl / NOT_YET_EVALUATED). 4// This lib gives the store-facing calls (approx distinct + approx quantile AT SCALE) and its gate MEASURES 5// estimate error against exact ground truth computed independently -- killing the unmeasured-claim debt. 6// license_tier: ORIGINAL 7import "nx_syscalls.nx" 8import "_hdl_build/nx_dataframe.nx" 9import "nx_sketch_hll.nx" 10import "nx_sketch_tdigest.nx" 11 12// approx COUNT DISTINCT of an i64 column via HLL++ (lg_k=12 -> ~1.6 percent rel stddev, 4KB registers). 13func dfa_distinct(col: *i64, n: i64, lg_k: i64) -> i64 { 14 let h: *Hll = nx_hll_alloc(lg_k, 2654435769) 15 if (h as i64) == 0 { return 0 - 1 } 16 let kb: *u8 = sys_mmap(8) 17 var i: i64 = 0 18 while i < n { 19 let v: i64 = col[i] 20 kb[0] = (v & 0xff) as u8 21 kb[1] = ((v >> 8) & 0xff) as u8 22 kb[2] = ((v >> 16) & 0xff) as u8 23 kb[3] = ((v >> 24) & 0xff) as u8 24 kb[4] = ((v >> 32) & 0xff) as u8 25 kb[5] = ((v >> 40) & 0xff) as u8 26 kb[6] = ((v >> 48) & 0xff) as u8 27 kb[7] = ((v >> 56) & 0xff) as u8 28 nx_hll_add(h, kb, 8) 29 i = i + 1 30 } 31 return nx_hll_estimate(h) 32} 33 34// EXACT distinct (first-seen scan) -- the independent ground truth the gate measures the sketch against. 35// O(n * d); fine at gate scale, and honest: no assumed cardinality, it is COUNTED. 36func dfa_distinct_exact(col: *i64, n: i64, scratch: *i64, max_d: i64) -> i64 { 37 var d: i64 = 0 38 var i: i64 = 0 39 while i < n { 40 let v: i64 = col[i] 41 var seen: i64 = 0 42 var j: i64 = 0 43 while j < d { if scratch[j] == v { seen = 1; j = d } else { j = j + 1 } } 44 if seen == 0 { if d < max_d { scratch[d] = v; d = d + 1 } } 45 i = i + 1 46 } 47 return d 48} 49 50// approx QUANTILE via t-digest (q_permil 0..1000, same scale as df_quantile). delta = compression (100 typical). 51func dfa_quantile(col: *i64, n: i64, q_permil: i64, delta: i64) -> i64 { 52 let td: *TDigest = nx_tdigest_alloc(delta) 53 if (td as i64) == 0 { return 0 - 1 } 54 var i: i64 = 0 55 while i < n { nx_tdigest_add(td, col[i]); i = i + 1 } 56 return nx_tdigest_quantile(td, q_permil) 57} 58 59// relative error in PERMIL between estimate and exact (|est-exact|*1000/exact); exact<=0 -> -1. 60func dfa_err_permil(est: i64, exact: i64) -> i64 { 61 if exact <= 0 { return 0 - 1 } 62 var d: i64 = est - exact 63 if d < 0 { d = 0 - d } 64 return (d * 1000) / exact 65}