Solver:Support autodiff for dyn. NUM_RESIDUALS

Enable use of dynamic number of residuals for autodiff.
Implemented with "Substitution failure is not an error" similar
to tiny_solver.h .
Move test from tiny_solver_test.cc to
tiny_solver_autodiff_function_test.cc .
Use cpplint.py from C++ Google Style Guide for formatting.

Change-Id: I2e1a159d17118552943c6ac7a833c5bbd0c927ec
diff --git a/include/ceres/tiny_solver_autodiff_function.h b/include/ceres/tiny_solver_autodiff_function.h
index c54a6e5..76e4a24 100644
--- a/include/ceres/tiny_solver_autodiff_function.h
+++ b/include/ceres/tiny_solver_autodiff_function.h
@@ -35,6 +35,8 @@
 #ifndef CERES_PUBLIC_TINY_SOLVER_AUTODIFF_FUNCTION_H_
 #define CERES_PUBLIC_TINY_SOLVER_AUTODIFF_FUNCTION_H_
 
+#include <memory>
+#include <type_traits>
 #include "Eigen/Core"
 
 #include "ceres/jet.h"
@@ -45,6 +47,7 @@
 // An adapter around autodiff-style CostFunctors to enable easier use of
 // TinySolver. See the example below showing how to use it:
 //
+//   // Example for cost functor with static residual size.
 //   // Same as an autodiff cost functor, but taking only 1 parameter.
 //   struct MyFunctor {
 //     template<typename T>
@@ -68,6 +71,37 @@
 //   TinySolver<AutoDiffFunction> solver;
 //   solver.Solve(f, &x);
 //
+//   // Example for cost functor with dynamic residual size.
+//   // NumResiduals() supplies dynamic size of residuals.
+//   // Same functionality as in tiny_solver.h but with autodiff.
+//   struct MyFunctorWithDynamicResiduals {
+//     int NumResiduals() const {
+//       return 2;
+//     }
+//
+//     template<typename T>
+//     bool operator()(const T* const parameters, T* residuals) const {
+//       const T& x = parameters[0];
+//       const T& y = parameters[1];
+//       const T& z = parameters[2];
+//       residuals[0] = x + static_cast<T>(2.)*y + static_cast<T>(4.)*z;
+//       residuals[1] = y * z;
+//       return true;
+//     }
+//   };
+//
+//   typedef TinySolverAutoDiffFunction<MyFunctorWithDynamicResiduals,
+//                                      Eigen::Dynamic,
+//                                      3>
+//       AutoDiffFunctionWithDynamicResiduals;
+//
+//   MyFunctorWithDynamicResiduals my_functor_dyn;
+//   AutoDiffFunctionWithDynamicResiduals f(my_functor_dyn);
+//
+//   Vec3 x = ...;
+//   TinySolver<AutoDiffFunctionWithDynamicResiduals> solver;
+//   solver.Solve(f, &x);
+//
 // WARNING: The cost function adapter is not thread safe.
 template<typename CostFunctor,
          int kNumResiduals,
