31
31
#include "ceres/dense_qr_solver.h"
35
35
#include "Eigen/Dense"
36
36
#include "ceres/dense_sparse_matrix.h"
37
37
#include "ceres/internal/eigen.h"
38
38
#include "ceres/internal/scoped_ptr.h"
39
#include "ceres/lapack.h"
39
40
#include "ceres/linear_solver.h"
40
41
#include "ceres/types.h"
41
42
#include "ceres/wall_time.h"
44
45
namespace internal {
46
47
DenseQRSolver::DenseQRSolver(const LinearSolver::Options& options)
47
: options_(options) {}
49
52
LinearSolver::Summary DenseQRSolver::SolveImpl(
50
53
DenseSparseMatrix* A,
52
55
const LinearSolver::PerSolveOptions& per_solve_options,
57
if (options_.dense_linear_algebra_library_type == EIGEN) {
58
return SolveUsingEigen(A, b, per_solve_options, x);
60
return SolveUsingLAPACK(A, b, per_solve_options, x);
63
LinearSolver::Summary DenseQRSolver::SolveUsingLAPACK(
66
const LinearSolver::PerSolveOptions& per_solve_options,
68
EventLogger event_logger("DenseQRSolver::Solve");
70
const int num_rows = A->num_rows();
71
const int num_cols = A->num_cols();
73
if (per_solve_options.D != NULL) {
74
// Temporarily append a diagonal block to the A matrix, but undo
75
// it before returning the matrix to the user.
76
A->AppendDiagonal(per_solve_options.D);
79
// TODO(sameeragarwal): Since we are copying anyways, the diagonal
80
// can be appended to the matrix instead of doing it on A.
83
if (per_solve_options.D != NULL) {
84
// Undo the modifications to the matrix A.
88
// rhs = [b;0] to account for the additional rows in the lhs.
89
if (rhs_.rows() != lhs_.rows()) {
90
rhs_.resize(lhs_.rows());
93
rhs_.head(num_rows) = ConstVectorRef(b, num_rows);
95
if (work_.rows() == 1) {
97
LAPACK::EstimateWorkSizeForQR(lhs_.rows(), lhs_.cols());
98
VLOG(3) << "Working memory for Dense QR factorization: "
99
<< work_size * sizeof(double);
100
work_.resize(work_size);
103
const int info = LAPACK::SolveUsingQR(lhs_.rows(),
109
event_logger.AddEvent("Solve");
111
LinearSolver::Summary summary;
112
summary.num_iterations = 1;
114
VectorRef(x, num_cols) = rhs_.head(num_cols);
115
summary.termination_type = TOLERANCE;
117
summary.termination_type = FAILURE;
120
event_logger.AddEvent("TearDown");
124
LinearSolver::Summary DenseQRSolver::SolveUsingEigen(
125
DenseSparseMatrix* A,
127
const LinearSolver::PerSolveOptions& per_solve_options,
54
129
EventLogger event_logger("DenseQRSolver::Solve");
56
131
const int num_rows = A->num_rows();
73
148
event_logger.AddEvent("Setup");
75
150
// Solve the system.
76
VectorRef(x, num_cols) = A->matrix().colPivHouseholderQr().solve(rhs_);
151
VectorRef(x, num_cols) = A->matrix().householderQr().solve(rhs_);
77
152
event_logger.AddEvent("Solve");
79
154
if (per_solve_options.D != NULL) {