dune-istl  2.11
matrixindexset.hh
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: Copyright © DUNE Project contributors, see file LICENSE.md in module root
2 // SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
3 // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
4 // vi: set et ts=4 sw=2 sts=2:
5 #ifndef DUNE_ISTL_MATRIXINDEXSET_HH
6 #define DUNE_ISTL_MATRIXINDEXSET_HH
7 
8 #include <algorithm>
9 #include <cstddef>
10 #include <cstdint>
11 #include <set>
12 #include <variant>
13 #include <vector>
14 
15 #include <dune/common/overloadset.hh>
16 
17 namespace Dune {
18 
19  namespace Impl {
20 
40  class RowIndexSet {
41  using Index = std::uint_least32_t;
42  class Vector : public std::vector<Index> {
43  // store max size within class so that variant uses less memory
44  size_type maxVectorSize_;
45  friend class RowIndexSet;
46  };
47 
49  static Index getMaxVectorSize(const RowIndexSet::Vector& v) {
50  return v.maxVectorSize_;
51  }
52 
53  public:
54  using size_type = Index;
55 
67  static constexpr size_type defaultMaxVectorSize = 2048;
68 
75  RowIndexSet(size_type maxVectorSize = defaultMaxVectorSize) : storage_{Vector()}
76  {
77  std::get<Vector>(storage_).maxVectorSize_ = maxVectorSize;
78  }
79 
88  void insert(size_type col){
89  std::visit(Dune::overload(
90  // If row is stored as set, call insert directly
91  [&](std::set<size_type>& set) {
92  set.insert(col);
93  },
94  // If row is stored as vector only insert directly
95  // if maxVectorSize_ is not reached. Otherwise switch
96  // to set storage first.
97  [&](Vector& sortedVector) {
98  auto it = std::lower_bound(sortedVector.cbegin(), sortedVector.cend(), col);
99  if (it == sortedVector.cend() or (*it != col)) {
100  if (sortedVector.size() < getMaxVectorSize(sortedVector)) {
101  sortedVector.insert(it, col);
102  } else {
103  std::set<size_type> set(sortedVector.cbegin(), sortedVector.cend());
104  set.insert(col);
105  storage_ = std::move(set);
106  }
107  }
108  }
109  ), storage_);
110  }
111 
118  bool contains(const Index& col) const {
119  return std::visit(Dune::overload(
120  [&](const std::set<Index>& set) {
121  return set.contains(col);
122  },
123  [&](const std::vector<Index>& sortedVector) {
124  return std::binary_search(sortedVector.cbegin(), sortedVector.cend(), col);
125  }
126  ), storage_);
127  }
128 
134  const auto& storage() const {
135  return storage_;
136  }
137 
143  size_type size() const {
144  return std::visit([&](const auto& rowIndices) {
145  return rowIndices.size();
146  }, storage_);
147  }
148 
152  void clear() {
153  std::visit([&](auto& rowIndices) {
154  rowIndices.clear();
155  }, storage_);
156  }
157 
158  private:
159  std::variant<Vector, std::set<Index>> storage_;
160  };
161  }
162 
163 
181  {
182  public:
183  using size_type = typename Impl::RowIndexSet::size_type;
184 
196  static constexpr size_type defaultMaxVectorSize = Impl::RowIndexSet::defaultMaxVectorSize;
197 
203  MatrixIndexSet(size_type maxVectorSize=defaultMaxVectorSize) noexcept : rows_(0), cols_(0), maxVectorSize_(maxVectorSize)
204  {}
205 
213  MatrixIndexSet(size_type rows, size_type cols, size_type maxVectorSize=defaultMaxVectorSize) : rows_(rows), cols_(cols), maxVectorSize_(maxVectorSize)
214  {
215  indices_.resize(rows_, Impl::RowIndexSet(maxVectorSize_));
216  }
217 
220  rows_ = rows;
221  cols_ = cols;
222  indices_.resize(rows_, Impl::RowIndexSet(maxVectorSize_));
223  }
224 
232  void add(size_type row, size_type col) {
233  indices_[row].insert(col);
234  }
235 
237  size_type size() const {
238  size_type entries = 0;
239  for (size_type i=0; i<rows_; i++)
240  entries += rowsize(i);
241  return entries;
242  }
243 
245  size_type rows() const {return rows_;}
246 
248  size_type cols() const {return cols_;}
249 
259  const auto& columnIndices(size_type row) const {
260  return indices_[row].storage();
261  }
262 
265  return indices_[row].size();
266  }
267 
274  template <class MatrixType>
275  void import(const MatrixType& m, size_type rowOffset=0, size_type colOffset=0) {
276 
277  typedef typename MatrixType::row_type RowType;
278  typedef typename RowType::ConstIterator ColumnIterator;
279 
280  for (size_type rowIdx=0; rowIdx<m.N(); rowIdx++) {
281 
282  const RowType& row = m[rowIdx];
283 
284  ColumnIterator cIt = row.begin();
285  ColumnIterator cEndIt = row.end();
286 
287  for(; cIt!=cEndIt; ++cIt)
288  add(rowIdx+rowOffset, cIt.index()+colOffset);
289 
290  }
291 
292  }
293 
299  template <class MatrixType>
300  void exportIdx(MatrixType& matrix) const {
301 
302  matrix.setSize(rows_, cols_);
303  matrix.setBuildMode(MatrixType::random);
304 
305  for (size_type row=0; row<rows_; row++)
306  matrix.setrowsize(row, rowsize(row));
307 
308  matrix.endrowsizes();
309 
310  for (size_type row=0; row<rows_; row++) {
311  std::visit([&](const auto& rowIndices) {
312  matrix.setIndicesNoSort(row, rowIndices.begin(), rowIndices.end());
313  }, indices_[row].storage());
314  }
315 
316  matrix.endindices();
317 
318  }
319 
320  private:
321 
322  std::vector<Impl::RowIndexSet> indices_;
323 
324  size_type rows_, cols_;
325  size_type maxVectorSize_;
326 
327  };
328 
329 
330 } // end namespace Dune
331 
332 #endif
size_type rowsize(size_type row) const
Return the number of entries in a given row.
Definition: matrixindexset.hh:264
void exportIdx(MatrixType &matrix) const
Initializes a BCRSMatrix with the indices contained in this MatrixIndexSet.
Definition: matrixindexset.hh:300
Col col
Definition: matrixmatrix.hh:351
size_type cols() const
Return the number of columns.
Definition: matrixindexset.hh:248
void add(size_type row, size_type col)
Add an index to the index set.
Definition: matrixindexset.hh:232
MatrixIndexSet(size_type maxVectorSize=defaultMaxVectorSize) noexcept
Constructor with custom maxVectorSize.
Definition: matrixindexset.hh:203
static constexpr size_type defaultMaxVectorSize
Default value for maxVectorSize.
Definition: matrixindexset.hh:196
size_type size() const
Return the number of entries.
Definition: matrixindexset.hh:237
Stores the nonzero entries for creating a sparse matrix.
Definition: matrixindexset.hh:180
MatrixIndexSet(size_type rows, size_type cols, size_type maxVectorSize=defaultMaxVectorSize)
Constructor setting the matrix size.
Definition: matrixindexset.hh:213
void resize(size_type rows, size_type cols)
Reset the size of an index set.
Definition: matrixindexset.hh:219
size_type rows() const
Return the number of rows.
Definition: matrixindexset.hh:245
Definition: allocator.hh:11
const auto & columnIndices(size_type row) const
Return column indices of entries in given row.
Definition: matrixindexset.hh:259
typename Impl::RowIndexSet::size_type size_type
Definition: matrixindexset.hh:183