Commit 6eaa8bf4 authored by Andrey Filippov's avatar Andrey Filippov

CLAUDE: REVERT lean sum scaling - falsified by LEAN-07 (peaks blur-dominated, not fz-dominated)

LEAN-07 (stored poses, all tiles, sum-scaled input): sqrt_l0 3.22 -> 5.58
(wider, not the predicted ~2.1), corr RMS 0.82 -> 1.005. At 16x signal-to-
fat-zero the normalize amplifies the blur-decorrelated high frequencies -
the fat zero was regularizing usefully. Root of the misdiagnosis: the width
comparison used the MB-COMPENSATED oracles (FILT150A 2.08, MBEN 2.75); the
correct no-MB control (NOMB oracle) has sqrt_l0 3.58 ~ lean's 3.22 - lean
peak shapes were normal all along, and Andrey's "there was no 16x
difference" was right where it mattered.

Consequences: (1) correlator input back to the true weighted average (the
same data as the -POSE-RT-COMPOSITE debug render - single upload again);
(2) the "fz-broadened peak content pull" roll-bias mechanism is falsified -
the +0.52/+0.33 mrad roll bias needs a new suspect (remaining engine
differences vs the NOMB oracle: neighbor consolidation min_str_neib,
min_confidence gates, peak-extraction parameters); (3) MB compensation in
lean (v2) is the main quality lever - MBEN sharpens peaks 3.6 -> 2.8 and
removes the 0.5 px wobble.

Verified: mvn -DskipTests clean package OK.
Co-Authored-By: 's avatarClaude Fable 5 <noreply@anthropic.com>
parent 41930c37
...@@ -319,30 +319,21 @@ public class CuasPoseRT { ...@@ -319,30 +319,21 @@ public class CuasPoseRT {
if (img_out != null) { if (img_out != null) {
gpuQuad.execConvertDirect(false, null, 1); gpuQuad.execConvertDirect(false, null, 1);
} }
// 3. the CPU consolidation bridge (future clt_average_sensors kernel) // 3. the CPU consolidation bridge (future clt_average_sensors kernel).
// The TRUE weighted average is fed to the correlator (NOT scaled to the oracle's
// 16-pair sum): the sum-scaling experiment (LEAN-07) made peaks WIDER (sqrt_l0
// 3.22 -> 5.58, corr RMS 0.82 -> 1.005) - at 16x signal-to-fat-zero the normalize
// amplifies the blur-decorrelated high frequencies. Peak width here is BLUR-
// dominated, not fz-dominated (NOMB oracle 3.58 ~ lean 3.22 at 16x different
// amplitude); the fat zero regularizes usefully at the average's operating point.
// By Claude on 07/04/2026, falsified-and-reverted per LEAN-07.
final float [][] fclt16 = gpuQuad.getCltData(false); final float [][] fclt16 = gpuQuad.getCltData(false);
final int [] td_counts = new int [fclt16[0].length / CuasTD.TD_CHUNK]; final float [] avg_td = CuasTD.consolidateSensorsTD(fclt16, null);
final float [] avg_td = CuasTD.consolidateSensorsTD(fclt16, td_counts); gpuQuad.setCltData(0, avg_td, false);
// DEBUG (img_out): render the TRUE weighted average - the input-verification image // DEBUG (img_out): render the composite the correlator sees (the weighted average)
// (comparable to the virtual render) - BEFORE the sum scaling below. Costs one extra
// H2D + imclt, debug mode only. By Claude on 07/04/2026.
if (img_out != null) { if (img_out != null) {
gpuQuad.setCltData(0, avg_td, false);
img_out[0] = com.elphel.imagej.cuas.CuasMotion.perSensorImagesFromTD(gpuQuad, false)[0]; img_out[0] = com.elphel.imagej.cuas.CuasMotion.perSensorImagesFromTD(gpuQuad, false)[0];
} }
// Scale the average back to the per-tile SUM of sensors - the oracle inter-corr
// operating point (it sums the pair products unweighted, and the FZ-normalize
// applies the same absolute fat zero). The 1/16 amplitude of the plain average
// made the effective fat zero 16x larger -> broadened peaks (sqrt_l0 3.22 vs
// oracle 2.08 measured on identical tiles) -> asymmetric-content centroid pull,
// the suspected roll-bias mechanism. Per-tile count (not fixed 16) matches the
// oracle exactly where sensors are missing. By Claude on 07/04/2026.
for (int chunk = 0; chunk < td_counts.length; chunk++) if (td_counts[chunk] > 1) {
final int offs = chunk * CuasTD.TD_CHUNK;
final float scale = td_counts[chunk];
for (int i = 0; i < CuasTD.TD_CHUNK; i++) avg_td[offs + i] *= scale;
}
gpuQuad.setCltData(0, avg_td, false);
// 4. single conj-multiply: only sensor 0 (holding the average) vs the center ref // 4. single conj-multiply: only sensor 0 (holding the average) vs the center ref
final double [] col_weights = scene.isMonochrome() ? final double [] col_weights = scene.isMonochrome() ?
(new double [] {1.0}) : (new double [] {1.0}) :
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment