OPAL (Object Oriented Parallel Accelerator Library) 2022.1
OPAL
Array2D.h
Go to the documentation of this file.
1#ifndef CLASSIC_Array2D_HH
2#define CLASSIC_Array2D_HH
3
4// ------------------------------------------------------------------------
5// $RCSfile: Array2D.h,v $
6// ------------------------------------------------------------------------
7// $Revision: 1.1.1.1 $
8// ------------------------------------------------------------------------
9// Copyright: see Copyright.readme
10// ------------------------------------------------------------------------
11//
12// Template class: Array2D
13//
14// ------------------------------------------------------------------------
15// Class category: Algebra
16// ------------------------------------------------------------------------
17//
18// $Date: 2000/03/27 09:32:32 $
19// $Author: fci $
20//
21// ------------------------------------------------------------------------
22
23#include "Algebra/Array1D.h"
26#include "Utilities/SizeError.h"
27#include <algorithm>
28#include <iosfwd>
29
30
31// Template class Array2D<T>
32// ------------------------------------------------------------------------
34// A templated representation for 2-dimensional arrays.
35// This class implements storage management and component access,
36// as well as access to rows and columns, but contains no arithmetic
37// operations.
38
39template<class T>
40class Array2D {
41
42public:
43
45 typedef T value_type;
46
48 typedef T *iterator;
49
51 // of a constant array.
52 typedef const T *const_iterator;
53
55 typedef T *row_iterator;
56
58 typedef const T *const_row_iterator;
59
62
65
67 // Constructs array of zero rows and zero columns.
69
71 // Reserves [b]rows[/b] times [b]cols[/b] elements and leaves
72 // them undefined.
73 Array2D(int rows, int cols);
74
76 // Reserves [b]rows[/b] x [b]cols[/b] elements and sets them to [b]t[/b].
77 Array2D(int rows, int cols, const T &t);
78
79 Array2D(const Array2D &);
82
84 // Return a reference to element in row [b]r[/b] and column [b]c[/b].
85 T &operator()(int r, int c);
86
88 // Return the value of element in row [b]r[/b] and column [b]c[/b].
89 const T &operator()(int r, int c) const;
90
92 int nrows() const;
93
95 int ncols() const;
96
98 int size() const;
99
100
102 // Treat the array as one-dimensional.
103 // Version for non-constant objects.
105
107 // Treat the array as one-dimensional.
108 // Version for non-constant objects.
110
112 // Treat the array as one-dimensional.
113 // Version for constant objects.
115
117 // Treat the array as one-dimensional.
118 // Version for constant objects.
120
121
123 // Return pointer to beginning of row r.
124 // Throw RangeError, if row is out of range.
125 // Version for non-constant objects.
127
129 // Return pointer past end of row r.
130 // Throw RangeError, if row is out of range.
131 // Version for non-constant objects.
133
135 // Return pointer to beginning of constant row r.
136 // Throws RangeError, if row is out of range.
137 // Version for constant objects.
139
141 // Return pointer past end of constant row r.
142 // Throws RangeError, if row is out of range.
143 // Version for constant objects.
145
146
148 // Return pointer to beginning of row r.
149 // Result is undefined, if r is out of range.
150 // Version for non-constant objects.
152
154 // Return pointer to beginning of row r.
155 // Result is undefined, if r is out of range.
156 // Version for constant objects.
158
159
161 // Return pointer to beginning of column c.
162 // Throw RangeError if c is out of range.
163 // Version for non-constant objects.
165
167 // Return pointer past end of column c.
168 // Throw RangeError if c is out of range.
169 // Version for non-constant objects.
171
173 // Return pointer to beginning of column c.
174 // Throw RangeError if c is out of range.
175 // Version for constant objects.
177
179 // Return pointer past end of column c.
180 // Throw RangeError if c is out of range.
181 // Version for constant objects.
183
184
186 // Store the column [b]c[/b] into the array [b]toArray[/b].
187 // Throw RangeError if c is out of range.
188 void getColumn(Array1D<T> &toArray, int c) const;
189
191 // Store the row [b]r[/b] into the array [b]toArray[/b].
192 // Throw RangeError if r is out of range.
193 void getRow(Array1D<T> &toArray, int r) const;
194
196 // Fill the column [b]c[/b] from the array [b]fromArray[/b].
197 // Throw RangeError if c is out of range.
198 void putColumn(const Array1D<T> &fromArray, int c);
199
201 // Fill the row [b]r[/b] from the array [b]fromArray[/b].
202 // Throw RangeError if r is out of range.
203 void putRow(const Array1D<T> &fromArray, int r);
204
206 // Exchange the columns [b]c1[/b] and [b]c2[/b].
207
208
209 // Throw RangeError, if either index is out of range.
210 void swapColumns(int c1, int c2);
211
213 // Exchange the rows [b]r1[/b] and [b]r2[/b].
214 // Throw RangeError, if either index is out of range.
215 void swapRows(int row1, int row2);
216
217protected:
218
219 // Array dimensions.
220 int rows;
221 int cols;
222 int len; // rows * cols
223
224 // Array data.
226};
227
228
229// Template implementation.
230// ------------------------------------------------------------------------
231
232template <class T>
234 rows(0), cols(0), len(0), data(0)
235{}
236
237
238template <class T>
239inline Array2D<T>::Array2D(const Array2D<T>& array):
240 rows(array.rows), cols(array.cols), len(array.len), data(new T[len]) {
241 std::copy(array.begin(), array.end(), begin());
242}
243
244
245template <class T>
246inline Array2D<T>::Array2D(int r, int c):
247 rows(r), cols(c), len(r *c), data(new T[len])
248{}
249
250
251template <class T>
252inline Array2D<T>::Array2D(int r, int c, const T &val):
253 rows(r), cols(c), len(r *c), data(new T[len]) {
254 std::fill(begin(), end(), val);
255}
256
257
258template <class T>
260 delete [] data;
261}
262
263
264template <class T>
266
267{
268 if(this != &rhs) {
269 if(rhs.len > len) {
270 delete [] data;
271 data = new T[rhs.len];
272 }
273 rows = rhs.rows;
274 cols = rhs.cols;
275 len = rhs.len;
276 std::copy(rhs.begin(), rhs.end(), begin());
277 }
278 return *this;
279}
280
281
282template <class T>
283inline T &Array2D<T>::operator()(int r, int c) {
284 if(r < 0 || r >= rows || c < 0 || c >= ncols()) {
285 throw CLRangeError("Array2d::operator()", "Index out of range.");
286 }
287 return data[cols*r+c];
288}
289
290
291template <class T>
292inline const T &Array2D<T>::operator()(int r, int c) const {
293 if(r < 0 || r >= rows || c < 0 || c >= ncols()) {
294 throw CLRangeError("Array2d::operator()", "Index out of range.");
295 }
296 return data[cols*r+c];
297}
298
299
300template <class T>
301inline int Array2D<T>::nrows() const {
302 return rows;
303}
304
305
306template <class T>
307inline int Array2D<T>::ncols() const {
308 return cols;
309}
310
311
312template <class T>
313inline int Array2D<T>::size() const {
314 return len;
315}
316
317
318template <class T>
320 return data;
321}
322
323
324template <class T>
326 return data + len;
327}
328
329
330template <class T>
332 return data;
333}
334
335
336template <class T>
338 return data + len;
339}
340
341
342template <class T>
344 if(r >= rows) {
345 throw CLRangeError("Array2D::row_begin()", "Row index out of range.");
346 }
347 return &data[cols*r];
348}
349
350
351template <class T>
353 if(r >= rows) {
354 throw CLRangeError("Array2D::row_end()", "Row index out of range.");
355 }
356 return &data[cols*(r+1)];
357}
358
359
360template <class T>
362 if(r >= rows) {
363 throw CLRangeError("Array2D::row_begin()", "Row index out of range.");
364 }
365 return &data[cols*r];
366}
367
368
369template <class T>
371 if(r >= rows) {
372 throw CLRangeError("Array2D::row_end()", "Row index out of range.");
373 }
374 return &data[cols*(r+1)];
375}
376
377
378template <class T>
380 return &data[cols*r];
381}
382
383
384template <class T>
386 return &data[cols*r];
387}
388
389
390template <class T>
392 if(c >= cols) {
393 throw CLRangeError("Array2D::col_begin()", "Column index out of range.");
394 }
395 return col_iterator(data + c, cols);
396}
397
398
399template <class T>
401 if(c >= cols) {
402 throw CLRangeError("Array2D::col_end()", "Column index out of range.");
403 }
404 return col_iterator(data + len + c, cols);
405}
406
407
408template <class T>
410 if(c >= cols) {
411 throw CLRangeError("Array2D::col_begin()", "Column index out of range.");
412 }
413 return const_col_iterator(data + c, cols);
414}
415
416
417template <class T>
419 if(c >= cols) {
420 throw CLRangeError("Array2D::col_end()", "Column index out of range.");
421 }
422 return const_col_iterator(data + len + c, cols);
423}
424
425
426template <class T>
427void Array2D<T>::getColumn(Array1D<T> &toArray, int c) const {
428 if(toArray.size() != rows) toArray = Array1D<T>(rows);
429 std::copy(col_begin(c), col_end(c), toArray.begin());
430}
431
432
433template <class T>
434void Array2D<T>::getRow(Array1D<T> &toArray, int r) const {
435 if(toArray.size() != cols) toArray = Array1D<T>(cols);
436 std::copy(row_begin(r), row_end(r), toArray.begin());
437}
438
439
440template <class T>
441void Array2D<T>::putColumn(const Array1D<T> &fromArray, int c) {
442 if(fromArray.size() != rows) {
443 throw SizeError("Array2D::putColumn()", "Dimensions inconsistent.");
444 }
445 std::copy(fromArray.begin(), fromArray.end(), col_begin(c));
446}
447
448
449template <class T>
450void Array2D<T>::putRow(const Array1D<T> &fromArray, int r) {
451 if(fromArray.size() != cols) {
452 throw SizeError("Array2D::putRow()", "Dimensions inconsistent.");
453 }
454 std::copy(fromArray.begin(), fromArray.end(), row_begin(r));
455}
456
457
458template <class T>
459void Array2D<T>::swapColumns(int col1, int col2) {
460 std::swap_ranges(col_begin(col1), col_end(col1), col_begin(col2));
461}
462
463
464template <class T>
465void Array2D<T>::swapRows(int row1, int row2) {
466 std::swap_ranges(row_begin(row1), row_end(row1), row_begin(row2));
467}
468
469
470template <class T>
471std::ostream &operator<<(std::ostream &os, const Array2D<T> &v) {
472 for(int i = 0; i < v.nrows(); ++i) {
473 for(int j = 0; j < v.ncols(); ++j) {
474 os << v(i, j) << " ";
475 }
476 os << std::endl;
477 }
478 return os;
479}
480
481
482#endif // CLASSIC_Array2D_HH
PartBunchBase< T, Dim >::ConstIterator begin(PartBunchBase< T, Dim > const &bunch)
std::ostream & operator<<(std::ostream &os, const Array2D< T > &v)
Definition: Array2D.h:471
Inform & endl(Inform &inf)
Definition: Inform.cpp:42
constexpr double c
The velocity of light in m/s.
Definition: Physics.h:45
One-dimensional array.
Definition: Array1D.h:36
iterator begin()
Get beginning of data.
Definition: Array1D.h:204
int size() const
Get array size.
Definition: Array1D.h:228
iterator end()
Get end of data.
Definition: Array1D.h:210
Two-dimensional array.
Definition: Array2D.h:40
const_col_iterator col_end(int c) const
Get column iterator.
Definition: Array2D.h:418
T & operator()(int r, int c)
Get element reference.
Definition: Array2D.h:283
row_iterator row_begin(int r)
Get row iterator.
Definition: Array2D.h:343
T value_type
The value type of the array.
Definition: Array2D.h:45
const_row_iterator operator[](int r) const
Get row iterator.
Definition: Array2D.h:385
int len
Definition: Array2D.h:222
const_iterator begin() const
Get pointer to beginning of data.
Definition: Array2D.h:331
void swapColumns(int c1, int c2)
Exchange columns.
Definition: Array2D.h:459
int size() const
Get total size (rows times columns).
Definition: Array2D.h:313
T * iterator
The iterator type for sequential access to all elements.
Definition: Array2D.h:48
iterator begin()
Get pointer to beginning of data.
Definition: Array2D.h:319
const T * const_row_iterator
The iterator type for access by rows for a constant array.
Definition: Array2D.h:58
int nrows() const
Get number of rows.
Definition: Array2D.h:301
void getColumn(Array1D< T > &toArray, int c) const
Fetch column.
Definition: Array2D.h:427
Array2D< T > & operator=(const Array2D< T > &)
Definition: Array2D.h:265
Array2D(const Array2D &)
Definition: Array2D.h:239
int rows
Definition: Array2D.h:220
const_row_iterator row_end(int r) const
Get row iterator.
Definition: Array2D.h:370
~Array2D()
Definition: Array2D.h:259
Array2D(int rows, int cols, const T &t)
Constructor.
Definition: Array2D.h:252
row_iterator row_end(int r)
Get row iterator.
Definition: Array2D.h:352
const T * const_iterator
The iterator type for sequential access to all elements.
Definition: Array2D.h:52
const_row_iterator row_begin(int r) const
Get row iterator.
Definition: Array2D.h:361
void putColumn(const Array1D< T > &fromArray, int c)
Store column.
Definition: Array2D.h:441
void putRow(const Array1D< T > &fromArray, int r)
Store row.
Definition: Array2D.h:450
void swapRows(int row1, int row2)
Exchange rows.
Definition: Array2D.h:465
iterator end()
Get pointer past end of data.
Definition: Array2D.h:325
const_iterator end() const
Get pointer past end of data.
Definition: Array2D.h:337
const T & operator()(int r, int c) const
Get element value.
Definition: Array2D.h:292
Array2D()
Default constructor.
Definition: Array2D.h:233
Array2D(int rows, int cols)
Constructor.
Definition: Array2D.h:246
T * data
Definition: Array2D.h:225
void getRow(Array1D< T > &toArray, int r) const
Fetch row.
Definition: Array2D.h:434
const_col_iterator col_begin(int c) const
Get column iterator.
Definition: Array2D.h:409
int cols
Definition: Array2D.h:221
T * row_iterator
The iterator type for access by rows.
Definition: Array2D.h:55
ConstSliceIterator< T > const_col_iterator
The iterator type for access by columns for a constant array.
Definition: Array2D.h:64
row_iterator operator[](int r)
Get row iterator.
Definition: Array2D.h:379
col_iterator col_begin(int c)
Get column iterator.
Definition: Array2D.h:391
col_iterator col_end(int c)
Get column iterator.
Definition: Array2D.h:400
int ncols() const
Get number of columns.
Definition: Array2D.h:307
SliceIterator< T > col_iterator
The iterator type for access by columns.
Definition: Array2D.h:61
Iterator for array slice.
Definition: SliceIterator.h:32
Iterator for array slice.
Range error.
Definition: CLRangeError.h:33
Size error exception.
Definition: SizeError.h:33