RepastHPC  2.3.1
matrix.h
1 /*
2  * Repast for High Performance Computing (Repast HPC)
3  *
4  * Copyright (c) 2010 Argonne National Laboratory
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with
8  * or without modification, are permitted provided that the following
9  * conditions are met:
10  *
11  * Redistributions of source code must retain the above copyright notice,
12  * this list of conditions and the following disclaimer.
13  *
14  * Redistributions in binary form must reproduce the above copyright notice,
15  * this list of conditions and the following disclaimer in the documentation
16  * and/or other materials provided with the distribution.
17  *
18  * Neither the name of the Argonne National Laboratory nor the names of its
19  * contributors may be used to endorse or promote products derived from
20  * this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
25  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE TRUSTEES OR
26  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
32  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33  *
34  *
35  * matrix.h
36  *
37  * Created on:
38  * Author: nick
39  */
40 
41 #ifndef MATRIX_H_
42 #define MATRIX_H_
43 
44 #include <vector>
45 #include <stdexcept>
46 #include <map>
47 
48 #include "Point.h"
49 #include "RepastErrors.h"
50 
51 namespace repast {
52 
56 template<typename T>
57 class Matrix {
58 
59 protected:
60 
61  int* stride;
62  T defValue;
63  Point<int> _size;
64  int dCount;
65 
66  int calcIndex(const Point<int>& index);
67  void boundsCheck(const Point<int>& index);
68  void create();
69 
70 public:
71 
77  explicit Matrix(const Point<int>& size, const T& defaultValue = T());
78  virtual ~Matrix();
79 
83  virtual T& get(const Point<int>& index) = 0;
84 
88  virtual void set(const T& value, const Point<int>& index) = 0;
89 
90  T& operator[](const Point<int>& index);
91  const T& operator[](const Point<int>& index) const;
92 
96  const T& defaultValue() const {
97  return defValue;
98  }
99 
103  const Point<int> shape() const {
104  return _size;
105  }
106 };
107 
108 template<typename T>
109 Matrix<T>::Matrix(const Point<int>& size, const T& defaultValue) :
110  defValue(defaultValue), _size(size), dCount(size.dimensionCount()) {
111  create();
112 }
113 
114 template<typename T>
115 void Matrix<T>::create() {
116  int tmpStride = 1;
117  stride = new int[dCount];
118  for (int i = dCount - 1; i >= 0; i--) {
119  stride[i] = tmpStride;
120  tmpStride *= _size.getCoordinate(i);
121  }
122 }
123 
124 template<typename T>
125 Matrix<T>::~Matrix() {
126  delete[] stride;
127 }
128 
129 template<typename T>
130 void Matrix<T>::boundsCheck(const Point<int>& index) {
131  if (index.dimensionCount() != dCount)
132  throw Repast_Error_47<Point<int> >(dCount, index.dimensionCount(), index); // Number of index dimensions != number of matrix dimensions
133  for (int i = 0; i < dCount; i++) {
134  if (index.getCoordinate(i) < 0 || index.getCoordinate(i) >= _size.getCoordinate(i))
135  throw Repast_Error_48<Point<int> >(i, index.getCoordinate(i), index, _size.getCoordinate(i)); // Matrix Bounds Check: index is out of range
136  }
137 }
138 
139 template<typename T>
140 int Matrix<T>::calcIndex(const Point<int>& index) {
141  int vIndex = 0;
142  for (size_t i = 0; i < index.dimensionCount(); i++) {
143  vIndex = vIndex + index[i] * stride[i];
144  }
145  return vIndex;
146 }
147 
148 template<typename T>
149 T& Matrix<T>::operator[](const Point<int>& index) {
150  return get(index);
151 }
152 
153 template<typename T>
154 const T& Matrix<T>::operator[](const Point<int>& index) const {
155  return get(index);
156 }
157 
161 template<typename T>
162 class DenseMatrix: public Matrix<T> {
163 
164 private:
165  std::vector<T> values;
166 
167 public:
171  DenseMatrix(const DenseMatrix<T>&);
172  DenseMatrix<T>& operator=(const DenseMatrix<T>&);
173 
177  explicit DenseMatrix(const Point<int>& shape, const T& defValue = T());
178 
179  ~DenseMatrix() {
180  }
181 
185  T& get(const Point<int>& index);
186 
190  void set(const T& value, const Point<int>& index);
191 
192 };
193 
194 template<typename T>
196  Matrix<T> (other._size, other.defaultValue()), values(other.values) {
197 
198 }
199 
200 template<typename T>
202  if (&rhs != this) {
203  delete[] Matrix<T>::stride;
204  Matrix<T>::_size = rhs._size;
205  Matrix<T>::dCount = rhs.dCount;
208 
209  values = std::vector<T>(rhs.values.begin(), rhs.values.end());
210  }
211  return *this;
212 }
213 
214 template<typename T>
215 DenseMatrix<T>::DenseMatrix(const Point<int>& size, const T& defValue) :
216  Matrix<T> (size) {
217  int _size = 1;
218  for (int i = 0; i < Matrix<T>::dCount; i++) {
219  _size *= size.getCoordinate(i);
220  }
221  values = std::vector<T>(_size, defValue);
222 }
223 
224 template<typename T>
225 T& DenseMatrix<T>::get(const Point<int>& index) {
226  Matrix<T>::boundsCheck(index);
227  int vIndex = Matrix<T>::calcIndex(index);
228  return values[vIndex];
229 }
230 
231 template<typename T>
232 void DenseMatrix<T>::set(const T& value, const Point<int>& index) {
233  Matrix<T>::boundsCheck(index);
234  int vIndex = Matrix<T>::calcIndex(index);
235  values[vIndex] = value;
236 }
237 
242 template<typename T>
243 class SparseMatrix: public Matrix<T> {
244 
245 private:
246  std::map<int, T> map;
247 
248  typedef typename std::map<int, T>::iterator map_iter;
249 
250 public:
252  SparseMatrix<T>& operator=(const SparseMatrix<T>&);
253 
257  explicit SparseMatrix(const Point<int>& size, const T& defValue = T());
258  ~SparseMatrix() {
259  }
260 
264  T& get(const Point<int>& index);
265 
269  void set(const T& value, const Point<int>& index);
270 
271 };
272 
273 template<typename T>
275  Matrix<T> (other._size, other.defaultValue()), map(other.map) {
276 }
277 
278 template<typename T>
279 SparseMatrix<T>& SparseMatrix<T>::operator=(const SparseMatrix<T>& rhs) {
280  if (&rhs != this) {
281  delete[] Matrix<T>::stride;
282  Matrix<T>::_size = rhs._size;
283  Matrix<T>::dCount = rhs.dCount;
284  Matrix<T>::defValue = rhs.defaultValue();
285  Matrix<T>::create();
286 
287  map = std::map<int, T>(rhs.map.begin(), rhs.map.end());
288  }
289  return *this;
290 }
291 
292 template<typename T>
293 SparseMatrix<T>::SparseMatrix(const Point<int>& size, const T& defValue) :
294  Matrix<T> (size, defValue) {
295 }
296 
297 template<typename T>
299  Matrix<T>::boundsCheck(index);
300  int vIndex = Matrix<T>::calcIndex(index);
301  // need to insert do an insert and return reference to
302  // result so that assignment via [] uses a reference in
303  // the map. insert inserts the entry if it doesn't exist
304  // and returns the entry or the existing entry
305  std::pair<map_iter, bool> res = map.insert(std::make_pair(vIndex, Matrix<T>::defValue));
306  return res.first->second;
307 }
308 
309 template<typename T>
310 void SparseMatrix<T>::set(const T& value, const Point<int>& index) {
311  Matrix<T>::boundsCheck(index);
312  int vIndex = Matrix<T>::calcIndex(index);
313  map[vIndex] = value;
314 }
315 
316 }
317 
318 #endif /* MATRIX_H_ */
repast::SparseMatrix::get
T & get(const Point< int > &index)
Gets the value at the specified index.
Definition: matrix.h:298
repast::DenseMatrix::get
T & get(const Point< int > &index)
Gets the value at the specified index.
Definition: matrix.h:225
repast::Matrix::set
virtual void set(const T &value, const Point< int > &index)=0
Sets the value at the specified index.
repast::Matrix
Base class for matrix implementations.
Definition: matrix.h:57
repast::Point::getCoordinate
T getCoordinate(int coordIndex) const
Gets the coodinate of the point in the specified dimension.
Definition: Point.h:320
repast::DenseMatrix::set
void set(const T &value, const Point< int > &index)
Sets the value at the specified index.
Definition: matrix.h:232
repast::Matrix::get
virtual T & get(const Point< int > &index)=0
Gets the value at the specified index.
repast::DenseMatrix
A dense matrix implementation that stores each cell individually.
Definition: matrix.h:162
repast::SparseMatrix
A sparse matrix implementation that stores values in a map.
Definition: matrix.h:243
repast::SparseMatrix::set
void set(const T &value, const Point< int > &index)
Sets the value at the specified index.
Definition: matrix.h:310
repast::Matrix::defaultValue
const T & defaultValue() const
Gets the default value of any unset matrix cell.
Definition: matrix.h:96
repast::DenseMatrix::DenseMatrix
DenseMatrix(const DenseMatrix< T > &)
Creates a DenseMatrix as a copy of the specified DenseMatrix.
Definition: matrix.h:195
repast::Point< int >
repast::Matrix::Matrix
Matrix(const Point< int > &size, const T &defaultValue=T())
Creates a matrix of the specified size and with the specified default value.
Definition: matrix.h:109
repast::Matrix::shape
const Point< int > shape() const
Gets the shape (i.e.
Definition: matrix.h:103