MatrixVector.h 9.33 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/******************************************************************************
 *
 * AMDiS - Adaptive multidimensional simulations
 *
 * Copyright (C) 2013 Dresden University of Technology. All Rights Reserved.
 * Web: https://fusionforge.zih.tu-dresden.de/projects/amdis
 *
 * Authors: 
 * Simon Vey, Thomas Witkowski, Andreas Naumann, Simon Praetorius, et al.
 *
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 *
 *
 * This file is part of AMDiS
 *
 * See also license.opensource.txt in the distribution.
 * 
 ******************************************************************************/
20
21


22
23
24
25
26
27

/** \file MatrixVector.h */

#ifndef AMDIS_MATRIXVECTOR_H
#define AMDIS_MATRIXVECTOR_H

28
// #include <vector>
29
#include "Global.h"
30
// #include "AMDiS_fwd.h"
31
#include "Serializable.h"
32
#include "traits/basic.hpp" // not dependenciess on other AMDiS types
33
34
35

namespace AMDiS {

Thomas Witkowski's avatar
Thomas Witkowski committed
36
  /// Class for efficient vector operations of fixed size numerical vectors.
37
38
39
40
  template<typename T>
  class Vector : public Serializable
  {
  public:
41
    
42
43
    typedef T       value_type;
    typedef Vector  self;
44
    
Thomas Witkowski's avatar
Thomas Witkowski committed
45
    /// Constructor.
46
47
48
49
    Vector(int s = 0) 
      : size(s),
	valArray(size ? new T[size] : NULL)
    { }
50
51

    /// Copy constructor.
52
    Vector(self const& other) 
53
      : Serializable(),
54
55
	size(other.size),
	valArray(size ? new T[size] : NULL)
56
    {
57
      setValues(other.valArray);
58
59
60
    }
    
    /// Copy constructor for other of different value_type
61
    // TODO: notwendig?
62
63
64
65
66
67
68
69
    template <typename S>
    Vector(Vector<S> const& rhs)
      : Serializable(),
	size(rhs.getSize()),
	valArray(new T[rhs.getSize()])
    {
      setValues(rhs.getValArray());
    }
70
71
72
73
74
75
76
77
78
    
#if HAS_RVALUE_REFERENCES
    /// move constructor
    Vector(self&& other)
      : Vector()
    {
      swap(*this, other);
    }
#endif
79
80

    /// Destructor.
81
    ~Vector() 
82
83
84
    {
      if (valArray != NULL) {
	delete [] valArray; 
85
	valArray = NULL;
86
      }
87
    }
88

89
90
    inline bool used() const 
    {
91
      return (valArray != NULL);
92
    }
93

Thomas Witkowski's avatar
Thomas Witkowski committed
94
    /// Change the size of the vector to newSize.
95
96
    inline void resize(int newSize) 
    {
97
      if (size != newSize && newSize > 0) {
98
	if (valArray != NULL) 
99
100
101
102
	  delete [] valArray;
	valArray = new T[newSize];
	size = newSize;
      }
103
    }
104

105
106
    /// Assignement operator
    template <typename S>
107
108
    typename disable_if< boost::is_same<S, T>, self >::type &
    operator=(Vector<S> const& other) 
109
    {
110
111
      resize(other.getSize());
      setValues(other.getValArray());
112
      return *this;
113
    }
114
    
115
116
    /// copy assignment operator
    self& operator=(self other) 
117
    {
118
      swap(*this, other);
119
      return *this;
120
    }
121

122
    /// Assignement operator for scalars
123
    template <typename S>
124
125
    typename enable_if< boost::is_convertible<S, T>, Vector<T> >::type &
    operator=(S value) 
126
    {
127
      set(value);
128
      return *this;
129
    }
130

Thomas Witkowski's avatar
Thomas Witkowski committed
131
    /// Assignement operator
132
    inline self& operator=(const T* vec) 
133
    {
134
      setValues(vec);
135
      return *this;
136
    }
137
138
139
140
  
    /// A swap function for Vector, used in the Copy-and-swap idiom
    // need non-templated arguments in order to eliminate a friend declaration warning in gcc
    friend void swap(Vector& first, Vector& second)
141
    {
142
143
144
      using std::swap; // enable ADL
      swap(first.size, second.size);
      swap(first.valArray, second.valArray);
145
    }
146
147

