SuiteSparse errors do not cause a fatal crash.

1. Move LinearSolverTerminationType to ceres::internal.
2. Add FATAL_ERROR as a new enum to LinearSolverTerminationType.
3. Pipe SuiteSparse errors via a LinearSolverTerminationType so
   to distinguish between fatal and non-fatal errors.
4. Update levenberg marquardt and dogleg strategies to deal
   with FATAL_ERROR.
5. Update trust_region_minimizer to terminate when FATAL_ERROR
   is encountered.
6. Remove SuiteSparse::SolveCholesky as it screws up the error
   handling.
7. Fix all clients calling SuiteSparse to handle the result of
   SuiteSparse::Cholesky correctly.
8. Remove fatal failures in SuiteSparse when symbolic factorization
   fails.
9. Fix all clients of SuiteSparse to deal with null symbolic factors.

This is a temporary fix to deal with some production problems. A more
extensive cleanup and testing regime will be put in place in a
subsequent CL.

Change-Id: I1f60d539799dd95db7ecc340911e261fa4824f92
diff --git a/internal/ceres/sparse_normal_cholesky_solver.cc b/internal/ceres/sparse_normal_cholesky_solver.cc
index f1a5237..697adc1 100644
--- a/internal/ceres/sparse_normal_cholesky_solver.cc
+++ b/internal/ceres/sparse_normal_cholesky_solver.cc
@@ -195,34 +195,50 @@
   VectorRef(x, num_cols).setZero();
 
   cholmod_sparse lhs = ss_.CreateSparseMatrixTransposeView(A);
-  cholmod_dense* rhs = ss_.CreateDenseVector(Atb.data(), num_cols, num_cols);
+
   event_logger.AddEvent("Setup");
 
   if (factor_ == NULL) {
     if (options_.use_postordering) {
-      factor_ =
-          CHECK_NOTNULL(ss_.BlockAnalyzeCholesky(&lhs,
-                                                 A->col_blocks(),
-                                                 A->row_blocks()));
+      factor_ = ss_.BlockAnalyzeCholesky(&lhs,
+                                         A->col_blocks(),
+                                         A->row_blocks());
     } else {
-      factor_ =
-      CHECK_NOTNULL(ss_.AnalyzeCholeskyWithNaturalOrdering(&lhs));
+      factor_ = ss_.AnalyzeCholeskyWithNaturalOrdering(&lhs);
     }
   }
-
   event_logger.AddEvent("Analysis");
 
-  cholmod_dense* sol = ss_.SolveCholesky(&lhs, factor_, rhs);
+  if (factor_ == NULL) {
+    if (per_solve_options.D != NULL) {
+      A->DeleteRows(num_cols);
+    }
+
+    summary.termination_type = FATAL_ERROR;
+    return summary;
+  }
+
+  const LinearSolverTerminationType status = ss_.Cholesky(&lhs, factor_);
+  if (status != TOLERANCE) {
+    if (per_solve_options.D != NULL) {
+      A->DeleteRows(num_cols);
+    }
+
+    summary.termination_type = FATAL_ERROR;
+    return summary;
+  }
+
+  cholmod_dense* rhs = ss_.CreateDenseVector(Atb.data(), num_cols, num_cols);
+  cholmod_dense* sol = ss_.Solve(factor_, rhs);
   event_logger.AddEvent("Solve");
 
   ss_.Free(rhs);
-  rhs = NULL;
-
   if (per_solve_options.D != NULL) {
     A->DeleteRows(num_cols);
   }
 
   summary.num_iterations = 1;
+
   if (sol != NULL) {
     memcpy(x, sol->x, num_cols * sizeof(*x));