From 60127782b76b5653a8d63639ca79bfae8994ca88 Mon Sep 17 00:00:00 2001 From: guido Date: Fri, 25 Oct 2002 15:42:39 +0000 Subject: [PATCH] iterator in BlockSparseMatrix git-svn-id: https://svn.dealii.org/trunk@6728 0785d39b-7218-0410-832d-ea1e28bc413d --- deal.II/lac/include/lac/block_sparse_matrix.h | 421 ++++++++++++++++++ 1 file changed, 421 insertions(+) diff --git a/deal.II/lac/include/lac/block_sparse_matrix.h b/deal.II/lac/include/lac/block_sparse_matrix.h index 7c631f9036..fd2a42f7f7 100644 --- a/deal.II/lac/include/lac/block_sparse_matrix.h +++ b/deal.II/lac/include/lac/block_sparse_matrix.h @@ -65,7 +65,146 @@ class BlockSparseMatrix : public Subscriptor * the STL container classes. */ typedef number value_type; + + class const_iterator; + /** + * Accessor class for iterators + */ + class Accessor + { + public: + /** + * Constructor. Since we use + * accessors only for read + * access, a const matrix + * pointer is sufficient. + */ + Accessor (const BlockSparseMatrix*, + unsigned int row, + unsigned short index); + + /** + * Row number of the element + * represented by this + * object. + */ + unsigned int row() const; + + /** + * Index in row of the element + * represented by this + * object. + */ + unsigned short index() const; + + /** + * Column number of the + * element represented by + * this object. + */ + unsigned int column() const; + + /** + * Value of this matrix entry. + */ + number value() const; + + protected: + /** + * The matrix accessed. + */ + const BlockSparseMatrix* matrix; + + /** + * Iterator of the underlying matrix class. + */ + typename SparseMatrix::const_iterator base_iterator; + + /** + * Number of block where row lies in. + */ + unsigned int block_row; + + /** + * First row of block. + */ + unsigned int row_start; + + /** + * Number of block column where column lies in. + */ + unsigned int block_col; + + /** + * First column of block. + */ + unsigned int col_start; + + /** + * Index in whole row. + */ + unsigned int a_index; + + friend class const_iterator; + }; + /** + * STL conforming iterator. + */ + class const_iterator : private Accessor + { + public: + /** + * Constructor. + */ + const_iterator(const BlockSparseMatrix*, + unsigned int row, + unsigned short index); + + /** + * Prefix increment. + */ + const_iterator& operator++ (); + + /** + * Postfix increment. + */ + const_iterator& operator++ (int); + + /** + * Dereferencing operator. + */ + const Accessor& operator* () const; + + /** + * Dereferencing operator. + */ + const Accessor* operator-> () const; + + /** + * Comparison. True, if + * both iterators point to + * the same matrix + * position. + */ + bool operator == (const const_iterator&) const; + /** + * Inverse of @p{==}. + */ + bool operator != (const const_iterator&) const; + + /** + * Comparison + * operator. Result is true + * if either the first row + * number is smaller or if + * the row numbers are + * equal and the first + * index is smaller. + */ + bool operator < (const const_iterator&) const; + }; + /** * Constructor; initializes the * matrix to be empty, without @@ -495,6 +634,28 @@ class BlockSparseMatrix : public Subscriptor const BlockSparsityPattern & get_sparsity_pattern () const; + /** + * STL-like iterator with the + * first entry. + */ + const_iterator begin () const; + + /** + * Final iterator. + */ + const_iterator end () const; + + /** + * STL-like iterator with the + * first entry of row @p{r}. + */ + const_iterator begin (unsigned int r) const; + + /** + * Final iterator of row @p{r}. + */ + const_iterator end (unsigned int r) const; + /** * Determine an estimate for the * memory consumption (in bytes) @@ -548,6 +709,9 @@ class BlockSparseMatrix : public Subscriptor * Array of sub-matrices. */ Table<2,SmartPointer > > sub_objects; + + friend class Accessor; + friend class const_iterator; }; @@ -555,6 +719,229 @@ class BlockSparseMatrix : public Subscriptor /* ------------------------- Template functions ---------------------- */ +template +inline +BlockSparseMatrix::Accessor::Accessor ( + const BlockSparseMatrix* matrix, + unsigned int r, + unsigned short i) + : matrix(matrix), + base_iterator(matrix->block(0,0).begin()), + block_row(0), + row_start(0), + block_col(0), + col_start(0), + a_index(0) +{ + Assert (i==0, ExcNotImplemented()); + + if (r < matrix->m()) + { + pair indices = matrix->sparsity_pattern + ->get_row_indices().global_to_local(r); + block_row = indices.first; + base_iterator = matrix->block(indices.first, 0).begin(indices.second); + row_start = matrix->sparsity_pattern + ->get_row_indices().local_to_global(block_row, 0); + } + else + { + block_row = matrix->n_block_rows(); + base_iterator = matrix->block(0, 0).begin(); + } +} + + +template +inline +unsigned int +BlockSparseMatrix::Accessor::row() const +{ + return row_start + base_iterator->row(); +} + + +template +inline +short unsigned int +BlockSparseMatrix::Accessor::index() const +{ + return a_index; +} + + +template +inline +unsigned int +BlockSparseMatrix::Accessor::column() const +{ + return col_start + base_iterator->column(); +} + + +template +inline +number +BlockSparseMatrix::Accessor::value () const +{ + return base_iterator->value(); +} + + +//----------------------------------------------------------------------// + + +template +inline +BlockSparseMatrix::const_iterator::const_iterator( + const BlockSparseMatrix* m, + unsigned int r, + unsigned short i) + : BlockSparseMatrix::Accessor(m, r, i) +{} + + + +template +inline +typename BlockSparseMatrix::const_iterator& +BlockSparseMatrix::const_iterator::operator++ () +{ + Assert (block_rown_block_rows(), ExcIteratorPastEnd()); + + // Remeber current row inside block + unsigned int local_row = base_iterator->row(); + // Advance inside block + ++base_iterator; + ++a_index; + // If end of row inside block, + // advance to next block + if (base_iterator == matrix->block(block_row, block_col).end(local_row)) + { + if (block_coln_block_cols()-1) + { + // Advance to next block in + // row + ++block_col; + col_start = matrix->sparsity_pattern + ->get_column_indices().local_to_global(block_col, 0); + } + else + { + // Advance to first block + // in next row + block_col = 0; + col_start = 0; + a_index = 0; + ++local_row; + if (local_row>=matrix->block(block_row,0).m()) + { + // If final row in + // block, go to next + // block row + local_row = 0; + ++block_row; + if (block_rown_block_rows()) + row_start = matrix->sparsity_pattern + ->get_row_indices().local_to_global(block_row, 0); + } + } + // Finally, set base_iterator + // to start of row determined + // above + if (block_rown_block_rows()) + base_iterator = matrix->block(block_row, block_col).begin(local_row); + else + // Set base_iterator to a + // defined state for + // comparison. This is the + // end() state. + base_iterator = matrix->block(0, 0).begin(); + } + return *this; +} + + + +// template +// inline +// const_iterator& +// BlockSparseMatrix::const_iterator::operator++ (int) +// { +// Assert (false, ExcNotImplemented()); +// } + + + + +template +inline +const typename BlockSparseMatrix::Accessor& +BlockSparseMatrix::const_iterator::operator* () const +{ + return *this; +} + + +template +inline +const typename BlockSparseMatrix::Accessor* +BlockSparseMatrix::const_iterator::operator-> () const +{ + return this; +} + + + +template +inline +bool +BlockSparseMatrix::const_iterator::operator == (const const_iterator& i) const +{ + if (matrix != i->matrix) + return false; + + if (block_row == i->block_row + && block_col == i->block_col + && base_iterator == i->base_iterator) + return true; + return false; +} + + + +template +inline +bool +BlockSparseMatrix::const_iterator::operator != (const const_iterator& i) const +{ + return !(*this == i); +} + + + +template +inline +bool +BlockSparseMatrix::const_iterator::operator < (const const_iterator& i) const +{ + if (block_rowblock_row) + return true; + if (block_row == i->block_row) + { + if (base_iterator->row() < i->base_iterator->row()) + return true; + if (base_iterator->row() == i->base_iterator->row()) + { + if (a_index < i->a_index) + return true; + } + } + return false; +} + +//----------------------------------------------------------------------// + template inline @@ -927,4 +1314,38 @@ precondition_Jacobi (BlockVector &dst, }; +template +inline +typename BlockSparseMatrix::const_iterator +BlockSparseMatrix::begin () const +{ + return const_iterator(this, 0, 0); +} + +template +inline +typename BlockSparseMatrix::const_iterator +BlockSparseMatrix::end () const +{ + return const_iterator(this, m(), 0); +} + +template +inline +typename BlockSparseMatrix::const_iterator +BlockSparseMatrix::begin (unsigned int r) const +{ + Assert (r +inline +typename BlockSparseMatrix::const_iterator +BlockSparseMatrix::end (unsigned int r) const +{ + Assert (r