From 1e241b7cc308fbb9d9f5dace18934fd7b352f4d6 Mon Sep 17 00:00:00 2001 From: Simon Rutishauser Date: Tue, 19 May 2015 12:44:23 +0200 Subject: [PATCH] Allow the LossFunction contained in a LossFunctionWrapper to be NULL. This is consistent with how NULL LossFunctions are treated everywhere else. Change-Id: Ic91e39ccb13137fcad7f85e78613a29ecde30d67 --- include/ceres/loss_function.h | 13 +++++++++++-- internal/ceres/loss_function_test.cc | 18 ++++++++++++++++++ 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/include/ceres/loss_function.h b/include/ceres/loss_function.h index 78397f0fe..44c6b8798 100644 --- a/include/ceres/loss_function.h +++ b/include/ceres/loss_function.h @@ -358,6 +358,9 @@ class CERES_EXPORT ScaledLoss : public LossFunction { // whose scale can be mutated after an optimization problem has been // constructed. // +// Since we treat the a NULL Loss function as the Identity loss +// function, rho = NULL is a valid input. +// // Example usage // // Problem problem; @@ -394,8 +397,14 @@ class CERES_EXPORT LossFunctionWrapper : public LossFunction { } virtual void Evaluate(double sq_norm, double out[3]) const { - CHECK_NOTNULL(rho_.get()); - rho_->Evaluate(sq_norm, out); + if (rho_.get() == NULL) { + out[0] = sq_norm; + out[1] = 1.0; + out[2] = 0.0; + } + else { + rho_->Evaluate(sq_norm, out); + } } void Reset(LossFunction* rho, Ownership ownership) { diff --git a/internal/ceres/loss_function_test.cc b/internal/ceres/loss_function_test.cc index d06f69e02..406ace731 100644 --- a/internal/ceres/loss_function_test.cc +++ b/internal/ceres/loss_function_test.cc @@ -228,6 +228,24 @@ TEST(LossFunction, LossFunctionWrapper) { for (int i = 0; i < 3; ++i) { EXPECT_NEAR(rho[i], rho_gold[i], 1e-12); } + + // Set to NULL + TrivialLoss loss_function4; + loss_function_wrapper.Reset(NULL, TAKE_OWNERSHIP); + loss_function_wrapper.Evaluate(s, rho); + loss_function4.Evaluate(s, rho_gold); + for (int i = 0; i < 3; ++i) { + EXPECT_NEAR(rho[i], rho_gold[i], 1e-12); + } + + // Set to NULL, not taking ownership + loss_function_wrapper.Reset(NULL, DO_NOT_TAKE_OWNERSHIP); + loss_function_wrapper.Evaluate(s, rho); + loss_function4.Evaluate(s, rho_gold); + for (int i = 0; i < 3; ++i) { + EXPECT_NEAR(rho[i], rho_gold[i], 1e-12); + } + } } // namespace internal