diff --git a/include/ceres/numeric_diff_cost_function.h b/include/ceres/numeric_diff_cost_function.h index bbaefca5b..8544e44d0 100644 --- a/include/ceres/numeric_diff_cost_function.h +++ b/include/ceres/numeric_diff_cost_function.h @@ -93,11 +93,13 @@ struct Differencer { using Eigen::Map; using Eigen::Matrix; using Eigen::RowMajor; + using Eigen::ColMajor; typedef Matrix ResidualVector; typedef Matrix ParameterVector; - typedef Matrix - JacobianMatrix; + typedef Matrix 1) ? ColMajor : RowMajor> JacobianMatrix; Map 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 1b17aa6c3..df12eb98d 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 @@ TEST(NumericDiffCostFunction, TransendentalOperationsInCostFunction) { } } + +template +class SizeTestingCostFunction : public SizedCostFunction { + 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 cost_function; + cost_function.reset( + new NumericDiffCostFunction, CENTRAL, 1, 1>( + new SizeTestingCostFunction<1,1>, ceres::TAKE_OWNERSHIP)); + + cost_function.reset( + new NumericDiffCostFunction, CENTRAL, 2, 1>( + new SizeTestingCostFunction<2,1>, ceres::TAKE_OWNERSHIP)); + + cost_function.reset( + new NumericDiffCostFunction, CENTRAL, 1, 2>( + new SizeTestingCostFunction<1,2>, ceres::TAKE_OWNERSHIP)); + + cost_function.reset( + new NumericDiffCostFunction, CENTRAL, 2, 2>( + new SizeTestingCostFunction<2,2>, ceres::TAKE_OWNERSHIP)); +} + } // namespace internal } // namespace ceres