@@ -75,8 +109,10 @@
          typename T = double>
 class TinySolverAutoDiffFunction {
  public:
-   TinySolverAutoDiffFunction(const CostFunctor& cost_functor)
-     : cost_functor_(cost_functor) {}
+  TinySolverAutoDiffFunction(const CostFunctor& cost_functor)
+      : cost_functor_(cost_functor) {
+    Initialize<kNumResiduals>(cost_functor);
+  }
 
   typedef T Scalar;
   enum {
@@ -102,21 +138,22 @@
     }
 
     // Initialize the output jets such that we can detect user errors.
-    for (int i = 0; i < kNumResiduals; ++i) {
+    for (int i = 0; i < num_residuals_; ++i) {
       jet_residuals_[i].a = kImpossibleValue;
       jet_residuals_[i].v.setConstant(kImpossibleValue);
     }
 
     // Execute the cost function, but with jets to find the derivative.
-    if (!cost_functor_(jet_parameters_, jet_residuals_)) {
+    if (!cost_functor_(jet_parameters_, jet_residuals_.data())) {
       return false;
     }
 
     // Copy the jacobian out of the derivative part of the residual jets.
-    Eigen::Map<Eigen::Matrix<T,
-                             kNumResiduals,
-                             kNumParameters>> jacobian_matrix(jacobian);
-    for (int r = 0; r < kNumResiduals; ++r) {
+    Eigen::Map<Eigen::Matrix<T, kNumResiduals, kNumParameters>> jacobian_matrix(
+        jacobian,
+        num_residuals_,
+        kNumParameters);
+    for (int r = 0; r < num_residuals_; ++r) {
       residuals[r] = jet_residuals_[r].a;
       // Note that while this looks like a fast vectorized write, in practice it
       // unfortunately thrashes the cache since the writes to the column-major
@@ -126,16 +163,42 @@
     return true;
   }
 
+  int NumResiduals() const {
+    return num_residuals_;  // Set by Initialize.
+  }
+
  private:
   const CostFunctor& cost_functor_;
 
+  // The number of residuals at runtime.
+  // This will be overriden if NUM_RESIDUALS == Eigen::Dynamic.
+  int num_residuals_ = kNumResiduals;
+
   // To evaluate the cost function with jets, temporary storage is needed. These
   // are the buffers that are used during evaluation; parameters for the input,
   // and jet_residuals_ are where the final cost and derivatives end up.
   //
   // Since this buffer is used for evaluation, the adapter is not thread safe.
-  mutable Jet<T, kNumParameters> jet_parameters_[kNumParameters];
-  mutable Jet<T, kNumParameters> jet_residuals_[kNumResiduals];
+  using JetType = Jet<T, kNumParameters>;
+  mutable JetType jet_parameters_[kNumParameters];
+  // Eigen::Matrix serves as static or dynamic container.
+  mutable Eigen::Matrix<JetType, kNumResiduals, 1> jet_residuals_;
+
+  // The number of residuals is dynamically sized and the number of
+  // parameters is statically sized.
+  template<int R>
+  typename std::enable_if<(R == Eigen::Dynamic), void>::type Initialize(
+      const CostFunctor& function) {
+    jet_residuals_.resize(function.NumResiduals());
+    num_residuals_ = function.NumResiduals();
+  }
+
+  // The number of parameters and residuals are statically sized.
+  template<int R>
+  typename std::enable_if<(R != Eigen::Dynamic), void>::type Initialize(
+      const CostFunctor& /* function */) {
+    num_residuals_ = kNumResiduals;
+  }
 };
 
 }  // namespace ceres
diff --git a/internal/ceres/tiny_solver_autodiff_function_test.cc b/internal/ceres/tiny_solver_autodiff_function_test.cc
index 7b54c0f..0b542a2 100644
--- a/internal/ceres/tiny_solver_autodiff_function_test.cc
+++ b/internal/ceres/tiny_solver_autodiff_function_test.cc
@@ -30,6 +30,8 @@
 // Author: mierle@gmail.com (Keir Mierle)
 
 #include "ceres/tiny_solver_autodiff_function.h"
+#include "ceres/tiny_solver.h"
+#include "ceres/tiny_solver_test_util.h"
 
 #include <algorithm>
 #include <cmath>
@@ -39,9 +41,6 @@
 
 namespace ceres {
 
-typedef Eigen::Matrix<double, 2, 1> Vec2;
-typedef Eigen::Matrix<double, 3, 1> Vec3;
-
 struct AutoDiffTestFunctor {
   template<typename T>
   bool operator()(const T* const parameters, T* residuals) const {
@@ -66,8 +65,8 @@
   AutoDiffTestFunctor autodiff_test_functor;
   AutoDiffTestFunction f(autodiff_test_functor);
 
-  Vec3 x(2.0, 1.0, 4.0);
-  Vec2 residuals;
+  Eigen::Vector3d x(2.0, 1.0, 4.0);
+  Eigen::Vector2d residuals;
 
   // Check the case with cost-only evaluation.
   residuals.setConstant(555);  // Arbitrary.
@@ -96,4 +95,57 @@
   EXPECT_NEAR(6.0, jacobian(1, 2), kTolerance);
 }
 
+class DynamicResidualsFunctor {
+ public:
+  typedef double Scalar;
+  enum {
+    NUM_RESIDUALS = Eigen::Dynamic,
+    NUM_PARAMETERS = 3,
+  };
+
+  int NumResiduals() const {
+    return 2;
+  }
+
+  template<typename T>
+  bool operator()(const T* parameters, T* residuals) const {
+    // Jacobian is not evaluated by cost function, but by autodiff.
+    T* jacobian = NULL;
+    return EvaluateResidualsAndJacobians(parameters, residuals, jacobian);
+  }
+};
+
+template<typename Function, typename Vector>
+void TestHelper(const Function& f, const Vector& x0) {
+  Vector x = x0;
+  Eigen::Vector2d residuals;
+  f(x.data(), residuals.data(), NULL);
+  EXPECT_GT(residuals.squaredNorm() / 2.0, 1e-10);
+
+  TinySolver<Function> solver;
+  solver.Solve(f, &x);
+  EXPECT_NEAR(0.0, solver.summary.final_cost, 1e-10);
+}
+
+// A test case for when the number of residuals is
+// dynamically sized and we use autodiff
+TEST(TinySolverAutoDiffFunction, ResidualsDynamicAutoDiff) {
+  Eigen::Vector3d x0(0.76026643, -30.01799744, 0.55192142);
+
+  DynamicResidualsFunctor f;
+  using AutoDiffCostFunctor =
+      ceres::TinySolverAutoDiffFunction<DynamicResidualsFunctor,
+                                        Eigen::Dynamic,
+                                        3>;
+  AutoDiffCostFunctor f_autodiff(f);
+
+  Eigen::Vector2d residuals;
+  f_autodiff(x0.data(), residuals.data(), NULL);
+  EXPECT_GT(residuals.squaredNorm() / 2.0, 1e-10);
+
+  TinySolver<AutoDiffCostFunctor> solver;
+  solver.Solve(f, &x0);
+  EXPECT_NEAR(0.0, solver.summary.final_cost, 1e-10);
+}
+
 }  // namespace ceres
diff --git a/internal/ceres/tiny_solver_test.cc b/internal/ceres/tiny_solver_test.cc
index df0101f..2a8cd39 100644
--- a/internal/ceres/tiny_solver_test.cc
+++ b/internal/ceres/tiny_solver_test.cc
@@ -30,6 +30,7 @@
 // Author: mierle@gmail.com (Keir Mierle)
 
 #include "ceres/tiny_solver.h"
+#include "ceres/tiny_solver_test_util.h"
 
 #include <algorithm>
 #include <cmath>
@@ -42,29 +43,6 @@
 typedef Eigen::Matrix<double, 3, 1> Vec3;
 typedef Eigen::VectorXd VecX;
 
-bool EvaluateResidualsAndJacobians(const double* parameters,
-                                   double* residuals,
-                                   double* jacobian) {
-  double x = parameters[0];
-  double y = parameters[1];
-  double z = parameters[2];
-
-  residuals[0] = x + 2*y + 4*z;
-  residuals[1] = y * z;
-
-  if (jacobian) {
-    jacobian[0 * 2 + 0] = 1;
-    jacobian[0 * 2 + 1] = 0;
-
-    jacobian[1 * 2 + 0] = 2;
-    jacobian[1 * 2 + 1] = z;
-
-    jacobian[2 * 2 + 0] = 4;
-    jacobian[2 * 2 + 1] = y;
-  }
-  return true;
-}
-
 class ExampleStatic {
  public:
   typedef double Scalar;
@@ -141,7 +119,7 @@
   }
 };
 
-template <typename Function, typename Vector>
+template<typename Function, typename Vector>
 void TestHelper(const Function& f, const Vector& x0) {
   Vector x = x0;
   Vec2 residuals;
@@ -161,7 +139,6 @@
   TestHelper(f, x0);
 }
 
-
 // A test case for when the number of parameters is dynamically sized.
 TEST(TinySolver, ParametersDynamic) {
   VecX x0(3);
diff --git a/internal/ceres/tiny_solver_test_util.h b/internal/ceres/tiny_solver_test_util.h
new file mode 100644
index 0000000..48fe955
--- /dev/null
+++ b/internal/ceres/tiny_solver_test_util.h
@@ -0,0 +1,63 @@
+
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2017 Google Inc. All rights reserved.
+// http://ceres-solver.org/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright notice,
+//   this list of conditions and the following disclaimer in the documentation
+//   and/or other materials provided with the distribution.
+// * Neither the name of Google Inc. nor the names of its contributors may be
+//   used to endorse or promote products derived from this software without
+//   specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: mierle@gmail.com (Keir Mierle)
+
+#ifndef CERES_INTERNAL_TINY_SOLVER_TEST_UTIL_H_
+#define CERES_INTERNAL_TINY_SOLVER_TEST_UTIL_H_
+
+namespace ceres {
+
+template<typename T>
+bool EvaluateResidualsAndJacobians(const T* parameters,
+                                   T* residuals,
+                                   T* jacobian) {
+  T x = parameters[0];
+  T y = parameters[1];
+  T z = parameters[2];
+
+  residuals[0] = x + static_cast<T>(2) * y + static_cast<T>(4) * z;
+  residuals[1] = y * z;
+
+  if (jacobian) {
+    jacobian[0 * 2 + 0] = static_cast<T>(1);
+    jacobian[0 * 2 + 1] = static_cast<T>(0);
+
+    jacobian[1 * 2 + 0] = static_cast<T>(2);
+    jacobian[1 * 2 + 1] = z;
+
+    jacobian[2 * 2 + 0] = static_cast<T>(4);
+    jacobian[2 * 2 + 1] = y;
+  }
+  return true;
+}
+
+}  // namespace ceres
+
+#endif  // CERES_INTERNAL_TINY_SOLVER_TEST_UTIL_H_