Fix Eigen3 Row/Column Major storage issue.

Eigen3 does not allow column vectors to be stored in row-major
format. NumericDiffCostFunction by default stores its Jacobian
matrices in row-major format. This works fine if the residual
contains more than one variable. But if the residual block
depends on one variable and has more than one residuals, the
resulting Jacobian matrix is a column matrix in row-major format
resulting in a compile time error.

The fix is to check the template parameters and switch to column-major
storage as needed.

Thanks to Lena Gieseke for reporting this.

Change-Id: Icc51c5b38e1f3609e0e1ecb3c4e4a02aecd72c3b
diff --git a/include/ceres/numeric_diff_cost_function.h b/include/ceres/numeric_diff_cost_function.h
index bbaefca..8544e44 100644
--- a/include/ceres/numeric_diff_cost_function.h
+++ b/include/ceres/numeric_diff_cost_function.h
@@ -93,11 +93,13 @@
     using Eigen::Map;
     using Eigen::Matrix;
     using Eigen::RowMajor;
+    using Eigen::ColMajor;
 
     typedef Matrix<double, num_residuals, 1> ResidualVector;
     typedef Matrix<double, parameter_block_size, 1> ParameterVector;
-    typedef Matrix<double, num_residuals, parameter_block_size, RowMajor>
-        JacobianMatrix;
+    typedef Matrix<double, num_residuals, parameter_block_size,
+                   (parameter_block_size == 1 &&
+                    num_residuals > 1) ? ColMajor : RowMajor> JacobianMatrix;
 
     Map<JacobianMatrix> parameter_jacobian(jacobians[parameter_block],
                                            num_residuals,
diff --git a/internal/ceres/numeric_diff_cost_function_test.cc b/internal/ceres/numeric_diff_cost_function_test.cc
index 1b17aa6..df12eb9 100644
--- a/internal/ceres/numeric_diff_cost_function_test.cc
+++ b/internal/ceres/numeric_diff_cost_function_test.cc
@@ -37,6 +37,7 @@
 #include "ceres/cost_function.h"
 #include "ceres/internal/macros.h"
 #include "ceres/internal/scoped_ptr.h"
+#include "ceres/sized_cost_function.h"
 #include "ceres/stringprintf.h"
 #include "ceres/test_util.h"
 #include "ceres/types.h"
@@ -230,5 +231,41 @@
   }
 }
 
+
+template<int num_rows, int num_cols>
+class SizeTestingCostFunction : public SizedCostFunction<num_rows, num_cols> {
+ public:
+  virtual bool Evaluate(double const* const* parameters,
+                        double* residuals,
+                        double** jacobians) const {
+    return true;
+  }
+};
+
+// As described in
+// http://forum.kde.org/viewtopic.php?f=74&t=98536#p210774
+// Eigen3 has restrictions on the Row/Column major storage of vectors,
+// depending on their dimensions. This test ensures that the correct
+// templates are instantiated for various shapes of the Jacobian
+// matrix.
+TEST(NumericDiffCostFunction, EigenRowMajorColMajorTest) {
+  scoped_ptr<CostFunction> cost_function;
+  cost_function.reset(
+      new NumericDiffCostFunction<SizeTestingCostFunction<1,1>,  CENTRAL, 1, 1>(
+          new SizeTestingCostFunction<1,1>, ceres::TAKE_OWNERSHIP));
+
+  cost_function.reset(
+      new NumericDiffCostFunction<SizeTestingCostFunction<2,1>,  CENTRAL, 2, 1>(
+          new SizeTestingCostFunction<2,1>, ceres::TAKE_OWNERSHIP));
+
+  cost_function.reset(
+      new NumericDiffCostFunction<SizeTestingCostFunction<1,2>,  CENTRAL, 1, 2>(
+          new SizeTestingCostFunction<1,2>, ceres::TAKE_OWNERSHIP));
+
+  cost_function.reset(
+      new NumericDiffCostFunction<SizeTestingCostFunction<2,2>,  CENTRAL, 2, 2>(
+          new SizeTestingCostFunction<2,2>, ceres::TAKE_OWNERSHIP));
+}
+
 }  // namespace internal
 }  // namespace ceres