Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'extern/ceres/internal/ceres/cgnr_solver.cc')
-rw-r--r--extern/ceres/internal/ceres/cgnr_solver.cc39
1 files changed, 30 insertions, 9 deletions
diff --git a/extern/ceres/internal/ceres/cgnr_solver.cc b/extern/ceres/internal/ceres/cgnr_solver.cc
index 61fae758d5b..9dba1cfb4a8 100644
--- a/extern/ceres/internal/ceres/cgnr_solver.cc
+++ b/extern/ceres/internal/ceres/cgnr_solver.cc
@@ -35,6 +35,7 @@
#include "ceres/conjugate_gradients_solver.h"
#include "ceres/internal/eigen.h"
#include "ceres/linear_solver.h"
+#include "ceres/subset_preconditioner.h"
#include "ceres/wall_time.h"
#include "glog/logging.h"
@@ -42,14 +43,19 @@ namespace ceres {
namespace internal {
CgnrSolver::CgnrSolver(const LinearSolver::Options& options)
- : options_(options),
- preconditioner_(NULL) {
+ : options_(options) {
if (options_.preconditioner_type != JACOBI &&
- options_.preconditioner_type != IDENTITY) {
- LOG(FATAL) << "CGNR only supports IDENTITY and JACOBI preconditioners.";
+ options_.preconditioner_type != IDENTITY &&
+ options_.preconditioner_type != SUBSET) {
+ LOG(FATAL)
+ << "Preconditioner = "
+ << PreconditionerTypeToString(options_.preconditioner_type) << ". "
+ << "Congratulations, you found a bug in Ceres. Please report it.";
}
}
+CgnrSolver::~CgnrSolver() {}
+
LinearSolver::Summary CgnrSolver::SolveImpl(
BlockSparseMatrix* A,
const double* b,
@@ -62,16 +68,31 @@ LinearSolver::Summary CgnrSolver::SolveImpl(
z.setZero();
A->LeftMultiply(b, z.data());
- // Precondition if necessary.
- LinearSolver::PerSolveOptions cg_per_solve_options = per_solve_options;
- if (options_.preconditioner_type == JACOBI) {
- if (preconditioner_.get() == NULL) {
+ if (!preconditioner_) {
+ if (options_.preconditioner_type == JACOBI) {
preconditioner_.reset(new BlockJacobiPreconditioner(*A));
+ } else if (options_.preconditioner_type == SUBSET) {
+ Preconditioner::Options preconditioner_options;
+ preconditioner_options.type = SUBSET;
+ preconditioner_options.subset_preconditioner_start_row_block =
+ options_.subset_preconditioner_start_row_block;
+ preconditioner_options.sparse_linear_algebra_library_type =
+ options_.sparse_linear_algebra_library_type;
+ preconditioner_options.use_postordering = options_.use_postordering;
+ preconditioner_options.num_threads = options_.num_threads;
+ preconditioner_options.context = options_.context;
+ preconditioner_.reset(
+ new SubsetPreconditioner(preconditioner_options, *A));
}
+ }
+
+ if (preconditioner_) {
preconditioner_->Update(*A, per_solve_options.D);
- cg_per_solve_options.preconditioner = preconditioner_.get();
}
+ LinearSolver::PerSolveOptions cg_per_solve_options = per_solve_options;
+ cg_per_solve_options.preconditioner = preconditioner_.get();
+
// Solve (AtA + DtD)x = z (= Atb).
VectorRef(x, A->num_cols()).setZero();
CgnrLinearOperator lhs(*A, per_solve_options.D);