From 4a3f008e6a50580f427cf4d0f44649353ebf62c5 Mon Sep 17 00:00:00 2001 From: Sameer Agarwal Date: Sun, 26 Oct 2025 17:53:56 -0700 Subject: [PATCH] Fix a bug in inner iterations Normally we expect it to be the case that inner iteration cost will be less than the trust region cost, but due to round off error it can be that it is larger, so make the test for inner iteration being successful to be stricter. Change-Id: Icbafe9fc6a311940d5368cca78eeac7ccd5fa943 --- internal/ceres/trust_region_minimizer.cc | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/internal/ceres/trust_region_minimizer.cc b/internal/ceres/trust_region_minimizer.cc index 068cc8d2e..c2c10f8f4 100644 --- a/internal/ceres/trust_region_minimizer.cc +++ b/internal/ceres/trust_region_minimizer.cc @@ -562,7 +562,13 @@ void TrustRegionMinimizer::DoInnerIterationsIfNeeded() { const double inner_iteration_cost_change = candidate_cost_ - inner_iteration_cost; model_cost_change_ += inner_iteration_cost_change; - inner_iterations_were_useful_ = inner_iteration_cost < x_cost_; + + // Make sure that the inner iteration has improved over both the current + // (x_cost_) and the trust region step cost (candidate_cost). In exact + // arithmetic we would expect that inner iterations cost can't possibly be + // worse than candidate_cost, but in finite precision this can happen due to + // round-off error. So, we check that we improve upon the minimum of both. + inner_iterations_were_useful_ = inner_iteration_cost < std::min(x_cost_, candidate_cost_); const double inner_iteration_relative_progress = 1.0 - inner_iteration_cost / candidate_cost_;