NumericDiffCostFunction supports dynamic number of residuals.

1. Update AutoDiffCostFunction template parameters to be consistent
with NumericDiffCostFunction.

2. Update the documentation for NumericDiffCostFunction and
AutoDiffCostFunction.

Change-Id: I113038abb5bedebb0f6f326f2a4ac31480d785fc
diff --git a/docs/source/building.rst b/docs/source/building.rst
index c326fd1..b74a9dd 100644
--- a/docs/source/building.rst
+++ b/docs/source/building.rst
@@ -1,8 +1,8 @@
 .. _chapter-building:
 
-=====================
-Building Ceres Solver
-=====================
+============
+Installation
+============
 
 Stable Ceres Solver releases are available for download at
 `code.google.com <http://code.google.com/p/ceres-solver/>`_. For the
diff --git a/docs/source/modeling.rst b/docs/source/modeling.rst
index 8e6de12..a5e875d 100644
--- a/docs/source/modeling.rst
+++ b/docs/source/modeling.rst
@@ -164,7 +164,7 @@
    .. code-block:: c++
 
      template <typename CostFunctor,
-            int M,        // Number of residuals, or ceres::DYNAMIC.
+            int kNumResiduals,  // Number of residuals, or ceres::DYNAMIC.
             int N0,       // Number of parameters in block 0.
             int N1 = 0,   // Number of parameters in block 1.
             int N2 = 0,   // Number of parameters in block 2.
@@ -176,7 +176,7 @@
             int N8 = 0,   // Number of parameters in block 8.
             int N9 = 0>   // Number of parameters in block 9.
      class AutoDiffCostFunction : public
