SuiteSparse cleanup. 1. CreateSparseMatrixTransposeView now returns a struct instead of a pointer. 2. Add AnalyzeCholeskyWithNaturalOrdering. Change-Id: If27a5502949c3994edd95be0d25ec7a0d1fa1ae1
diff --git a/internal/ceres/sparse_normal_cholesky_solver.cc b/internal/ceres/sparse_normal_cholesky_solver.cc index aacba86..7ece965 100644 --- a/internal/ceres/sparse_normal_cholesky_solver.cc +++ b/internal/ceres/sparse_normal_cholesky_solver.cc
@@ -199,9 +199,7 @@ VectorRef(x, num_cols).setZero(); - scoped_ptr<cholmod_sparse> lhs(ss_.CreateSparseMatrixTransposeView(A)); - CHECK_NOTNULL(lhs.get()); - + cholmod_sparse lhs = ss_.CreateSparseMatrixTransposeView(A); cholmod_dense* rhs = ss_.CreateDenseVector(Atb.data(), num_cols, num_cols); event_logger.AddEvent("Setup"); @@ -216,7 +214,7 @@ } event_logger.AddEvent("Analysis"); - cholmod_dense* sol = ss_.SolveCholesky(lhs.get(), factor_, rhs); + cholmod_dense* sol = ss_.SolveCholesky(&lhs, factor_, rhs); event_logger.AddEvent("Solve"); ss_.Free(rhs);
diff --git a/internal/ceres/suitesparse.cc b/internal/ceres/suitesparse.cc index 87fae75..9063fa0 100644 --- a/internal/ceres/suitesparse.cc +++ b/internal/ceres/suitesparse.cc
@@ -87,23 +87,23 @@ return cholmod_triplet_to_sparse(&triplet, triplet.nnz, &cc_); } -cholmod_sparse* SuiteSparse::CreateSparseMatrixTransposeView( +cholmod_sparse SuiteSparse::CreateSparseMatrixTransposeView( CompressedRowSparseMatrix* A) { - cholmod_sparse* m = new cholmod_sparse_struct; - m->nrow = A->num_cols(); - m->ncol = A->num_rows(); - m->nzmax = A->num_nonzeros(); - - m->p = reinterpret_cast<void*>(A->mutable_rows()); - m->i = reinterpret_cast<void*>(A->mutable_cols()); - m->x = reinterpret_cast<void*>(A->mutable_values()); - - m->stype = 0; // Matrix is not symmetric. - m->itype = CHOLMOD_INT; - m->xtype = CHOLMOD_REAL; - m->dtype = CHOLMOD_DOUBLE; - m->sorted = 1; - m->packed = 1; + cholmod_sparse m; + m.nrow = A->num_cols(); + m.ncol = A->num_rows(); + m.nzmax = A->num_nonzeros(); + m.nz = NULL; + m.p = reinterpret_cast<void*>(A->mutable_rows()); + m.i = reinterpret_cast<void*>(A->mutable_cols()); + m.x = reinterpret_cast<void*>(A->mutable_values()); + m.z = NULL; + m.stype = 0; // Matrix is not symmetric. + m.itype = CHOLMOD_INT; + m.xtype = CHOLMOD_REAL; + m.dtype = CHOLMOD_DOUBLE; + m.sorted = 1; + m.packed = 1; return m; } @@ -172,6 +172,23 @@ return factor; } +cholmod_factor* SuiteSparse::AnalyzeCholeskyWithNaturalOrdering(cholmod_sparse* A) { + cc_.nmethods = 1; + cc_.method[0].ordering = CHOLMOD_NATURAL; + cc_.postorder = 0; + + cholmod_factor* factor = cholmod_analyze(A, &cc_); + CHECK_EQ(cc_.status, CHOLMOD_OK) + << "Cholmod symbolic analysis failed " << cc_.status; + CHECK_NOTNULL(factor); + + if (VLOG_IS_ON(2)) { + cholmod_print_common(const_cast<char*>("Symbolic Analysis"), &cc_); + } + + return factor; +} + bool SuiteSparse::BlockAMDOrdering(const cholmod_sparse* A, const vector<int>& row_blocks, const vector<int>& col_blocks,
diff --git a/internal/ceres/suitesparse.h b/internal/ceres/suitesparse.h index 5a8ef63..131716d 100644 --- a/internal/ceres/suitesparse.h +++ b/internal/ceres/suitesparse.h
@@ -70,10 +70,8 @@ // Create a cholmod_sparse wrapper around the contents of A. This is // a shallow object, which refers to the contents of A and does not - // use the SuiteSparse machinery to allocate memory, this object - // should be disposed off with a delete and not a call to Free as is - // the case for objects returned by CreateSparseMatrixTranspose. - cholmod_sparse* CreateSparseMatrixTransposeView(CompressedRowSparseMatrix* A); + // use the SuiteSparse machinery to allocate memory. + cholmod_sparse CreateSparseMatrixTransposeView(CompressedRowSparseMatrix* A); // Given a vector x, build a cholmod_dense vector of size out_size // with the first in_size entries copied from x. If x is NULL, then @@ -135,6 +133,12 @@ cholmod_factor* AnalyzeCholeskyWithUserOrdering(cholmod_sparse* A, const vector<int>& ordering); + // Perform a symbolic factorization of A without re-ordering A. No + // postordering of the elimination tree is performed. This ensures + // that the symbolic factor does not introduce an extra permutation + // on the matrix. See the documentation for CHOLMOD for more details. + cholmod_factor* AnalyzeCholeskyWithNaturalOrdering(cholmod_sparse* A); + // Use the symbolic factorization in L, to find the numerical // factorization for the matrix A or AA^T. Return true if // successful, false otherwise. L contains the numeric factorization