RotationScaleMerge: without a GPU, fold the partials' corr update into the rescale pass

RunScalingLoop rescales after every iteration before anything reads corr, so the iteration's
UpdateCorr and the rescale are one pass over the partials instead of two: the G and fitted frames
as the iteration left them, then the ratio on top - the same two roundings in the same order.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D1G8gJVAy6gp1K5Dz3NE5C
This commit is contained in:
leonarski_fandClaude Opus 5.5 committed 2026-09-26 22:49:32 +02:00
1 parent 6df56e661b
commit 45a8db03d4
1 file changed
+14 -1
@@ -5439,16 +5439,29 @@ RotationScaleMerge::Result RotationScaleMerge::Run(bool for_search, bool full_st
}
#endif
if (!scaled_on_gpu) {
// RunScalingLoop rescales after every iteration before anything reads corr, so the iteration's
// UpdateCorr is folded into that pass over the partials: the G and the fitted frames as the
// iteration left them, then the rescale on top - the same two roundings, one pass instead of two.
std::vector<double> g_fitted;
std::vector<uint8_t> frame_fitted;
partial_loop = RunScalingLoop("partials", g_partial, frame_count, smooth_window,
/*release_restraint=*/false, [&] {
ReducePartialGroupMeans(n_groups, partial_mean);
FitPerFrameG(partials, frame_start, frame_count, partial_mean, /*unity=*/false, g_partial);
UpdateCorr(partials, g_partial, frame_scaled_scratch);
g_fitted = g_partial;
frame_fitted = frame_scaled_scratch;
}, [&](const std::vector<uint8_t> &apply, const std::vector<double> &ratio) {
ParallelChunks(static_cast<int>(partials.size()), ThreadsForWork(partials.size(), nthreads),
[&](int lo, int hi) {
for (int i = lo; i < hi; ++i) {
Obs &o = partials[i];
if (frame_fitted[o.frame]) { // UpdateCorr
const double denom = static_cast<double>(o.partiality) * g_fitted[o.frame];
if (std::isfinite(o.prescaling_corr) && std::isfinite(denom) && denom > 0.0)
o.corr = static_cast<float>(o.prescaling_corr / denom);
else
o.corr = NAN;
}
if (apply[o.frame] && std::isfinite(o.corr))
o.corr = static_cast<float>(o.corr * ratio[o.frame]);
}