SparseTable.hpp
Go to the documentation of this file.
1//===========================================================================
2//
3// File: SparseTable.hpp
4//
5// Created: Fri Apr 24 09:50:27 2009
6//
7// Author(s): Atgeirr F Rasmussen <atgeirr@sintef.no>
8//
9// $Date$
10//
11// $Revision$
12//
13//===========================================================================
14
15/*
16 Copyright 2009, 2010 SINTEF ICT, Applied Mathematics.
17 Copyright 2009, 2010 Statoil ASA.
18
19 This file is part of the Open Porous Media project (OPM).
20
21 OPM is free software: you can redistribute it and/or modify
22 it under the terms of the GNU General Public License as published by
23 the Free Software Foundation, either version 3 of the License, or
24 (at your option) any later version.
25
26 OPM is distributed in the hope that it will be useful,
27 but WITHOUT ANY WARRANTY; without even the implied warranty of
28 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29 GNU General Public License for more details.
30
31 You should have received a copy of the GNU General Public License
32 along with OPM. If not, see <http://www.gnu.org/licenses/>.
33*/
34
35#ifndef OPM_SPARSETABLE_HEADER
36#define OPM_SPARSETABLE_HEADER
37
38#include <vector>
39#include <numeric>
40#include <algorithm>
41#include <opm/common/ErrorMacros.hpp>
43
44#include <ostream>
45
46namespace Opm
47{
48
53 template <typename T>
55 {
56 public:
59 : row_start_(1, 0)
60 {
61 }
62
68 template <typename DataIter, typename IntegerIter>
69 SparseTable(DataIter data_beg, DataIter data_end,
70 IntegerIter rowsize_beg, IntegerIter rowsize_end)
71 : data_(data_beg, data_end)
72 {
73 setRowStartsFromSizes(rowsize_beg, rowsize_end);
74 }
75
76
83 template <typename DataIter, typename IntegerIter>
84 void assign(DataIter data_beg, DataIter data_end,
85 IntegerIter rowsize_beg, IntegerIter rowsize_end)
86 {
87 data_.assign(data_beg, data_end);
88 setRowStartsFromSizes(rowsize_beg, rowsize_end);
89 }
90
91
95 template <typename IntegerIter>
96 void allocate(IntegerIter rowsize_beg, IntegerIter rowsize_end)
97 {
98 typedef typename std::vector<T>::size_type sz_t;
99
100 sz_t ndata = std::accumulate(rowsize_beg, rowsize_end, sz_t(0));
101 data_.resize(ndata);
102 setRowStartsFromSizes(rowsize_beg, rowsize_end);
103 }
104
105
107 template <typename DataIter>
108 void appendRow(DataIter row_beg, DataIter row_end)
109 {
110 data_.insert(data_.end(), row_beg, row_end);
111 row_start_.push_back(data_.size());
112 }
113
115 bool empty() const
116 {
117 return row_start_.size()==1;
118 }
119
121 int size() const
122 {
123 return row_start_.size() - 1;
124 }
125
127 void reserve(int exptd_nrows, int exptd_ndata)
128 {
129 row_start_.reserve(exptd_nrows + 1);
130 data_.reserve(exptd_ndata);
131 }
132
134 void swap(SparseTable<T>& other)
135 {
136 row_start_.swap(other.row_start_);
137 data_.swap(other.data_);
138 }
139
141 int dataSize() const
142 {
143 return data_.size();
144 }
145
147 int rowSize(int row) const
148 {
149#ifndef NDEBUG
150 OPM_ERROR_IF(row < 0 || row >= size(),
151 "Row index " + std::to_string(row) + " is out of range");
152#endif
153 return row_start_[row + 1] - row_start_[row];
154 }
155
157 void clear()
158 {
159 data_.clear();
160 row_start_.resize(1);
161 }
162
166
168 row_type operator[](int row) const
169 {
170 assert(row >= 0 && row < size());
171 return row_type{data_.begin()+ row_start_[row],
172 data_.begin() + row_start_[row + 1]};
177 {
178 assert(row >= 0 && row < size());
179 return mutable_row_type{data_.begin() + row_start_[row],
180 data_.begin() + row_start_[row + 1]};
181 }
182
186 {
187 public:
188 Iterator(const SparseTable& table, const int begin_row_index)
189 : table_(table)
190 , row_index_(begin_row_index)
191 {
192 }
194 {
195 ++row_index_;
196 return *this;
197 }
199 {
200 return table_[row_index_];
201 }
202 bool operator==(const Iterator& other)
203 {
204 assert(&table_ == &other.table_);
205 return row_index_ == other.row_index_;
206 }
207 bool operator!=(const Iterator& other)
208 {
209 return !(*this == other);
210 }
211 private:
212 const SparseTable& table_;
213 int row_index_;
214 };
215
218 {
219 return Iterator(*this, 0);
220 }
221 Iterator end() const
222 {
223 return Iterator(*this, size());
224 }
225
227 bool operator==(const SparseTable& other) const
228 {
229 return data_ == other.data_ && row_start_ == other.row_start_;
230 }
231
232 template<class charT, class traits>
233 void print(std::basic_ostream<charT, traits>& os) const
234 {
235 os << "Number of rows: " << size() << '\n';
236
237 os << "Row starts = [";
238 std::copy(row_start_.begin(), row_start_.end(),
239 std::ostream_iterator<int>(os, " "));
240 os << "\b]\n";
241
242 os << "Data values = [";
243 std::copy(data_.begin(), data_.end(),
244 std::ostream_iterator<T>(os, " "));
245 os << "\b]\n";
246 }
247 const T data(int i)const {
248 return data_[i];
249 }
250
251 private:
252 std::vector<T> data_;
253 // Like in the compressed row sparse matrix format,
254 // row_start_.size() is equal to the number of rows + 1.
255 std::vector<int> row_start_;
256
257 template <class IntegerIter>
258 void setRowStartsFromSizes(IntegerIter rowsize_beg, IntegerIter rowsize_end)
259 {
260#ifndef NDEBUG
261 // Check that all row sizes given are nonnegative.
262 for (auto it = rowsize_beg; it != rowsize_end; ++it) {
263 if (*it < 0) {
264 OPM_THROW(std::runtime_error, "Negative row size given.");
265 }
266 }
267#endif
268 // Since we do not store the row sizes, but cumulative row sizes,
269 // we have to create the cumulative ones.
270 int num_rows = rowsize_end - rowsize_beg;
271 row_start_.resize(num_rows + 1);
272 row_start_[0] = 0;
273 std::partial_sum(rowsize_beg, rowsize_end, row_start_.begin() + 1);
274 // Check that data_ and row_start_ match.
275 if (int(data_.size()) != row_start_.back()) {
276 OPM_THROW(std::runtime_error, "End of row start indices different from data size.");
277 }
278
279 }
280 };
281
282} // namespace Opm
283
284
285#endif // OPM_SPARSETABLE_HEADER
A class used as a row type for OrientedEntityTable.
Definition: OrientedEntityTable.hpp:55
Definition: SparseTable.hpp:186
bool operator==(const Iterator &other)
Definition: SparseTable.hpp:202
Iterator(const SparseTable &table, const int begin_row_index)
Definition: SparseTable.hpp:188
bool operator!=(const Iterator &other)
Definition: SparseTable.hpp:207
row_type operator*() const
Definition: SparseTable.hpp:198
Iterator & operator++()
Definition: SparseTable.hpp:193
Definition: SparseTable.hpp:55
Iterator end() const
Definition: SparseTable.hpp:221
void reserve(int exptd_nrows, int exptd_ndata)
Allocate storage for table of expected size.
Definition: SparseTable.hpp:127
const T data(int i) const
Definition: SparseTable.hpp:247
void assign(DataIter data_beg, DataIter data_end, IntegerIter rowsize_beg, IntegerIter rowsize_end)
Definition: SparseTable.hpp:84
bool empty() const
True if the table contains no rows.
Definition: SparseTable.hpp:115
void appendRow(DataIter row_beg, DataIter row_end)
Appends a row to the table.
Definition: SparseTable.hpp:108
void swap(SparseTable< T > &other)
Swap contents for other SparseTable<T>
Definition: SparseTable.hpp:134
int size() const
Returns the number of rows in the table.
Definition: SparseTable.hpp:121
row_type operator[](int row) const
Returns a row of the table.
Definition: SparseTable.hpp:168
Iterator begin() const
Iterator access.
Definition: SparseTable.hpp:217
int rowSize(int row) const
Returns the size of a table row.
Definition: SparseTable.hpp:147
int dataSize() const
Returns the number of data elements.
Definition: SparseTable.hpp:141
void print(std::basic_ostream< charT, traits > &os) const
Definition: SparseTable.hpp:233
SparseTable(DataIter data_beg, DataIter data_end, IntegerIter rowsize_beg, IntegerIter rowsize_end)
Definition: SparseTable.hpp:69
void allocate(IntegerIter rowsize_beg, IntegerIter rowsize_end)
Definition: SparseTable.hpp:96
SparseTable()
Default constructor. Yields an empty SparseTable.
Definition: SparseTable.hpp:58
void clear()
Makes the table empty().
Definition: SparseTable.hpp:157
bool operator==(const SparseTable &other) const
Equality.
Definition: SparseTable.hpp:227
Holds the implementation of the CpGrid as a pimple.
Definition: CellQuadrature.hpp:26
Definition: IteratorRange.hpp:50
Definition: IteratorRange.hpp:70