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;