Add a templated TypedPreconditioner class.
This sets the stage of preconditioners that can utilize
different kinds of matrix layouts, just like the LinearSolver
class hierarchy.
Change-Id: I3579cf344bcd2eeeecb1ae621cab02a3c9a0f920
diff --git a/internal/ceres/preconditioner.h b/internal/ceres/preconditioner.h
index 7206536..cb0a381 100644
--- a/internal/ceres/preconditioner.h
+++ b/internal/ceres/preconditioner.h
@@ -32,6 +32,8 @@
#define CERES_INTERNAL_PRECONDITIONER_H_
#include <vector>
+#include "ceres/casts.h"
+#include "ceres/compressed_row_sparse_matrix.h"
#include "ceres/linear_operator.h"
#include "ceres/sparse_matrix.h"
@@ -105,7 +107,7 @@
//
// D can be NULL, in which case its interpreted as a diagonal matrix
// of size zero.
- virtual bool Update(const BlockSparseMatrix& A, const double* D) = 0;
+ virtual bool Update(const LinearOperator& A, const double* D) = 0;
// LinearOperator interface. Since the operator is symmetric,
// LeftMultiply and num_cols are just calls to RightMultiply and
@@ -122,19 +124,40 @@
}
};
+// This templated subclass of Preconditioner serves as a base class for
+// other preconditioners that depend on the particular matrix layout of
+// the underlying linear operator.
+template <typename MatrixType>
+class TypedPreconditioner : public Preconditioner {
+ public:
+ virtual ~TypedPreconditioner() {}
+ virtual bool Update(const LinearOperator& A, const double* D) {
+ return UpdateImpl(*down_cast<const MatrixType*>(&A), D);
+ }
+
+ private:
+ virtual bool UpdateImpl(const MatrixType& A, const double* D) = 0;
+};
+
+// Preconditioners that depend on acccess to the low level structure
+// of a SparseMatrix.
+typedef TypedPreconditioner<SparseMatrix> SparseMatrixPreconditioner; // NOLINT
+typedef TypedPreconditioner<BlockSparseMatrix> BlockSparseMatrixPreconditioner; // NOLINT
+typedef TypedPreconditioner<CompressedRowSparseMatrix> CompressedRowSparseMatrixPreconditioner; // NOLINT
+
// Wrap a SparseMatrix object as a preconditioner.
-class SparseMatrixPreconditionerWrapper : public Preconditioner {
+class SparseMatrixPreconditionerWrapper : public SparseMatrixPreconditioner {
public:
// Wrapper does NOT take ownership of the matrix pointer.
explicit SparseMatrixPreconditionerWrapper(const SparseMatrix* matrix);
virtual ~SparseMatrixPreconditionerWrapper();
// Preconditioner interface
- virtual bool Update(const BlockSparseMatrix& A, const double* D);
virtual void RightMultiply(const double* x, double* y) const;
virtual int num_rows() const;
private:
+ virtual bool UpdateImpl(const SparseMatrix& A, const double* D);
const SparseMatrix* matrix_;
};