Expand check for lack of a sparse linear algebra library.
The LinearSolver factory was creating a NULL linear solver
if only Eigen's sparse linear algebra backend was available.
Thanks to Michael Samples and Domink Reitzle for reporting this.
Change-Id: I35e3a6c0fd0da2a31934adb5dfe4cad29577cc73
diff --git a/internal/ceres/linear_solver.cc b/internal/ceres/linear_solver.cc
index e983e2c..d905ec2 100644
--- a/internal/ceres/linear_solver.cc
+++ b/internal/ceres/linear_solver.cc
@@ -75,14 +75,18 @@
return new CgnrSolver(options);
case SPARSE_NORMAL_CHOLESKY:
-#if defined(CERES_NO_SUITESPARSE) && defined(CERES_NO_CXSPARSE)
+#if defined(CERES_NO_SUITESPARSE) && \
+ defined(CERES_NO_CXSPARSE) && \
+ !defined(CERES_USE_EIGEN_SPARSE)
return NULL;
#else
return new SparseNormalCholeskySolver(options);
#endif
case SPARSE_SCHUR:
-#if defined(CERES_NO_SUITESPARSE) && defined(CERES_NO_CXSPARSE)
+#if defined(CERES_NO_SUITESPARSE) && \
+ defined(CERES_NO_CXSPARSE) && \
+ !defined(CERES_USE_EIGEN_SPARSE)
return NULL;
#else
return new SparseSchurComplementSolver(options);
diff --git a/internal/ceres/solver_test.cc b/internal/ceres/solver_test.cc
index f2ead06..cd82f55 100644
--- a/internal/ceres/solver_test.cc
+++ b/internal/ceres/solver_test.cc
@@ -247,6 +247,14 @@
string message;
EXPECT_FALSE(options.IsValid(&message));
}
+
+TEST(Solver, SparseSchurNoSuiteSparse) {
+ Solver::Options options;
+ options.sparse_linear_algebra_library_type = SUITE_SPARSE;
+ options.linear_solver_type = SPARSE_SCHUR;
+ string message;
+ EXPECT_FALSE(options.IsValid(&message));
+}
#endif
#if defined(CERES_NO_CXSPARSE)
@@ -257,6 +265,32 @@
string message;
EXPECT_FALSE(options.IsValid(&message));
}
+
+TEST(Solver, SparseSchurNoCXSparse) {
+ Solver::Options options;
+ options.sparse_linear_algebra_library_type = CX_SPARSE;
+ options.linear_solver_type = SPARSE_SCHUR;
+ string message;
+ EXPECT_FALSE(options.IsValid(&message));
+}
+#endif
+
+#if !defined(CERES_USE_EIGEN_SPARSE)
+TEST(Solver, SparseNormalCholeskyNoEigenSparse) {
+ Solver::Options options;
+ options.sparse_linear_algebra_library_type = EIGEN_SPARSE;
+ options.linear_solver_type = SPARSE_NORMAL_CHOLESKY;
+ string message;
+ EXPECT_FALSE(options.IsValid(&message));
+}
+
+TEST(Solver, SparseSchurNoEigenSparse) {
+ Solver::Options options;
+ options.sparse_linear_algebra_library_type = EIGEN_SPARSE;
+ options.linear_solver_type = SPARSE_SCHUR;
+ string message;
+ EXPECT_FALSE(options.IsValid(&message));
+}
#endif
TEST(Solver, IterativeLinearSolverForDogleg) {
@@ -284,7 +318,9 @@
EXPECT_TRUE(options.IsValid(&message));
options.linear_solver_type = SPARSE_SCHUR;
-#if defined(CERES_NO_SUITESPARSE) && defined(CERES_NO_CXSPARSE)
+#if defined(CERES_NO_SUITESPARSE) && \
+ defined(CERES_NO_CXSPARSE) && \
+ !defined(CERES_USE_EIGEN_SPARSE)
EXPECT_FALSE(options.IsValid(&message));
#else
EXPECT_TRUE(options.IsValid(&message));
@@ -311,7 +347,7 @@
TEST(Solver, FixedCostForConstantProblem) {
double x = 1.0;
Problem problem;
- problem.AddResidualBlock(new DummyCostFunction<2,1>(), NULL, &x);
+ problem.AddResidualBlock(new DummyCostFunction<2, 1>(), NULL, &x);
problem.SetParameterBlockConstant(&x);
const double expected_cost = 41.0 / 2.0; // 1/2 * ((4 + 0)^2 + (4 + 1)^2)
Solver::Options options;