Commit 972bcbda authored by Andrey Filippov's avatar Andrey Filippov

CLAUDE: curt.pose_lambda - near-GN inner LMA start + innerLMA counts in trace

Root cause of the 6-13 outer cycles (Andrey's diagnosis, confirmed in code):
the inner runLma restarts at ilp.ilma_lambda=0.1 EVERY outer measure<->solve
cycle, and the 0.1%-improvement inner exit fires while steps are still
lambda-limited -> outer loop under-relaxes (~0.8/cycle decay). New
curt.pose_lambda (default 0.001, 0 = legacy ilma_lambda) starts the inner
solve near-Gauss-Newton for the near-linear overdetermined 3-angle problem.
Trace line now also logs inner runLma iterations per outer cycle + lambda0.

07/12 21:56 run (legacy convergence + uniform MB): dstored RMS az/tilt/roll
0.1416/0.0777/0.0983 vs per-tile-MB baseline 0.1355/0.0765/0.1005 = uniform
MB VALIDATED (A1); 0 degenerates; outer cycles mean 7.4, max 13 @ lambda 0.1.
Co-Authored-By: 's avatarClaude Fable 5 <noreply@anthropic.com>
parent 923f3785
...@@ -572,7 +572,14 @@ public class CuasPoseRT { ...@@ -572,7 +572,14 @@ public class CuasPoseRT {
final int max_cycles = (fixed_cycles > 0) ? fixed_cycles : clt_parameters.imp.max_cycles; final int max_cycles = (fixed_cycles > 0) ? fixed_cycles : clt_parameters.imp.max_cycles;
double last_diff_atr = Double.NaN; // By Claude on 07/12/2026 double last_diff_atr = Double.NaN; // By Claude on 07/12/2026
final double [] cycle_datr = new double [max_cycles]; // per-cycle ATR-change trace (convergence trajectory) // By Claude on 07/12/2026 final double [] cycle_datr = new double [max_cycles]; // per-cycle ATR-change trace (convergence trajectory) // By Claude on 07/12/2026
final int [] cycle_inner = new int [max_cycles]; // inner runLma iterations per outer cycle // By Claude on 07/12/2026
int ncyc = 0; // cycles actually executed // By Claude on 07/12/2026 int ncyc = 0; // cycles actually executed // By Claude on 07/12/2026
// lean v2 (Andrey 07/12/2026): the inner LMA restarts at ilp.ilma_lambda (0.1) every
// outer cycle; combined with the 0.1%-improvement inner exit this under-relaxes the
// outer loop (~0.8/cycle decay, 6-13 cycles observed). pose_lambda > 0 overrides
// with a near-Gauss-Newton start for the near-linear 3-angle problem.
final double lma_lambda = (clt_parameters.curt.pose_lambda > 0) ?
clt_parameters.curt.pose_lambda : clt_parameters.ilp.ilma_lambda; // By Claude on 07/12/2026
int nlma = 0; int nlma = 0;
for (; nlma < max_cycles; nlma++) { for (; nlma < max_cycles; nlma++) {
cm = leanMeasure( cm = leanMeasure(
...@@ -602,7 +609,7 @@ public class CuasPoseRT { ...@@ -602,7 +609,7 @@ public class CuasPoseRT {
null, // dbg_prefix null, // dbg_prefix
clt_parameters.imp.debug_level); // debug_level clt_parameters.imp.debug_level); // debug_level
final int lmaResult = intersceneLma.runLma( final int lmaResult = intersceneLma.runLma(
clt_parameters.ilp.ilma_lambda, lma_lambda, // curt.pose_lambda override (0 = legacy ilp.ilma_lambda) // By Claude on 07/12/2026
clt_parameters.ilp.ilma_lambda_scale_good, clt_parameters.ilp.ilma_lambda_scale_good,
clt_parameters.ilp.ilma_lambda_scale_bad, clt_parameters.ilp.ilma_lambda_scale_bad,
clt_parameters.ilp.ilma_lambda_max, clt_parameters.ilp.ilma_lambda_max,
...@@ -619,6 +626,7 @@ public class CuasPoseRT { ...@@ -619,6 +626,7 @@ public class CuasPoseRT {
final double [] diffs_xyz = intersceneLma.getV3Diff(ErsCorrection.DP_DSX); final double [] diffs_xyz = intersceneLma.getV3Diff(ErsCorrection.DP_DSX);
last_diff_atr = diffs_atr[0]; // By Claude on 07/12/2026 last_diff_atr = diffs_atr[0]; // By Claude on 07/12/2026
cycle_datr[nlma] = diffs_atr[0]; // By Claude on 07/12/2026 cycle_datr[nlma] = diffs_atr[0]; // By Claude on 07/12/2026
cycle_inner[nlma] = lmaResult; // inner runLma iterations this cycle // By Claude on 07/12/2026
ncyc = nlma + 1; // By Claude on 07/12/2026 ncyc = nlma + 1; // By Claude on 07/12/2026
if ((fixed_cycles <= 0) && // lean v2: fixed count = no early exit // By Claude on 07/12/2026 if ((fixed_cycles <= 0) && // lean v2: fixed count = no early exit // By Claude on 07/12/2026
(diffs_atr[0] < clt_parameters.imp.exit_change_atr) && (diffs_atr[0] < clt_parameters.imp.exit_change_atr) &&
...@@ -643,8 +651,11 @@ public class CuasPoseRT { ...@@ -643,8 +651,11 @@ public class CuasPoseRT {
if (debugLevel > -4) { if (debugLevel > -4) {
final StringBuilder tsb = new StringBuilder(); final StringBuilder tsb = new StringBuilder();
for (int i = 0; i < ncyc; i++) tsb.append(String.format(" %.3g", cycle_datr[i])); for (int i = 0; i < ncyc; i++) tsb.append(String.format(" %.3g", cycle_datr[i]));
final StringBuilder isb = new StringBuilder(); // inner runLma iterations per cycle // By Claude on 07/12/2026
for (int i = 0; i < ncyc; i++) isb.append(" "+cycle_inner[i]);
System.out.println("CuasPoseRT cycles: scene "+scene.getImageName()+ System.out.println("CuasPoseRT cycles: scene "+scene.getImageName()+
" ("+ncyc+" of max "+max_cycles+") dATR/cycle ="+tsb); " ("+ncyc+" of max "+max_cycles+", lambda0 "+lma_lambda+") dATR/cycle ="+tsb+
"; innerLMA ="+isb);
} }
if (lma_rms != null) { if (lma_rms != null) {
final double [] last_rms = intersceneLma.getLastRms(); final double [] last_rms = intersceneLma.getLastRms();
......
...@@ -30,6 +30,7 @@ public class CuasRtParameters { ...@@ -30,6 +30,7 @@ public class CuasRtParameters {
public boolean pose_stored = false; // DEBUG: decouple rendering/measurement from the LMA - use the STORED (oracle vintage) pose for every scene, no adjustment; one leanMeasure per scene feeds -POSE-RT-HYPER/-CORR2D/-COMPOSITE. The composite must then match the oracle CUAS-MERGED-CUAS-DBG renders tile-for-tile. Lean engine only. // By Claude on 07/04/2026 public boolean pose_stored = false; // DEBUG: decouple rendering/measurement from the LMA - use the STORED (oracle vintage) pose for every scene, no adjustment; one leanMeasure per scene feeds -POSE-RT-HYPER/-CORR2D/-COMPOSITE. The composite must then match the oracle CUAS-MERGED-CUAS-DBG renders tile-for-tile. Lean engine only. // By Claude on 07/04/2026
public boolean pose_mb_uniform = true; // lean v2 (Andrey's ruling 07/12/2026): ONE uniform motion-blur vector per scene, shared by ALL tiles - under constant-rpm rotation the image flow is uniform across the frame up to the roll flow component (roll rate << azimuth/tilt) and the wobble contribution (second-degree), both ignored. Same Jacobian-times-rates product as the per-tile OpticalFlow.getMotionBlur (identical sign/scale conventions), evaluated at ONE representative point (frame center, mean reference disparity) and broadcast; rates source unchanged (finite differences of predicted poses). OFF = legacy per-tile getMotionBlur (the A/B knob). // By Claude on 07/12/2026 public boolean pose_mb_uniform = true; // lean v2 (Andrey's ruling 07/12/2026): ONE uniform motion-blur vector per scene, shared by ALL tiles - under constant-rpm rotation the image flow is uniform across the frame up to the roll flow component (roll rate << azimuth/tilt) and the wobble contribution (second-degree), both ignored. Same Jacobian-times-rates product as the per-tile OpticalFlow.getMotionBlur (identical sign/scale conventions), evaluated at ONE representative point (frame center, mean reference disparity) and broadcast; rates source unchanged (finite differences of predicted poses). OFF = legacy per-tile getMotionBlur (the A/B knob). // By Claude on 07/12/2026
public int pose_cycles = 3; // lean v2 (Andrey's ruling 07/12/2026): run EXACTLY this many LMA measure<->solve cycles per scene, no convergence-based early exit - CUAS scenes are near-identical perturbations of the same view, so the needed count is a constant of the setup (and a fixed count gives the GPU pipeline a static launch shape). The convergence delta is still computed: a QC line flags scenes whose last ATR change misses the legacy imp.exit_change_atr threshold (diagnostic only). 0 = legacy convergence exit (imp.max_cycles cap + exit_change thresholds - for varying-scene/flying-camera applications). // By Claude on 07/12/2026 public int pose_cycles = 3; // lean v2 (Andrey's ruling 07/12/2026): run EXACTLY this many LMA measure<->solve cycles per scene, no convergence-based early exit - CUAS scenes are near-identical perturbations of the same view, so the needed count is a constant of the setup (and a fixed count gives the GPU pipeline a static launch shape). The convergence delta is still computed: a QC line flags scenes whose last ATR change misses the legacy imp.exit_change_atr threshold (diagnostic only). 0 = legacy convergence exit (imp.max_cycles cap + exit_change thresholds - for varying-scene/flying-camera applications). // By Claude on 07/12/2026
public double pose_lambda = 0.001; // lean v2 (Andrey 07/12/2026): INITIAL LMA lambda for the inner pose solve, replacing ilp.ilma_lambda (0.1) which restarts every outer measure<->solve cycle. 0.1 + the 0.1%-improvement inner exit = under-relaxation: the inner loop quits while still lambda-limited, the outer cycle re-measures and lambda resets - hence the observed ~0.8/cycle outer decay needing 6-13 cycles. The 3-angle/150-tile problem is heavily overdetermined and near-linear: a near-zero lambda makes the first inner steps ~Gauss-Newton so each outer cycle closes the measurable gap. 0 = legacy (use ilp.ilma_lambda). // By Claude on 07/12/2026
public boolean rend_test = false; // RT full-render product (CuasRender.testRenderSequence): per scene raw /jp4/ -> conditionSceneToGpu -> virtual-grid render at BORROWED stored pose+ERS rates -> -CUAS-RT-RENDER hyperstack [s00..s15, merged][scenes], comparable to -CUAS-INDIVIDUAL/MERGED-CUAS-DBG. NON-exclusive: runs AFTER the pose stage when both are ON (the pose stage is part of the RT cycle - Andrey 07/06/2026). // By Claude on 07/05/2026 public boolean rend_test = false; // RT full-render product (CuasRender.testRenderSequence): per scene raw /jp4/ -> conditionSceneToGpu -> virtual-grid render at BORROWED stored pose+ERS rates -> -CUAS-RT-RENDER hyperstack [s00..s15, merged][scenes], comparable to -CUAS-INDIVIDUAL/MERGED-CUAS-DBG. NON-exclusive: runs AFTER the pose stage when both are ON (the pose stage is part of the RT cycle - Andrey 07/06/2026). // By Claude on 07/05/2026
public boolean log_test = false; // LoG A/B with the RT render (CuasRender): also save -CUAS-RT-RENDER-LOG-ORACLE (product convolved with the EXISTING pre-DNN pixel LoG, LINEAR alpha=1) and -CUAS-RT-RENDER-LOG-FOLDED (same render, LoG folded into the GPU aberration kernels via CuasLogFold - no pixel convolution; originals restored). The aberration+LoG kernel-fold validation (RT-seed step 1b). // By Claude on 07/06/2026 public boolean log_test = false; // LoG A/B with the RT render (CuasRender): also save -CUAS-RT-RENDER-LOG-ORACLE (product convolved with the EXISTING pre-DNN pixel LoG, LINEAR alpha=1) and -CUAS-RT-RENDER-LOG-FOLDED (same render, LoG folded into the GPU aberration kernels via CuasLogFold - no pixel convolution; originals restored). The aberration+LoG kernel-fold validation (RT-seed step 1b). // By Claude on 07/06/2026
public boolean log_ident = false; // LoG ISOLATION test with the RT render (CuasRender): render with IDENTITY kernels (-CUAS-RT-RENDER-ID, aberrations skipped), pixel-LoG it (-ID-LOG-ORACLE), and render with PURE-LoG kernels (-LOG-ONLY). If -LOG-ONLY vs -ID-LOG-ORACLE residual persists, the fold/L0 is wrong; if it collapses to the wrap floor, the aberration-kernel interaction was responsible (Andrey 07/06/2026). // By Claude on 07/06/2026 public boolean log_ident = false; // LoG ISOLATION test with the RT render (CuasRender): render with IDENTITY kernels (-CUAS-RT-RENDER-ID, aberrations skipped), pixel-LoG it (-ID-LOG-ORACLE), and render with PURE-LoG kernels (-LOG-ONLY). If -LOG-ONLY vs -ID-LOG-ORACLE residual persists, the fold/L0 is wrong; if it collapses to the wrap floor, the aberration-kernel interaction was responsible (Andrey 07/06/2026). // By Claude on 07/06/2026
...@@ -138,6 +139,8 @@ public class CuasRtParameters { ...@@ -138,6 +139,8 @@ public class CuasRtParameters {
"Lean v2 (CUAS): ONE motion-blur vector per scene shared by all tiles - constant-rpm flow is uniform up to the (small) roll component; wobble is second-degree. Same Jacobian-times-rates as the per-tile oracle, evaluated at the frame center. OFF = legacy per-tile getMotionBlur (A/B)."); "Lean v2 (CUAS): ONE motion-blur vector per scene shared by all tiles - constant-rpm flow is uniform up to the (small) roll component; wobble is second-degree. Same Jacobian-times-rates as the per-tile oracle, evaluated at the frame center. OFF = legacy per-tile getMotionBlur (A/B).");
gd.addNumericField("Pose lean fixed LMA cycles", this.pose_cycles, 0,7,"", // By Claude on 07/12/2026 gd.addNumericField("Pose lean fixed LMA cycles", this.pose_cycles, 0,7,"", // By Claude on 07/12/2026
"Lean v2 (CUAS): run EXACTLY this many measure<->solve cycles per scene (near-identical scenes need a constant count; fixed count = static GPU launch shape). A QC line flags scenes missing the legacy exit threshold. 0 = legacy convergence-based exit (imp.max_cycles + exit_change)."); "Lean v2 (CUAS): run EXACTLY this many measure<->solve cycles per scene (near-identical scenes need a constant count; fixed count = static GPU launch shape). A QC line flags scenes missing the legacy exit threshold. 0 = legacy convergence-based exit (imp.max_cycles + exit_change).");
gd.addNumericField("Pose lean initial LMA lambda", this.pose_lambda, 6,8,"", // By Claude on 07/12/2026
"Initial lambda of the INNER pose LMA (restarts every outer cycle). The legacy 0.1 start + 0.1%-improvement inner exit under-relaxes the outer loop (~0.8/cycle decay, 6-13 cycles). Near-zero = ~Gauss-Newton first steps for the near-linear 3-angle problem. 0 = legacy ilp.ilma_lambda.");
gd.addCheckbox ("CUAS RT render (full product)", this.rend_test, // By Claude on 07/05/2026 gd.addCheckbox ("CUAS RT render (full product)", this.rend_test, // By Claude on 07/05/2026
"Full RT-chain render: raw jp4 -> conditioning -> virtual-grid render at borrowed stored poses/ERS; saves -CUAS-RT-RENDER [s00..s15+merged][scenes], comparable to the -CUAS-*-DBG oracle products. NON-exclusive: runs AFTER the pose stage when both are ON."); "Full RT-chain render: raw jp4 -> conditioning -> virtual-grid render at borrowed stored poses/ERS; saves -CUAS-RT-RENDER [s00..s15+merged][scenes], comparable to the -CUAS-*-DBG oracle products. NON-exclusive: runs AFTER the pose stage when both are ON.");
gd.addCheckbox ("RT render LoG A/B (folded kernels)", this.log_test, // By Claude on 07/06/2026 gd.addCheckbox ("RT render LoG A/B (folded kernels)", this.log_test, // By Claude on 07/06/2026
...@@ -318,6 +321,7 @@ public class CuasRtParameters { ...@@ -318,6 +321,7 @@ public class CuasRtParameters {
this.pose_stored = gd.getNextBoolean(); // By Claude on 07/04/2026 this.pose_stored = gd.getNextBoolean(); // By Claude on 07/04/2026
this.pose_mb_uniform = gd.getNextBoolean(); // By Claude on 07/12/2026 this.pose_mb_uniform = gd.getNextBoolean(); // By Claude on 07/12/2026
this.pose_cycles = (int) gd.getNextNumber(); // By Claude on 07/12/2026 this.pose_cycles = (int) gd.getNextNumber(); // By Claude on 07/12/2026
this.pose_lambda = gd.getNextNumber(); // By Claude on 07/12/2026
this.rend_test = gd.getNextBoolean(); // By Claude on 07/05/2026 this.rend_test = gd.getNextBoolean(); // By Claude on 07/05/2026
this.log_test = gd.getNextBoolean(); // By Claude on 07/06/2026 this.log_test = gd.getNextBoolean(); // By Claude on 07/06/2026
this.log_ident = gd.getNextBoolean(); // By Claude on 07/06/2026 this.log_ident = gd.getNextBoolean(); // By Claude on 07/06/2026
...@@ -418,6 +422,7 @@ public class CuasRtParameters { ...@@ -418,6 +422,7 @@ public class CuasRtParameters {
properties.setProperty(prefix+"pose_stored", this.pose_stored+""); // boolean // By Claude on 07/04/2026 properties.setProperty(prefix+"pose_stored", this.pose_stored+""); // boolean // By Claude on 07/04/2026
properties.setProperty(prefix+"pose_mb_uniform", this.pose_mb_uniform+"");// boolean // By Claude on 07/12/2026 properties.setProperty(prefix+"pose_mb_uniform", this.pose_mb_uniform+"");// boolean // By Claude on 07/12/2026
properties.setProperty(prefix+"pose_cycles", this.pose_cycles+""); // int // By Claude on 07/12/2026 properties.setProperty(prefix+"pose_cycles", this.pose_cycles+""); // int // By Claude on 07/12/2026
properties.setProperty(prefix+"pose_lambda", this.pose_lambda+""); // double // By Claude on 07/12/2026
properties.setProperty(prefix+"rend_test", this.rend_test+""); // boolean // By Claude on 07/05/2026 properties.setProperty(prefix+"rend_test", this.rend_test+""); // boolean // By Claude on 07/05/2026
properties.setProperty(prefix+"log_test", this.log_test+""); // boolean // By Claude on 07/06/2026 properties.setProperty(prefix+"log_test", this.log_test+""); // boolean // By Claude on 07/06/2026
properties.setProperty(prefix+"log_ident", this.log_ident+""); // boolean // By Claude on 07/06/2026 properties.setProperty(prefix+"log_ident", this.log_ident+""); // boolean // By Claude on 07/06/2026
...@@ -518,6 +523,7 @@ public class CuasRtParameters { ...@@ -518,6 +523,7 @@ public class CuasRtParameters {
if (properties.getProperty(prefix+"pose_stored")!=null) this.pose_stored=Boolean.parseBoolean(properties.getProperty(prefix+"pose_stored")); // By Claude on 07/04/2026 if (properties.getProperty(prefix+"pose_stored")!=null) this.pose_stored=Boolean.parseBoolean(properties.getProperty(prefix+"pose_stored")); // By Claude on 07/04/2026
if (properties.getProperty(prefix+"pose_mb_uniform")!=null) this.pose_mb_uniform=Boolean.parseBoolean(properties.getProperty(prefix+"pose_mb_uniform")); // By Claude on 07/12/2026 if (properties.getProperty(prefix+"pose_mb_uniform")!=null) this.pose_mb_uniform=Boolean.parseBoolean(properties.getProperty(prefix+"pose_mb_uniform")); // By Claude on 07/12/2026
if (properties.getProperty(prefix+"pose_cycles")!=null) this.pose_cycles=Integer.parseInt(properties.getProperty(prefix+"pose_cycles")); // By Claude on 07/12/2026 if (properties.getProperty(prefix+"pose_cycles")!=null) this.pose_cycles=Integer.parseInt(properties.getProperty(prefix+"pose_cycles")); // By Claude on 07/12/2026
if (properties.getProperty(prefix+"pose_lambda")!=null) this.pose_lambda=Double.parseDouble(properties.getProperty(prefix+"pose_lambda")); // By Claude on 07/12/2026
if (properties.getProperty(prefix+"rend_test")!=null) this.rend_test=Boolean.parseBoolean(properties.getProperty(prefix+"rend_test")); // By Claude on 07/05/2026 if (properties.getProperty(prefix+"rend_test")!=null) this.rend_test=Boolean.parseBoolean(properties.getProperty(prefix+"rend_test")); // By Claude on 07/05/2026
if (properties.getProperty(prefix+"log_test")!=null) this.log_test=Boolean.parseBoolean(properties.getProperty(prefix+"log_test")); // By Claude on 07/06/2026 if (properties.getProperty(prefix+"log_test")!=null) this.log_test=Boolean.parseBoolean(properties.getProperty(prefix+"log_test")); // By Claude on 07/06/2026
if (properties.getProperty(prefix+"log_ident")!=null) this.log_ident=Boolean.parseBoolean(properties.getProperty(prefix+"log_ident")); // By Claude on 07/06/2026 if (properties.getProperty(prefix+"log_ident")!=null) this.log_ident=Boolean.parseBoolean(properties.getProperty(prefix+"log_ident")); // By Claude on 07/06/2026
...@@ -621,6 +627,7 @@ public class CuasRtParameters { ...@@ -621,6 +627,7 @@ public class CuasRtParameters {
cp.pose_stored = this.pose_stored; // By Claude on 07/04/2026 cp.pose_stored = this.pose_stored; // By Claude on 07/04/2026
cp.pose_mb_uniform = this.pose_mb_uniform; // By Claude on 07/12/2026 cp.pose_mb_uniform = this.pose_mb_uniform; // By Claude on 07/12/2026
cp.pose_cycles = this.pose_cycles; // By Claude on 07/12/2026 cp.pose_cycles = this.pose_cycles; // By Claude on 07/12/2026
cp.pose_lambda = this.pose_lambda; // By Claude on 07/12/2026
cp.rend_test = this.rend_test; // By Claude on 07/05/2026 cp.rend_test = this.rend_test; // By Claude on 07/05/2026
cp.log_test = this.log_test; // By Claude on 07/06/2026 cp.log_test = this.log_test; // By Claude on 07/06/2026
cp.log_ident = this.log_ident; // By Claude on 07/06/2026 cp.log_ident = this.log_ident; // By Claude on 07/06/2026
......
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