code wiki / (root) / sketch_ucb1.nx

sketch_ucb1.nx

buildroot/runtime/sketch_ucb1.nx

6981 B215 linesdepth 4pulls 6 transitivereach 2 importersview sourcekind sketch/demotopic sketch
docsdependenciesstructsconstsfunctions

about

sketch_ucb1.nx -- UCB1 multi-armed bandit (Auer-Cesa-Bianchi-Fischer 2002). Online-learning primitive. Given N "arms" (actions), select the best one over time while balancing EXPLORATION (try arms we haven't pulled) and EXPLOITATION (favor arms with high observed reward). UCB1 selection rule: score_i = mean_i + sqrt(2 * ln(N_total) / count_i) pull arg max score_i Where: mean_i = sum_reward_i / count_i (estimated value) sqrt(...) = exploration bonus (shrinks as count_i grows) Arms with count_i = 0 have score = +inf (must-pull first). PROVEN PROPERTIES (Auer 2002): regret bound: O(sqrt(K * N * ln(N))) where K = #arms, N = total pulls. Near-optimal for adversarial problems; optimal up to log factor for stochastic. USE CASES (extends NishiLang substrate beyond DataSketches scope): - A/B testing with multi-arm allocation (Bayesian alternative) - Recommendation with cold-start exploration - Hyperparameter tuning under budget constraints - Game AI move selection INTEGER-FIXED-POINT IMPLEMENTATION: - rewards scaled to PPM (0..1_000_000 = [0, 1.0]) - mean_i = sum_reward_ppm / count_i - ln(N) ≈ (bitlen(N) - 1) * 693147 / 1000 ppm (factor of ln(2)) - sqrt() via isqrt (Newton) - score_i in PPM LOSSLESS-LANGUAGE DISCIPLINE: nx_ucb_query returns ApproxI64 with NX_ENV_REL_STDDEV = 1/sqrt(count_i). Bandits are stochastic by nature; the envelope honestly declares estimation uncertainty.

dependencies 3 imports · 2 importers

syscalls.nx sketch_types.nx nx_vecmath.nx sketch_ucb1.nx sketch_thompson_vs_ucb1_bench.nx sketch_ucb1_test.nx

imports: syscalls.nxsketch_types.nxnx_vecmath.nx

imported by: sketch_thompson_vs_ucb1_bench.nxsketch_ucb1_test.nx

structs

49struct Ucb1 {

consts

44const NX_UCB_ARMS_MIN: i64 = 2
45const NX_UCB_ARMS_MAX: i64 = 10000
46const NX_UCB_LN2_PPM: i64 = 693147 // ln(2) * 1_000_000
47const NX_UCB_REWARD_MAX: i64 = 1000000 // 1.0 in PPM

functions

58func nx_ucb_alloc(n_arms: i64) -> *Ucb1 {
80func nx_ucb_isqrt(x: i64) -> i64 { return vm_isqrt(x) }
88func nx_ucb_bitlen(x: i64) -> i64 {
100func nx_ucb_ln_ppm(n: i64) -> i64 {
119func nx_ucb_score(b: *Ucb1, arm: i64) -> i64 {
136func nx_ucb_select(b: *Ucb1) -> i64 {
156func nx_ucb_update(b: *Ucb1, arm: i64, reward_ppm: i64) -> i64 {
169func nx_ucb_mean_ppm(b: *Ucb1, arm: i64) -> i64 {
175func nx_ucb_count(b: *Ucb1, arm: i64) -> i64 {
180func nx_ucb_best_arm(b: *Ucb1) -> i64 {
199func nx_ucb_query(b: *Ucb1, arm: i64) -> *ApproxI64 {
213func nx_ucb_memory_bytes(b: *Ucb1) -> i64 {