* Constructor.
*/
Accessor (MatrixType *matrix,
- const std::size_t index_with_matrix);
+ const std::size_t index_within_matrix);
/**
* Constructor. Construct the end accessor for the given matrix.
* Since there is a specialization of this class for
* <tt>Constness=false</tt>, this class is for iterators to constant
* matrices.
+ *
+ * @note This class operates directly on the internal data structures of the
+ * SparsityPattern and SparseMatrix classes. As a consequence, some operations
+ * are cheap and some are not. In particular, it is cheap to access the column
+ * index and the value of an entry pointed to. On the other hand, it is expensive
+ * to access the row index (this requires $O(\log(N))$ operations for a
+ * matrix with $N$ row). As a consequence, when you design algorithms that
+ * use these iterators, it is common practice to not loop over <i>all</i>
+ * elements of a sparse matrix at once, but to have an outer loop over
+ * all rows and within this loop iterate over the elements of this row.
+ * This way, you only ever need to dereference the iterator to obtain
+ * the column indices and values whereas the (expensive) lookup of the row index
+ * can be avoided by using the loop index instead.
*/
template <typename number, bool Constness>
class Iterator
inline
Accessor<number,true>::
Accessor (const MatrixType *matrix,
- const std::size_t index)
+ const std::size_t index_within_matrix)
:
SparsityPatternIterators::Accessor (&matrix->get_sparsity_pattern(),
- index),
+ index_within_matrix),
matrix (matrix)
{}
number
Accessor<number, true>::value () const
{
- AssertIndexRange(a_index, matrix->n_nonzero_elements());
- return matrix->val[a_index];
+ AssertIndexRange(index_within_sparsity, matrix->n_nonzero_elements());
+ return matrix->val[index_within_sparsity];
}
inline
Accessor<number, false>::Reference::operator number() const
{
- AssertIndexRange(accessor->a_index, accessor->matrix->n_nonzero_elements());
- return accessor->matrix->val[accessor->a_index];
+ AssertIndexRange(accessor->index_within_sparsity, accessor->matrix->n_nonzero_elements());
+ return accessor->matrix->val[accessor->index_within_sparsity];
}
const typename Accessor<number, false>::Reference &
Accessor<number, false>::Reference::operator = (const number n) const
{
- AssertIndexRange(accessor->a_index, accessor->matrix->n_nonzero_elements());
- accessor->matrix->val[accessor->a_index] = n;
+ AssertIndexRange(accessor->index_within_sparsity, accessor->matrix->n_nonzero_elements());
+ accessor->matrix->val[accessor->index_within_sparsity] = n;
return *this;
}
const typename Accessor<number, false>::Reference &
Accessor<number, false>::Reference::operator += (const number n) const
{
- AssertIndexRange(accessor->a_index, accessor->matrix->n_nonzero_elements());
- accessor->matrix->val[accessor->a_index] += n;
+ AssertIndexRange(accessor->index_within_sparsity, accessor->matrix->n_nonzero_elements());
+ accessor->matrix->val[accessor->index_within_sparsity] += n;
return *this;
}
const typename Accessor<number, false>::Reference &
Accessor<number, false>::Reference::operator -= (const number n) const
{
- AssertIndexRange(accessor->a_index, accessor->matrix->n_nonzero_elements());
- accessor->matrix->val[accessor->a_index] -= n;
+ AssertIndexRange(accessor->index_within_sparsity, accessor->matrix->n_nonzero_elements());
+ accessor->matrix->val[accessor->index_within_sparsity] -= n;
return *this;
}
const typename Accessor<number, false>::Reference &
Accessor<number, false>::Reference::operator *= (const number n) const
{
- AssertIndexRange(accessor->a_index, accessor->matrix->n_nonzero_elements());
- accessor->matrix->val[accessor->a_index] *= n;
+ AssertIndexRange(accessor->index_within_sparsity, accessor->matrix->n_nonzero_elements());
+ accessor->matrix->val[accessor->index_within_sparsity] *= n;
return *this;
}
const typename Accessor<number, false>::Reference &
Accessor<number, false>::Reference::operator /= (const number n) const
{
- AssertIndexRange(accessor->a_index, accessor->matrix->n_nonzero_elements());
- accessor->matrix->val[accessor->a_index] /= n;
+ AssertIndexRange(accessor->index_within_sparsity, accessor->matrix->n_nonzero_elements());
+ accessor->matrix->val[accessor->index_within_sparsity] /= n;
return *this;
}
Assert (&accessor.get_matrix() == &other.accessor.get_matrix(),
ExcInternalError());
- return (*this)->a_index - other->a_index;
+ return (*this)->index_within_sparsity - other->index_within_sparsity;
}
unsigned int row () const;
/**
- * Index in row of the element represented by this object. This function
+ * Index within the current row of the element represented by this object. This function
* can only be called for entries for which is_valid_entry() is true.
*/
unsigned int index () const;
const SparsityPattern *sparsity_pattern;
/**
- * Index in global sparsity pattern.
+ * Index in global sparsity pattern. This index represents the location
+ * the iterator/accessor points to within the array of the SparsityPattern
+ * class that stores the column numbers. It is also the index within the
+ * values array of a sparse matrix that stores the corresponding value of
+ * this site.
*/
- std::size_t a_index;
+ std::size_t index_within_sparsity;
/**
* Move the accessor to the next nonzero entry in the matrix.
* that the elements of a row are actually traversed in an order in which
* columns monotonically increase. See the documentation of the
* SparsityPattern class for more information.
+ *
+ * @note This class operates directly on the internal data structures of the
+ * SparsityPattern class. As a consequence, some operations are cheap and
+ * some are not. In particular, it is cheap to access the column index of
+ * the sparsity pattern entry pointed to. On the other hand, it is expensive
+ * to access the row index (this requires $O(\log(N))$ operations for a
+ * matrix with $N$ row). As a consequence, when you design algorithms that
+ * use these iterators, it is common practice to not loop over <i>all</i>
+ * elements of a sparsity pattern at once, but to have an outer loop over
+ * all rows and within this loop iterate over the elements of this row.
+ * This way, you only ever need to dereference the iterator to obtain
+ * the column indices whereas the (expensive) lookup of the row index
+ * can be avoided by using the loop index instead.
*/
class Iterator
{
const unsigned int i)
:
sparsity_pattern(sparsity_pattern),
- a_index(sparsity_pattern->rowstart[r]+i)
+ index_within_sparsity(sparsity_pattern->rowstart[r]+i)
{}
const std::size_t i)
:
sparsity_pattern(sparsity_pattern),
- a_index(i)
+ index_within_sparsity(i)
{}
Accessor (const SparsityPattern *sparsity_pattern)
:
sparsity_pattern(sparsity_pattern),
- a_index(sparsity_pattern->rowstart[sparsity_pattern->rows])
+ index_within_sparsity(sparsity_pattern->rowstart[sparsity_pattern->rows])
{}
bool
Accessor::is_valid_entry () const
{
- return (a_index < sparsity_pattern->rowstart[sparsity_pattern->rows]
+ return (index_within_sparsity < sparsity_pattern->rowstart[sparsity_pattern->rows]
&&
- sparsity_pattern->colnums[a_index]
+ sparsity_pattern->colnums[index_within_sparsity]
!= SparsityPattern::invalid_entry);
}
const std::size_t * insert_point =
std::upper_bound(sparsity_pattern->rowstart,
sparsity_pattern->rowstart + sparsity_pattern->rows + 1,
- a_index);
+ index_within_sparsity);
return insert_point - sparsity_pattern->rowstart - 1;
}
{
Assert (is_valid_entry() == true, ExcInvalidIterator());
- return (sparsity_pattern->colnums[a_index]);
+ return (sparsity_pattern->colnums[index_within_sparsity]);
}
{
Assert (is_valid_entry() == true, ExcInvalidIterator());
- return a_index - sparsity_pattern->rowstart[row()];
+ return index_within_sparsity - sparsity_pattern->rowstart[row()];
}
Accessor::operator == (const Accessor &other) const
{
return (sparsity_pattern == other.sparsity_pattern &&
- a_index == other.a_index);
+ index_within_sparsity == other.index_within_sparsity);
}
Assert (sparsity_pattern == other.sparsity_pattern,
ExcInternalError());
- return a_index < other.a_index;
+ return index_within_sparsity < other.index_within_sparsity;
}
void
Accessor::advance ()
{
- Assert (a_index < sparsity_pattern->rowstart[sparsity_pattern->rows],
+ Assert (index_within_sparsity < sparsity_pattern->rowstart[sparsity_pattern->rows],
ExcIteratorPastEnd());
- ++a_index;
+ ++index_within_sparsity;
}
Assert (accessor.sparsity_pattern == other.accessor.sparsity_pattern,
ExcInternalError());
- return (*this)->a_index - other->a_index;
+ return (*this)->index_within_sparsity - other->index_within_sparsity;
}
}