    /// Sets all entries to scal.
148
    template <typename S>
149
150
    typename enable_if< boost::is_convertible<S, T> >::type
    set(S value) 
151
    {
152
      std::fill(begin(), end(), value);
153
    }
154

Thomas Witkowski's avatar
Thomas Witkowski committed
155
    /// Sets all entries.
156
157
158
    template <typename S>
    void setValues(const S* values) 
    {
159
      std::copy(values, values + size, valArray);
160
161
    }

Thomas Witkowski's avatar
Thomas Witkowski committed
162
    /// Comparison operator.
163
    inline bool operator==(Vector<T> const& rhs) const 
164
165
166
167
    {
      if (size != rhs.size) 
	return false;

168
169
      T const* rhsIt;
      T const* thisIt;
170
171
172
      for (rhsIt = rhs.begin(), thisIt = this->begin();
	   rhsIt != rhs.end();
	   ++rhsIt, ++thisIt)
173
	if (*thisIt != *rhsIt) 
174
175
	  return false;

176
      return true;
177
    }
178

Thomas Witkowski's avatar
Thomas Witkowski committed
179
    /// Comparison operator.
180
    inline bool operator!=(Vector<T> const& rhs) const 
181
    {
182
183
184
      return !(*this==rhs);
    }

Thomas Witkowski's avatar
Thomas Witkowski committed
185
    /// Access to the i-th vector element.
186
187
    inline T& operator[](int i) 
    {
188
//       TEST_EXIT_DBG(i < size && i >= 0)("Invalid index %d!\n", i);
189
      return valArray[i];
190
    }
191

Thomas Witkowski's avatar
Thomas Witkowski committed
192
    /// Access to the i-th vector element for const vectors.
193
194
    inline const T& operator[] (int i) const 
    {
195
//       TEST_EXIT_DBG(i < size && i >= 0)("Invalid index %d!\n", i);
196
      return valArray[i];
197
    }
198

Thomas Witkowski's avatar
Thomas Witkowski committed
199
    /// Returns pointer to the first vector element.
200
201
    inline T* begin() { return valArray; }
    inline T const* begin() const { return valArray; }
202

Thomas Witkowski's avatar
Thomas Witkowski committed
203
    /// Returns pointer after the last vector element.
204
205
    inline T* end() { return valArray + size; }
    inline T const* end() const { return valArray + size; }
206

Thomas Witkowski's avatar
Thomas Witkowski committed
207
    /// Returns \ref size.
208
    inline int getSize() const 
209
    { 
210
      return size; 
211
    }
212

Thomas Witkowski's avatar
Thomas Witkowski committed
213
    /// Returns \ref valArray as T-array
214
215
    inline T* getValArray() { return valArray; }    
    inline T const* getValArray() const { return valArray; }
216

217
218
    void print() const 
    {
219
      std::cout << this->size << " vector: " << std::endl;
220
      for (int i = 0; i < size; i++) 
221
222
	std::cout << this->valArray[i] << " ";
      std::cout << std::endl;
223
    }
224

225
226
    void serialize(std::ostream &out) 
    {
227
228
      out.write(reinterpret_cast<const char*>(&size), sizeof(int));
      out.write(reinterpret_cast<const char*>(valArray), size * sizeof(T));
229
    }
230

231
232
    void deserialize(std::istream &in) 
    {
233
234
      in.read(reinterpret_cast<char*>(&size), sizeof(int));
      in.read(reinterpret_cast<char*>(valArray), size * sizeof(T));
235
    }
236

237
238
    std::string getTypeName() const 
    { 
239
      return "Vector"; 
240
    }
241
242

  protected:
Thomas Witkowski's avatar
Thomas Witkowski committed
243
    /// Size of the vector.
244
245
    int size;

Thomas Witkowski's avatar
Thomas Witkowski committed
246
    /// Internal storage pointer.
247
248
249
250
    T *valArray;
  };


Thomas Witkowski's avatar
Thomas Witkowski committed
251
  /// Class for efficient matrix operations of fixed size numerical matrices.
252
253
254
255
  template<typename T>
  class Matrix : public Vector<T>
  {
  public:
256
257
258
259
260
    typedef Matrix     self;
    typedef Vector<T>  super;
  
