mirror of
https://github.com/ceres-solver/ceres-solver.git
synced 2026-08-29 08:34:37 +08:00
Death to BlockSparseMatrixBase
Change-Id: I13b2b951297ae81bfab0a7b4991a791ed91d594c
This commit is contained in:
committed by
Gerrit Code Review
parent
cbdeb79e91
commit
c1e10d9f57
@@ -41,7 +41,7 @@ namespace ceres {
|
||||
namespace internal {
|
||||
|
||||
BlockJacobiPreconditioner::BlockJacobiPreconditioner(
|
||||
const BlockSparseMatrixBase& A)
|
||||
const BlockSparseMatrix& A)
|
||||
: num_rows_(A.num_rows()),
|
||||
block_structure_(*A.block_structure()) {
|
||||
// Calculate the amount of storage needed.
|
||||
@@ -66,19 +66,19 @@ BlockJacobiPreconditioner::BlockJacobiPreconditioner(
|
||||
|
||||
BlockJacobiPreconditioner::~BlockJacobiPreconditioner() {}
|
||||
|
||||
bool BlockJacobiPreconditioner::Update(const BlockSparseMatrixBase& A,
|
||||
bool BlockJacobiPreconditioner::Update(const BlockSparseMatrix& A,
|
||||
const double* D) {
|
||||
const CompressedRowBlockStructure* bs = A.block_structure();
|
||||
|
||||
// Compute the diagonal blocks by block inner products.
|
||||
std::fill(block_storage_.begin(), block_storage_.end(), 0.0);
|
||||
const double* values = A.values();
|
||||
for (int r = 0; r < bs->rows.size(); ++r) {
|
||||
const int row_block_size = bs->rows[r].block.size;
|
||||
const vector<Cell>& cells = bs->rows[r].cells;
|
||||
const double* row_values = A.RowBlockValues(r);
|
||||
for (int c = 0; c < cells.size(); ++c) {
|
||||
const int col_block_size = bs->cols[cells[c].block_id].size;
|
||||
ConstMatrixRef m(row_values + cells[c].position,
|
||||
ConstMatrixRef m(values + cells[c].position,
|
||||
row_block_size,
|
||||
col_block_size);
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
namespace ceres {
|
||||
namespace internal {
|
||||
|
||||
class BlockSparseMatrixBase;
|
||||
class BlockSparseMatrix;
|
||||
struct CompressedRowBlockStructure;
|
||||
class LinearOperator;
|
||||
|
||||
@@ -54,11 +54,11 @@ class LinearOperator;
|
||||
class BlockJacobiPreconditioner : public Preconditioner {
|
||||
public:
|
||||
// A must remain valid while the BlockJacobiPreconditioner is.
|
||||
explicit BlockJacobiPreconditioner(const BlockSparseMatrixBase& A);
|
||||
explicit BlockJacobiPreconditioner(const BlockSparseMatrix& A);
|
||||
virtual ~BlockJacobiPreconditioner();
|
||||
|
||||
// Preconditioner interface
|
||||
virtual bool Update(const BlockSparseMatrixBase& A, const double* D);
|
||||
virtual bool Update(const BlockSparseMatrix& A, const double* D);
|
||||
virtual void RightMultiply(const double* x, double* y) const;
|
||||
virtual void LeftMultiply(const double* x, double* y) const;
|
||||
virtual int num_rows() const { return num_rows_; }
|
||||
|
||||
@@ -46,37 +46,6 @@ namespace internal {
|
||||
class SparseMatrixProto;
|
||||
class TripletSparseMatrix;
|
||||
|
||||
// A further extension of the SparseMatrix interface to support block-oriented
|
||||
// matrices. The key addition is the RowBlockValues() accessor, which enables
|
||||
// the lazy block sparse matrix implementation.
|
||||
class BlockSparseMatrixBase : public SparseMatrix {
|
||||
public:
|
||||
BlockSparseMatrixBase() {}
|
||||
virtual ~BlockSparseMatrixBase() {}
|
||||
|
||||
// Convert this matrix into a triplet sparse matrix.
|
||||
virtual void ToTripletSparseMatrix(TripletSparseMatrix* matrix) const = 0;
|
||||
|
||||
// Returns a pointer to the block structure. Does not transfer
|
||||
// ownership.
|
||||
virtual const CompressedRowBlockStructure* block_structure() const = 0;
|
||||
|
||||
// Returns a pointer to a row of the matrix. The returned array is only valid
|
||||
// until the next call to RowBlockValues. The caller does not own the result.
|
||||
//
|
||||
// The returned array is laid out such that cells on the specified row are
|
||||
// contiguous in the returned array, though neighbouring cells in row order
|
||||
// may not be contiguous in the row values. The cell values for cell
|
||||
// (row_block, cell_block) are found at offset
|
||||
//
|
||||
// block_structure()->rows[row_block].cells[cell_block].position
|
||||
//
|
||||
virtual const double* RowBlockValues(int row_block_index) const = 0;
|
||||
|
||||
private:
|
||||
CERES_DISALLOW_COPY_AND_ASSIGN(BlockSparseMatrixBase);
|
||||
};
|
||||
|
||||
// This class implements the SparseMatrix interface for storing and
|
||||
// manipulating block sparse matrices. The block structure is stored
|
||||
// in the CompressedRowBlockStructure object and one is needed to
|
||||
@@ -85,7 +54,7 @@ class BlockSparseMatrixBase : public SparseMatrix {
|
||||
//
|
||||
// internal/ceres/block_structure.h
|
||||
//
|
||||
class BlockSparseMatrix : public BlockSparseMatrixBase {
|
||||
class BlockSparseMatrix : public SparseMatrix {
|
||||
public:
|
||||
// Construct a block sparse matrix with a fully initialized
|
||||
// CompressedRowBlockStructure objected. The matrix takes over
|
||||
@@ -121,12 +90,8 @@ class BlockSparseMatrix : public BlockSparseMatrixBase {
|
||||
virtual const double* values() const { return values_.get(); }
|
||||
virtual double* mutable_values() { return values_.get(); }
|
||||
|
||||
// Implementation of BlockSparseMatrixBase interface.
|
||||
virtual void ToTripletSparseMatrix(TripletSparseMatrix* matrix) const;
|
||||
virtual const CompressedRowBlockStructure* block_structure() const;
|
||||
virtual const double* RowBlockValues(int row_block_index) const {
|
||||
return values_.get();
|
||||
}
|
||||
void ToTripletSparseMatrix(TripletSparseMatrix* matrix) const;
|
||||
const CompressedRowBlockStructure* block_structure() const;
|
||||
|
||||
private:
|
||||
int num_rows_;
|
||||
|
||||
@@ -46,7 +46,7 @@ CgnrSolver::CgnrSolver(const LinearSolver::Options& options)
|
||||
}
|
||||
|
||||
LinearSolver::Summary CgnrSolver::SolveImpl(
|
||||
BlockSparseMatrixBase* A,
|
||||
BlockSparseMatrix* A,
|
||||
const double* b,
|
||||
const LinearSolver::PerSolveOptions& per_solve_options,
|
||||
double* x) {
|
||||
|
||||
@@ -48,11 +48,11 @@ class BlockJacobiPreconditioner;
|
||||
//
|
||||
// as required for solving for x in the least squares sense. Currently only
|
||||
// block diagonal preconditioning is supported.
|
||||
class CgnrSolver : public BlockSparseMatrixBaseSolver {
|
||||
class CgnrSolver : public BlockSparseMatrixSolver {
|
||||
public:
|
||||
explicit CgnrSolver(const LinearSolver::Options& options);
|
||||
virtual Summary SolveImpl(
|
||||
BlockSparseMatrixBase* A,
|
||||
BlockSparseMatrix* A,
|
||||
const double* b,
|
||||
const LinearSolver::PerSolveOptions& per_solve_options,
|
||||
double* x);
|
||||
|
||||
@@ -55,7 +55,7 @@ ImplicitSchurComplement::ImplicitSchurComplement(int num_eliminate_blocks,
|
||||
ImplicitSchurComplement::~ImplicitSchurComplement() {
|
||||
}
|
||||
|
||||
void ImplicitSchurComplement::Init(const BlockSparseMatrixBase& A,
|
||||
void ImplicitSchurComplement::Init(const BlockSparseMatrix& A,
|
||||
const double* D,
|
||||
const double* b) {
|
||||
// Since initialization is reasonably heavy, perhaps we can save on
|
||||
|
||||
@@ -44,7 +44,6 @@ namespace ceres {
|
||||
namespace internal {
|
||||
|
||||
class BlockSparseMatrix;
|
||||
class BlockSparseMatrixBase;
|
||||
|
||||
// This class implements various linear algebraic operations related
|
||||
// to the Schur complement without explicitly forming it.
|
||||
@@ -110,7 +109,7 @@ class ImplicitSchurComplement : public LinearOperator {
|
||||
// is important that the matrix A have a BlockStructure object
|
||||
// associated with it and has a block structure that is compatible
|
||||
// with the SchurComplement solver.
|
||||
void Init(const BlockSparseMatrixBase& A, const double* D, const double* b);
|
||||
void Init(const BlockSparseMatrix& A, const double* D, const double* b);
|
||||
|
||||
// y += Sx, where S is the Schur complement.
|
||||
virtual void RightMultiply(const double* x, double* y) const;
|
||||
|
||||
@@ -62,7 +62,7 @@ IterativeSchurComplementSolver::~IterativeSchurComplementSolver() {
|
||||
}
|
||||
|
||||
LinearSolver::Summary IterativeSchurComplementSolver::SolveImpl(
|
||||
BlockSparseMatrixBase* A,
|
||||
BlockSparseMatrix* A,
|
||||
const double* b,
|
||||
const LinearSolver::PerSolveOptions& per_solve_options,
|
||||
double* x) {
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
namespace ceres {
|
||||
namespace internal {
|
||||
|
||||
class BlockSparseMatrixBase;
|
||||
class BlockSparseMatrix;
|
||||
class ImplicitSchurComplement;
|
||||
class Preconditioner;
|
||||
|
||||
@@ -67,14 +67,14 @@ class Preconditioner;
|
||||
// a proof of this fact and others related to this solver please see
|
||||
// the section on Domain Decomposition Methods in Saad's book
|
||||
// "Iterative Methods for Sparse Linear Systems".
|
||||
class IterativeSchurComplementSolver : public BlockSparseMatrixBaseSolver {
|
||||
class IterativeSchurComplementSolver : public BlockSparseMatrixSolver {
|
||||
public:
|
||||
explicit IterativeSchurComplementSolver(const LinearSolver::Options& options);
|
||||
virtual ~IterativeSchurComplementSolver();
|
||||
|
||||
private:
|
||||
virtual LinearSolver::Summary SolveImpl(
|
||||
BlockSparseMatrixBase* A,
|
||||
BlockSparseMatrix* A,
|
||||
const double* b,
|
||||
const LinearSolver::PerSolveOptions& options,
|
||||
double* x);
|
||||
|
||||
@@ -316,7 +316,6 @@ class TypedLinearSolver : public LinearSolver {
|
||||
// Linear solvers that depend on acccess to the low level structure of
|
||||
// a SparseMatrix.
|
||||
typedef TypedLinearSolver<BlockSparseMatrix> BlockSparseMatrixSolver; // NOLINT
|
||||
typedef TypedLinearSolver<BlockSparseMatrixBase> BlockSparseMatrixBaseSolver; // NOLINT
|
||||
typedef TypedLinearSolver<CompressedRowSparseMatrix> CompressedRowSparseMatrixSolver; // NOLINT
|
||||
typedef TypedLinearSolver<DenseSparseMatrix> DenseSparseMatrixSolver; // NOLINT
|
||||
typedef TypedLinearSolver<TripletSparseMatrix> TripletSparseMatrixSolver; // NOLINT
|
||||
|
||||
@@ -45,7 +45,7 @@ namespace ceres {
|
||||
namespace internal {
|
||||
|
||||
PartitionedMatrixView::PartitionedMatrixView(
|
||||
const BlockSparseMatrixBase& matrix,
|
||||
const BlockSparseMatrix& matrix,
|
||||
int num_col_blocks_a)
|
||||
: matrix_(matrix),
|
||||
num_col_blocks_e_(num_col_blocks_a) {
|
||||
@@ -96,8 +96,8 @@ void PartitionedMatrixView::RightMultiplyE(const double* x, double* y) const {
|
||||
|
||||
// Iterate over the first num_row_blocks_e_ row blocks, and multiply
|
||||
// by the first cell in each row block.
|
||||
const double* values = matrix_.values();
|
||||
for (int r = 0; r < num_row_blocks_e_; ++r) {
|
||||
const double* row_values = matrix_.RowBlockValues(r);
|
||||
const Cell& cell = bs->rows[r].cells[0];
|
||||
const int row_block_pos = bs->rows[r].block.position;
|
||||
const int row_block_size = bs->rows[r].block.size;
|
||||
@@ -105,7 +105,7 @@ void PartitionedMatrixView::RightMultiplyE(const double* x, double* y) const {
|
||||
const int col_block_pos = bs->cols[col_block_id].position;
|
||||
const int col_block_size = bs->cols[col_block_id].size;
|
||||
MatrixVectorMultiply<Eigen::Dynamic, Eigen::Dynamic, 1>(
|
||||
row_values + cell.position, row_block_size, col_block_size,
|
||||
values + cell.position, row_block_size, col_block_size,
|
||||
x + col_block_pos,
|
||||
y + row_block_pos);
|
||||
}
|
||||
@@ -119,17 +119,17 @@ void PartitionedMatrixView::RightMultiplyF(const double* x, double* y) const {
|
||||
// E. If the row block is not in E (i.e its in the bottom
|
||||
// num_row_blocks - num_row_blocks_e row blocks), then all the cells
|
||||
// are of type F and multiply by them all.
|
||||
const double* values = matrix_.values();
|
||||
for (int r = 0; r < bs->rows.size(); ++r) {
|
||||
const int row_block_pos = bs->rows[r].block.position;
|
||||
const int row_block_size = bs->rows[r].block.size;
|
||||
const vector<Cell>& cells = bs->rows[r].cells;
|
||||
for (int c = (r < num_row_blocks_e_) ? 1 : 0; c < cells.size(); ++c) {
|
||||
const double* row_values = matrix_.RowBlockValues(r);
|
||||
const int col_block_id = cells[c].block_id;
|
||||
const int col_block_pos = bs->cols[col_block_id].position;
|
||||
const int col_block_size = bs->cols[col_block_id].size;
|
||||
MatrixVectorMultiply<Eigen::Dynamic, Eigen::Dynamic, 1>(
|
||||
row_values + cells[c].position, row_block_size, col_block_size,
|
||||
values + cells[c].position, row_block_size, col_block_size,
|
||||
x + col_block_pos - num_cols_e(),
|
||||
y + row_block_pos);
|
||||
}
|
||||
@@ -141,16 +141,16 @@ void PartitionedMatrixView::LeftMultiplyE(const double* x, double* y) const {
|
||||
|
||||
// Iterate over the first num_row_blocks_e_ row blocks, and multiply
|
||||
// by the first cell in each row block.
|
||||
const double* values = matrix_.values();
|
||||
for (int r = 0; r < num_row_blocks_e_; ++r) {
|
||||
const Cell& cell = bs->rows[r].cells[0];
|
||||
const double* row_values = matrix_.RowBlockValues(r);
|
||||
const int row_block_pos = bs->rows[r].block.position;
|
||||
const int row_block_size = bs->rows[r].block.size;
|
||||
const int col_block_id = cell.block_id;
|
||||
const int col_block_pos = bs->cols[col_block_id].position;
|
||||
const int col_block_size = bs->cols[col_block_id].size;
|
||||
MatrixTransposeVectorMultiply<Eigen::Dynamic, Eigen::Dynamic, 1>(
|
||||
row_values + cell.position, row_block_size, col_block_size,
|
||||
values + cell.position, row_block_size, col_block_size,
|
||||
x + row_block_pos,
|
||||
y + col_block_pos);
|
||||
}
|
||||
@@ -164,17 +164,17 @@ void PartitionedMatrixView::LeftMultiplyF(const double* x, double* y) const {
|
||||
// E. If the row block is not in E (i.e its in the bottom
|
||||
// num_row_blocks - num_row_blocks_e row blocks), then all the cells
|
||||
// are of type F and multiply by them all.
|
||||
const double* values = matrix_.values();
|
||||
for (int r = 0; r < bs->rows.size(); ++r) {
|
||||
const int row_block_pos = bs->rows[r].block.position;
|
||||
const int row_block_size = bs->rows[r].block.size;
|
||||
const vector<Cell>& cells = bs->rows[r].cells;
|
||||
for (int c = (r < num_row_blocks_e_) ? 1 : 0; c < cells.size(); ++c) {
|
||||
const double* row_values = matrix_.RowBlockValues(r);
|
||||
const int col_block_id = cells[c].block_id;
|
||||
const int col_block_pos = bs->cols[col_block_id].position;
|
||||
const int col_block_size = bs->cols[col_block_id].size;
|
||||
MatrixTransposeVectorMultiply<Eigen::Dynamic, Eigen::Dynamic, 1>(
|
||||
row_values + cells[c].position, row_block_size, col_block_size,
|
||||
values + cells[c].position, row_block_size, col_block_size,
|
||||
x + row_block_pos,
|
||||
y + col_block_pos - num_cols_e());
|
||||
}
|
||||
@@ -248,9 +248,8 @@ void PartitionedMatrixView::UpdateBlockDiagonalEtE(
|
||||
block_diagonal->block_structure();
|
||||
|
||||
block_diagonal->SetZero();
|
||||
|
||||
const double* values = matrix_.values();
|
||||
for (int r = 0; r < num_row_blocks_e_ ; ++r) {
|
||||
const double* row_values = matrix_.RowBlockValues(r);
|
||||
const Cell& cell = bs->rows[r].cells[0];
|
||||
const int row_block_size = bs->rows[r].block.size;
|
||||
const int block_id = cell.block_id;
|
||||
@@ -260,8 +259,8 @@ void PartitionedMatrixView::UpdateBlockDiagonalEtE(
|
||||
|
||||
MatrixTransposeMatrixMultiply
|
||||
<Eigen::Dynamic, Eigen::Dynamic, Eigen::Dynamic, Eigen::Dynamic, 1>(
|
||||
row_values + cell.position, row_block_size, col_block_size,
|
||||
row_values + cell.position, row_block_size, col_block_size,
|
||||
values + cell.position, row_block_size, col_block_size,
|
||||
values + cell.position, row_block_size, col_block_size,
|
||||
block_diagonal->mutable_values() + cell_position,
|
||||
0, 0, col_block_size, col_block_size);
|
||||
}
|
||||
@@ -279,10 +278,10 @@ void PartitionedMatrixView::UpdateBlockDiagonalFtF(
|
||||
block_diagonal->block_structure();
|
||||
|
||||
block_diagonal->SetZero();
|
||||
const double* values = matrix_.values();
|
||||
for (int r = 0; r < bs->rows.size(); ++r) {
|
||||
const int row_block_size = bs->rows[r].block.size;
|
||||
const vector<Cell>& cells = bs->rows[r].cells;
|
||||
const double* row_values = matrix_.RowBlockValues(r);
|
||||
for (int c = (r < num_row_blocks_e_) ? 1 : 0; c < cells.size(); ++c) {
|
||||
const int col_block_id = cells[c].block_id;
|
||||
const int col_block_size = bs->cols[col_block_id].size;
|
||||
@@ -292,8 +291,8 @@ void PartitionedMatrixView::UpdateBlockDiagonalFtF(
|
||||
|
||||
MatrixTransposeMatrixMultiply
|
||||
<Eigen::Dynamic, Eigen::Dynamic, Eigen::Dynamic, Eigen::Dynamic, 1>(
|
||||
row_values + cells[c].position, row_block_size, col_block_size,
|
||||
row_values + cells[c].position, row_block_size, col_block_size,
|
||||
values + cells[c].position, row_block_size, col_block_size,
|
||||
values + cells[c].position, row_block_size, col_block_size,
|
||||
block_diagonal->mutable_values() + cell_position,
|
||||
0, 0, col_block_size, col_block_size);
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ class PartitionedMatrixView {
|
||||
public:
|
||||
// matrix = [E F], where the matrix E contains the first
|
||||
// num_col_blocks_a column blocks.
|
||||
PartitionedMatrixView(const BlockSparseMatrixBase& matrix,
|
||||
PartitionedMatrixView(const BlockSparseMatrix& matrix,
|
||||
int num_col_blocks_a);
|
||||
~PartitionedMatrixView();
|
||||
|
||||
@@ -107,7 +107,7 @@ class PartitionedMatrixView {
|
||||
BlockSparseMatrix* CreateBlockDiagonalMatrixLayout(int start_col_block,
|
||||
int end_col_block) const;
|
||||
|
||||
const BlockSparseMatrixBase& matrix_;
|
||||
const BlockSparseMatrix& matrix_;
|
||||
int num_row_blocks_e_;
|
||||
int num_col_blocks_e_;
|
||||
int num_col_blocks_f_;
|
||||
|
||||
@@ -45,7 +45,7 @@ SparseMatrixPreconditionerWrapper::SparseMatrixPreconditionerWrapper(
|
||||
SparseMatrixPreconditionerWrapper::~SparseMatrixPreconditionerWrapper() {
|
||||
}
|
||||
|
||||
bool SparseMatrixPreconditionerWrapper::Update(const BlockSparseMatrixBase& A,
|
||||
bool SparseMatrixPreconditionerWrapper::Update(const BlockSparseMatrix& A,
|
||||
const double* D) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
namespace ceres {
|
||||
namespace internal {
|
||||
|
||||
class BlockSparseMatrixBase;
|
||||
class BlockSparseMatrix;
|
||||
class SparseMatrix;
|
||||
|
||||
class Preconditioner : public LinearOperator {
|
||||
@@ -105,7 +105,7 @@ class Preconditioner : public LinearOperator {
|
||||
//
|
||||
// D can be NULL, in which case its interpreted as a diagonal matrix
|
||||
// of size zero.
|
||||
virtual bool Update(const BlockSparseMatrixBase& A, const double* D) = 0;
|
||||
virtual bool Update(const BlockSparseMatrix& A, const double* D) = 0;
|
||||
|
||||
// LinearOperator interface. Since the operator is symmetric,
|
||||
// LeftMultiply and num_cols are just calls to RightMultiply and
|
||||
@@ -130,7 +130,7 @@ class SparseMatrixPreconditionerWrapper : public Preconditioner {
|
||||
virtual ~SparseMatrixPreconditionerWrapper();
|
||||
|
||||
// Preconditioner interface
|
||||
virtual bool Update(const BlockSparseMatrixBase& A, const double* D);
|
||||
virtual bool Update(const BlockSparseMatrix& A, const double* D);
|
||||
virtual void RightMultiply(const double* x, double* y) const;
|
||||
virtual int num_rows() const;
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ namespace ceres {
|
||||
namespace internal {
|
||||
|
||||
LinearSolver::Summary SchurComplementSolver::SolveImpl(
|
||||
BlockSparseMatrixBase* A,
|
||||
BlockSparseMatrix* A,
|
||||
const double* b,
|
||||
const LinearSolver::PerSolveOptions& per_solve_options,
|
||||
double* x) {
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
namespace ceres {
|
||||
namespace internal {
|
||||
|
||||
class BlockSparseMatrixBase;
|
||||
class BlockSparseMatrix;
|
||||
|
||||
// Base class for Schur complement based linear least squares
|
||||
// solvers. It assumes that the input linear system Ax = b can be
|
||||
@@ -100,7 +100,7 @@ class BlockSparseMatrixBase;
|
||||
// set to DENSE_SCHUR and SPARSE_SCHUR
|
||||
// respectively. LinearSolver::Options::elimination_groups[0] should be
|
||||
// at least 1.
|
||||
class SchurComplementSolver : public BlockSparseMatrixBaseSolver {
|
||||
class SchurComplementSolver : public BlockSparseMatrixSolver {
|
||||
public:
|
||||
explicit SchurComplementSolver(const LinearSolver::Options& options)
|
||||
: options_(options) {
|
||||
@@ -111,7 +111,7 @@ class SchurComplementSolver : public BlockSparseMatrixBaseSolver {
|
||||
// LinearSolver methods
|
||||
virtual ~SchurComplementSolver() {}
|
||||
virtual LinearSolver::Summary SolveImpl(
|
||||
BlockSparseMatrixBase* A,
|
||||
BlockSparseMatrix* A,
|
||||
const double* b,
|
||||
const LinearSolver::PerSolveOptions& per_solve_options,
|
||||
double* x);
|
||||
|
||||
@@ -170,7 +170,7 @@ class SchurEliminatorBase {
|
||||
// also the caller's responsibilty to ensure that the
|
||||
// CompressedRowBlockStructure object passed to this method is the
|
||||
// same one (or is equivalent to) the one associated with the
|
||||
// BlockSparseMatrixBase objects below.
|
||||
// BlockSparseMatrix objects below.
|
||||
virtual void Init(int num_eliminate_blocks,
|
||||
const CompressedRowBlockStructure* bs) = 0;
|
||||
|
||||
@@ -185,7 +185,7 @@ class SchurEliminatorBase {
|
||||
//
|
||||
// Since the Schur complement is a symmetric matrix, only the upper
|
||||
// triangular part of the Schur complement is computed.
|
||||
virtual void Eliminate(const BlockSparseMatrixBase* A,
|
||||
virtual void Eliminate(const BlockSparseMatrix* A,
|
||||
const double* b,
|
||||
const double* D,
|
||||
BlockRandomAccessMatrix* lhs,
|
||||
@@ -194,7 +194,7 @@ class SchurEliminatorBase {
|
||||
// Given values for the variables z in the F block of A, solve for
|
||||
// the optimal values of the variables y corresponding to the E
|
||||
// block in A.
|
||||
virtual void BackSubstitute(const BlockSparseMatrixBase* A,
|
||||
virtual void BackSubstitute(const BlockSparseMatrix* A,
|
||||
const double* b,
|
||||
const double* D,
|
||||
const double* z,
|
||||
@@ -226,12 +226,12 @@ class SchurEliminator : public SchurEliminatorBase {
|
||||
virtual ~SchurEliminator();
|
||||
virtual void Init(int num_eliminate_blocks,
|
||||
const CompressedRowBlockStructure* bs);
|
||||
virtual void Eliminate(const BlockSparseMatrixBase* A,
|
||||
virtual void Eliminate(const BlockSparseMatrix* A,
|
||||
const double* b,
|
||||
const double* D,
|
||||
BlockRandomAccessMatrix* lhs,
|
||||
double* rhs);
|
||||
virtual void BackSubstitute(const BlockSparseMatrixBase* A,
|
||||
virtual void BackSubstitute(const BlockSparseMatrix* A,
|
||||
const double* b,
|
||||
const double* D,
|
||||
const double* z,
|
||||
@@ -273,7 +273,7 @@ class SchurEliminator : public SchurEliminatorBase {
|
||||
|
||||
void ChunkDiagonalBlockAndGradient(
|
||||
const Chunk& chunk,
|
||||
const BlockSparseMatrixBase* A,
|
||||
const BlockSparseMatrix* A,
|
||||
const double* b,
|
||||
int row_block_counter,
|
||||
typename EigenTypes<kEBlockSize, kEBlockSize>::Matrix* eet,
|
||||
@@ -282,7 +282,7 @@ class SchurEliminator : public SchurEliminatorBase {
|
||||
BlockRandomAccessMatrix* lhs);
|
||||
|
||||
void UpdateRhs(const Chunk& chunk,
|
||||
const BlockSparseMatrixBase* A,
|
||||
const BlockSparseMatrix* A,
|
||||
const double* b,
|
||||
int row_block_counter,
|
||||
const double* inverse_ete_g,
|
||||
@@ -293,18 +293,18 @@ class SchurEliminator : public SchurEliminatorBase {
|
||||
const double* buffer,
|
||||
const BufferLayoutType& buffer_layout,
|
||||
BlockRandomAccessMatrix* lhs);
|
||||
void EBlockRowOuterProduct(const BlockSparseMatrixBase* A,
|
||||
void EBlockRowOuterProduct(const BlockSparseMatrix* A,
|
||||
int row_block_index,
|
||||
BlockRandomAccessMatrix* lhs);
|
||||
|
||||
|
||||
void NoEBlockRowsUpdate(const BlockSparseMatrixBase* A,
|
||||
void NoEBlockRowsUpdate(const BlockSparseMatrix* A,
|
||||
const double* b,
|
||||
int row_block_counter,
|
||||
BlockRandomAccessMatrix* lhs,
|
||||
double* rhs);
|
||||
|
||||
void NoEBlockRowOuterProduct(const BlockSparseMatrixBase* A,
|
||||
void NoEBlockRowOuterProduct(const BlockSparseMatrix* A,
|
||||
int row_block_index,
|
||||
BlockRandomAccessMatrix* lhs);
|
||||
|
||||
|
||||
@@ -168,7 +168,7 @@ Init(int num_eliminate_blocks, const CompressedRowBlockStructure* bs) {
|
||||
template <int kRowBlockSize, int kEBlockSize, int kFBlockSize>
|
||||
void
|
||||
SchurEliminator<kRowBlockSize, kEBlockSize, kFBlockSize>::
|
||||
Eliminate(const BlockSparseMatrixBase* A,
|
||||
Eliminate(const BlockSparseMatrix* A,
|
||||
const double* b,
|
||||
const double* D,
|
||||
BlockRandomAccessMatrix* lhs,
|
||||
@@ -299,7 +299,7 @@ Eliminate(const BlockSparseMatrixBase* A,
|
||||
template <int kRowBlockSize, int kEBlockSize, int kFBlockSize>
|
||||
void
|
||||
SchurEliminator<kRowBlockSize, kEBlockSize, kFBlockSize>::
|
||||
BackSubstitute(const BlockSparseMatrixBase* A,
|
||||
BackSubstitute(const BlockSparseMatrix* A,
|
||||
const double* b,
|
||||
const double* D,
|
||||
const double* z,
|
||||
@@ -324,9 +324,9 @@ BackSubstitute(const BlockSparseMatrixBase* A,
|
||||
ete.setZero();
|
||||
}
|
||||
|
||||
const double* values = A->values();
|
||||
for (int j = 0; j < chunk.size; ++j) {
|
||||
const CompressedRow& row = bs->rows[chunk.start + j];
|
||||
const double* row_values = A->RowBlockValues(chunk.start + j);
|
||||
const Cell& e_cell = row.cells.front();
|
||||
DCHECK_EQ(e_block_id, e_cell.block_id);
|
||||
|
||||
@@ -342,20 +342,20 @@ BackSubstitute(const BlockSparseMatrixBase* A,
|
||||
const int r_block = f_block_id - num_eliminate_blocks_;
|
||||
|
||||
MatrixVectorMultiply<kRowBlockSize, kFBlockSize, -1>(
|
||||
row_values + row.cells[c].position, row.block.size, f_block_size,
|
||||
values + row.cells[c].position, row.block.size, f_block_size,
|
||||
z + lhs_row_layout_[r_block],
|
||||
sj.get());
|
||||
}
|
||||
|
||||
MatrixTransposeVectorMultiply<kRowBlockSize, kEBlockSize, 1>(
|
||||
row_values + e_cell.position, row.block.size, e_block_size,
|
||||
values + e_cell.position, row.block.size, e_block_size,
|
||||
sj.get(),
|
||||
y_ptr);
|
||||
|
||||
MatrixTransposeMatrixMultiply
|
||||
<kRowBlockSize, kEBlockSize, kRowBlockSize, kEBlockSize, 1>(
|
||||
row_values + e_cell.position, row.block.size, e_block_size,
|
||||
row_values + e_cell.position, row.block.size, e_block_size,
|
||||
values + e_cell.position, row.block.size, e_block_size,
|
||||
values + e_cell.position, row.block.size, e_block_size,
|
||||
ete.data(), 0, 0, e_block_size, e_block_size);
|
||||
}
|
||||
|
||||
@@ -370,7 +370,7 @@ template <int kRowBlockSize, int kEBlockSize, int kFBlockSize>
|
||||
void
|
||||
SchurEliminator<kRowBlockSize, kEBlockSize, kFBlockSize>::
|
||||
UpdateRhs(const Chunk& chunk,
|
||||
const BlockSparseMatrixBase* A,
|
||||
const BlockSparseMatrix* A,
|
||||
const double* b,
|
||||
int row_block_counter,
|
||||
const double* inverse_ete_g,
|
||||
@@ -380,9 +380,9 @@ UpdateRhs(const Chunk& chunk,
|
||||
const int e_block_size = bs->cols[e_block_id].size;
|
||||
|
||||
int b_pos = bs->rows[row_block_counter].block.position;
|
||||
const double* values = A->values();
|
||||
for (int j = 0; j < chunk.size; ++j) {
|
||||
const CompressedRow& row = bs->rows[row_block_counter + j];
|
||||
const double *row_values = A->RowBlockValues(row_block_counter + j);
|
||||
const Cell& e_cell = row.cells.front();
|
||||
|
||||
typename EigenTypes<kRowBlockSize>::Vector sj =
|
||||
@@ -390,7 +390,7 @@ UpdateRhs(const Chunk& chunk,
|
||||
(b + b_pos, row.block.size);
|
||||
|
||||
MatrixVectorMultiply<kRowBlockSize, kEBlockSize, -1>(
|
||||
row_values + e_cell.position, row.block.size, e_block_size,
|
||||
values + e_cell.position, row.block.size, e_block_size,
|
||||
inverse_ete_g, sj.data());
|
||||
|
||||
for (int c = 1; c < row.cells.size(); ++c) {
|
||||
@@ -399,7 +399,7 @@ UpdateRhs(const Chunk& chunk,
|
||||
const int block = block_id - num_eliminate_blocks_;
|
||||
CeresMutexLock l(rhs_locks_[block]);
|
||||
MatrixTransposeVectorMultiply<kRowBlockSize, kFBlockSize, 1>(
|
||||
row_values + row.cells[c].position,
|
||||
values + row.cells[c].position,
|
||||
row.block.size, block_size,
|
||||
sj.data(), rhs + lhs_row_layout_[block]);
|
||||
}
|
||||
@@ -431,7 +431,7 @@ void
|
||||
SchurEliminator<kRowBlockSize, kEBlockSize, kFBlockSize>::
|
||||
ChunkDiagonalBlockAndGradient(
|
||||
const Chunk& chunk,
|
||||
const BlockSparseMatrixBase* A,
|
||||
const BlockSparseMatrix* A,
|
||||
const double* b,
|
||||
int row_block_counter,
|
||||
typename EigenTypes<kEBlockSize, kEBlockSize>::Matrix* ete,
|
||||
@@ -447,9 +447,9 @@ ChunkDiagonalBlockAndGradient(
|
||||
// contribution of its F blocks to the Schur complement, the
|
||||
// contribution of its E block to the matrix EE' (ete), and the
|
||||
// corresponding block in the gradient vector.
|
||||
const double* values = A->values();
|
||||
for (int j = 0; j < chunk.size; ++j) {
|
||||
const CompressedRow& row = bs->rows[row_block_counter + j];
|
||||
const double *row_values = A->RowBlockValues(row_block_counter + j);
|
||||
|
||||
if (row.cells.size() > 1) {
|
||||
EBlockRowOuterProduct(A, row_block_counter + j, lhs);
|
||||
@@ -459,13 +459,13 @@ ChunkDiagonalBlockAndGradient(
|
||||
const Cell& e_cell = row.cells.front();
|
||||
MatrixTransposeMatrixMultiply
|
||||
<kRowBlockSize, kEBlockSize, kRowBlockSize, kEBlockSize, 1>(
|
||||
row_values + e_cell.position, row.block.size, e_block_size,
|
||||
row_values + e_cell.position, row.block.size, e_block_size,
|
||||
values + e_cell.position, row.block.size, e_block_size,
|
||||
values + e_cell.position, row.block.size, e_block_size,
|
||||
ete->data(), 0, 0, e_block_size, e_block_size);
|
||||
|
||||
// g += E_i' b_i
|
||||
MatrixTransposeVectorMultiply<kRowBlockSize, kEBlockSize, 1>(
|
||||
row_values + e_cell.position, row.block.size, e_block_size,
|
||||
values + e_cell.position, row.block.size, e_block_size,
|
||||
b + b_pos,
|
||||
g);
|
||||
|
||||
@@ -479,8 +479,8 @@ ChunkDiagonalBlockAndGradient(
|
||||
buffer + FindOrDie(chunk.buffer_layout, f_block_id);
|
||||
MatrixTransposeMatrixMultiply
|
||||
<kRowBlockSize, kEBlockSize, kRowBlockSize, kFBlockSize, 1>(
|
||||
row_values + e_cell.position, row.block.size, e_block_size,
|
||||
row_values + row.cells[c].position, row.block.size, f_block_size,
|
||||
values + e_cell.position, row.block.size, e_block_size,
|
||||
values + row.cells[c].position, row.block.size, f_block_size,
|
||||
buffer_ptr, 0, 0, e_block_size, f_block_size);
|
||||
}
|
||||
b_pos += row.block.size;
|
||||
@@ -551,21 +551,21 @@ ChunkOuterProduct(const CompressedRowBlockStructure* bs,
|
||||
template <int kRowBlockSize, int kEBlockSize, int kFBlockSize>
|
||||
void
|
||||
SchurEliminator<kRowBlockSize, kEBlockSize, kFBlockSize>::
|
||||
NoEBlockRowsUpdate(const BlockSparseMatrixBase* A,
|
||||
NoEBlockRowsUpdate(const BlockSparseMatrix* A,
|
||||
const double* b,
|
||||
int row_block_counter,
|
||||
BlockRandomAccessMatrix* lhs,
|
||||
double* rhs) {
|
||||
const CompressedRowBlockStructure* bs = A->block_structure();
|
||||
const double* values = A->values();
|
||||
for (; row_block_counter < bs->rows.size(); ++row_block_counter) {
|
||||
const CompressedRow& row = bs->rows[row_block_counter];
|
||||
const double *row_values = A->RowBlockValues(row_block_counter);
|
||||
for (int c = 0; c < row.cells.size(); ++c) {
|
||||
const int block_id = row.cells[c].block_id;
|
||||
const int block_size = bs->cols[block_id].size;
|
||||
const int block = block_id - num_eliminate_blocks_;
|
||||
MatrixTransposeVectorMultiply<Eigen::Dynamic, Eigen::Dynamic, 1>(
|
||||
row_values + row.cells[c].position, row.block.size, block_size,
|
||||
values + row.cells[c].position, row.block.size, block_size,
|
||||
b + row.block.position,
|
||||
rhs + lhs_row_layout_[block]);
|
||||
}
|
||||
@@ -591,12 +591,12 @@ NoEBlockRowsUpdate(const BlockSparseMatrixBase* A,
|
||||
template <int kRowBlockSize, int kEBlockSize, int kFBlockSize>
|
||||
void
|
||||
SchurEliminator<kRowBlockSize, kEBlockSize, kFBlockSize>::
|
||||
NoEBlockRowOuterProduct(const BlockSparseMatrixBase* A,
|
||||
NoEBlockRowOuterProduct(const BlockSparseMatrix* A,
|
||||
int row_block_index,
|
||||
BlockRandomAccessMatrix* lhs) {
|
||||
const CompressedRowBlockStructure* bs = A->block_structure();
|
||||
const CompressedRow& row = bs->rows[row_block_index];
|
||||
const double *row_values = A->RowBlockValues(row_block_index);
|
||||
const double* values = A->values();
|
||||
for (int i = 0; i < row.cells.size(); ++i) {
|
||||
const int block1 = row.cells[i].block_id - num_eliminate_blocks_;
|
||||
DCHECK_GE(block1, 0);
|
||||
@@ -612,8 +612,8 @@ NoEBlockRowOuterProduct(const BlockSparseMatrixBase* A,
|
||||
// symmetric outer product.
|
||||
MatrixTransposeMatrixMultiply
|
||||
<Eigen::Dynamic, Eigen::Dynamic, Eigen::Dynamic, Eigen::Dynamic, 1>(
|
||||
row_values + row.cells[i].position, row.block.size, block1_size,
|
||||
row_values + row.cells[i].position, row.block.size, block1_size,
|
||||
values + row.cells[i].position, row.block.size, block1_size,
|
||||
values + row.cells[i].position, row.block.size, block1_size,
|
||||
cell_info->values, r, c, row_stride, col_stride);
|
||||
}
|
||||
|
||||
@@ -630,8 +630,8 @@ NoEBlockRowOuterProduct(const BlockSparseMatrixBase* A,
|
||||
CeresMutexLock l(&cell_info->m);
|
||||
MatrixTransposeMatrixMultiply
|
||||
<Eigen::Dynamic, Eigen::Dynamic, Eigen::Dynamic, Eigen::Dynamic, 1>(
|
||||
row_values + row.cells[i].position, row.block.size, block1_size,
|
||||
row_values + row.cells[j].position, row.block.size, block2_size,
|
||||
values + row.cells[i].position, row.block.size, block1_size,
|
||||
values + row.cells[j].position, row.block.size, block2_size,
|
||||
cell_info->values, r, c, row_stride, col_stride);
|
||||
}
|
||||
}
|
||||
@@ -644,12 +644,12 @@ NoEBlockRowOuterProduct(const BlockSparseMatrixBase* A,
|
||||
template <int kRowBlockSize, int kEBlockSize, int kFBlockSize>
|
||||
void
|
||||
SchurEliminator<kRowBlockSize, kEBlockSize, kFBlockSize>::
|
||||
EBlockRowOuterProduct(const BlockSparseMatrixBase* A,
|
||||
EBlockRowOuterProduct(const BlockSparseMatrix* A,
|
||||
int row_block_index,
|
||||
BlockRandomAccessMatrix* lhs) {
|
||||
const CompressedRowBlockStructure* bs = A->block_structure();
|
||||
const CompressedRow& row = bs->rows[row_block_index];
|
||||
const double *row_values = A->RowBlockValues(row_block_index);
|
||||
const double* values = A->values();
|
||||
for (int i = 1; i < row.cells.size(); ++i) {
|
||||
const int block1 = row.cells[i].block_id - num_eliminate_blocks_;
|
||||
DCHECK_GE(block1, 0);
|
||||
@@ -664,8 +664,8 @@ EBlockRowOuterProduct(const BlockSparseMatrixBase* A,
|
||||
// block += b1.transpose() * b1;
|
||||
MatrixTransposeMatrixMultiply
|
||||
<kRowBlockSize, kFBlockSize, kRowBlockSize, kFBlockSize, 1>(
|
||||
row_values + row.cells[i].position, row.block.size, block1_size,
|
||||
row_values + row.cells[i].position, row.block.size, block1_size,
|
||||
values + row.cells[i].position, row.block.size, block1_size,
|
||||
values + row.cells[i].position, row.block.size, block1_size,
|
||||
cell_info->values, r, c, row_stride, col_stride);
|
||||
}
|
||||
|
||||
@@ -683,8 +683,8 @@ EBlockRowOuterProduct(const BlockSparseMatrixBase* A,
|
||||
CeresMutexLock l(&cell_info->m);
|
||||
MatrixTransposeMatrixMultiply
|
||||
<kRowBlockSize, kFBlockSize, kRowBlockSize, kFBlockSize, 1>(
|
||||
row_values + row.cells[i].position, row.block.size, block1_size,
|
||||
row_values + row.cells[j].position, row.block.size, block2_size,
|
||||
values + row.cells[i].position, row.block.size, block1_size,
|
||||
values + row.cells[j].position, row.block.size, block2_size,
|
||||
cell_info->values, r, c, row_stride, col_stride);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ void SchurJacobiPreconditioner::InitEliminator(
|
||||
}
|
||||
|
||||
// Update the values of the preconditioner matrix and factorize it.
|
||||
bool SchurJacobiPreconditioner::Update(const BlockSparseMatrixBase& A,
|
||||
bool SchurJacobiPreconditioner::Update(const BlockSparseMatrix& A,
|
||||
const double* D) {
|
||||
const int num_rows = m_->num_rows();
|
||||
CHECK_GT(num_rows, 0);
|
||||
|
||||
@@ -50,7 +50,7 @@ namespace ceres {
|
||||
namespace internal {
|
||||
|
||||
class BlockRandomAccessSparseMatrix;
|
||||
class BlockSparseMatrixBase;
|
||||
class BlockSparseMatrix;
|
||||
struct CompressedRowBlockStructure;
|
||||
class SchurEliminatorBase;
|
||||
|
||||
@@ -86,7 +86,7 @@ class SchurJacobiPreconditioner : public Preconditioner {
|
||||
virtual ~SchurJacobiPreconditioner();
|
||||
|
||||
// Preconditioner interface.
|
||||
virtual bool Update(const BlockSparseMatrixBase& A, const double* D);
|
||||
virtual bool Update(const BlockSparseMatrix& A, const double* D);
|
||||
virtual void RightMultiply(const double* x, double* y) const;
|
||||
virtual int num_rows() const;
|
||||
|
||||
|
||||
@@ -324,7 +324,7 @@ void VisibilityBasedPreconditioner::InitEliminator(
|
||||
}
|
||||
|
||||
// Update the values of the preconditioner matrix and factorize it.
|
||||
bool VisibilityBasedPreconditioner::Update(const BlockSparseMatrixBase& A,
|
||||
bool VisibilityBasedPreconditioner::Update(const BlockSparseMatrix& A,
|
||||
const double* D) {
|
||||
const time_t start_time = time(NULL);
|
||||
const int num_rows = m_->num_rows();
|
||||
|
||||
@@ -62,7 +62,7 @@ namespace ceres {
|
||||
namespace internal {
|
||||
|
||||
class BlockRandomAccessSparseMatrix;
|
||||
class BlockSparseMatrixBase;
|
||||
class BlockSparseMatrix;
|
||||
struct CompressedRowBlockStructure;
|
||||
class SchurEliminatorBase;
|
||||
|
||||
@@ -136,7 +136,7 @@ class VisibilityBasedPreconditioner : public Preconditioner {
|
||||
virtual ~VisibilityBasedPreconditioner();
|
||||
|
||||
// Preconditioner interface
|
||||
virtual bool Update(const BlockSparseMatrixBase& A, const double* D);
|
||||
virtual bool Update(const BlockSparseMatrix& A, const double* D);
|
||||
virtual void RightMultiply(const double* x, double* y) const;
|
||||
virtual int num_rows() const;
|
||||
|
||||
@@ -215,7 +215,7 @@ class VisibilityBasedPreconditioner : public Preconditioner {
|
||||
virtual void LeftMultiply(const double* x, double* y) const {}
|
||||
virtual int num_rows() const { return -1; }
|
||||
virtual int num_cols() const { return -1; }
|
||||
bool Update(const BlockSparseMatrixBase& A, const double* D) {
|
||||
bool Update(const BlockSparseMatrix& A, const double* D) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user