diff options
Diffstat (limited to 'extern/libmv/third_party/ceres/internal/ceres/sparse_normal_cholesky_solver.cc')
-rw-r--r-- | extern/libmv/third_party/ceres/internal/ceres/sparse_normal_cholesky_solver.cc | 73 |
1 files changed, 45 insertions, 28 deletions
diff --git a/extern/libmv/third_party/ceres/internal/ceres/sparse_normal_cholesky_solver.cc b/extern/libmv/third_party/ceres/internal/ceres/sparse_normal_cholesky_solver.cc index f1a52378e2b..1ead8f70ae2 100644 --- a/extern/libmv/third_party/ceres/internal/ceres/sparse_normal_cholesky_solver.cc +++ b/extern/libmv/third_party/ceres/internal/ceres/sparse_normal_cholesky_solver.cc @@ -102,6 +102,9 @@ LinearSolver::Summary SparseNormalCholeskySolver::SolveImplUsingCXSparse( LinearSolver::Summary summary; summary.num_iterations = 1; + summary.termination_type = LINEAR_SOLVER_SUCCESS; + summary.message = "Success."; + const int num_cols = A->num_cols(); Vector Atb = Vector::Zero(num_cols); A->LeftMultiply(b, Atb.data()); @@ -137,21 +140,23 @@ LinearSolver::Summary SparseNormalCholeskySolver::SolveImplUsingCXSparse( // Compute symbolic factorization if not available. if (cxsparse_factor_ == NULL) { if (options_.use_postordering) { - cxsparse_factor_ = - CHECK_NOTNULL(cxsparse_.BlockAnalyzeCholesky(AtA, - A->col_blocks(), - A->col_blocks())); + cxsparse_factor_ = cxsparse_.BlockAnalyzeCholesky(AtA, + A->col_blocks(), + A->col_blocks()); } else { - cxsparse_factor_ = - CHECK_NOTNULL(cxsparse_.AnalyzeCholeskyWithNaturalOrdering(AtA)); + cxsparse_factor_ = cxsparse_.AnalyzeCholeskyWithNaturalOrdering(AtA); } } event_logger.AddEvent("Analysis"); - // Solve the linear system. - if (cxsparse_.SolveCholesky(AtA, cxsparse_factor_, Atb.data())) { + if (cxsparse_factor_ == NULL) { + summary.termination_type = LINEAR_SOLVER_FATAL_ERROR; + summary.message = + "CXSparse failure. Unable to find symbolic factorization."; + } else if (cxsparse_.SolveCholesky(AtA, cxsparse_factor_, Atb.data())) { VectorRef(x, Atb.rows()) = Atb; - summary.termination_type = TOLERANCE; + } else { + summary.termination_type = LINEAR_SOLVER_FAILURE; } event_logger.AddEvent("Solve"); @@ -179,56 +184,68 @@ LinearSolver::Summary SparseNormalCholeskySolver::SolveImplUsingSuiteSparse( const LinearSolver::PerSolveOptions& per_solve_options, double * x) { EventLogger event_logger("SparseNormalCholeskySolver::SuiteSparse::Solve"); + LinearSolver::Summary summary; + summary.termination_type = LINEAR_SOLVER_SUCCESS; + summary.num_iterations = 1; + summary.message = "Success."; const int num_cols = A->num_cols(); - LinearSolver::Summary summary; Vector Atb = Vector::Zero(num_cols); A->LeftMultiply(b, Atb.data()); if (per_solve_options.D != NULL) { - // Temporarily append a diagonal block to the A matrix, but undo it before - // returning the matrix to the user. + // Temporarily append a diagonal block to the A matrix, but undo + // it before returning the matrix to the user. CompressedRowSparseMatrix D(per_solve_options.D, num_cols); A->AppendRows(D); } 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(), + &summary.message); } else { - factor_ = - CHECK_NOTNULL(ss_.AnalyzeCholeskyWithNaturalOrdering(&lhs)); + factor_ = ss_.AnalyzeCholeskyWithNaturalOrdering(&lhs, &summary.message); } } - 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 = LINEAR_SOLVER_FATAL_ERROR; + return summary; + } + + summary.termination_type = ss_.Cholesky(&lhs, factor_, &summary.message); + if (summary.termination_type != LINEAR_SOLVER_SUCCESS) { + if (per_solve_options.D != NULL) { + A->DeleteRows(num_cols); + } + return summary; + } + + cholmod_dense* rhs = ss_.CreateDenseVector(Atb.data(), num_cols, num_cols); + cholmod_dense* sol = ss_.Solve(factor_, rhs, &summary.message); 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)); - ss_.Free(sol); - sol = NULL; - summary.termination_type = TOLERANCE; + } else { + summary.termination_type = LINEAR_SOLVER_FAILURE; } event_logger.AddEvent("Teardown"); |