diff --git a/internal/ceres/evaluator_test.cc b/internal/ceres/evaluator_test.cc index 79006f787..a0b28eea9 100644 --- a/internal/ceres/evaluator_test.cc +++ b/internal/ceres/evaluator_test.cc @@ -55,12 +55,14 @@ using std::string; using std::vector; // TODO(keir): Consider pushing this into a common test utils file. -template +template class ParameterIgnoringCostFunction - : public SizedCostFunction { - typedef SizedCostFunction Base; + : public SizedCostFunction { + typedef SizedCostFunction Base; + public: + ParameterIgnoringCostFunction(bool succeeds = true) : succeeds_(succeeds) {} + virtual bool Evaluate(double const* const* parameters, double* residuals, double** jacobians) const { @@ -91,8 +93,11 @@ class ParameterIgnoringCostFunction } } } - return kSucceeds; + return succeeds_; } + + private: + bool succeeds_; }; struct EvaluatorTestOptions { @@ -112,7 +117,7 @@ struct EvaluatorTest : public ::testing::TestWithParam { Evaluator* CreateEvaluator(Program* program) { // This program is straight from the ProblemImpl, and so has no index/offset - // yet; compute it here as required by the evalutor implementations. + // yet; compute it here as required by the evaluator implementations. program->SetParameterOffsetsAndIndex(); if (VLOG_IS_ON(1)) { @@ -457,12 +462,12 @@ TEST_P(EvaluatorTest, MultipleResidualProblemWithSomeConstantParameters) { problem.AddParameterBlock(z, 4); // f(x, y) in R^2 - problem.AddResidualBlock(new ParameterIgnoringCostFunction<1, 2, 2, 3>, + problem.AddResidualBlock(new ParameterIgnoringCostFunction<1, 2, 2, 3>, NULL, x, y); // g(x, z) in R^3 - problem.AddResidualBlock(new ParameterIgnoringCostFunction<2, 3, 2, 4>, + problem.AddResidualBlock(new ParameterIgnoringCostFunction<2, 3, 2, 4>, NULL, x, z); @@ -526,7 +531,7 @@ TEST_P(EvaluatorTest, MultipleResidualProblemWithSomeConstantParameters) { TEST_P(EvaluatorTest, EvaluatorAbortsForResidualsThatFailToEvaluate) { // Switch the return value to failure. problem.AddResidualBlock( - new ParameterIgnoringCostFunction<20, 3, 2, 3, 4, false>, NULL, x, y, z); + new ParameterIgnoringCostFunction<20, 3, 2, 3, 4>(false), NULL, x, y, z); // The values are ignored. double state[9]; diff --git a/internal/ceres/line_search_preprocessor_test.cc b/internal/ceres/line_search_preprocessor_test.cc index d0a866b8b..301509c07 100644 --- a/internal/ceres/line_search_preprocessor_test.cc +++ b/internal/ceres/line_search_preprocessor_test.cc @@ -105,8 +105,8 @@ TEST(LineSearchPreprocessor, RemoveParameterBlocksSucceeds) { EXPECT_TRUE(preprocessor.Preprocess(options, &problem, &pp)); } -template -class DummyCostFunction : public SizedCostFunction { +template +class DummyCostFunction : public SizedCostFunction { public: bool Evaluate(double const* const* parameters, double* residuals, diff --git a/internal/ceres/parameter_block_ordering_test.cc b/internal/ceres/parameter_block_ordering_test.cc index 339e73b09..ba61be657 100644 --- a/internal/ceres/parameter_block_ordering_test.cc +++ b/internal/ceres/parameter_block_ordering_test.cc @@ -51,8 +51,8 @@ using std::vector; typedef Graph HessianGraph; typedef std::unordered_set VertexSet; -template -class DummyCostFunction: public SizedCostFunction { +template +class DummyCostFunction : public SizedCostFunction { virtual bool Evaluate(double const* const* parameters, double* residuals, double** jacobians) const { diff --git a/internal/ceres/program_test.cc b/internal/ceres/program_test.cc index 52eaa4069..01bf2337e 100644 --- a/internal/ceres/program_test.cc +++ b/internal/ceres/program_test.cc @@ -35,9 +35,10 @@ #include #include -#include "ceres/sized_cost_function.h" +#include "ceres/internal/integer_sequence_algorithm.h" #include "ceres/problem_impl.h" #include "ceres/residual_block.h" +#include "ceres/sized_cost_function.h" #include "ceres/triplet_sparse_matrix.h" #include "gtest/gtest.h" @@ -62,22 +63,23 @@ class UnaryIdentityCostFunction : public SizedCostFunction<1, 1> { }; // Templated base class for the CostFunction signatures. -template -class MockCostFunctionBase : public -SizedCostFunction { +template +class MockCostFunctionBase : public SizedCostFunction { public: virtual bool Evaluate(double const* const* parameters, double* residuals, double** jacobians) const { + const int kNumParameters = Sum>::Value; + for (int i = 0; i < kNumResiduals; ++i) { - residuals[i] = kNumResiduals + N0 + N1 + N2; + residuals[i] = kNumResiduals + kNumParameters; } return true; } }; -class UnaryCostFunction : public MockCostFunctionBase<2, 1, 0, 0> {}; -class BinaryCostFunction : public MockCostFunctionBase<2, 1, 1, 0> {}; +class UnaryCostFunction : public MockCostFunctionBase<2, 1> {}; +class BinaryCostFunction : public MockCostFunctionBase<2, 1, 1> {}; class TernaryCostFunction : public MockCostFunctionBase<2, 1, 1, 1> {}; TEST(Program, RemoveFixedBlocksNothingConstant) { @@ -247,14 +249,14 @@ TEST(Program, CreateJacobianBlockSparsityTranspose) { problem.AddParameterBlock(y, 3); problem.AddParameterBlock(&z, 1); - problem.AddResidualBlock(new MockCostFunctionBase<2, 2, 0, 0>(), NULL, x); - problem.AddResidualBlock(new MockCostFunctionBase<3, 1, 2, 0>(), NULL, &z, x); - problem.AddResidualBlock(new MockCostFunctionBase<4, 1, 3, 0>(), NULL, &z, y); - problem.AddResidualBlock(new MockCostFunctionBase<5, 1, 3, 0>(), NULL, &z, y); - problem.AddResidualBlock(new MockCostFunctionBase<1, 2, 1, 0>(), NULL, x, &z); - problem.AddResidualBlock(new MockCostFunctionBase<2, 1, 3, 0>(), NULL, &z, y); - problem.AddResidualBlock(new MockCostFunctionBase<2, 2, 1, 0>(), NULL, x, &z); - problem.AddResidualBlock(new MockCostFunctionBase<1, 3, 0, 0>(), NULL, y); + problem.AddResidualBlock(new MockCostFunctionBase<2, 2>(), NULL, x); + problem.AddResidualBlock(new MockCostFunctionBase<3, 1, 2>(), NULL, &z, x); + problem.AddResidualBlock(new MockCostFunctionBase<4, 1, 3>(), NULL, &z, y); + problem.AddResidualBlock(new MockCostFunctionBase<5, 1, 3>(), NULL, &z, y); + problem.AddResidualBlock(new MockCostFunctionBase<1, 2, 1>(), NULL, x, &z); + problem.AddResidualBlock(new MockCostFunctionBase<2, 1, 3>(), NULL, &z, y); + problem.AddResidualBlock(new MockCostFunctionBase<2, 2, 1>(), NULL, x, &z); + problem.AddResidualBlock(new MockCostFunctionBase<1, 3>(), NULL, y); TripletSparseMatrix expected_block_sparse_jacobian(3, 8, 14); { @@ -386,7 +388,7 @@ TEST(Program, ProblemHasNanParameterBlocks) { double x[2]; x[0] = 1.0; x[1] = std::numeric_limits::quiet_NaN(); - problem.AddResidualBlock(new MockCostFunctionBase<1, 2, 0, 0>(), NULL, x); + problem.AddResidualBlock(new MockCostFunctionBase<1, 2>(), NULL, x); string error; EXPECT_FALSE(problem.program().ParameterBlocksAreFinite(&error)); EXPECT_NE(error.find("has at least one invalid value"), @@ -396,7 +398,7 @@ TEST(Program, ProblemHasNanParameterBlocks) { TEST(Program, InfeasibleParameterBlock) { ProblemImpl problem; double x[] = {0.0, 0.0}; - problem.AddResidualBlock(new MockCostFunctionBase<1, 2, 0, 0>(), NULL, x); + problem.AddResidualBlock(new MockCostFunctionBase<1, 2>(), NULL, x); problem.SetParameterLowerBound(x, 0, 2.0); problem.SetParameterUpperBound(x, 0, 1.0); string error; @@ -407,7 +409,7 @@ TEST(Program, InfeasibleParameterBlock) { TEST(Program, InfeasibleConstantParameterBlock) { ProblemImpl problem; double x[] = {0.0, 0.0}; - problem.AddResidualBlock(new MockCostFunctionBase<1, 2, 0, 0>(), NULL, x); + problem.AddResidualBlock(new MockCostFunctionBase<1, 2>(), NULL, x); problem.SetParameterLowerBound(x, 0, 1.0); problem.SetParameterUpperBound(x, 0, 2.0); problem.SetParameterBlockConstant(x); diff --git a/internal/ceres/reorder_program_test.cc b/internal/ceres/reorder_program_test.cc index be548efd6..cf3e9f6ef 100644 --- a/internal/ceres/reorder_program_test.cc +++ b/internal/ceres/reorder_program_test.cc @@ -45,9 +45,8 @@ namespace internal { using std::vector; // Templated base class for the CostFunction signatures. -template -class MockCostFunctionBase : public -SizedCostFunction { +template +class MockCostFunctionBase : public SizedCostFunction { public: virtual bool Evaluate(double const* const* parameters, double* residuals, @@ -57,8 +56,8 @@ SizedCostFunction { } }; -class UnaryCostFunction : public MockCostFunctionBase<2, 1, 0, 0> {}; -class BinaryCostFunction : public MockCostFunctionBase<2, 1, 1, 0> {}; +class UnaryCostFunction : public MockCostFunctionBase<2, 1> {}; +class BinaryCostFunction : public MockCostFunctionBase<2, 1, 1> {}; class TernaryCostFunction : public MockCostFunctionBase<2, 1, 1, 1> {}; TEST(_, ReorderResidualBlockNormalFunction) { diff --git a/internal/ceres/solver_test.cc b/internal/ceres/solver_test.cc index d11fef478..6acae0b39 100644 --- a/internal/ceres/solver_test.cc +++ b/internal/ceres/solver_test.cc @@ -453,8 +453,8 @@ TEST(Solver, CantMixEvaluationCallbackWithInnerIterations) { EXPECT_TRUE(options.IsValid(&message)); } -template -class DummyCostFunction : public SizedCostFunction { +template +class DummyCostFunction : public SizedCostFunction { public: bool Evaluate(double const* const* parameters, double* residuals, diff --git a/internal/ceres/trust_region_preprocessor_test.cc b/internal/ceres/trust_region_preprocessor_test.cc index 0c91e216e..47cc4fbdb 100644 --- a/internal/ceres/trust_region_preprocessor_test.cc +++ b/internal/ceres/trust_region_preprocessor_test.cc @@ -28,6 +28,7 @@ // // Author: sameeragarwal@google.com (Sameer Agarwal) +#include #include #include "ceres/ordered_groups.h" @@ -113,8 +114,8 @@ TEST(TrustRegionPreprocessor, RemoveParameterBlocksSucceeds) { EXPECT_TRUE(preprocessor.Preprocess(options, &problem, &pp)); } -template -class DummyCostFunction : public SizedCostFunction { +template +class DummyCostFunction : public SizedCostFunction { public: bool Evaluate(double const* const* parameters, double* residuals, @@ -127,30 +128,13 @@ class DummyCostFunction : public SizedCostFunction { return true; } - if (jacobians[0] != NULL) { - MatrixRef j(jacobians[0], kNumResiduals, N1); - j.setOnes(); - j *= kNumResiduals * N1; - } - - if (N2 == 0) { - return true; - } - - if (jacobians[1] != NULL) { - MatrixRef j(jacobians[1], kNumResiduals, N2); - j.setOnes(); - j *= kNumResiduals * N2; - } - - if (N3 == 0) { - return true; - } - - if (jacobians[2] != NULL) { - MatrixRef j(jacobians[2], kNumResiduals, N3); - j.setOnes(); - j *= kNumResiduals * N3; + std::array N{Ns...}; + for (size_t i = 0; i < N.size(); ++i) { + if (jacobians[i] != NULL) { + MatrixRef j(jacobians[i], kNumResiduals, N[i]); + j.setOnes(); + j *= kNumResiduals * N[i]; + } } return true;