Death to BlockSparseMatrixBase

Change-Id: I13b2b951297ae81bfab0a7b4991a791ed91d594c
diff --git a/internal/ceres/block_jacobi_preconditioner.cc b/internal/ceres/block_jacobi_preconditioner.cc
index 1d5f9d7..5525d4c 100644
--- a/internal/ceres/block_jacobi_preconditioner.cc
+++ b/internal/ceres/block_jacobi_preconditioner.cc
@@ -41,7 +41,7 @@
 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() {}
 
-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);
 
diff --git a/internal/ceres/block_jacobi_preconditioner.h b/internal/ceres/block_jacobi_preconditioner.h
index ed5eebc..dc291bf 100644
--- a/internal/ceres/block_jacobi_preconditioner.h
+++ b/internal/ceres/block_jacobi_preconditioner.h
@@ -37,7 +37,7 @@
 namespace ceres {
 namespace internal {
 
-class BlockSparseMatrixBase;
+class BlockSparseMatrix;
 struct CompressedRowBlockStructure;
 class LinearOperator;
 
@@ -54,11 +54,11 @@
 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_; }
diff --git a/internal/ceres/block_sparse_matrix.h b/internal/ceres/block_sparse_matrix.h
index 513d398..e03c56f 100644
--- a/internal/ceres/block_sparse_matrix.h
+++ b/internal/ceres/block_sparse_matrix.h
@@ -46,37 +46,6 @@
 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 @@
 //
 //   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 @@
   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_;
diff --git a/internal/ceres/cgnr_solver.cc b/internal/ceres/cgnr_solver.cc
index e2e799f..9b8f980 100644
--- a/internal/ceres/cgnr_solver.cc
+++ b/internal/ceres/cgnr_solver.cc
@@ -46,7 +46,7 @@
 }
 
 LinearSolver::Summary CgnrSolver::SolveImpl(
-    BlockSparseMatrixBase* A,
+    BlockSparseMatrix* A,
     const double* b,
     const LinearSolver::PerSolveOptions& per_solve_options,
     double* x) {
diff --git a/internal/ceres/cgnr_solver.h b/internal/ceres/cgnr_solver.h
index d560a9d..c63484c 100644
--- a/internal/ceres/cgnr_solver.h
+++ b/internal/ceres/cgnr_solver.h
@@ -48,11 +48,11 @@
 //
 // 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);
diff --git a/internal/ceres/implicit_schur_complement.cc b/internal/ceres/implicit_schur_complement.cc
index 4af030a..7c934fb 100644
--- a/internal/ceres/implicit_schur_complement.cc
+++ b/internal/ceres/implicit_schur_complement.cc
@@ -55,7 +55,7 @@
 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
diff --git a/internal/ceres/implicit_schur_complement.h b/internal/ceres/implicit_schur_complement.h
index b9ebaa4..c1bb6e1 100644
--- a/internal/ceres/implicit_schur_complement.h
+++ b/internal/ceres/implicit_schur_complement.h
@@ -44,7 +44,6 @@
 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 @@
   // 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;
diff --git a/internal/ceres/iterative_schur_complement_solver.cc b/internal/ceres/iterative_schur_complement_solver.cc
index 15e0bdc..d39d7db 100644
--- a/internal/ceres/iterative_schur_complement_solver.cc
+++ b/internal/ceres/iterative_schur_complement_solver.cc
@@ -62,7 +62,7 @@
 }
 
 LinearSolver::Summary IterativeSchurComplementSolver::SolveImpl(
-    BlockSparseMatrixBase* A,
+    BlockSparseMatrix* A,
     const double* b,
     const LinearSolver::PerSolveOptions& per_solve_options,
     double* x) {
diff --git a/internal/ceres/iterative_schur_complement_solver.h b/internal/ceres/iterative_schur_complement_solver.h
index f8abe04..b056a69 100644
--- a/internal/ceres/iterative_schur_complement_solver.h
+++ b/internal/ceres/iterative_schur_complement_solver.h
@@ -39,7 +39,7 @@
 namespace ceres {
 namespace internal {
 
-class BlockSparseMatrixBase;
+class BlockSparseMatrix;
 class ImplicitSchurComplement;
 class Preconditioner;
 
@@ -67,14 +67,14 @@
 // 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);
diff --git a/internal/ceres/linear_solver.h b/internal/ceres/linear_solver.h
index ca10faa..bdf7b56 100644
--- a/internal/ceres/linear_solver.h
+++ b/internal/ceres/linear_solver.h
@@ -316,7 +316,6 @@
 // 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
diff --git a/internal/ceres/partitioned_matrix_view.cc b/internal/ceres/partitioned_matrix_view.cc
index c488184..5dad438 100644
--- a/internal/ceres/partitioned_matrix_view.cc
+++ b/internal/ceres/partitioned_matrix_view.cc
@@ -45,7 +45,7 @@
 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 @@
 
   // 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 @@
     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 @@
   // 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 @@
 
   // 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 @@
   // 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 @@
       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 @@
 
     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 @@
       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 @@
 
       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);
     }
diff --git a/internal/ceres/partitioned_matrix_view.h b/internal/ceres/partitioned_matrix_view.h
index cfe4de5..ebfbe40 100644
--- a/internal/ceres/partitioned_matrix_view.h
+++ b/internal/ceres/partitioned_matrix_view.h
@@ -60,7 +60,7 @@
  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 @@
   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_;
diff --git a/internal/ceres/preconditioner.cc b/internal/ceres/preconditioner.cc
index 05e539f..19e58fc 100644
--- a/internal/ceres/preconditioner.cc
+++ b/internal/ceres/preconditioner.cc
@@ -45,7 +45,7 @@
 SparseMatrixPreconditionerWrapper::~SparseMatrixPreconditionerWrapper() {
 }
 
-bool SparseMatrixPreconditionerWrapper::Update(const BlockSparseMatrixBase& A,
+bool SparseMatrixPreconditionerWrapper::Update(const BlockSparseMatrix& A,
                                                const double* D) {
   return true;
 }
diff --git a/internal/ceres/preconditioner.h b/internal/ceres/preconditioner.h
index d7c8829..7206536 100644
--- a/internal/ceres/preconditioner.h
+++ b/internal/ceres/preconditioner.h
@@ -38,7 +38,7 @@
 namespace ceres {
 namespace internal {
 
-class BlockSparseMatrixBase;
+class BlockSparseMatrix;
 class SparseMatrix;
 
 class Preconditioner : public LinearOperator {
@@ -105,7 +105,7 @@
   //
   // 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 @@
   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;
 
diff --git a/internal/ceres/schur_complement_solver.cc b/internal/ceres/schur_complement_solver.cc
index 8afb121..9539c0d 100644
--- a/internal/ceres/schur_complement_solver.cc
+++ b/internal/ceres/schur_complement_solver.cc
@@ -58,7 +58,7 @@
 namespace internal {
 
 LinearSolver::Summary SchurComplementSolver::SolveImpl(
-    BlockSparseMatrixBase* A,
+    BlockSparseMatrix* A,
     const double* b,
     const LinearSolver::PerSolveOptions& per_solve_options,
     double* x) {
diff --git a/internal/ceres/schur_complement_solver.h b/internal/ceres/schur_complement_solver.h
index 7c8d2e7..9525e37 100644
--- a/internal/ceres/schur_complement_solver.h
+++ b/internal/ceres/schur_complement_solver.h
@@ -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 @@
 // 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 @@
   // LinearSolver methods
   virtual ~SchurComplementSolver() {}
   virtual LinearSolver::Summary SolveImpl(
-      BlockSparseMatrixBase* A,
+      BlockSparseMatrix* A,
       const double* b,
       const LinearSolver::PerSolveOptions& per_solve_options,
       double* x);
diff --git a/internal/ceres/schur_eliminator.h b/internal/ceres/schur_eliminator.h
index f2c247a..8fe8b9c 100644
--- a/internal/ceres/schur_eliminator.h
+++ b/internal/ceres/schur_eliminator.h
@@ -170,7 +170,7 @@
   // 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 @@
   //
   // 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 @@
   // 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 @@
   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 @@
 
   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 @@
       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 @@
                          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);
 
diff --git a/internal/ceres/schur_eliminator_impl.h b/internal/ceres/schur_eliminator_impl.h
index 835f879..f072c88 100644
--- a/internal/ceres/schur_eliminator_impl.h
+++ b/internal/ceres/schur_eliminator_impl.h
@@ -168,7 +168,7 @@
 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 @@
 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 @@
       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 @@
         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 @@
 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 @@
   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 @@
         (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 @@
       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 @@
 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 @@
   // 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 @@
     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 @@
           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 @@
 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 @@
 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 @@
       // 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 @@
         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 @@
 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 @@
       // 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 @@
         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);
       }
     }
diff --git a/internal/ceres/schur_jacobi_preconditioner.cc b/internal/ceres/schur_jacobi_preconditioner.cc
index 33a666e..780795b 100644
--- a/internal/ceres/schur_jacobi_preconditioner.cc
+++ b/internal/ceres/schur_jacobi_preconditioner.cc
@@ -91,7 +91,7 @@
 }
 
 // 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);
diff --git a/internal/ceres/schur_jacobi_preconditioner.h b/internal/ceres/schur_jacobi_preconditioner.h
index 3addd73..b80a249 100644
--- a/internal/ceres/schur_jacobi_preconditioner.h
+++ b/internal/ceres/schur_jacobi_preconditioner.h
@@ -50,7 +50,7 @@
 namespace internal {
 
 class BlockRandomAccessSparseMatrix;
-class BlockSparseMatrixBase;
+class BlockSparseMatrix;
 struct CompressedRowBlockStructure;
 class SchurEliminatorBase;
 
@@ -86,7 +86,7 @@
   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;
 
diff --git a/internal/ceres/visibility_based_preconditioner.cc b/internal/ceres/visibility_based_preconditioner.cc
index 4b1e26a..94266e5 100644
--- a/internal/ceres/visibility_based_preconditioner.cc
+++ b/internal/ceres/visibility_based_preconditioner.cc
@@ -324,7 +324,7 @@
 }
 
 // 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();
diff --git a/internal/ceres/visibility_based_preconditioner.h b/internal/ceres/visibility_based_preconditioner.h
index dae4987..54a03e6 100644
--- a/internal/ceres/visibility_based_preconditioner.h
+++ b/internal/ceres/visibility_based_preconditioner.h
@@ -62,7 +62,7 @@
 namespace internal {
 
 class BlockRandomAccessSparseMatrix;
-class BlockSparseMatrixBase;
+class BlockSparseMatrix;
 struct CompressedRowBlockStructure;
 class SchurEliminatorBase;
 
@@ -136,7 +136,7 @@
   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 @@
   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;
   }
 };