Skip to content

Commit b540362

Browse files
Fabian Schenkmeta-codesync[bot]
authored andcommitted
Fix StdDeviationConstraint singularity and add lower bound for std deviation parameter
Differential Revision: D100588139 fbshipit-source-id: b894b27a0c99380d23fe2843dd51f8fe2acba19d
1 parent e404042 commit b540362

3 files changed

Lines changed: 23 additions & 2 deletions

File tree

opensfm/src/bundle/error/parameters_errors.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,9 @@ struct StdDeviationConstraint {
99

1010
template <typename T>
1111
bool operator()(const T* const std_deviation, T* residuals) const {
12-
T std = std_deviation[0];
13-
residuals[0] = ceres::log(T(1.0) / ceres::sqrt(T(2.0 * M_PI) * std * std));
12+
constexpr double kEps = 1e-20;
13+
T std_sq = std_deviation[0] * std_deviation[0] + T(kEps);
14+
residuals[0] = ceres::log(T(1.0) / ceres::sqrt(T(2.0 * M_PI) * std_sq));
1415
return true;
1516
}
1617
};

opensfm/src/bundle/src/bundle_adjuster.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -732,6 +732,7 @@ void BundleAdjuster::Run() {
732732
new StdDeviationConstraint());
733733
problem.AddResidualBlock(std_dev_cost_function, nullptr,
734734
&std_deviations[i]);
735+
problem.SetParameterLowerBound(&std_deviations[i], 0, 1e-10);
735736
}
736737
} else {
737738
for (int i = 0; i < std_deviations.size(); ++i) {

opensfm/src/bundle/test/bundle_data_test.cc

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include <bundle/bundle_adjuster.h>
22
#include <bundle/error/absolute_motion_errors.h>
3+
#include <bundle/error/parameters_errors.h>
34
#include <gmock/gmock.h>
45
#include <gtest/gtest.h>
56

@@ -227,3 +228,21 @@ TEST(TranslationPriorError, ZeroPriorNormClamped) {
227228
EXPECT_TRUE(error(instance1.data(), instance2.data(), &residual));
228229
EXPECT_TRUE(std::isfinite(residual));
229230
}
231+
232+
TEST(StdDeviationConstraint, FiniteResidualAtLowerBound) {
233+
// Regression test: at the Ceres lower bound of 1e-10, the residual must
234+
// be finite (not -inf or NaN from log(0)).
235+
bundle::StdDeviationConstraint constraint;
236+
constexpr double std_dev = 1e-10;
237+
double residual = 0.0;
238+
EXPECT_TRUE(constraint(&std_dev, &residual));
239+
EXPECT_TRUE(std::isfinite(residual));
240+
}
241+
242+
TEST(StdDeviationConstraint, FiniteResidualAtZero) {
243+
bundle::StdDeviationConstraint constraint;
244+
constexpr double std_dev = 0.0;
245+
double residual = 0.0;
246+
EXPECT_TRUE(constraint(&std_dev, &residual));
247+
EXPECT_TRUE(std::isfinite(residual));
248+
}

0 commit comments

Comments
 (0)