Fix an exact equality test causing breakage in gradient_checker_test. Also clang-format the file to fix some accumulated cruft. Change-Id: Icf41e3f864a4fe925426477893602b50ff2131f4
diff --git a/internal/ceres/gradient_checker_test.cc b/internal/ceres/gradient_checker_test.cc index 3d40a4d..85d58b9 100644 --- a/internal/ceres/gradient_checker_test.cc +++ b/internal/ceres/gradient_checker_test.cc
@@ -1,5 +1,5 @@ // Ceres Solver - A fast non-linear least squares minimizer -// Copyright 2015 Google Inc. All rights reserved. +// Copyright 2016 Google Inc. All rights reserved. // http://ceres-solver.org/ // // Redistribution and use in source and binary forms, with or without @@ -58,7 +58,7 @@ // version, they are both block vectors, of course. class GoodTestTerm : public CostFunction { public: - GoodTestTerm(int arity, int const *dim) : arity_(arity), return_value_(true) { + GoodTestTerm(int arity, int const* dim) : arity_(arity), return_value_(true) { // Make 'arity' random vectors. a_.resize(arity_); for (int j = 0; j < arity_; ++j) { @@ -98,7 +98,7 @@ if (jacobians[j]) { for (int u = 0; u < parameter_block_sizes()[j]; ++u) { // See comments before class. - jacobians[j][u] = - f * a_[j][u]; + jacobians[j][u] = -f * a_[j][u]; } } } @@ -107,9 +107,7 @@ return true; } - void SetReturnValue(bool return_value) { - return_value_ = return_value; - } + void SetReturnValue(bool return_value) { return_value_ = return_value; } private: int arity_; @@ -119,7 +117,7 @@ class BadTestTerm : public CostFunction { public: - BadTestTerm(int arity, int const *dim) : arity_(arity) { + BadTestTerm(int arity, int const* dim) : arity_(arity) { // Make 'arity' random vectors. a_.resize(arity_); for (int j = 0; j < arity_; ++j) { @@ -156,7 +154,7 @@ if (jacobians[j]) { for (int u = 0; u < parameter_block_sizes()[j]; ++u) { // See comments before class. - jacobians[j][u] = - f * a_[j][u] + 0.001; + jacobians[j][u] = -f * a_[j][u] + 0.001; } } } @@ -172,10 +170,10 @@ const double kTolerance = 1e-6; -void CheckDimensions( - const GradientChecker::ProbeResults& results, - const std::vector<int>& parameter_sizes, - const std::vector<int>& local_parameter_sizes, int residual_size) { +void CheckDimensions(const GradientChecker::ProbeResults& results, + const std::vector<int>& parameter_sizes, + const std::vector<int>& local_parameter_sizes, + int residual_size) { CHECK_EQ(parameter_sizes.size(), local_parameter_sizes.size()); int num_parameters = parameter_sizes.size(); ASSERT_EQ(residual_size, results.residuals.size()); @@ -187,7 +185,8 @@ EXPECT_EQ(residual_size, results.local_jacobians.at(i).rows()); EXPECT_EQ(local_parameter_sizes[i], results.local_jacobians.at(i).cols()); EXPECT_EQ(residual_size, results.local_numeric_jacobians.at(i).rows()); - EXPECT_EQ(local_parameter_sizes[i], results.local_numeric_jacobians.at(i).cols()); + EXPECT_EQ(local_parameter_sizes[i], + results.local_numeric_jacobians.at(i).cols()); EXPECT_EQ(residual_size, results.jacobians.at(i).rows()); EXPECT_EQ(parameter_sizes[i], results.jacobians.at(i).cols()); EXPECT_EQ(residual_size, results.numeric_jacobians.at(i).rows()); @@ -221,9 +220,9 @@ GoodTestTerm good_term(num_parameters, parameter_sizes.data()); GradientChecker good_gradient_checker(&good_term, NULL, numeric_diff_options); EXPECT_TRUE(good_gradient_checker.Probe(parameters.get(), kTolerance, NULL)); - EXPECT_TRUE(good_gradient_checker.Probe(parameters.get(), kTolerance, - &results)) - << results.error_log; + EXPECT_TRUE( + good_gradient_checker.Probe(parameters.get(), kTolerance, &results)) + << results.error_log; // Check that results contain sensible data. ASSERT_EQ(results.return_value, true); @@ -235,9 +234,9 @@ // Test that if the cost function return false, Probe should return false. good_term.SetReturnValue(false); EXPECT_FALSE(good_gradient_checker.Probe(parameters.get(), kTolerance, NULL)); - EXPECT_FALSE(good_gradient_checker.Probe(parameters.get(), kTolerance, - &results)) - << results.error_log; + EXPECT_FALSE( + good_gradient_checker.Probe(parameters.get(), kTolerance, &results)) + << results.error_log; // Check that results contain sensible data. ASSERT_EQ(results.return_value, false); @@ -254,8 +253,8 @@ BadTestTerm bad_term(num_parameters, parameter_sizes.data()); GradientChecker bad_gradient_checker(&bad_term, NULL, numeric_diff_options); EXPECT_FALSE(bad_gradient_checker.Probe(parameters.get(), kTolerance, NULL)); - EXPECT_FALSE(bad_gradient_checker.Probe(parameters.get(), kTolerance, - &results)); + EXPECT_FALSE( + bad_gradient_checker.Probe(parameters.get(), kTolerance, &results)); // Check that results contain sensible data. ASSERT_EQ(results.return_value, true); @@ -279,7 +278,6 @@ } } - /** * Helper cost function that multiplies the parameters by the given jacobians * and adds a constant offset. @@ -291,7 +289,8 @@ set_num_residuals(residuals_offset_.size()); } - virtual bool Evaluate(double const* const* parameter_ptrs, double* residuals_ptr, + virtual bool Evaluate(double const* const* parameter_ptrs, + double* residuals_ptr, double** residual_J_params) const { CHECK_GE(residual_J_params_.size(), 0.0); VectorRef residuals(residuals_ptr, residual_J_params_[0].rows()); @@ -308,8 +307,8 @@ // Return Jacobian. if (residual_J_params != NULL && residual_J_params[i] != NULL) { Eigen::Map<Matrix> residual_J_param_out(residual_J_params[i], - residual_J_param.rows(), - residual_J_param.cols()); + residual_J_param.rows(), + residual_J_param.cols()); if (jacobian_offsets_.count(i) != 0) { residual_J_param_out = residual_J_param + jacobian_offsets_.at(i); } else { @@ -414,8 +413,8 @@ Matrix residual_expected = residual_offset + j0 * param0 + j1 * param1; - EXPECT_TRUE(j1_out == j0); - EXPECT_TRUE(j2_out == j1); + ExpectMatricesClose(j1_out, j0, std::numeric_limits<double>::epsilon()); + ExpectMatricesClose(j2_out, j1, std::numeric_limits<double>::epsilon()); ExpectMatricesClose(residual, residual_expected, kTolerance); // Create local parameterization. @@ -433,7 +432,9 @@ Eigen::Matrix<double, 3, 2, Eigen::RowMajor> global_J_local_out; parameterization.ComputeJacobian(x.data(), global_J_local_out.data()); - EXPECT_TRUE(global_J_local_out == global_J_local); + ExpectMatricesClose(global_J_local_out, + global_J_local, + std::numeric_limits<double>::epsilon()); Eigen::Vector3d x_plus_delta; parameterization.Plus(x.data(), delta.data(), x_plus_delta.data()); @@ -446,8 +447,8 @@ parameterizations[1] = NULL; NumericDiffOptions numeric_diff_options; GradientChecker::ProbeResults results; - GradientChecker gradient_checker(&cost_function, ¶meterizations, - numeric_diff_options); + GradientChecker gradient_checker( + &cost_function, ¶meterizations, numeric_diff_options); Problem::Options problem_options; problem_options.cost_function_ownership = DO_NOT_TAKE_OWNERSHIP; @@ -457,8 +458,8 @@ Eigen::Vector2d param1_solver; problem.AddParameterBlock(param0_solver.data(), 3, ¶meterization); problem.AddParameterBlock(param1_solver.data(), 2); - problem.AddResidualBlock(&cost_function, NULL, param0_solver.data(), - param1_solver.data()); + problem.AddResidualBlock( + &cost_function, NULL, param0_solver.data(), param1_solver.data()); Solver::Options solver_options; solver_options.check_gradients = true; solver_options.initial_trust_region_radius = 1e10; @@ -468,20 +469,25 @@ // First test case: everything is correct. EXPECT_TRUE(gradient_checker.Probe(parameters.data(), kTolerance, NULL)); EXPECT_TRUE(gradient_checker.Probe(parameters.data(), kTolerance, &results)) - << results.error_log; + << results.error_log; // Check that results contain correct data. ASSERT_EQ(results.return_value, true); - ASSERT_TRUE(results.residuals == residual); + ExpectMatricesClose( + results.residuals, residual, std::numeric_limits<double>::epsilon()); CheckDimensions(results, parameter_sizes, local_parameter_sizes, 3); - ExpectMatricesClose(results.local_jacobians.at(0), j0 * global_J_local, - kTolerance); - EXPECT_TRUE(results.local_jacobians.at(1) == j1); - ExpectMatricesClose(results.local_numeric_jacobians.at(0), - j0 * global_J_local, kTolerance); + ExpectMatricesClose( + results.local_jacobians.at(0), j0 * global_J_local, kTolerance); + ExpectMatricesClose(results.local_jacobians.at(1), + j1, + std::numeric_limits<double>::epsilon()); + ExpectMatricesClose( + results.local_numeric_jacobians.at(0), j0 * global_J_local, kTolerance); ExpectMatricesClose(results.local_numeric_jacobians.at(1), j1, kTolerance); - EXPECT_TRUE(results.jacobians.at(0) == j0); - EXPECT_TRUE(results.jacobians.at(1) == j1); + ExpectMatricesClose( + results.jacobians.at(0), j0, std::numeric_limits<double>::epsilon()); + ExpectMatricesClose( + results.jacobians.at(1), j1, std::numeric_limits<double>::epsilon()); ExpectMatricesClose(results.numeric_jacobians.at(0), j0, kTolerance); ExpectMatricesClose(results.numeric_jacobians.at(1), j1, kTolerance); EXPECT_GE(results.maximum_relative_error, 0.0); @@ -502,22 +508,27 @@ cost_function.SetJacobianOffset(0, j0_offset); EXPECT_FALSE(gradient_checker.Probe(parameters.data(), kTolerance, NULL)); EXPECT_FALSE(gradient_checker.Probe(parameters.data(), kTolerance, &results)) - << results.error_log; + << results.error_log; // Check that results contain correct data. ASSERT_EQ(results.return_value, true); - ASSERT_TRUE(results.residuals == residual); + ExpectMatricesClose( + results.residuals, residual, std::numeric_limits<double>::epsilon()); CheckDimensions(results, parameter_sizes, local_parameter_sizes, 3); ASSERT_EQ(results.local_jacobians.size(), 2); ASSERT_EQ(results.local_numeric_jacobians.size(), 2); ExpectMatricesClose(results.local_jacobians.at(0), - (j0 + j0_offset) * global_J_local, kTolerance); - EXPECT_TRUE(results.local_jacobians.at(1) == j1); - ExpectMatricesClose(results.local_numeric_jacobians.at(0), - j0 * global_J_local, kTolerance); + (j0 + j0_offset) * global_J_local, + kTolerance); + ExpectMatricesClose(results.local_jacobians.at(1), + j1, + std::numeric_limits<double>::epsilon()); + ExpectMatricesClose( + results.local_numeric_jacobians.at(0), j0 * global_J_local, kTolerance); ExpectMatricesClose(results.local_numeric_jacobians.at(1), j1, kTolerance); ExpectMatricesClose(results.jacobians.at(0), j0 + j0_offset, kTolerance); - EXPECT_TRUE(results.jacobians.at(1) == j1); + ExpectMatricesClose( + results.jacobians.at(1), j1, std::numeric_limits<double>::epsilon()); ExpectMatricesClose(results.numeric_jacobians.at(0), j0, kTolerance); ExpectMatricesClose(results.numeric_jacobians.at(1), j1, kTolerance); EXPECT_GT(results.maximum_relative_error, 0.0); @@ -536,23 +547,28 @@ // Verify that the gradient checker does not treat this as an error. EXPECT_TRUE(gradient_checker.Probe(parameters.data(), kTolerance, &results)) - << results.error_log; + << results.error_log; // Check that results contain correct data. ASSERT_EQ(results.return_value, true); - ASSERT_TRUE(results.residuals == residual); + ExpectMatricesClose( + results.residuals, residual, std::numeric_limits<double>::epsilon()); CheckDimensions(results, parameter_sizes, local_parameter_sizes, 3); ASSERT_EQ(results.local_jacobians.size(), 2); ASSERT_EQ(results.local_numeric_jacobians.size(), 2); ExpectMatricesClose(results.local_jacobians.at(0), (j0 + j0_offset) * parameterization.global_J_local, kTolerance); - EXPECT_TRUE(results.local_jacobians.at(1) == j1); + ExpectMatricesClose(results.local_jacobians.at(1), + j1, + std::numeric_limits<double>::epsilon()); ExpectMatricesClose(results.local_numeric_jacobians.at(0), - j0 * parameterization.global_J_local, kTolerance); + j0 * parameterization.global_J_local, + kTolerance); ExpectMatricesClose(results.local_numeric_jacobians.at(1), j1, kTolerance); ExpectMatricesClose(results.jacobians.at(0), j0 + j0_offset, kTolerance); - EXPECT_TRUE(results.jacobians.at(1) == j1); + ExpectMatricesClose( + results.jacobians.at(1), j1, std::numeric_limits<double>::epsilon()); ExpectMatricesClose(results.numeric_jacobians.at(0), j0, kTolerance); ExpectMatricesClose(results.numeric_jacobians.at(1), j1, kTolerance); EXPECT_GE(results.maximum_relative_error, 0.0);