Skip to content

Commit 23f7b2f

Browse files
committed
examples: motion = bit shift × transform no-op × shaping — measured
The operator's factorization of M1: motion compensation in this substrate is bit shift (integer motion = addressing, zero arithmetic — the deterministic PLACE / VPGATHERDD) × transform no-op (the DCT a real codec puts after MC collapses to identity when prediction is good) × shaping (the residue applied directly as a shape, not transform-coded). M1 already IS this: recon = shifted_ref + residual, no transform, and 62.5% of blocks had residual == 0 (transform fully absent). This probe MEASURES the factorization as a tradeoff curve. All three codings are orthonormal (equal PSNR at a fixed quant step Q); bytes = order-0 Shannon entropy (ideal rANS). Residual lag-1 autocorrelation ρ is the motion-quality proxy (good motion → white residual → ρ→0), because a transform cannot compress white noise. Measured (128x128, 8x8 blocks, Q=6): residual ρ(meas) direct wht dct dct/dir wht/dct ρ≈0.00 -0.001 9135 9579 9581 0.95x 1.00x ρ≈0.30 0.053 8386 8609 8608 0.97x 1.00x ρ≈0.60 0.419 7664 7147 7146 1.07x 1.00x ρ≈0.90 0.961 7641 3846 3754 2.04x 1.02x Both falsifiable claims hold: 1. transform no-op grows with motion quality — dct/dir → 1 (even below, 0.95x) as the residual whitens; the transform is a literal no-op in the good-motion regime and only earns its keep (2.04x) on structured residuals (poor motion), the regime good bit-shift avoids. The transform's value is inversely coupled to motion quality. 2. a multiply-free sign transform suffices — wht/dct ≈ 1.00–1.02x across the whole sweep. The ±1 add/subtract Walsh–Hadamard transform (the shader's "zero FP, zero matmul" idiom) matches the full multiply DCT within 2%, even where the transform matters most. The substrate never needs a DCT. So motion = bit shift (free) × transform no-op (WHT, vanishing as motion improves) × shaping (direct residue) — one tradeoff curve, not three stages. Ties to H-7 via the residue CellMode histogram. fmt + clippy clean, gated. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MLBnPuScZy6w9di2QEjsXM
1 parent 55cb21b commit 23f7b2f

2 files changed

Lines changed: 315 additions & 0 deletions

File tree

Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,10 @@ required-features = ["codec"]
8787
name = "mc_via_shader"
8888
required-features = ["codec"]
8989

90+
[[example]]
91+
name = "motion_transform_noop"
92+
required-features = ["codec"]
93+
9094
[[example]]
9195
name = "entropy_ladder_probe"
9296
required-features = ["std"]

examples/motion_transform_noop.rs

Lines changed: 311 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,311 @@
1+
//! Motion = bit shift × transform no-op × shaping — the measured factorization.
2+
//!
3+
//! The operator's reframe (2026-07-04): motion compensation in this substrate
4+
//! factors as **bit shift** (integer motion = addressing, zero arithmetic — the
5+
//! deterministic PLACE / `VPGATHERDD`) × **transform no-op** (the DCT stage a
6+
//! real codec puts after MC collapses to identity when prediction is good) ×
7+
//! **shaping** (the residue applied directly, coded as a shape — not
8+
//! transform-coded). M1 already IS this: `recon = shifted_ref + residual`, no
9+
//! transform; and M1 measured 62.5% of blocks with residual == 0 (transform
10+
//! fully absent — pure bit shift).
11+
//!
12+
//! The factorization is a **tradeoff curve, not three stages**: better bit-shift
13+
//! ⇒ whiter residual ⇒ the transform has less to compact ⇒ shaping is trivial.
14+
//! This probe MEASURES that curve, because a transform CANNOT compress white
15+
//! noise (its coding gain → 1). The falsifiable claims:
16+
//!
17+
//! 1. **transform no-op grows with motion quality** — the DCT's byte advantage
18+
//! over *direct* shaping (no transform) → 1 as the residual whitens
19+
//! (i.e. as motion improves). When it hits 1, the transform is a literal
20+
//! no-op and can be dropped.
21+
//! 2. **a multiply-free sign transform suffices** — the Walsh–Hadamard
22+
//! transform (±1 basis, add/subtract only — the shader's "zero FP, zero
23+
//! matmul" idiom) tracks the DCT within a few %, so the substrate never
24+
//! needs a multiply-based DCT. WHT is the honest "transform" for a codec
25+
//! that IS the zero-FP cognitive shader.
26+
//!
27+
//! # Fairness
28+
//!
29+
//! All three transforms are **orthonormal**, so quantising coefficients with the
30+
//! same step `Q` yields the same L2 distortion (Parseval) — an equal-PSNR byte
31+
//! comparison. Bytes = order-0 Shannon entropy `H₀` of the quantised symbols
32+
//! (what an ideal rANS coder spends). "direct" = quantise the residual in the
33+
//! spatial domain (no transform = pure shaping); "wht"/"dct" = transform, then
34+
//! quantise the coefficients.
35+
//!
36+
//! Residual correlation `ρ` (lag-1 autocorrelation) is the stand-in for motion
37+
//! quality: good motion ⇒ white residual (`ρ → 0`); poor motion ⇒ structured
38+
//! residual (`ρ → 1`). This is the textbook "MC decorrelates, leaving a
39+
//! near-white residual" — here quantified on the substrate.
40+
//!
41+
//! Run: `cargo run --release --example motion_transform_noop --features codec`
42+
43+
use ndarray::hpc::codec::CellMode;
44+
45+
const W: usize = 128;
46+
const H: usize = 128;
47+
const B: usize = 8; // transform block edge (8×8), B = 2³ for the fast WHT
48+
const K: usize = B * B;
49+
const BX: usize = W / B;
50+
const BY: usize = H / B;
51+
const Q: f64 = 6.0; // quantisation step (same for all three → equal PSNR)
52+
53+
fn mix(mut z: u64) -> u64 {
54+
z = z.wrapping_add(0x9E37_79B9_7F4A_7C15);
55+
z = (z ^ (z >> 30)).wrapping_mul(0xBF58_476D_1CE4_E5B9);
56+
z = (z ^ (z >> 27)).wrapping_mul(0x94D0_49BB_1331_11EB);
57+
z ^ (z >> 31)
58+
}
59+
60+
/// A residual field at controlled lag-1 correlation `rho` — a blend of a smooth
61+
/// (correlated) component and white noise. `rho ≈ 0` = white (good motion);
62+
/// `rho ≈ 1` = structured (poor motion). Zero-mean.
63+
fn residual_field(rho: f64) -> Vec<f64> {
64+
let mut f = vec![0.0f64; W * H];
65+
for y in 0..H {
66+
for x in 0..W {
67+
let (xf, yf) = (x as f64, y as f64);
68+
let smooth = 40.0 * (xf * 0.05).sin() * (yf * 0.045).cos() + 20.0 * (yf * 0.03).sin();
69+
let white = ((mix((y as u64) << 20 | x as u64) & 0xFF) as f64) - 127.5;
70+
f[y * W + x] = rho * smooth + (1.0 - rho) * (white * 0.5);
71+
}
72+
}
73+
f
74+
}
75+
76+
/// Measured lag-1 autocorrelation (horizontal + vertical averaged) — the honest
77+
/// whiteness readout, independent of the `rho` knob.
78+
fn autocorr_lag1(f: &[f64]) -> f64 {
79+
let mean = f.iter().sum::<f64>() / f.len() as f64;
80+
let var = f.iter().map(|&v| (v - mean) * (v - mean)).sum::<f64>() / f.len() as f64;
81+
if var < 1e-12 {
82+
return 0.0;
83+
}
84+
let mut cov = 0.0;
85+
let mut n = 0.0;
86+
for y in 0..H {
87+
for x in 0..W {
88+
if x + 1 < W {
89+
cov += (f[y * W + x] - mean) * (f[y * W + x + 1] - mean);
90+
n += 1.0;
91+
}
92+
if y + 1 < H {
93+
cov += (f[y * W + x] - mean) * (f[(y + 1) * W + x] - mean);
94+
n += 1.0;
95+
}
96+
}
97+
}
98+
(cov / n) / var
99+
}
100+
101+
/// Orthonormal 8-point DCT-II basis row `k`.
102+
fn dct_row(k: usize) -> [f64; B] {
103+
let mut r = [0.0f64; B];
104+
let alpha = if k == 0 {
105+
(1.0 / B as f64).sqrt()
106+
} else {
107+
(2.0 / B as f64).sqrt()
108+
};
109+
for (n, rn) in r.iter_mut().enumerate() {
110+
*rn = alpha * (std::f64::consts::PI * (2.0 * n as f64 + 1.0) * k as f64 / (2.0 * B as f64)).cos();
111+
}
112+
r
113+
}
114+
115+
/// 2-D separable orthonormal DCT-II of an 8×8 block (full multiplies).
116+
fn dct2(block: &[f64; K]) -> [f64; K] {
117+
let basis: Vec<[f64; B]> = (0..B).map(dct_row).collect();
118+
// rows
119+
let mut tmp = [0.0f64; K];
120+
for r in 0..B {
121+
for k in 0..B {
122+
let mut s = 0.0;
123+
for n in 0..B {
124+
s += basis[k][n] * block[r * B + n];
125+
}
126+
tmp[r * B + k] = s;
127+
}
128+
}
129+
// cols
130+
let mut out = [0.0f64; K];
131+
for c in 0..B {
132+
for k in 0..B {
133+
let mut s = 0.0;
134+
for n in 0..B {
135+
s += basis[k][n] * tmp[n * B + c];
136+
}
137+
out[k * B + c] = s;
138+
}
139+
}
140+
out
141+
}
142+
143+
/// 2-D separable orthonormal Walsh–Hadamard transform of an 8×8 block. The basis
144+
/// is ±1/√8 — the transform is pure add/subtract (a sign transform), ZERO
145+
/// multiplies in the butterfly. This is the codec transform that matches the
146+
/// "zero FP, zero matmul" cognitive shader. (Multiplies here are only the final
147+
/// 1/√8 normalisation, foldable into the quant step.)
148+
fn wht2(block: &[f64; K]) -> [f64; K] {
149+
let mut m = *block;
150+
let scale = 1.0 / (B as f64).sqrt();
151+
// rows: in-place fast WHT (add/subtract butterfly), then normalise
152+
for r in 0..B {
153+
fwht(&mut m[r * B..r * B + B]);
154+
}
155+
// cols
156+
let mut col = [0.0f64; B];
157+
for c in 0..B {
158+
for r in 0..B {
159+
col[r] = m[r * B + c];
160+
}
161+
fwht(&mut col);
162+
for r in 0..B {
163+
m[r * B + c] = col[r] * scale * scale;
164+
}
165+
}
166+
m
167+
}
168+
169+
/// In-place fast Walsh–Hadamard transform (natural order), length 8 = 2³.
170+
/// Add/subtract butterflies only — no multiplies.
171+
fn fwht(a: &mut [f64]) {
172+
let n = a.len();
173+
let mut h = 1;
174+
while h < n {
175+
let mut i = 0;
176+
while i < n {
177+
for j in i..i + h {
178+
let (x, y) = (a[j], a[j + h]);
179+
a[j] = x + y;
180+
a[j + h] = x - y;
181+
}
182+
i += 2 * h;
183+
}
184+
h *= 2;
185+
}
186+
}
187+
188+
/// Order-0 Shannon entropy of an integer symbol stream, in bytes.
189+
fn entropy_bytes(sym: &[i64]) -> f64 {
190+
use std::collections::HashMap;
191+
let mut hist: HashMap<i64, u64> = HashMap::new();
192+
for &s in sym {
193+
*hist.entry(s).or_insert(0) += 1;
194+
}
195+
let n = sym.len() as f64;
196+
let bits: f64 = hist
197+
.values()
198+
.map(|&c| {
199+
let p = c as f64 / n;
200+
-(c as f64) * p.log2()
201+
})
202+
.sum();
203+
bits / 8.0
204+
}
205+
206+
/// Quantise a coefficient/sample to the nearest multiple of `Q` → integer symbol.
207+
fn quant(v: f64) -> i64 {
208+
(v / Q).round() as i64
209+
}
210+
211+
fn main() {
212+
let block_at = |f: &[f64], bx: usize, by: usize| -> [f64; K] {
213+
let mut blk = [0.0f64; K];
214+
for j in 0..B {
215+
for i in 0..B {
216+
blk[j * B + i] = f[(by * B + j) * W + (bx * B + i)];
217+
}
218+
}
219+
blk
220+
};
221+
222+
println!("Motion = bit shift × transform no-op × shaping — measured");
223+
println!(" {W}×{H}, {B}×{B} blocks, Q={Q} (orthonormal ⇒ equal PSNR); bytes = H₀ (ideal rANS)");
224+
println!(" ρ = residual lag-1 autocorrelation (motion quality proxy: ρ→0 = good motion)\n");
225+
println!(
226+
" {:<10} {:>7} {:>10} {:>10} {:>10} {:>8} {:>8}",
227+
"residual", "ρ", "direct", "wht", "dct", "dct/dir", "wht/dct"
228+
);
229+
230+
for &rho in &[0.0, 0.3, 0.6, 0.9] {
231+
let f = residual_field(rho);
232+
let rho_meas = autocorr_lag1(&f);
233+
234+
let (mut direct, mut wht, mut dct) = (Vec::new(), Vec::new(), Vec::new());
235+
for by in 0..BY {
236+
for bx in 0..BX {
237+
let blk = block_at(&f, bx, by);
238+
// direct = pure shaping (quantise spatial residual, no transform)
239+
for &v in &blk {
240+
direct.push(quant(v));
241+
}
242+
// wht = multiply-free sign transform
243+
for &v in &wht2(&blk) {
244+
wht.push(quant(v));
245+
}
246+
// dct = full multiply transform
247+
for &v in &dct2(&blk) {
248+
dct.push(quant(v));
249+
}
250+
}
251+
}
252+
let (db, wb, cb) = (entropy_bytes(&direct), entropy_bytes(&wht), entropy_bytes(&dct));
253+
println!(
254+
" ρ≈{:<7.2} {:>7.3} {:>10.0} {:>10.0} {:>10.0} {:>7.2}× {:>7.2}×",
255+
rho,
256+
rho_meas,
257+
db,
258+
wb,
259+
cb,
260+
db / cb, // transform's advantage over direct shaping (>1 ⇒ transform earns keep)
261+
wb / cb, // multiply-free vs full transform (≈1 ⇒ WHT suffices)
262+
);
263+
}
264+
265+
// H-7 tie-in: for the white residual (good motion), how many transform coeffs
266+
// survive quantisation? Near-white ⇒ energy spread ⇒ few zeros; the point is
267+
// the transform buys nothing there (dct/dir ≈ 1 above), so the CellMode of the
268+
// *direct* residue is what the codec actually stores.
269+
let fw = residual_field(0.0);
270+
let mut modes = [0usize; 3];
271+
for by in 0..BY {
272+
for bx in 0..BX {
273+
for &v in &block_at(&fw, bx, by) {
274+
let q = quant(v);
275+
let mode = if q == 0 {
276+
CellMode::Skip
277+
} else if q.abs() <= 127 {
278+
CellMode::Delta
279+
} else {
280+
CellMode::Escape
281+
};
282+
modes[match mode {
283+
CellMode::Skip => 0,
284+
CellMode::Delta => 1,
285+
_ => 2,
286+
}] += 1;
287+
}
288+
}
289+
}
290+
println!(
291+
"\n [H-7] white-residual (good motion) direct CellMode: skip={} delta={} escape={}",
292+
modes[0], modes[1], modes[2]
293+
);
294+
295+
println!(
296+
"\n MEASURED CONCLUSION:\n\
297+
\x20 • dct/dir is the transform's byte advantage over direct shaping. As the\n\
298+
\x20 residual whitens (ρ→0, i.e. motion improves) it approaches 1 — the\n\
299+
\x20 transform becomes a literal NO-OP and can be dropped. It only earns its\n\
300+
\x20 keep on structured residuals (ρ high = poor motion), the regime good\n\
301+
\x20 bit-shift motion avoids. This IS 'transform no-op': the transform's\n\
302+
\x20 value is inversely coupled to the motion's quality.\n\
303+
\x20 • wht/dct ≈ 1 across the sweep — the multiply-free ±1 sign transform\n\
304+
\x20 (add/subtract only, the shader's zero-FP idiom) matches the full DCT.\n\
305+
\x20 The substrate never needs a multiply-based DCT; WHT is the codec\n\
306+
\x20 transform that IS the cognitive shader.\n\
307+
\x20 • So: motion = bit shift (free addressing) × transform no-op (WHT, and\n\
308+
\x20 vanishing as motion improves) × shaping (the direct residue). The three\n\
309+
\x20 factors are one tradeoff curve, not three independent stages."
310+
);
311+
}

0 commit comments

Comments
 (0)