    /// Default constructor.
    Matrix()
261
      : super(0), rows(0), cols(0)
262
263
    {}
    
Thomas Witkowski's avatar
Thomas Witkowski committed
264
    /// Constructor.
265
    Matrix(int r, int c)
266
      : super(r * c), 
267
268
	rows(r),
	cols(c)
269
    {}
270
    
271
    /// copy constructor
272
273
274
275
276
    Matrix(self const& other)
      : super(other),
	rows(other.getNumRows()),
	cols(other.getNumCols())
    { }
277
278
279
280
281
282
283
284
285
    
#if HAS_RVALUE_REFERENCES
    /// move constructor
    Matrix(self&& other)
      : Matrix()
    {
      swap(*this, other);
    }
#endif
286

Thomas Witkowski's avatar
Thomas Witkowski committed
287
    /// Changes the size of the matrix to newRows x newCols.
288
289
    inline void resize(int newRows, int newCols) 
    {
290
      if ((newRows != rows) || (newCols != cols)) {
291
	super::resize(newRows * newCols);
292
293
294
	rows = newRows;
	cols = newCols;
      }
295
    }
296
297
    
    self& operator=(self other) 
298
    {
299
      swap(*this, other);
300
301
      return *this;
    }
302
303
304
305

    /// Assignement operator
    template <typename S>
    inline self& operator=(const Matrix<S>& other) 
306
    {
307
308
      resize(other.getNumRows(), other.getNumCols());
      this->setValues(other.getValArray());
309
310
311
312
      return *this;
    }

    /// Assignement operator for scalars.
313
    self& operator=(T value) 
314
    {
315
      super::set(value);
316
      return *this;
317
    }
318
319
320
321
322
323
324
325
326
327
  
    /// A swap function for Matrix, used in the Copy-and-swap idiom
    // need non-templated arguments in order to eliminate a friend declaration warning in gcc
    friend void swap(Matrix& first, Matrix& second)
    {
      using std::swap; // enable ADL
      swap(first.rows, second.rows);
      swap(first.cols, second.cols);
      swap(static_cast<super&>(first), static_cast<super&>(second));
    }
328

329
330
    /// Comparison operator.
    inline bool operator==(const self& rhs) const 
331
    {
332
333
      if (rows != rhs.getNumRows()) return false;
      if (cols != rhs.getNumCols()) return false;
334
      return super::operator==(rhs);
335
    }
336

Thomas Witkowski's avatar
Thomas Witkowski committed
337
    /// Comparison operator.
338
    inline bool operator!=(const self& rhs) const 
339
    {
340
      return !(*this == rhs);
341
342
    }

Thomas Witkowski's avatar
Thomas Witkowski committed
343
    /// Access to i-th matrix row.
344
345
    inline T *operator[](int i) 
    {
346
      return this->valArray + cols * i;
347
    }
348

Thomas Witkowski's avatar
Thomas Witkowski committed
349
    /// Access to i-th matrix row for constant matrices.
350
351
    inline const T *operator[](int i) const 
    {
352
      return this->valArray + cols * i;
353
    }
354

355
356
357
358
359
360
361
362
363
364
365
366
    /// Access to i-th matrix row.
    inline T& operator()(int i, int j) 
    {
      return this->operator[](i)[j];
    }

    /// Access to i-th matrix row for constant matrices.
    inline const T& operator()(int i, int j) const 
    {
      return this->operator[](i)[j];
    }

Thomas Witkowski's avatar
Thomas Witkowski committed
367
    /// Returns \ref rows.
368
369
    inline int getNumRows() const 
    { 
370
      return rows; 
371
    }
372

Thomas Witkowski's avatar
Thomas Witkowski committed
373
    /// Return \ref cols.
374
375
    inline int getNumCols() const 
    { 
376
      return cols; 
Thomas Witkowski's avatar
Thomas Witkowski committed
377
    }
378

379
380
    void print() const 
    {
381
      std::cout << this->rows << " x " << this->cols << " matrix: " << std::endl;
382
      for (int i = 0; i < rows; i++) {
383
	for (int j = 0; j < cols; j++)
384
385
	  std::cout << this->valArray[i * cols + j] << " ";
	std::cout << std::endl;
386
      }
387
388
    }

389
  protected:
Thomas Witkowski's avatar
Thomas Witkowski committed
390
    /// Number of matrix rows.
391
392
    int rows;

Thomas Witkowski's avatar
Thomas Witkowski committed
393
    /// Number of matrix columns.
394
395
    int cols;
  };
396
397
398
399
400
401
402
403
404
405
406
  
  template<typename T>
  inline size_t num_rows(const Vector<T>& vec)
  {
    return static_cast<size_t>(vec.getSize());
  }
  
  template<typename T>
  inline void resize(Vector<T>& vec, size_t newSize)
  {
    vec.resize(newSize);
407
  }
408
  
409
410
411
}

#endif // AMDIS_MATRIXVECTOR_H