Multiple sparse linear algebra backends.

1. Added support for CXSparse - SparseNormalCholesky and
   SchurComplementSolver support SuiteSparse and CXSparse now.
   I am not sure I will add suport for visibility based
   preconditioning using CXSparse. Its not a high priority.

2. New enum SparseLinearAlgebraLibraryType which allows the user
   to indicate which sparse linear algebra library should be used.

3. Updated tests for SolverImpl and system_test.

4. Build system changes to automatically detect CXSparse and
   link to it by default -- just like SuiteSparse.

5. Minor bug fixes dealing in the cmake files and VBP.

6. Changed the order of the system test.

7. Deduped the unsymmetric linear solver test.

Change-Id: I33252a103c87b722ecb7ed7b5f0ae7fd91249244
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 39d4c64..ab00deb 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -59,27 +59,31 @@
 # Locations to search for Eigen
 SET(EIGEN_SEARCH_HEADERS ${SEARCH_HEADERS})
 LIST(APPEND EIGEN_SEARCH_HEADERS /usr/include/eigen3) # Ubuntu 10.04's default location.
-LIST(APPEND EIGEN_SEARCH_HEADERS /usr/local/include/eigen3) 
+LIST(APPEND EIGEN_SEARCH_HEADERS /usr/local/include/eigen3)
 LIST(APPEND EIGEN_SEARCH_HEADERS /usr/local/homebrew/include/eigen3)  # Mac OS X
 LIST(APPEND EIGEN_SEARCH_HEADERS /opt/local/var/macports/software/eigen3/opt/local/include/eigen3) # Mac OS X
 
 # Locations to search for SuiteSparse
 SET(SUITESPARSE_SEARCH_LIBS ${SEARCH_LIBS})
 LIST(APPEND SUITESPARSE_SEARCH_LIBS /usr/lib/suitesparse) # Ubuntu
-LIST(APPEND SUITESPARSE_SEARCH_LIBS /usr/local/lib/suitesparse) 
+LIST(APPEND SUITESPARSE_SEARCH_LIBS /usr/local/lib/suitesparse)
 LIST(APPEND SUITESPARSE_SEARCH_LIBS /opt/local/lib/ufsparse) # Mac OS X
 
 SET(SUITESPARSE_SEARCH_HEADERS ${SEARCH_HEADERS})
 LIST(APPEND SUITESPARSE_SEARCH_HEADERS /usr/include/suitesparse) # Ubuntu
-LIST(APPEND SUITESPARSE_SEARCH_HEADERS /usr/local/include/suitesparse) 
+LIST(APPEND SUITESPARSE_SEARCH_HEADERS /usr/local/include/suitesparse)
 LIST(APPEND SUITESPARSE_SEARCH_HEADERS /opt/local/include/ufsparse) # Mac OS X
 
+SET(CXSPARSE_SEARCH_LIBS ${SEARCH_LIBS})
+SET(CXSPARSE_SEARCH_HEADERS ${SEARCH_HEADERS})
+LIST(APPEND CXSPARSE_SEARCH_HEADERS /usr/include/suitesparse) # Ubuntu
+
 # Check for SuiteSparse dependencies
 MESSAGE("-- Check for AMD")
 SET(AMD_FOUND TRUE)
 
 FIND_LIBRARY(AMD_LIB NAMES amd PATHS ${SUITESPARSE_SEARCH_LIBS})
-IF (EXISTS ${AMD_LIB}) 
+IF (EXISTS ${AMD_LIB})
   MESSAGE("-- Found AMD library: ${AMD_LIB}")
 ELSE (EXISTS ${AMD_LIB})
   MESSAGE("-- Did not find AMD library")
@@ -87,7 +91,7 @@
 ENDIF (EXISTS ${AMD_LIB})
 
 FIND_PATH(AMD_INCLUDE NAMES amd.h PATHS ${SUITESPARSE_SEARCH_HEADERS})
-IF (EXISTS ${AMD_INCLUDE}) 
+IF (EXISTS ${AMD_INCLUDE})
   MESSAGE("-- Found AMD header in: ${AMD_INCLUDE}")
 ELSE (EXISTS ${AMD_INCLUDE})
   MESSAGE("-- Did not find AMD header")
@@ -98,7 +102,7 @@
 SET(CAMD_FOUND TRUE)
 
 FIND_LIBRARY(CAMD_LIB NAMES camd PATHS ${SUITESPARSE_SEARCH_LIBS})
-IF (EXISTS ${CAMD_LIB}) 
+IF (EXISTS ${CAMD_LIB})
   MESSAGE("-- Found CAMD library: ${CAMD_LIB}")
 ELSE (EXISTS ${CAMD_LIB})
   MESSAGE("-- Did not find CAMD library")
@@ -106,7 +110,7 @@
 ENDIF (EXISTS ${CAMD_LIB})
 
 FIND_PATH(CAMD_INCLUDE NAMES camd.h PATHS ${SUITESPARSE_SEARCH_HEADERS})
