diff --git a/docs/changes.tex b/docs/changes.tex index 5e5bf44e4..cd41fd3f5 100644 --- a/docs/changes.tex +++ b/docs/changes.tex @@ -12,6 +12,8 @@ TolerantLossFunction} and \texttt{ComposedLossFunction}. (James Roseborough). \item New \texttt{DENSE\_NORMAL\_CHOLESKY} linear solver, which uses Eigen's LDLT factorization on the normal equations. +\item Cached symbolic factorization when using \texttt{CXSparse}. + (Petter Strandark) \item The traditional Dogleg solver now uses an elliptical trust region (Markus Moll) \item Support for returning initial and final gradients \& Jacobians. @@ -38,7 +40,7 @@ \begin{itemize} \item Do not link to \texttt{libgomp} when building on windows. (Petter Strandmark) -\item Include \texttt{gflags.h} in \texttt{test_utils.cc}. (Petter +\item Include \texttt{gflags.h} in \texttt{test\_utils.cc}. (Petter Strandmark) \item Use standard random number generation routines. (Petter Strandmark) \item \texttt{TrustRegionMinimizer} does not implicitly negate the diff --git a/internal/ceres/cxsparse.cc b/internal/ceres/cxsparse.cc index f54d24ffd..ca36ce076 100644 --- a/internal/ceres/cxsparse.cc +++ b/internal/ceres/cxsparse.cc @@ -48,7 +48,9 @@ CXSparse::~CXSparse() { } } -bool CXSparse::SolveCholesky(cs_di* A, cs_dis* factor, double* b) { +bool CXSparse::SolveCholesky(cs_di* A, + cs_dis* symbolic_factorization, + double* b) { // Make sure we have enough scratch space available. if (scratch_size_ < A->n) { if (scratch_size_ > 0) { @@ -58,28 +60,29 @@ bool CXSparse::SolveCholesky(cs_di* A, cs_dis* factor, double* b) { } // Solve using Cholesky factorization - csn* N = cs_chol(A, factor); - if (N == NULL) { + csn* numeric_factorization = cs_chol(A, symbolic_factorization); + if (numeric_factorization == NULL) { LOG(WARNING) << "Cholesky factorization failed."; return false; } // When the Cholesky factorization succeeded, these methods are guaranteed to - // succeed as well. In the comments below, "x" refers to the scratch space. + // succeeded as well. In the comments below, "x" refers to the scratch space. + // // Set x = P * b. - cs_ipvec(factor->pinv, b, scratch_, A->n); + cs_ipvec(symbolic_factorization->pinv, b, scratch_, A->n); // Set x = L \ x. - cs_lsolve(N->L, scratch_); + cs_lsolve(numeric_factorization->L, scratch_); // Set x = L' \ x. - cs_ltsolve(N->L, scratch_); + cs_ltsolve(numeric_factorization->L, scratch_); // Set b = P' * x. - cs_pvec(factor->pinv, scratch_, b, A->n); + cs_pvec(symbolic_factorization->pinv, scratch_, b, A->n); // Free Cholesky factorization. - cs_nfree(N); + cs_nfree(numeric_factorization); return true; } diff --git a/internal/ceres/cxsparse.h b/internal/ceres/cxsparse.h index a1265103a..d3b64fcd1 100644 --- a/internal/ceres/cxsparse.h +++ b/internal/ceres/cxsparse.h @@ -51,13 +51,13 @@ class CXSparse { ~CXSparse(); // Solves a symmetric linear system A * x = b using Cholesky factorization. - // A - The system matrix. - // factor - The symbolic factorization of A. This is obtained from - // AnalyzeCholesky. - // b - The right hand size of the linear equation. This array will also - // recieve the solution. + // A - The system matrix. + // symbolic_factorization - The symbolic factorization of A. This is obtained + // from AnalyzeCholesky. + // b - The right hand size of the linear equation. This + // array will also recieve the solution. // Returns false if Cholesky factorization of A fails. - bool SolveCholesky(cs_di* A, cs_dis* factor, double* b); + bool SolveCholesky(cs_di* A, cs_dis* symbolic_factorization, double* b); // Creates a sparse matrix from a compressed-column form. No memory is // allocated or copied; the structure A is filled out with info from the