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/dense_qr_solver.cc')
-rw-r--r--extern/ceres/internal/ceres/dense_qr_solver.cc112
1 files changed, 14 insertions, 98 deletions
diff --git a/extern/ceres/internal/ceres/dense_qr_solver.cc b/extern/ceres/internal/ceres/dense_qr_solver.cc
index 44388f30aee..24cb25abd8e 100644
--- a/extern/ceres/internal/ceres/dense_qr_solver.cc
+++ b/extern/ceres/internal/ceres/dense_qr_solver.cc
@@ -33,9 +33,9 @@
#include <cstddef>
#include "Eigen/Dense"
+#include "ceres/dense_qr.h"
#include "ceres/dense_sparse_matrix.h"
#include "ceres/internal/eigen.h"
-#include "ceres/lapack.h"
#include "ceres/linear_solver.h"
#include "ceres/types.h"
#include "ceres/wall_time.h"
@@ -44,124 +44,40 @@ namespace ceres {
namespace internal {
DenseQRSolver::DenseQRSolver(const LinearSolver::Options& options)
- : options_(options) {
- work_.resize(1);
-}
+ : options_(options), dense_qr_(DenseQR::Create(options)) {}
LinearSolver::Summary DenseQRSolver::SolveImpl(
DenseSparseMatrix* A,
const double* b,
const LinearSolver::PerSolveOptions& per_solve_options,
double* x) {
- if (options_.dense_linear_algebra_library_type == EIGEN) {
- return SolveUsingEigen(A, b, per_solve_options, x);
- } else {
- return SolveUsingLAPACK(A, b, per_solve_options, x);
- }
-}
-
-LinearSolver::Summary DenseQRSolver::SolveUsingLAPACK(
- DenseSparseMatrix* A,
- const double* b,
- const LinearSolver::PerSolveOptions& per_solve_options,
- double* x) {
EventLogger event_logger("DenseQRSolver::Solve");
const int num_rows = A->num_rows();
const int num_cols = A->num_cols();
+ const int num_augmented_rows =
+ num_rows + ((per_solve_options.D != nullptr) ? num_cols : 0);
- 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.
- A->AppendDiagonal(per_solve_options.D);
+ if (lhs_.rows() != num_augmented_rows || lhs_.cols() != num_cols) {
+ lhs_.resize(num_augmented_rows, num_cols);
+ rhs_.resize(num_augmented_rows);
}
- // TODO(sameeragarwal): Since we are copying anyways, the diagonal
- // can be appended to the matrix instead of doing it on A.
- lhs_ = A->matrix();
-
- if (per_solve_options.D != NULL) {
- // Undo the modifications to the matrix A.
- A->RemoveDiagonal();
- }
-
- // rhs = [b;0] to account for the additional rows in the lhs.
- if (rhs_.rows() != lhs_.rows()) {
- rhs_.resize(lhs_.rows());
- }
- rhs_.setZero();
+ lhs_.topRows(num_rows) = A->matrix();
rhs_.head(num_rows) = ConstVectorRef(b, num_rows);
- if (work_.rows() == 1) {
- const int work_size =
- LAPACK::EstimateWorkSizeForQR(lhs_.rows(), lhs_.cols());
- VLOG(3) << "Working memory for Dense QR factorization: "
- << work_size * sizeof(double);
- work_.resize(work_size);
+ if (num_rows != num_augmented_rows) {
+ lhs_.bottomRows(num_cols) =
+ ConstVectorRef(per_solve_options.D, num_cols).asDiagonal();
+ rhs_.tail(num_cols).setZero();
}
LinearSolver::Summary summary;
+ summary.termination_type = dense_qr_->FactorAndSolve(
+ lhs_.rows(), lhs_.cols(), lhs_.data(), rhs_.data(), x, &summary.message);
summary.num_iterations = 1;
- summary.termination_type = LAPACK::SolveInPlaceUsingQR(lhs_.rows(),
- lhs_.cols(),
- lhs_.data(),
- work_.rows(),
- work_.data(),
- rhs_.data(),
- &summary.message);
event_logger.AddEvent("Solve");
- if (summary.termination_type == LINEAR_SOLVER_SUCCESS) {
- VectorRef(x, num_cols) = rhs_.head(num_cols);
- }
-
- event_logger.AddEvent("TearDown");
- return summary;
-}
-
-LinearSolver::Summary DenseQRSolver::SolveUsingEigen(
- DenseSparseMatrix* A,
- const double* b,
- const LinearSolver::PerSolveOptions& per_solve_options,
- double* x) {
- EventLogger event_logger("DenseQRSolver::Solve");
-
- const int num_rows = A->num_rows();
- const int num_cols = A->num_cols();
-
- 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.
- A->AppendDiagonal(per_solve_options.D);
- }
-
- // rhs = [b;0] to account for the additional rows in the lhs.
- const int augmented_num_rows =
- num_rows + ((per_solve_options.D != NULL) ? num_cols : 0);
- if (rhs_.rows() != augmented_num_rows) {
- rhs_.resize(augmented_num_rows);
- rhs_.setZero();
- }
- rhs_.head(num_rows) = ConstVectorRef(b, num_rows);
- event_logger.AddEvent("Setup");
-
- // Solve the system.
- VectorRef(x, num_cols) = A->matrix().householderQr().solve(rhs_);
- event_logger.AddEvent("Solve");
-
- if (per_solve_options.D != NULL) {
- // Undo the modifications to the matrix A.
- A->RemoveDiagonal();
- }
-
- // We always succeed, since the QR solver returns the best solution
- // it can. It is the job of the caller to determine if the solution
- // is good enough or not.
- LinearSolver::Summary summary;
- summary.num_iterations = 1;
- summary.termination_type = LINEAR_SOLVER_SUCCESS;
- summary.message = "Success.";
- event_logger.AddEvent("TearDown");
return summary;
}