-IF (EXISTS ${CAMD_INCLUDE}) 
+IF (EXISTS ${CAMD_INCLUDE})
   MESSAGE("-- Found CAMD header in: ${CAMD_INCLUDE}")
 ELSE (EXISTS ${CAMD_INCLUDE})
   MESSAGE("-- Did not find CAMD header")
@@ -117,7 +121,7 @@
 SET(COLAMD_FOUND TRUE)
 
 FIND_LIBRARY(COLAMD_LIB NAMES colamd PATHS ${SUITESPARSE_SEARCH_LIBS})
-IF (EXISTS ${COLAMD_LIB}) 
+IF (EXISTS ${COLAMD_LIB})
   MESSAGE("-- Found COLAMD library: ${COLAMD_LIB}")
 ELSE (EXISTS ${COLAMD_LIB})
   MESSAGE("-- Did not find COLAMD library")
@@ -125,7 +129,7 @@
 ENDIF (EXISTS ${COLAMD_LIB})
 
 FIND_PATH(COLAMD_INCLUDE NAMES colamd.h PATHS ${SUITESPARSE_SEARCH_HEADERS})
-IF (EXISTS ${COLAMD_INCLUDE}) 
+IF (EXISTS ${COLAMD_INCLUDE})
   MESSAGE("-- Found COLAMD header in: ${COLAMD_INCLUDE}")
 ELSE (EXISTS ${COLAMD_INCLUDE})
   MESSAGE("-- Did not find COLAMD header")
@@ -136,7 +140,7 @@
 SET(CCOLAMD_FOUND TRUE)
 
 FIND_LIBRARY(CCOLAMD_LIB NAMES ccolamd PATHS ${SUITESPARSE_SEARCH_LIBS})
-IF (EXISTS ${CCOLAMD_LIB}) 
+IF (EXISTS ${CCOLAMD_LIB})
   MESSAGE("-- Found CCOLAMD library: ${CCOLAMD_LIB}")
 ELSE (EXISTS ${CCOLAMD_LIB})
   MESSAGE("-- Did not find CCOLAMD library")
@@ -144,7 +148,7 @@
 ENDIF (EXISTS ${CCOLAMD_LIB})
 
 FIND_PATH(CCOLAMD_INCLUDE NAMES ccolamd.h PATHS ${SUITESPARSE_SEARCH_HEADERS})
-IF (EXISTS ${CCOLAMD_INCLUDE}) 
+IF (EXISTS ${CCOLAMD_INCLUDE})
   MESSAGE("-- Found CCOLAMD header in: ${CCOLAMD_INCLUDE}")
 ELSE (EXISTS ${CCOLAMD_INCLUDE})
   MESSAGE("-- Did not find CCOLAMD header")
@@ -155,7 +159,7 @@
 SET(CHOLMOD_FOUND TRUE)
 
 FIND_LIBRARY(CHOLMOD_LIB NAMES cholmod PATHS ${SUITESPARSE_SEARCH_LIBS})
-IF (EXISTS ${CHOLMOD_LIB}) 
+IF (EXISTS ${CHOLMOD_LIB})
   MESSAGE("-- Found CHOLMOD library: ${CHOLMOD_LIB}")
 ELSE (EXISTS ${CHOLMOD_LIB})
   MESSAGE("-- Did not find CHOLMOD library")
@@ -163,7 +167,7 @@
 ENDIF (EXISTS ${CHOLMOD_LIB})
 
 FIND_PATH(CHOLMOD_INCLUDE NAMES cholmod.h PATHS ${SUITESPARSE_SEARCH_HEADERS})
-IF (EXISTS ${CHOLMOD_INCLUDE}) 
+IF (EXISTS ${CHOLMOD_INCLUDE})
   MESSAGE("-- Found CHOLMOD header in: ${CHOLMOD_INCLUDE}")
 ELSE (EXISTS ${CHOLMOD_INCLUDE})
   MESSAGE("-- Did not find CHOLMOD header")
@@ -173,7 +177,7 @@
 MESSAGE("-- Check for METIS (optional)")
 FIND_LIBRARY(METIS_LIB NAMES metis PATHS ${SUITESPARSE_SEARCH_LIBS})
 
-IF (EXISTS ${METIS_LIB}) 
+IF (EXISTS ${METIS_LIB})
   MESSAGE("-- Found METIS library: ${METIS_LIB}")
 ELSE (EXISTS ${METIS_LIB})
   MESSAGE("-- Did not find METIS library")
@@ -187,7 +191,7 @@
   FIND_LIBRARY(LAPACK_LIB NAMES vecLib)
 ELSE (APPLE)
   FIND_LIBRARY(BLAS_LIB NAMES blas)
-  IF (EXISTS ${BLAS_LIB}) 
+  IF (EXISTS ${BLAS_LIB})
     MESSAGE("-- Found BLAS library: ${BLAS_LIB}")
   ELSE (EXISTS ${BLAS_LIB})
     MESSAGE("-- Did not find BLAS library")
@@ -196,14 +200,14 @@
   FIND_LIBRARY(LAPACK_LIB NAMES lapack)
 ENDIF (APPLE)
 
