* The template argument @p{MATRIX} is a class providing the the
* matrix-vector multiplication functions @p{vmult} etc. defined in
* this class, but with arguments of type @p{VECTOR} instead of
- * @p{BlockVector<VECTOR>}. @ref{SparseMatrix} is a possible entry
- * type.
+ * @p{BlockVector<VECTOR>}.
*
* @author Guido Kanschat, 2000, 2001
*/
class BlockMatrixArray : public Subscriptor
{
public:
+ /**
+ * Type of matrix entries. In analogy to
+ * the STL container classes.
+ */
+ typedef typename MATRIX::value_type value_type;
+
+ /**
+ * Accessor class for iterators
+ */
+ class Accessor
+ {
+ public:
+ /**
+ * Constructor. Since we use
+ * accessors only for read
+ * access, a const matrix
+ * pointer is sufficient.
+ */
+ Accessor (const BlockMatrixArray<MATRIX>*,
+ 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.
+ */
+ typename MATRIX::value_type value() const;
+
+ protected:
+ /**
+ * The matrix accessed.
+ */
+ const BlockMatrixArray<MATRIX>* matrix;
+
+ /**
+ * Iterator of the underlying matrix class.
+ */
+ typename MATRIX::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;
+ };
+
+ /**
+ * STL conforming iterator.
+ */
+ class const_iterator : private Accessor
+ {
+ public:
+ /**
+ * Constructor.
+ */
+ const_iterator(const BlockMatrixArray<MATRIX>*,
+ 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 fixing the
* dimensions.
{}
+//----------------------------------------------------------------------//
+
+
+template <class MATRIX>
+inline
+BlockMatrixArray<MATRIX>::Accessor::Accessor (
+ const BlockMatrixArray<MATRIX>* matrix,
+ unsigned int r,
+ unsigned short i)
+ : matrix(matrix),
+ block_row(0),
+ row_start(0),
+ block_col(0),
+ col_start(0),
+ a_index(0)
+{
+ Assert (i==0, ExcNotImplemented());
+ while (block_row < matrix->n_block_rows())
+ {
+ const unsigned int block_size = matrix->block(block_row, 0).m();
+ row_start += block_size;
+ if (r<row_start)
+ break;
+ ++block_row;
+ r -= block_size;
+ }
+ if (block_row<n_block_rows())
+ base_iterator = matrix->block(block_row, 0).begin(r);
+ else
+ base_iterator = matrix->block(0, 0).begin();
+}
+
+
+template <class MATRIX>
+inline
+unsigned int
+BlockMatrixArray<MATRIX>::Accessor::row() const
+{
+ return row_start + base_iterator->row();
+}
+
+
+template <class MATRIX>
+inline
+short unsigned int
+BlockMatrixArray<MATRIX>::Accessor::index() const
+{
+ return a_index;
+}
+
+
+template <class MATRIX>
+inline
+unsigned int
+BlockMatrixArray<MATRIX>::Accessor::column() const
+{
+ return col_start + base_iterator->column();
+}
+
+
+template <class MATRIX>
+inline
+typename MATRIX::value_type
+BlockMatrixArray<MATRIX>::Accessor::value () const
+{
+ return base_iterator->value();
+}
+
+
+//----------------------------------------------------------------------//
+
+
+template <class MATRIX>
+inline
+BlockMatrixArray<MATRIX>::const_iterator::const_iterator(
+ const BlockMatrixArray<MATRIX>* m,
+ unsigned int r,
+ unsigned short i)
+ : BlockMatrixArray<MATRIX>::Accessor(m, r, i)
+{}
+
+
+
+template <class MATRIX>
+inline
+typename BlockMatrixArray<MATRIX>::const_iterator&
+BlockMatrixArray<MATRIX>::const_iterator::operator++ ()
+{
+ Assert (block_row<n_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_col<n_block_cols()-1)
+ {
+ // Advance to next block in
+ // row
+ ++block_col;
+ }
+ else
+ {
+ // Advance to first block
+ // in next row
+ block_col = 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;
+ }
+ }
+ // Finally, set base_iterator
+ // to start of row determined
+ // above
+ if (block_row<n_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 <class MATRIX>
+// inline
+// const_iterator&
+// BlockMatrixArray<MATRIX>::const_iterator::operator++ (int)
+// {
+// Assert (false, ExcNotImplemented());
+// }
+
+
+
+
+template <class MATRIX>
+inline
+const typename BlockMatrixArray<MATRIX>::Accessor&
+BlockMatrixArray<MATRIX>::const_iterator::operator* () const
+{
+ return *this;
+}
+
+
+template <class MATRIX>
+inline
+const typename BlockMatrixArray<MATRIX>::Accessor*
+BlockMatrixArray<MATRIX>::const_iterator::operator-> () const
+{
+ return this;
+}
+
+
+
+template <class MATRIX>
+inline
+bool
+BlockMatrixArray<MATRIX>::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 <class MATRIX>
+inline
+bool
+BlockMatrixArray<MATRIX>::const_iterator::operator != (const const_iterator& i) const
+{
+ return !(*this == i);
+}
+
+
+
+template <class MATRIX>
+inline
+bool
+BlockMatrixArray<MATRIX>::const_iterator::operator < (const const_iterator& i) const
+{
+ if (block_row<i->block_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 <class MATRIX>
inline