class ChunkSparsityPattern;
template <typename number> class FullMatrix;
template <typename number> class SparseMatrix;
+template <typename number> class SparseLUDecomposition;
+template <typename number> class SparseILU;
template <class VECTOR> class VectorSlice;
class CompressedSparsityPattern;
class CompressedSimpleSparsityPattern;
+namespace ChunkSparsityPatternIterators
+{
+ class Accessor;
+}
+
/*! @addtogroup Sparsity
*@{
* also the base class for both const and non-const accessor classes
* into sparse matrices.
*
- * Note that this class only allows read access to elements, providing
- * their row and column number. It does not allow modifying the
- * sparsity pattern itself.
+ * Note that this class only allows read access to elements, providing their
+ * row and column number (or alternatively the index within the complete
+ * sparsity pattern). It does not allow modifying the sparsity pattern
+ * itself.
*
* @author Wolfgang Bangerth
* @date 2004
const unsigned int row,
const unsigned int index);
+ /**
+ * Constructor.
+ */
+ Accessor (const SparsityPattern *matrix,
+ const std::size_t index_within_sparsity);
+
/**
* Constructor. Construct the end accessor for the given sparsity pattern.
*/
*/
bool is_valid_entry () const;
-
/**
* Comparison. True, if both iterators point to the same matrix position.
*/
bool operator == (const Accessor &) 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.
* sparsity pattern.
*/
bool operator < (const Accessor &) const;
+
protected:
/**
* The sparsity pattern we operate on accessed.
const SparsityPattern *sparsity_pattern;
/**
- * Current row number.
+ * Index in global sparsity pattern.
*/
- unsigned int a_row;
-
- /**
- * Current index in row.
- */
- unsigned int a_index;
+ std::size_t a_index;
/**
* Move the accessor to the next nonzero entry in the matrix.
* Grant access to iterator class.
*/
friend class Iterator;
+
+ /**
+ * Grant access to accessor class of ChunkSparsityPattern.
+ */
+ friend class ChunkSparsityPatternIterators::Accessor;
};
const unsigned int row,
const unsigned int index);
+ /**
+ * Constructor. Create an iterator into the sparsity pattern @p sp for the
+ * given global index (i.e., the index of the given element counting from
+ * the zeroth row).
+ */
+ Iterator (const SparsityPattern *sp,
+ const std::size_t index_within_sparsity);
+
/**
* Prefix increment.
*/
* yourself, you should also rename this function to avoid programs relying
* on outdated information!
*/
- const std::size_t *get_rowstart_indices () const;
+ const std::size_t *get_rowstart_indices () const DEAL_II_DEPRECATED;
/**
* @deprecated. Use @p row_length and @p column_number instead. Also, using
* yourself, you should also rename this function to avoid programs relying
* on outdated information!
*/
- const unsigned int *get_column_numbers () const;
+ const unsigned int *get_column_numbers () const DEAL_II_DEPRECATED;
BOOST_SERIALIZATION_SPLIT_MEMBER()
/** @addtogroup Exceptions
* Make all sparse matrices friends of this class.
*/
template <typename number> friend class SparseMatrix;
+ template <typename number> friend class SparseLUDecomposition;
+ template <typename number> friend class SparseILU;
template <typename number> friend class ChunkSparseMatrix;
friend class ChunkSparsityPattern;
+
+ /**
+ * Also give access to internal details to the iterator/accessor
+ * classes.
+ */
+ friend class SparsityPatternIterators::Iterator;
+ friend class SparsityPatternIterators::Accessor;
};
const unsigned int i)
:
sparsity_pattern(sparsity_pattern),
- a_row(r),
+ a_index(sparsity_pattern->rowstart[r]+i)
+ {}
+
+
+ inline
+ Accessor::
+ Accessor (const SparsityPattern *sparsity_pattern,
+ const std::size_t i)
+ :
+ sparsity_pattern(sparsity_pattern),
a_index(i)
{}
Accessor (const SparsityPattern *sparsity_pattern)
:
sparsity_pattern(sparsity_pattern),
- a_row(sparsity_pattern->n_rows()),
- a_index(0)
+ a_index(sparsity_pattern->rowstart[sparsity_pattern->rows])
{}
bool
Accessor::is_valid_entry () const
{
- return (sparsity_pattern
- ->get_column_numbers()[sparsity_pattern
- ->get_rowstart_indices()[a_row]+a_index]
+ return (a_index < sparsity_pattern->rowstart[sparsity_pattern->rows]
+ &&
+ sparsity_pattern->colnums[a_index]
!= SparsityPattern::invalid_entry);
}
{
Assert (is_valid_entry() == true, ExcInvalidIterator());
- return a_row;
+ const std::size_t * insert_point =
+ std::upper_bound(sparsity_pattern->rowstart,
+ sparsity_pattern->rowstart + sparsity_pattern->rows + 1,
+ a_index);
+ return insert_point - sparsity_pattern->rowstart - 1;
}
{
Assert (is_valid_entry() == true, ExcInvalidIterator());
- return (sparsity_pattern
- ->get_column_numbers()[sparsity_pattern
- ->get_rowstart_indices()[a_row]+a_index]);
+ return (sparsity_pattern->colnums[a_index]);
}
{
Assert (is_valid_entry() == true, ExcInvalidIterator());
- return a_index;
+ return a_index - sparsity_pattern->rowstart[row()];
}
bool
Accessor::operator == (const Accessor &other) const
{
- return (sparsity_pattern == other.sparsity_pattern &&
- a_row == other.a_row &&
+ return (sparsity_pattern == other.sparsity_pattern &&
a_index == other.a_index);
}
Assert (sparsity_pattern == other.sparsity_pattern,
ExcInternalError());
- return (a_row < other.a_row ||
- (a_row == other.a_row &&
- a_index < other.a_index));
+ return a_index < other.a_index;
}
void
Accessor::advance ()
{
- Assert (a_row < sparsity_pattern->n_rows(), ExcIteratorPastEnd());
-
+ Assert (a_index < sparsity_pattern->rowstart[sparsity_pattern->rows],
+ ExcIteratorPastEnd());
++a_index;
-
- // if at end of line: cycle until we find a row with a nonzero number of
- // entries
- while (a_index >= sparsity_pattern->row_length(a_row))
- {
- a_index = 0;
- ++a_row;
-
- // if we happened to find the end of the matrix, then stop here
- if (a_row == sparsity_pattern->n_rows())
- break;
- }
}
+ inline
+ Iterator::Iterator (const SparsityPattern *sparsity_pattern,
+ const std::size_t i)
+ :
+ accessor(sparsity_pattern, i)
+ {}
+
+
+
inline
Iterator &
Iterator::operator++ ()
SparsityPattern::iterator
SparsityPattern::begin () const
{
- // search for the first line with a nonzero number of entries
- for (unsigned int r=0; r<n_rows(); ++r)
- if (row_length(r) > 0)
- return iterator(this, r, 0);
-
- // alright, this matrix is completely empty. that's strange but ok. simply
- // return the end() iterator
- return end();
+ return iterator(this, rowstart[0]);
}
SparsityPattern::iterator
SparsityPattern::end () const
{
- return iterator(this, n_rows(), 0);
+ return iterator(this, rowstart[rows]);
}
{
Assert (r<n_rows(), ExcIndexRange(r,0,n_rows()));
- if (row_length(r) > 0)
- return iterator(this, r, 0);
- else
- return end (r);
+ return iterator(this, rowstart[r]);
}
{
Assert (r<n_rows(), ExcIndexRange(r,0,n_rows()));
- // place the iterator on the first entry past this line, or at the end of
- // the matrix
- for (unsigned int i=r+1; i<n_rows(); ++i)
- if (row_length(i) > 0)
- return iterator(this, i, 0);
-
- // if there is no such line, then take the end iterator of the matrix
- return end();
+ return iterator(this, rowstart[r+1]);
}