-     SizedCostFunction<M, N0, N1, N2, N3, N4, N5, N6, N7, N8, N9> {
+     SizedCostFunction<kNumResiduals, N0, N1, N2, N3, N4, N5, N6, N7, N8, N9> {
      };
 
    To get an auto differentiated cost function, you must define a
@@ -254,6 +254,22 @@
    computing a 1-dimensional output from two arguments, both
    2-dimensional.
 
+   :class:`AutoDiffCostFunction` also supports cost functions with a
+   runtime-determined number of residuals. For example:
+
+   .. code-block:: c++
+
+     CostFunction* cost_function
+         = new AutoDiffCostFunction<MyScalarCostFunctor, DYNAMIC, 2, 2>(
+             new CostFunctorWithDynamicNumResiduals(1.0),   ^     ^  ^
+             runtime_number_of_residuals); <----+           |     |  |
+                                                |           |     |  |
+                                                |           |     |  |
+               Actual number of residuals ------+           |     |  |
+               Indicate dynamic number of residuals --------+     |  |
+               Dimension of x ------------------------------------+  |
+               Dimension of y ---------------------------------------+
+
    The framework can currently accommodate cost functions of up to 10
    independent variables, and there is no limit on the dimensionality
    of each of them.
@@ -342,12 +358,21 @@
 
     .. code-block:: c++
 
-      template <typename CostFunctionNoJacobian,
-                NumericDiffMethod method = CENTRAL, int M = 0,
-                int N0 = 0, int N1 = 0, int N2 = 0, int N3 = 0, int N4 = 0,
-                int N5 = 0, int N6 = 0, int N7 = 0, int N8 = 0, int N9 = 0>
+      template <typename CostFunctor,
+                NumericDiffMethod method = CENTRAL,
+                int kNumResiduals,  // Number of residuals, or ceres::DYNAMIC.
+                int N0,       // Number of parameters in block 0.
+                int N1 = 0,   // Number of parameters in block 1.
+                int N2 = 0,   // Number of parameters in block 2.
+                int N3 = 0,   // Number of parameters in block 3.
+                int N4 = 0,   // Number of parameters in block 4.
+                int N5 = 0,   // Number of parameters in block 5.
+                int N6 = 0,   // Number of parameters in block 6.
+                int N7 = 0,   // Number of parameters in block 7.
+                int N8 = 0,   // Number of parameters in block 8.
+                int N9 = 0>   // Number of parameters in block 9.
       class NumericDiffCostFunction
-        : public SizedCostFunction<M, N0, N1, N2, N3, N4, N5, N6, N7, N8, N9> {
+        : public SizedCostFunction<kNumResiduals, N0, N1, N2, N3, N4, N5, N6, N7, N8, N9> {
       };
 
    To get a numerically differentiated :class:`CostFunction`, you must
@@ -426,6 +451,24 @@
    computing a 1-dimensional output from two arguments, both
    2-dimensional.
 
+   NumericDiffCostFunction also supports cost functions with a
+   runtime-determined number of residuals. For example:
+
+   .. code-block:: c++
+
+     CostFunction* cost_function
+         = new NumericDiffCostFunction<MyScalarCostFunctor, CENTRAL, DYNAMIC, 2, 2>(
+             new CostFunctorWithDynamicNumResiduals(1.0),   ^     ^  ^
+             TAKE_OWNERSHIP,                                |     |  |
+             runtime_number_of_residuals); <----+           |     |  |
+                                                |           |     |  |
+                                                |           |     |  |
+               Actual number of residuals ------+           |     |  |
+               Indicate dynamic number of residuals --------+     |  |
+               Dimension of x ------------------------------------+  |
+               Dimension of y ---------------------------------------+
+
+
    The framework can currently accommodate cost functions of up to 10
    independent variables, and there is no limit on the dimensionality
    of each of them.
diff --git a/include/ceres/autodiff_cost_function.h b/include/ceres/autodiff_cost_function.h
index 371a11f..cb6801f 100644
--- a/include/ceres/autodiff_cost_function.h
+++ b/include/ceres/autodiff_cost_function.h
@@ -96,7 +96,7 @@
 // "MyScalarCostFunctor", "1, 2, 2", describe the functor as computing a
 // 1-dimensional output from two arguments, both 2-dimensional.
 //
-// The autodiff cost function also supports cost functions with a
+// AutoDiffCostFunction also supports cost functions with a
 // runtime-determined number of residuals. For example:
 //
 //   CostFunction* cost_function
@@ -110,8 +110,9 @@
 //             Dimension of x ------------------------------------+  |
 //             Dimension of y ---------------------------------------+
 //
-// The framework can currently accommodate cost functions of up to 6 independent
-// variables, and there is no limit on the dimensionality of each of them.
+// The framework can currently accommodate cost functions of up to 10
+// independent variables, and there is no limit on the dimensionality
+// of each of them.
 //
 // WARNING #1: Since the functor will get instantiated with different types for
 // T, you must to convert from other numeric types to T before mixing
@@ -145,13 +146,13 @@
 //
 // The constructors take ownership of the cost functor.
 //
-// If the number of residuals (argument "M" below) is ceres::DYNAMIC, then the
-// two-argument constructor must be used. The second constructor takes a number
-// of residuals (in addition to the templated number of residuals). This allows
-// for varying the number of residuals for a single autodiff cost function at
-// runtime.
+// If the number of residuals (argument kNumResiduals below) is
+// ceres::DYNAMIC, then the two-argument constructor must be used. The
+// second constructor takes a number of residuals (in addition to the
+// templated number of residuals). This allows for varying the number
+// of residuals for a single autodiff cost function at runtime.
 template <typename CostFunctor,
-          int M,        // Number of residuals, or ceres::DYNAMIC.
+          int kNumResiduals,  // Number of residuals, or ceres::DYNAMIC.
           int N0,       // Number of parameters in block 0.
           int N1 = 0,   // Number of parameters in block 1.
           int N2 = 0,   // Number of parameters in block 2.
@@ -162,28 +163,30 @@
           int N7 = 0,   // Number of parameters in block 7.
           int N8 = 0,   // Number of parameters in block 8.
           int N9 = 0>   // Number of parameters in block 9.
-class AutoDiffCostFunction : public SizedCostFunction<M,
+class AutoDiffCostFunction : public SizedCostFunction<kNumResiduals,
                                                       N0, N1, N2, N3, N4,
                                                       N5, N6, N7, N8, N9> {
  public:
   // Takes ownership of functor. Uses the template-provided value for the
-  // number of residuals ("M").
+  // number of residuals ("kNumResiduals").
   explicit AutoDiffCostFunction(CostFunctor* functor)
       : functor_(functor) {
-    CHECK_NE(M, DYNAMIC) << "Can't run the fixed-size constructor if the "
-                         << "number of residuals is set to ceres::DYNAMIC.";
+    CHECK_NE(kNumResiduals, DYNAMIC)
+        << "Can't run the fixed-size constructor if the "
+        << "number of residuals is set to ceres::DYNAMIC.";
   }
 
-  // Takes ownership of functor. Ignores the template-provided number of
-  // residuals ("M") in favor of the "num_residuals" argument provided.
+  // Takes ownership of functor. Ignores the template-provided
+  // kNumResiduals in favor of the "num_residuals" argument provided.
   //
   // This allows for having autodiff cost functions which return varying
   // numbers of residuals at runtime.
   AutoDiffCostFunction(CostFunctor* functor, int num_residuals)
       : functor_(functor) {
-    CHECK_EQ(M, DYNAMIC) << "Can't run the dynamic-size constructor if the "
-                         << "number of residuals is not ceres::DYNAMIC.";
-    SizedCostFunction<M, N0, N1, N2, N3, N4, N5, N6, N7, N8, N9>
+    CHECK_EQ(kNumResiduals, DYNAMIC)
+        << "Can't run the dynamic-size constructor if the "
+        << "number of residuals is not ceres::DYNAMIC.";
+    SizedCostFunction<kNumResiduals, N0, N1, N2, N3, N4, N5, N6, N7, N8, N9>
         ::set_num_residuals(num_residuals);
   }
 
@@ -206,7 +209,7 @@
            N0, N1, N2, N3, N4, N5, N6, N7, N8, N9>::Differentiate(
                *functor_,
                parameters,
-               SizedCostFunction<M, N0, N1, N2, N3, N4, N5, N6, N7, N8, N9>
+               SizedCostFunction<kNumResiduals, N0, N1, N2, N3, N4, N5, N6, N7, N8, N9>
                    ::num_residuals(),
                residuals,
                jacobians);
diff --git a/include/ceres/internal/numeric_diff.h b/include/ceres/internal/numeric_diff.h
index 4058366..5048348 100644
--- a/include/ceres/internal/numeric_diff.h
+++ b/include/ceres/internal/numeric_diff.h
@@ -90,6 +90,7 @@
       const CostFunctor* functor,
       double const* residuals_at_eval_point,
       const double relative_step_size,
+      int num_residuals,
       double **parameters,
       double *jacobian) {
     using Eigen::Map;
@@ -97,15 +98,21 @@
     using Eigen::RowMajor;
     using Eigen::ColMajor;
 
+    const int NUM_RESIDUALS =
+        (kNumResiduals != ceres::DYNAMIC ? kNumResiduals : num_residuals);
+
     typedef Matrix<double, kNumResiduals, 1> ResidualVector;
     typedef Matrix<double, kParameterBlockSize, 1> ParameterVector;
-    typedef Matrix<double, kNumResiduals, kParameterBlockSize,
+    typedef Matrix<double,
+                   kNumResiduals,
+                   kParameterBlockSize,
                    (kParameterBlockSize == 1 &&
-                    kNumResiduals > 1) ? ColMajor : RowMajor> JacobianMatrix;
+                    kNumResiduals > 1) ? ColMajor : RowMajor>
+        JacobianMatrix;
 
 
     Map<JacobianMatrix> parameter_jacobian(jacobian,
-                                           kNumResiduals,
+                                           NUM_RESIDUALS,
                                            kParameterBlockSize);
 
     // Mutate 1 element at a time and then restore.
@@ -125,16 +132,16 @@
 
     // For each parameter in the parameter block, use finite differences to
     // compute the derivative for that parameter.
+
+    ResidualVector residuals(NUM_RESIDUALS);
     for (int j = 0; j < kParameterBlockSize; ++j) {
       const double delta =
           (step_size(j) == 0.0) ? fallback_step_size : step_size(j);
 
       x_plus_delta(j) = x(j) + delta;
 
-      double residuals[kNumResiduals];  // NOLINT
-
       if (!EvaluateImpl<CostFunctor, N0, N1, N2, N3, N4, N5, N6, N7, N8, N9>(
-              functor, parameters, residuals, functor)) {
+              functor, parameters, residuals.data(), functor)) {
         return false;
       }
 
@@ -142,8 +149,7 @@
       // 1. Store residuals for the forward part.
       // 2. Subtract residuals for the backward (or 0) part.
       // 3. Divide out the run.
-      parameter_jacobian.col(j) =
-          Map<const ResidualVector>(residuals, kNumResiduals);
+      parameter_jacobian.col(j) = residuals;
 
       double one_over_delta = 1.0 / delta;
       if (kMethod == CENTRAL) {
@@ -151,17 +157,16 @@
         x_plus_delta(j) = x(j) - delta;
 
         if (!EvaluateImpl<CostFunctor, N0, N1, N2, N3, N4, N5, N6, N7, N8, N9>(
-                functor, parameters, residuals, functor)) {
+                functor, parameters, residuals.data(), functor)) {
           return false;
         }
 
-        parameter_jacobian.col(j) -=
-            Map<ResidualVector>(residuals, kNumResiduals, 1);
+        parameter_jacobian.col(j) -= residuals;
         one_over_delta /= 2;
       } else {
         // Forward difference only; reuse existing residuals evaluation.
         parameter_jacobian.col(j) -=
-            Map<const ResidualVector>(residuals_at_eval_point, kNumResiduals);
+            Map<const ResidualVector>(residuals_at_eval_point, NUM_RESIDUALS);
       }
       x_plus_delta(j) = x(j);  // Restore x_plus_delta.
 
@@ -186,6 +191,7 @@
       const CostFunctor* functor,
       double const* residuals_at_eval_point,
       const double relative_step_size,
+      const int num_residuals,
       double **parameters,
       double *jacobian) {
     LOG(FATAL) << "Control should never reach here.";
diff --git a/include/ceres/numeric_diff_cost_function.h b/include/ceres/numeric_diff_cost_function.h
index a47a66d..94573e5 100644
--- a/include/ceres/numeric_diff_cost_function.h
+++ b/include/ceres/numeric_diff_cost_function.h
@@ -95,6 +95,21 @@
 // "MyScalarCostFunctor", "1, 2, 2", describe the functor as computing
 // a 1-dimensional output from two arguments, both 2-dimensional.
 //
+// NumericDiffCostFunction also supports cost functions with a
+// runtime-determined number of residuals. For example:
+//
+//   CostFunction* cost_function
+//       = new NumericDiffCostFunction<MyScalarCostFunctor, CENTRAL, DYNAMIC, 2, 2>(
+//           new CostFunctorWithDynamicNumResiduals(1.0),   ^     ^  ^
+//           TAKE_OWNERSHIP,                                |     |  |
+//           runtime_number_of_residuals); <----+           |     |  |
+//                                              |           |     |  |
+//                                              |           |     |  |
+//             Actual number of residuals ------+           |     |  |
+//             Indicate dynamic number of residuals --------+     |  |
+//             Dimension of x ------------------------------------+  |
+//             Dimension of y ---------------------------------------+
+//
 // The framework can currently accommodate cost functions of up to 10
 // independent variables, and there is no limit on the dimensionality
 // of each of them.
@@ -104,8 +119,6 @@
 // central differences begin with, and only after that works, trying forward
 // difference to improve performance.
 //
-// TODO(sameeragarwal): Add support for dynamic number of residuals.
-//
 // WARNING #1: A common beginner's error when first using
 // NumericDiffCostFunction is to get the sizing wrong. In particular,
 // there is a tendency to set the template parameters to (dimension of
@@ -177,17 +190,17 @@
                                N5, N6, N7, N8, N9> {
  public:
   NumericDiffCostFunction(CostFunctor* functor,
+                          Ownership ownership = TAKE_OWNERSHIP,
+                          int num_residuals = kNumResiduals,
                           const double relative_step_size = 1e-6)
       :functor_(functor),
-       ownership_(TAKE_OWNERSHIP),
-       relative_step_size_(relative_step_size) {}
-
-  NumericDiffCostFunction(CostFunctor* functor,
-                          Ownership ownership,
-                          const double relative_step_size = 1e-6)
-      : functor_(functor),
-        ownership_(ownership),
-        relative_step_size_(relative_step_size) {}
+       ownership_(ownership),
+       relative_step_size_(relative_step_size) {
+    if (kNumResiduals == DYNAMIC) {
+      SizedCostFunction<kNumResiduals, N0, N1, N2, N3, N4, N5, N6, N7, N8, N9>
+          ::set_num_residuals(num_residuals);
+    }
+  }
 
   ~NumericDiffCostFunction() {
     if (ownership_ != TAKE_OWNERSHIP) {
@@ -216,7 +229,7 @@
       return false;
     }
 
-    if (!jacobians) {
+    if (jacobians == NULL) {
       return true;
     }
 
@@ -264,6 +277,7 @@
                            functor_.get(),                              \
                            residuals,                                   \
                            relative_step_size_,                         \
+                           SizedCostFunction<kNumResiduals, N0, N1, N2, N3, N4, N5, N6, N7, N8, N9>::num_residuals(), \
                            parameters_reference_copy.get(),             \
                            jacobians[block])) {                         \
         return false;                                                   \
diff --git a/internal/ceres/numeric_diff_cost_function_test.cc b/internal/ceres/numeric_diff_cost_function_test.cc
index 3953ded..422c712 100644
--- a/internal/ceres/numeric_diff_cost_function_test.cc
+++ b/internal/ceres/numeric_diff_cost_function_test.cc
@@ -184,5 +184,18 @@
           new SizeTestingCostFunction<2,2>, ceres::TAKE_OWNERSHIP));
 }
 
+TEST(NumericDiffCostFunction, EasyCaseFunctorCentralDifferencesAndDynamicNumResiduals) {
+  internal::scoped_ptr<CostFunction> cost_function;
+  cost_function.reset(
+      new NumericDiffCostFunction<EasyFunctor,
+                                  CENTRAL,
+                                  ceres::DYNAMIC,
+                                  5,  /* size of x1 */
+                                  5   /* size of x2 */>(
+                                      new EasyFunctor, TAKE_OWNERSHIP, 3));
+  EasyFunctor functor;
+  functor.ExpectCostFunctionEvaluationIsNearlyCorrect(*cost_function, CENTRAL);
+}
+
 }  // namespace internal
 }  // namespace ceres