code wiki / (root) / nx_lbp_cluster.nx

nx_lbp_cluster.nx source

↩ module page · 58 lines · 2982 B

1// nx_lbp_cluster.nx -- SOVEREIGN face-descriptor RUNG 4 GATE: greedy chi-square clustering of descriptors 2// into person groups (cluster_greedy in nx_lbp_core.nx). Pure NishiLang, no benchmark. KAT on synthetic 3// descriptors with 3 clearly-separated groups -> exactly 3 clusters with correct membership; plus threshold 4// neg-controls (huge thresh -> 1 cluster, zero thresh -> every item its own). This is the engine that will 5// turn the corpus descriptor store into galx_face_index (cid->person). Build/run: 6// ./_offc/nx_sov_build_run.elf nx_lbp_cluster license_tier: ORIGINAL 7import "nx_syscalls.nx" 8import "nx_lbp_core.nx" 9const K_MAGIC_50000: i64 = 50000 10const K_MAGIC_1000000000: i64 = 1000000000 11 12func setrow(buf: *i64, i: i64, d: i64, b0: i64, b1: i64, b2: i64, b3: i64) -> i64 { 13 buf[i*d+0]=b0; buf[i*d+1]=b1; buf[i*d+2]=b2; buf[i*d+3]=b3; return 0 14} 15 16func main() -> i64 { 17 var fail: i64 = 0 18 let D: i64 = 4 19 let M: i64 = 6 20 let buf: *i64 = sys_mmap(8*M*D) as *i64 21 // group A (mass bin0): A1,A2 ; group B (mass bin2): B1,B2 ; group C (mass bin1): C1,C2 22 setrow(buf, 0, D, 100, 0, 0, 0) // A1 23 setrow(buf, 1, D, 90, 10, 0, 0) // A2 (near A1) 24 setrow(buf, 2, D, 0, 0, 100, 0) // B1 25 setrow(buf, 3, D, 0, 0, 90, 10) // B2 (near B1) 26 setrow(buf, 4, D, 0, 100, 0, 0) // C1 27 setrow(buf, 5, D, 10, 90, 0, 0) // C2 (near C1) 28 29 let assign: *i64 = sys_mmap(8*M) as *i64 30 let reps: *i64 = sys_mmap(8*M) as *i64 31 32 // within-group chi2 ~10526, across-group ~>120000 -> thresh 50000 separates cleanly 33 let nc: i64 = cluster_greedy(buf, M, D, K_MAGIC_50000, 1000, assign, reps) 34 lp("clusters="); ln(nc); lp(" assign=[") 35 var i: i64=0; while i<M { ln(assign[i]); if i<M-1 { lp(" " as *u8) } i=i+1 } lp("] expect 3 [0 0 1 1 2 2] -> ") 36 var ok: i64 = 1 37 if nc != 3 { ok = 0 } 38 if assign[0] != assign[1] { ok = 0 } 39 if assign[2] != assign[3] { ok = 0 } 40 if assign[4] != assign[5] { ok = 0 } 41 if assign[0] == assign[2] { ok = 0 } 42 if assign[0] == assign[4] { ok = 0 } 43 if assign[2] == assign[4] { ok = 0 } 44 if ok == 1 { lp("PASS\n" as *u8) } else { lp("FAIL\n" as *u8); fail = 1 } 45 46 // neg-control 1: huge threshold -> everything merges into 1 cluster 47 let nc1: i64 = cluster_greedy(buf, M, D, K_MAGIC_1000000000, 1000, assign, reps) 48 lp("thresh=BIG clusters="); ln(nc1); lp(" expect 1 -> ") 49 if nc1 == 1 { lp("PASS\n" as *u8) } else { lp("FAIL\n" as *u8); fail = 1 } 50 51 // neg-control 2: zero threshold -> nothing merges, M clusters 52 let nc2: i64 = cluster_greedy(buf, M, D, 0, 1000, assign, reps) 53 lp("thresh=0 clusters="); ln(nc2); lp(" expect 6 -> ") 54 if nc2 == M { lp("PASS\n" as *u8) } else { lp("FAIL\n" as *u8); fail = 1 } 55 56 if fail == 0 { lp("nx_lbp_cluster RUNG4 GREEN (3 groups -> 3 clusters; threshold controls granularity)\n" as *u8); sys_exit(0); return 0 } 57 lp("nx_lbp_cluster RUNG4 RED\n" as *u8); sys_exit(1); return 1 58}