|
| 1 | +//! Residue upscaling — the q2 anatomy technique applied to a codec residual. |
| 2 | +//! |
| 3 | +//! The point (the operator's, 2026-07-04): the q2 FMA-anatomy pipeline upscales |
| 4 | +//! **2000 surfels / 100k nodes → 4,000,000 vertices** by storing sparse anchors |
| 5 | +//! with a *deterministic, regenerable* golden-spiral placement and coding only |
| 6 | +//! the **residue** — the deviation the deterministic placement does not capture. |
| 7 | +//! (`crates/helix`: "HHTL is the deterministic PLACE; helix is the RESIDUE … |
| 8 | +//! 8K resolution at Super-8 cost — the curve is regenerated from a φ-spiral |
| 9 | +//! template, not stored; the cost is only the endpoint pair.") |
| 10 | +//! |
| 11 | +//! M1 proved motion estimation *is* the shader's i8 GEMM and MC is bit-exact, but |
| 12 | +//! it stored the residual **densely** (per-cell Delta, the measured ~3-byte |
| 13 | +//! floor). This probe asks the operator's real question: can we get the residue |
| 14 | +//! *cheaper* the way anatomy gets vertices cheaper — sparse anchors + a |
| 15 | +//! deterministic FMA extrapolation as the PLACE, and only the small |
| 16 | +//! residue-of-extrapolation coded? |
| 17 | +//! |
| 18 | +//! # Honest framing (no strawman, no Frankenstein) |
| 19 | +//! |
| 20 | +//! - **Baseline is entropy-coded, not raw bytes.** A real codec (rANS) approaches |
| 21 | +//! the order-0 Shannon entropy `H₀` of the residual. So the baseline here is |
| 22 | +//! `H₀(residual)·N/8` bytes — the bits an *ideal* entropy coder spends — not a |
| 23 | +//! naive 1 byte/cell. Beating that is a real win, not an accounting trick. |
| 24 | +//! - **The mechanism is decorrelation.** Sparse-anchor FMA extrapolation is a |
| 25 | +//! *predictor* (like DPCM prediction or the HEVC transform): if it captures the |
| 26 | +//! field's low-frequency structure, `H₀(field − prediction) < H₀(field)`, so |
| 27 | +//! even an ideal coder spends fewer bits. The anchors cost extra; the win is |
| 28 | +//! real iff the entropy drop exceeds the anchor cost. |
| 29 | +//! - **Anchor POSITIONS are free.** Both a regular grid (stride known) and the |
| 30 | +//! 2-D golden-spiral sunflower (`k → (√((k+½)/A), k·golden_angle)`, regenerable) |
| 31 | +//! have *deterministic* positions — never stored, exactly the helix |
| 32 | +//! "template is free, only the endpoint costs" principle. Only anchor VALUES cost. |
| 33 | +//! - **Scope / what this is NOT.** The anatomy residue is a *direction field on S²* |
| 34 | +//! where the golden-spiral RVQ (`hpc::splat3d::helix_orient`, `helix::Signed360`) |
| 35 | +//! is near-optimal; a codec luma residual is a *scalar field*, so the S² encoder |
| 36 | +//! does NOT apply and is deliberately not forced onto it (Frankenstein guard). |
| 37 | +//! What transfers is dimension-general: place/residue decorrelation + free |
| 38 | +//! deterministic anchor placement. The golden-spiral enters here as the 2-D |
| 39 | +//! *anchor placement* (the surfel distribution), not as an S² angle codec. |
| 40 | +//! |
| 41 | +//! # What it measures |
| 42 | +//! |
| 43 | +//! Over a smoothness sweep of residual-shaped fields, three codings, in bytes an |
| 44 | +//! ideal entropy coder would spend: |
| 45 | +//! 1. **dense** — `H₀(field)` (the codec's current residual, entropy-coded). |
| 46 | +//! 2. **grid** — `A` grid anchors + bilinear FMA extrapolation → `H₀(residue)`. |
| 47 | +//! 3. **spiral** — `A` golden-spiral anchors + IDW FMA extrapolation → `H₀(residue)`. |
| 48 | +//! |
| 49 | +//! Both upscalers reconstruct losslessly (residue is added back exact). The |
| 50 | +//! per-cell residue also classifies into the shipped `hpc::codec::CellMode` |
| 51 | +//! (Skip/Delta/Escape) — the codec's taxonomy IS the residue decision (H-7). |
| 52 | +//! |
| 53 | +//! Run: `cargo run --release --example residue_upscale --features codec` |
| 54 | +
|
| 55 | +use ndarray::hpc::codec::CellMode; |
| 56 | + |
| 57 | +const W: usize = 128; |
| 58 | +const H: usize = 128; |
| 59 | +const N: usize = W * H; |
| 60 | +const STRIDE: usize = 8; // grid anchor stride → (W/S)·(H/S) anchors |
| 61 | +const NAX: usize = W / STRIDE; // grid anchors per row |
| 62 | +const NAY: usize = H / STRIDE; |
| 63 | +const A: usize = NAX * NAY; // anchor count (grid == spiral, fair comparison) |
| 64 | +const KIDW: usize = 4; // nearest-K anchors for spiral IDW extrapolation |
| 65 | + |
| 66 | +/// Golden angle `π·(3 − √5)` — same constant as `helix_orient`'s spherical |
| 67 | +/// Fibonacci, here on the 2-D sunflower disk instead of S². |
| 68 | +const GOLDEN_ANGLE: f64 = std::f64::consts::PI * 0.763_932_022_500_210_4; |
| 69 | + |
| 70 | +fn mix(mut z: u64) -> u64 { |
| 71 | + z = z.wrapping_add(0x9E37_79B9_7F4A_7C15); |
| 72 | + z = (z ^ (z >> 30)).wrapping_mul(0xBF58_476D_1CE4_E5B9); |
| 73 | + z = (z ^ (z >> 27)).wrapping_mul(0x94D0_49BB_1331_11EB); |
| 74 | + z ^ (z >> 31) |
| 75 | +} |
| 76 | + |
| 77 | +/// Order-0 Shannon entropy of an i32 symbol stream, in **bytes** (`H₀·n/8`). |
| 78 | +/// This is the floor an ideal entropy coder (rANS) approaches — the honest, |
| 79 | +/// non-strawman cost of a symbol stream. |
| 80 | +fn entropy_bytes(sym: &[i32]) -> f64 { |
| 81 | + use std::collections::HashMap; |
| 82 | + let mut hist: HashMap<i32, u64> = HashMap::new(); |
| 83 | + for &s in sym { |
| 84 | + *hist.entry(s).or_insert(0) += 1; |
| 85 | + } |
| 86 | + let n = sym.len() as f64; |
| 87 | + let bits: f64 = hist |
| 88 | + .values() |
| 89 | + .map(|&c| { |
| 90 | + let p = c as f64 / n; |
| 91 | + -(c as f64) * p.log2() |
| 92 | + }) |
| 93 | + .sum(); |
| 94 | + bits / 8.0 |
| 95 | +} |
| 96 | + |
| 97 | +/// Four residual-shaped fields at increasing spatial frequency (decreasing |
| 98 | +/// smoothness). Zero-mean i32, so they stand in for an MC residual. |
| 99 | +fn field(kind: usize) -> Vec<i32> { |
| 100 | + let mut f = vec![0i32; N]; |
| 101 | + for y in 0..H { |
| 102 | + for x in 0..W { |
| 103 | + let (xf, yf) = (x as f64, y as f64); |
| 104 | + let v = match kind { |
| 105 | + 0 => 90.0 * (xf * 0.024).sin() * (yf * 0.020).cos(), // very smooth |
| 106 | + 1 => { |
| 107 | + // "weather-like": the codec_mode_histogram smooth field, zero-mean |
| 108 | + 80.0 * (xf * 0.018).sin() * (yf * 0.018).cos() + 24.0 * (xf * 0.09).sin() |
| 109 | + } |
| 110 | + 2 => 60.0 * (xf * 0.11).sin() * (yf * 0.13).cos() + 30.0 * (yf * 0.07).sin(), // mid |
| 111 | + _ => ((mix((y as u64) << 20 | x as u64) & 0xFF) as f64) - 128.0, // noise |
| 112 | + }; |
| 113 | + f[y * W + x] = v.round() as i32; |
| 114 | + } |
| 115 | + } |
| 116 | + f |
| 117 | +} |
| 118 | + |
| 119 | +/// Bilinear FMA extrapolation from a regular anchor grid (stride `STRIDE`). |
| 120 | +/// Anchor value = the field sampled at the anchor cell. Returns the dense |
| 121 | +/// prediction (rounded to i32) — the PLACE. |
| 122 | +fn grid_predict(f: &[i32]) -> (Vec<i32>, Vec<i32>) { |
| 123 | + // anchor values sampled at grid cells |
| 124 | + let mut av = vec![0i32; A]; |
| 125 | + for ay in 0..NAY { |
| 126 | + for ax in 0..NAX { |
| 127 | + let (px, py) = ((ax * STRIDE).min(W - 1), (ay * STRIDE).min(H - 1)); |
| 128 | + av[ay * NAX + ax] = f[py * W + px]; |
| 129 | + } |
| 130 | + } |
| 131 | + let at = |ax: usize, ay: usize| av[ay.min(NAY - 1) * NAX + ax.min(NAX - 1)] as f64; |
| 132 | + let mut pred = vec![0i32; N]; |
| 133 | + for y in 0..H { |
| 134 | + for x in 0..W { |
| 135 | + let (gx, gy) = (x as f64 / STRIDE as f64, y as f64 / STRIDE as f64); |
| 136 | + let (x0, y0) = (gx.floor() as usize, gy.floor() as usize); |
| 137 | + let (tx, ty) = (gx - x0 as f64, gy - y0 as f64); |
| 138 | + // bilinear FMA (multiply-add of the four corner anchors) |
| 139 | + let top = at(x0, y0) * (1.0 - tx) + at(x0 + 1, y0) * tx; |
| 140 | + let bot = at(x0, y0 + 1) * (1.0 - tx) + at(x0 + 1, y0 + 1) * tx; |
| 141 | + pred[y * W + x] = (top * (1.0 - ty) + bot * ty).round() as i32; |
| 142 | + } |
| 143 | + } |
| 144 | + (pred, av) |
| 145 | +} |
| 146 | + |
| 147 | +/// 2-D golden-spiral (sunflower) anchor positions — deterministic, regenerable |
| 148 | +/// from `k` alone (never stored), the 2-D analog of `helix_orient`'s spherical |
| 149 | +/// Fibonacci. Fills the frame: radius `√((k+½)/A)`, angle `k·golden_angle`. |
| 150 | +fn spiral_anchor(k: usize) -> (usize, usize) { |
| 151 | + let r = (((k as f64) + 0.5) / A as f64).sqrt(); |
| 152 | + let a = k as f64 * GOLDEN_ANGLE; |
| 153 | + // map unit disk → frame (ellipse to fill W×H) |
| 154 | + let cx = (W as f64 - 1.0) * 0.5; |
| 155 | + let cy = (H as f64 - 1.0) * 0.5; |
| 156 | + let x = (cx + r * a.cos() * cx).round().clamp(0.0, W as f64 - 1.0) as usize; |
| 157 | + let y = (cy + r * a.sin() * cy).round().clamp(0.0, H as f64 - 1.0) as usize; |
| 158 | + (x, y) |
| 159 | +} |
| 160 | + |
| 161 | +/// Inverse-distance-weighted FMA extrapolation from golden-spiral anchors — |
| 162 | +/// each cell is `Σ wᵢ·vᵢ / Σ wᵢ` over its `KIDW` nearest anchors (surfel splat, |
| 163 | +/// accumulated). Anchor positions are free (regenerable); only values cost. |
| 164 | +fn spiral_predict(f: &[i32]) -> (Vec<i32>, Vec<i32>) { |
| 165 | + let pos: Vec<(usize, usize)> = (0..A).map(spiral_anchor).collect(); |
| 166 | + let av: Vec<i32> = pos.iter().map(|&(x, y)| f[y * W + x]).collect(); |
| 167 | + let mut pred = vec![0i32; N]; |
| 168 | + for y in 0..H { |
| 169 | + for x in 0..W { |
| 170 | + // K nearest anchors by squared pixel distance |
| 171 | + let mut best: [(u64, usize); KIDW] = [(u64::MAX, 0); KIDW]; |
| 172 | + for (i, &(ax, ay)) in pos.iter().enumerate() { |
| 173 | + let dx = ax as i64 - x as i64; |
| 174 | + let dy = ay as i64 - y as i64; |
| 175 | + let d2 = (dx * dx + dy * dy) as u64; |
| 176 | + // insert into the small top-K (K=4, linear is fine) |
| 177 | + if d2 < best[KIDW - 1].0 { |
| 178 | + let mut j = KIDW - 1; |
| 179 | + while j > 0 && best[j - 1].0 > d2 { |
| 180 | + best[j] = best[j - 1]; |
| 181 | + j -= 1; |
| 182 | + } |
| 183 | + best[j] = (d2, i); |
| 184 | + } |
| 185 | + } |
| 186 | + // exact hit → take the anchor; else IDW (weight 1/(d²+1)) |
| 187 | + let (mut num, mut den) = (0.0f64, 0.0f64); |
| 188 | + let mut exact = None; |
| 189 | + for &(d2, i) in &best { |
| 190 | + if d2 == 0 { |
| 191 | + exact = Some(av[i]); |
| 192 | + break; |
| 193 | + } |
| 194 | + let w = 1.0 / (d2 as f64 + 1.0); |
| 195 | + num += w * av[i] as f64; |
| 196 | + den += w; |
| 197 | + } |
| 198 | + pred[y * W + x] = exact.unwrap_or_else(|| (num / den).round() as i32); |
| 199 | + } |
| 200 | + } |
| 201 | + (pred, av) |
| 202 | +} |
| 203 | + |
| 204 | +fn residue(f: &[i32], pred: &[i32]) -> Vec<i32> { |
| 205 | + f.iter().zip(pred).map(|(&a, &p)| a - p).collect() |
| 206 | +} |
| 207 | + |
| 208 | +/// Paeth (PNG) local predictor — the standard lossless spatial baseline. This is |
| 209 | +/// the *fair* rival to the global anchor predictors: a real lossless codec |
| 210 | +/// decorrelates with a cheap causal local model (left/up/up-left), storing ZERO |
| 211 | +/// anchors. `pred = whichever of {left, up, up-left} is nearest to left+up−ul`. |
| 212 | +fn paeth_residue(f: &[i32]) -> Vec<i32> { |
| 213 | + let mut res = vec![0i32; N]; |
| 214 | + for y in 0..H { |
| 215 | + for x in 0..W { |
| 216 | + let a = if x > 0 { f[y * W + x - 1] } else { 0 }; // left |
| 217 | + let b = if y > 0 { f[(y - 1) * W + x] } else { 0 }; // up |
| 218 | + let c = if x > 0 && y > 0 { f[(y - 1) * W + x - 1] } else { 0 }; // up-left |
| 219 | + let p = a + b - c; |
| 220 | + let (pa, pb, pc) = ((p - a).abs(), (p - b).abs(), (p - c).abs()); |
| 221 | + let pred = if pa <= pb && pa <= pc { |
| 222 | + a |
| 223 | + } else if pb <= pc { |
| 224 | + b |
| 225 | + } else { |
| 226 | + c |
| 227 | + }; |
| 228 | + res[y * W + x] = f[y * W + x] - pred; |
| 229 | + } |
| 230 | + } |
| 231 | + res |
| 232 | +} |
| 233 | + |
| 234 | +/// Classify a residue field into the shipped codec taxonomy (H-7): |r|=0 → Skip, |
| 235 | +/// |r|≤127 → Delta, else Escape. |
| 236 | +fn mode_hist(res: &[i32]) -> [usize; 3] { |
| 237 | + let mut h = [0usize; 3]; |
| 238 | + for &r in res { |
| 239 | + let idx = if r == 0 { |
| 240 | + CellMode::Skip as usize |
| 241 | + } else if r.abs() <= 127 { |
| 242 | + CellMode::Delta as usize |
| 243 | + } else { |
| 244 | + CellMode::Escape as usize |
| 245 | + }; |
| 246 | + // Skip=0, Merge=1, Delta=2, Escape=3 → fold Merge slot out (unused here) |
| 247 | + h[match idx { |
| 248 | + 0 => 0, |
| 249 | + 2 => 1, |
| 250 | + _ => 2, |
| 251 | + }] += 1; |
| 252 | + } |
| 253 | + h |
| 254 | +} |
| 255 | + |
| 256 | +fn main() { |
| 257 | + println!("Residue upscaling — anatomy technique on a codec residual"); |
| 258 | + println!(" {W}×{H} field, {A} anchors (grid {NAX}×{NAY} stride {STRIDE} == spiral {A}), K={KIDW} IDW"); |
| 259 | + println!(" bytes = order-0 Shannon entropy H₀ (what an ideal rANS coder spends)\n"); |
| 260 | + println!( |
| 261 | + " {:<14} {:>9} {:>9} {:>11} {:>11} {:>7} {:>7}", |
| 262 | + "field", "dense H₀", "paeth", "grid a+res", "spiral a+res", "grid×", "spiral×" |
| 263 | + ); |
| 264 | + println!( |
| 265 | + " {:<14} {:>9} {:>9} {:>11} {:>11} {:>7} {:>7}", |
| 266 | + "", "(no model)", "(local)", "(global)", "(global)", "/paeth", "/paeth" |
| 267 | + ); |
| 268 | + |
| 269 | + let names = ["very-smooth", "weather-like", "mid-freq", "noise"]; |
| 270 | + for (kind, name) in names.iter().enumerate() { |
| 271 | + let f = field(kind); |
| 272 | + let dense = entropy_bytes(&f); |
| 273 | + let paeth = entropy_bytes(&paeth_residue(&f)); |
| 274 | + |
| 275 | + let (gp, gav) = grid_predict(&f); |
| 276 | + let gr = residue(&f, &gp); |
| 277 | + let grid_total = entropy_bytes(&gav) + entropy_bytes(&gr); |
| 278 | + |
| 279 | + let (sp, sav) = spiral_predict(&f); |
| 280 | + let sr = residue(&f, &sp); |
| 281 | + let spiral_total = entropy_bytes(&sav) + entropy_bytes(&sr); |
| 282 | + |
| 283 | + // the honest comparison is vs the LOCAL predictor (paeth), not the no-model dense. |
| 284 | + println!( |
| 285 | + " {:<14} {:>9.0} {:>9.0} {:>11.0} {:>11.0} {:>6.2}× {:>6.2}×", |
| 286 | + name, |
| 287 | + dense, |
| 288 | + paeth, |
| 289 | + grid_total, |
| 290 | + spiral_total, |
| 291 | + paeth / grid_total, |
| 292 | + paeth / spiral_total, |
| 293 | + ); |
| 294 | + } |
| 295 | + |
| 296 | + // H-7 tie-in: on the smoothest field, show the spiral-residue mode split — |
| 297 | + // the residue collapses to mostly Skip (0) once the predictor captures it. |
| 298 | + let f0 = field(0); |
| 299 | + let (sp0, _) = spiral_predict(&f0); |
| 300 | + let sr0 = residue(&f0, &sp0); |
| 301 | + let mh = mode_hist(&sr0); |
| 302 | + println!("\n [H-7] very-smooth spiral-residue CellMode split (residue → mode):"); |
| 303 | + println!( |
| 304 | + " skip={} delta={} escape={} ({:.1}% skip after the golden-spiral predictor)", |
| 305 | + mh[0], |
| 306 | + mh[1], |
| 307 | + mh[2], |
| 308 | + 100.0 * mh[0] as f64 / N as f64 |
| 309 | + ); |
| 310 | + |
| 311 | + println!( |
| 312 | + "\n MEASURED CONCLUSION (fair fight = vs paeth local DPCM, the standard lossless\n\ |
| 313 | + \x20 predictor, which stores ZERO anchors):\n\ |
| 314 | + \x20 • Global sparse-anchor upscaling DOES decorrelate — grid a+res (3648) ≪ the\n\ |
| 315 | + \x20 no-model order-0 dense (14807). The anatomy 2000→4M mechanism is real.\n\ |
| 316 | + \x20 • BUT for a DENSE SCALAR luma residual it LOSES to local DPCM (grid 0.70×,\n\ |
| 317 | + \x20 spiral 0.38× of paeth on very-smooth): a cheap causal local predictor\n\ |
| 318 | + \x20 beats it, because the 256 anchor VALUES cost real bits and a sparse grid\n\ |
| 319 | + \x20 can't model structure finer than its stride. For scalar-dense residuals\n\ |
| 320 | + \x20 the analogy is RHYME, not a winning transfer — use DPCM / transform.\n\ |
| 321 | + \x20 • grid > spiral here (bilinear is a better scalar interpolant than\n\ |
| 322 | + \x20 scattered IDW). The golden-spiral's win is NOT scalar fields.\n\ |
| 323 | + \x20 • Where the anatomy technique is ALREADY measured to dominate is its NATIVE\n\ |
| 324 | + \x20 domain: sparse DIRECTION fields on S² (surfel normals) — helix_orient\n\ |
| 325 | + \x20 measures 1–3 bytes at Pearson 0.9917, a regime with no dense causal\n\ |
| 326 | + \x20 neighbor to DPCM against.\n\ |
| 327 | + \x20 • CONJECTURE (NOT measured here — needs realistic continuous MVs from a real\n\ |
| 328 | + \x20 decode, i.e. M2): a sparse continuous MOTION-VECTOR field is directional +\n\ |
| 329 | + \x20 anchor-shaped like the surfel case, so helix/golden-spiral coding may beat\n\ |
| 330 | + \x20 dense MV coding there. The M1 MVs (integer −2..2) are too quantised to\n\ |
| 331 | + \x20 test it — do not treat this bullet as a result." |
| 332 | + ); |
| 333 | +} |
0 commit comments