SparseVector.hpp
Go to the documentation of this file.
1 //===========================================================================
2 //
3 // File: SparseVector.hpp
4 //
5 // Created: Mon Jun 29 15:28:59 2009
6 //
7 // Author(s): Atgeirr F Rasmussen <atgeirr@sintef.no>
8 // Bård Skaflestad <bard.skaflestad@sintef.no>
9 //
10 // $Date$
11 //
12 // $Revision$
13 //
14 //===========================================================================
15 
16 /*
17  Copyright 2009, 2010 SINTEF ICT, Applied Mathematics.
18  Copyright 2009, 2010 Statoil ASA.
19 
20  This file is part of the Open Porous Media project (OPM).
21 
22  OPM is free software: you can redistribute it and/or modify
23  it under the terms of the GNU General Public License as published by
24  the Free Software Foundation, either version 3 of the License, or
25  (at your option) any later version.
26 
27  OPM is distributed in the hope that it will be useful,
28  but WITHOUT ANY WARRANTY; without even the implied warranty of
29  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30  GNU General Public License for more details.
31 
32  You should have received a copy of the GNU General Public License
33  along with OPM. If not, see <http://www.gnu.org/licenses/>.
34 */
35 
36 
37 #ifndef OPM_SPARSEVECTOR_HEADER
38 #define OPM_SPARSEVECTOR_HEADER
39 
40 #include <vector>
41 #include <numeric>
42 #include <algorithm>
43 #include <boost/range/iterator_range.hpp>
44 #include <opm/common/ErrorMacros.hpp>
45 
46 namespace Opm
47 {
48 
54  template <typename T>
56  {
57  public:
60  : size_(0), default_elem_()
61  {
62  }
63 
66  explicit SparseVector(int sz)
67  : size_(sz), default_elem_()
68  {
69  }
70 
76  template <typename DataIter, typename IntegerIter>
77  SparseVector(int sz,
78  DataIter data_beg, DataIter data_end,
79  IntegerIter index_beg, IntegerIter index_end)
80  : size_(sz), data_(data_beg, data_end), indices_(index_beg, index_end),
81  default_elem_()
82  {
83 #ifndef NDEBUG
84  OPM_ERROR_IF(sz < 0, "The size of a SparseVector must be non-negative");
85  OPM_ERROR_IF(indices_.size() != data_.size(), "The number of indices of a SparseVector must equal to the number of entries");
86  int last_index = -1;
87  int num_ind = indices_.size();
88  for (int i = 0; i < num_ind; ++i) {
89  int index = indices_[i];
90  if (index <= last_index || index >= sz) {
91  OPM_THROW(std::logic_error, "Error in SparseVector construction, index is nonincreasing or out of range.");
92  }
93  last_index = index;
94  }
95 #endif
96  }
97 
98 
102  void addElement(const T& elem, int index)
103  {
104  assert(indices_.empty() || index > indices_.back());
105  assert(index < size_);
106  data_.push_back(elem);
107  indices_.push_back(index);
108  }
109 
111  bool empty() const
112  {
113  return size_ == 0;
114  }
115 
118  int size() const
119  {
120  return size_;
121  }
122 
124  int nonzeroSize() const
125  {
126  return data_.size();
127  }
128 
130  void clear()
131  {
132  data_.clear();
133  indices_.clear();
134  size_ = 0;
135  }
136 
138  bool operator==(const SparseVector& other) const
139  {
140  return size_ == other.size_ && data_ == other.data_ && indices_ == other.indices_;
141  }
142 
147  const T& element(int index) const
148  {
149 #ifndef NDEBUG
150  OPM_ERROR_IF(index < 0, "The index of a SparseVector must be non-negative (is " << index << ")");
151  OPM_ERROR_IF(index >= size_, "The index of a SparseVector must be smaller than the maximum value (is " << index << ", max value: " << size_ <<")");
152 #endif
153  std::vector<int>::const_iterator lb = std::lower_bound(indices_.begin(), indices_.end(), index);
154  if (lb != indices_.end() && *lb == index) {
155  return data_[lb - indices_.begin()];
156  } else {
157  return default_elem_;
158  }
159  }
160 
164  const T& nonzeroElement(int nzindex) const
165  {
166 #ifndef NDEBUG
167  OPM_ERROR_IF(nzindex < 0, "The index of a SparseVector must be non-negative (is " << nzindex << ")");
168  OPM_ERROR_IF(nzindex >= nonzeroSize(), "The index of a SparseVector must be smaller than the maximum value (is " << nzindex << ", max value: " << nonzeroSize() <<")");
169 #endif
170  return data_[nzindex];
171  }
172 
176  int nonzeroIndex(int nzindex) const
177  {
178  assert(nzindex >= 0);
179  assert(nzindex < nonzeroSize());
180  return indices_[nzindex];
181  }
182 
183  private:
184  // The vectors data_ and indices_ are always the same size.
185  // The indices are supposed to be stored in increasing order,
186  // to be unique, and to be in [0, size_ - 1].
187  // default_elem_ is returned when a default element is requested.
188  int size_;
189  std::vector<T> data_;
190  std::vector<int> indices_;
191  T default_elem_;
192  };
193 
194 } // namespace Opm
195 
196 
197 
198 
199 #endif // OPM_SPARSEVECTOR_HEADER
Definition: SparseVector.hpp:55
Definition: AnisotropicEikonal.hpp:43
SparseVector(int sz, DataIter data_beg, DataIter data_end, IntegerIter index_beg, IntegerIter index_end)
Definition: SparseVector.hpp:77
bool operator==(const SparseVector &other) const
Equality.
Definition: SparseVector.hpp:138
const T & nonzeroElement(int nzindex) const
Definition: SparseVector.hpp:164
int nonzeroSize() const
Returns the number of nonzero data elements.
Definition: SparseVector.hpp:124
int size() const
Definition: SparseVector.hpp:118
int nonzeroIndex(int nzindex) const
Definition: SparseVector.hpp:176
void addElement(const T &elem, int index)
Definition: SparseVector.hpp:102
SparseVector(int sz)
Definition: SparseVector.hpp:66
void clear()
Makes the vector empty().
Definition: SparseVector.hpp:130
const T & element(int index) const
Definition: SparseVector.hpp:147
bool empty() const
Definition: SparseVector.hpp:111
SparseVector()
Default constructor. Yields an empty SparseVector.
Definition: SparseVector.hpp:59