-IF (EXISTS ${LAPACK_LIB}) 
+IF (EXISTS ${LAPACK_LIB})
   MESSAGE("-- Found LAPACK library: ${LAPACK_LIB}")
 ELSE (EXISTS ${LAPACK_LIB})
   SET(BLAS_AND_LAPACK_FOUND FALSE)
   MESSAGE("-- Did not find LAPACK library")
 ENDIF (EXISTS ${LAPACK_LIB})
 
-SET(SUITESPARSE_FOUND 
+SET(SUITESPARSE_FOUND
     AMD_FOUND AND
     CAMD_FOUND AND
     COLAMD_FOUND AND
@@ -215,20 +219,65 @@
 # built with SuiteSparse support. -DSUITESPARSE=ON/OFF can be used to
 # enable/disable SuiteSparse explicitly.
 IF (DEFINED SUITESPARSE)
-  IF (SUITESPARSE AND NOT SUITESPARSE_FOUND)
-    MESSAGE(FATAL_ERROR "One or more of SuiteSparse's dependencies was not found")
-  ENDIF (SUITESPARSE AND NOT SUITESPARSE_FOUND)
+  IF (SUITESPARSE)
+    IF (NOT SUITESPARSE_FOUND)
+      MESSAGE(FATAL_ERROR "One or more of SuiteSparse's dependencies was not found")
+    ENDIF (NOT SUITESPARSE_FOUND)
+  ELSE (SUITESPARSE)
+    ADD_DEFINITIONS(-DCERES_NO_SUITESPARSE)
+  ENDIF (SUITESPARSE)
 ELSE (DEFINED SUITESPARSE)
   IF (SUITESPARSE_FOUND)
     MESSAGE("-- Found all SuiteSparse dependencies. Building with SuiteSparse")
     SET(SUITESPARSE ON)
   ELSE (SUITESPARSE_FOUND)
-    MESSAGE("-- Did not find all SuiteSparse dependencies. Building without SuiteSparse")	
+    MESSAGE("-- Did not find all SuiteSparse dependencies. Building without SuiteSparse")
     SET(SUITESPARSE OFF)
     ADD_DEFINITIONS(-DCERES_NO_SUITESPARSE)
   ENDIF (SUITESPARSE_FOUND)
 ENDIF (DEFINED SUITESPARSE)
 
+# By default, if all of CXSparse's dependencies are found, Ceres is
+# built with CXSparse support. -DCXSPARSE=ON/OFF can be used to
+# enable/disable CXSparse explicitly.
+MESSAGE("-- Check for CXSparse")
+SET(CXSPARSE_FOUND ON)
+
+FIND_LIBRARY(CXSPARSE_LIB NAMES cxsparse PATHS ${CXSPARSE_SEARCH_LIBS})
+IF (EXISTS ${CXSPARSE_LIB})
+  MESSAGE("-- Found CXSparse library in: ${CXSPARSE_LIB}")
+ELSE (EXISTS ${CXSPARSE_LIB})
+  MESSAGE("-- Did not find CXSparse header")
+  SET(CXSPARSE_FOUND FALSE)
+ENDIF (EXISTS ${CXSPARSE_LIB})
+
+FIND_PATH(CXSPARSE_INCLUDE NAMES cs.h PATHS ${CXSPARSE_SEARCH_HEADERS})
+IF (EXISTS ${CXSPARSE_INCLUDE})
+  MESSAGE("-- Found CXSparse header in: ${CXSPARSE_INCLUDE}")
+ELSE (EXISTS ${CXSPARSE_INCLUDE})
+  MESSAGE("-- Did not find CXSparse header")
+  SET(CXSPARSE_FOUND FALSE)
+ENDIF (EXISTS ${CXSPARSE_INCLUDE})
+
+IF (DEFINED CXSPARSE)
+  IF (CXSPARSE)
+    IF (NOT CXSPARSE_FOUND)
+      MESSAGE(FATAL_ERROR "-- CXSparse not found.")
+    ENDIF (NOT CXSPARSE_FOUND)
+  ELSE (CXSPARSE)
+    ADD_DEFINITIONS(-DCERES_NO_CXSPARSE)
+  ENDIF (CXSPARSE)
+ELSE (DEFINED CXSPARSE)
+  IF (CXSPARSE_FOUND)
+    MESSAGE("-- Building with CXSparse support.")
+    SET(CXSPARSE ON)
+  ELSE (CXSPARSE_FOUND)
+    MESSAGE("-- Building without CXSparse.")
+    SET(CXSPARSE OFF)
+    ADD_DEFINITIONS(-DCERES_NO_CXSPARSE)
+  ENDIF (CXSPARSE_FOUND)
+ENDIF (DEFINED CXSPARSE)
+
 # Google Flags
 OPTION(GFLAGS
        "Enable Google Flags."
@@ -352,6 +401,10 @@
   INCLUDE_DIRECTORIES(${CHOLMOD_INCLUDE})
 ENDIF(SUITESPARSE)
 
+IF (CXSPARSE)
+  INCLUDE_DIRECTORIES(${CXSPARSE_INCLUDE})
+ENDIF(CXSPARSE)
+
 IF (GFLAGS)
   INCLUDE_DIRECTORIES(${GFLAGS_INCLUDE})
 ENDIF (GFLAGS)