Imagine++
MultiArray.h
1 // ===========================================================================
2 // Imagine++ Libraries
3 // Copyright (C) Imagine
4 // For detailed information: http://imagine.enpc.fr/software
5 // ===========================================================================
6 
7 namespace Imagine {
10 
11 
21  template <typename T, int dim> class MultiArray : public Array<T> {
22 
23  private:
24  // Based on Array
25  typedef Array<T> Base;
26  Coords<dim> _sz; // Sizes of the array.
27  FArray<size_t,dim> _stride; // Strides to navigate to neighbors in each dimension
28  // Set size and compute stride
29  void setSizes(const Coords<dim>& sz)
30  {
31  _sz=sz;
32  _stride[0] = 1;
33  for (int i=0;i<dim-1;i++) {
34  _stride[i+1] = _stride[i]*_sz[i];
35  }
36  }
37  // Set size and stride from another MultiArray
38  template <typename Y> void setSizes(const MultiArray<Y,dim>& A)
39  {
40  _sz=A.sizes(); _stride=A.stride();
41  }
42 
43  public:
45  typedef T* iterator;
47  typedef const T* const_iterator;
48 
49 
55  MultiArray() : Base() { _sz = 0; }
62  explicit MultiArray(const Coords<dim>& sz) : Base(sz.prod()) { setSizes(sz); }
70  MultiArray(int s0,int s1) : Base(size_t(s0)*s1) { assert(dim==2); setSizes(Coords<2>(s0,s1)); }
79  MultiArray(int s0,int s1, int s2) : Base(size_t(s0)*s1*s2) { assert(dim==3); setSizes(Coords<3>(s0,s1,s2)); }
91  MultiArray(T* ptr, const Coords<dim>& sz,bool handleDelete=false) : Base(ptr,sz.prod(),handleDelete) { setSizes(sz); }
103  MultiArray(T* ptr, int s0,int s1,bool handleDelete=false) : Base(ptr,size_t(s0)*s1,handleDelete) { assert(dim==2); setSizes(Coords<2>(s0,s1)); }
116  MultiArray(T* ptr, int s0,int s1,int s2,bool handleDelete=false) : Base(ptr,size_t(s0)*s1*s2,handleDelete) { assert(dim==3); setSizes(Coords<3>(s0,s1,s2)); }
123  explicit MultiArray(const MultiArray& A) : Base(A) { setSizes(A); }
131  template <typename T2>
132  MultiArray(const MultiArray<T2,dim>& A) : Base(A) { setSizes(A); }
135  virtual ~MultiArray() {}
146  void setSize(const Coords<dim>& sz) {
147  if (sz==_sz) return;
148  Base::setSize(sz.prod());
149  setSizes(sz);
150  }
158  void setSize(int s0, int s1) { setSize(Coords<2>(s0,s1)); }
167  void setSize(int s0, int s1, int s2) { setSize(Coords<3>(s0,s1,s2)); }
175  MultiArray& operator=(const MultiArray& A) { Base::operator =(A); setSizes(A); return *this; }
184  template <typename T2> MultiArray& operator= (const MultiArray<T2,dim>& A) { Base::operator = (A); setSizes(A); return *this; }
191  MultiArray clone() const {
192  if (this->empty()) return MultiArray();
193  MultiArray A(_sz);
194  std::copy( this->begin(), this->end(), A.begin() );
195  return A;
196  }
204  MultiArray& fill(T x) { Base::fill(x); return *this; }
211  Coords<dim> sizes() const { return _sz; }
218  size_t totalSize() const { return Array<T>::size(); }
225  int size(int i) const { assert(i>=0 && i<dim); return _sz[i]; }
232  int width() const { assert(dim>=1); return _sz[0]; }
239  int height() const { assert(dim>=2); return _sz[1]; }
246  int depth() const { assert(dim>=3); return _sz[2]; }
253  FArray<size_t,dim> stride() const { return _stride; }
260  size_t stride(int i) const { assert(i>=0 && i<dim); return _stride[i]; }
270  MultiArray A(sz);
271  for (CoordsIterator<dim> p = A.coordsBegin() ; p != A.coordsEnd() ; ++p) {
272  A(*p)=operator()(*p+offset);
273  }
274  return A;
275  }
283  size_t offset(const Coords<dim>& c) const {
284  size_t o = c[dim-1];
285  assert(o<size_t(_sz[dim-1]));
286  for (int d=dim-2;d>=0;d--) {
287  assert(c[d]>=0 && c[d]<_sz[d]);
288  o=o*_sz[d]+c[d];
289  }
290  return o;
291  }
299  size_t offset(int x, int y) const {
300  assert(dim==2);
301  assert(x>=0); assert(x<_sz[0]);
302  assert(y>=0); assert(y<_sz[1]);
303  return x+(size_t)_sz[0]*y;
304  }
312  size_t offset(int x, int y, int z) const {
313  assert(dim==3);
314  assert(x>=0); assert(x<_sz[0]);
315  assert(y>=0); assert(y<_sz[1]);
316  assert(z>=0); assert(z<_sz[2]);
317  return x+_sz[0]*(y+(size_t)_sz[1]*z);
318  }
326  const T& operator() (const Coords<dim>& c) const {
327  return (*this)[offset(c)];
328  }
336  T& operator() (const Coords<dim>& c) { return (*this)[offset(c)]; }
344  const T& operator()(int x, int y) const { return (*this)[offset(x,y)]; }
352  T& operator()(int x, int y) { return (*this)[offset(x,y)]; }
360  const T& operator()(int x, int y, int z) const { return (*this)[offset(x,y,z)]; }
368  T& operator()(int x, int y, int z) { return (*this)[offset(x,y,z)]; }
393  friend void write(std::ostream& out,const MultiArray& A) {
394  write(out,A._sz);
395  out.write((const char*)A.data(),A.totalSize()*sizeof(T));
396  }
405 
406  friend void read(std::istream& in,MultiArray& A) {
407  Coords<dim> sz;
408  read(in,sz);
409  A.setSize(sz);
410  in.read((char*)A.data(),A.totalSize()*sizeof(T));
411  }
421  friend inline std::ostream& operator<<(std::ostream& out,const MultiArray& A) {
422  out<<A.sizes()<<" ";
423  for (size_t i=0;i<A.totalSize();i++) {
424  out<<A[i];
425  if (i<A.totalSize()-1) out<<" ";
426  }
427  return out;
428  }
438  friend inline std::istream& operator>>(std::istream& in,MultiArray& A) {
439  Coords<dim> sz;
440  in>>sz;
441  A.setSize(sz);
442  for (size_t i=0;i<A.totalSize();i++)
443  in>>A[i];
444  return in;
445  }
446  };
447 
448 
450 }
Coordinates.
Definition: Coords.h:16
size_t prod() const
Product of coordinates.
Definition: Coords.h:71
MultiArray(const Coords< dim > &sz)
Constructor (known size).
Definition: MultiArray.h:62
MultiArray(int s0, int s1, int s2)
Constructor (3D shorcut).
Definition: MultiArray.h:79
void setSize(const Coords< dim > &sz)
Change sizes.
Definition: MultiArray.h:146
void setSize(int s0, int s1, int s2)
Change size 3D alias.
Definition: MultiArray.h:167
T & operator()(int x, int y, int z)
Write access 3D alias.
Definition: MultiArray.h:368
size_t stride(int i) const
ith stride.
Definition: MultiArray.h:260
friend std::istream & operator>>(std::istream &in, MultiArray &A)
ASCII read.
Definition: MultiArray.h:438
MultiArray clone() const
Cloning.
Definition: MultiArray.h:191
Array of variable size.
Definition: Array.h:20
Array & operator=(const Array &A)
Assignment.
Definition: Array.h:154
size_t size() const
Size.
Definition: Array.h:194
MultiArray & operator=(const MultiArray &A)
Assignment.
Definition: MultiArray.h:175
Iterator on Coordinates.
Definition: Coords.h:83
const T & operator()(int x, int y) const
Read access 2D alias.
Definition: MultiArray.h:344
MultiArray getSubArray(const Coords< dim > &offset, const Coords< dim > &sz) const
Sub array.
Definition: MultiArray.h:269
MultiArray(const MultiArray &A)
Copy constructor.
Definition: MultiArray.h:123
int size(int i) const
ith size.
Definition: MultiArray.h:225
Coords< dim > sizes() const
Sizes.
Definition: MultiArray.h:211
size_t offset(int x, int y) const
Offset (2D alias).
Definition: MultiArray.h:299
MultiArray(T *ptr, int s0, int s1, bool handleDelete=false)
Constructor (pre-allocated) 2D alias.
Definition: MultiArray.h:103
size_t offset(int x, int y, int z) const
Offset (3D alias).
Definition: MultiArray.h:312
MultiArray()
Empty constructor.
Definition: MultiArray.h:55
size_t totalSize() const
Total Size.
Definition: MultiArray.h:218
size_t offset(const Coords< dim > &c) const
Offset.
Definition: MultiArray.h:283
void setSize(int s0, int s1)
Change size 2D alias.
Definition: MultiArray.h:158
void setSize(size_t size)
Change size.
Definition: Array.h:143
MultiArray(T *ptr, const Coords< dim > &sz, bool handleDelete=false)
Constructor (pre-allocated).
Definition: MultiArray.h:91
T * data()
Data pointer (read/write).
Definition: Array.h:217
const T & operator()(const Coords< dim > &c) const
Read access.
Definition: MultiArray.h:326
CoordsIterator< dim > coordsEnd() const
End coords iterator.
Definition: MultiArray.h:384
bool empty() const
Is empty.
Definition: Array.h:187
FArray< size_t, dim > stride() const
Stride.
Definition: MultiArray.h:253
nD array of variable size.
Definition: MultiArray.h:21
virtual ~MultiArray()
Destructor.
Definition: MultiArray.h:135
MultiArray(T *ptr, int s0, int s1, int s2, bool handleDelete=false)
Constructor (pre-allocated) 3D alias.
Definition: MultiArray.h:116
MultiArray & fill(T x)
Filling.
Definition: MultiArray.h:204
int height() const
Size alias 1.
Definition: MultiArray.h:239
T * iterator
Iterator type.
Definition: MultiArray.h:45
T & operator()(int x, int y)
Write access 2D alias.
Definition: MultiArray.h:352
Array & fill(const T &x)
Filling.
Definition: Array.h:276
MultiArray(const MultiArray< T2, dim > &A)
Constructor (different type).
Definition: MultiArray.h:132
int depth() const
Size alias 2.
Definition: MultiArray.h:246
friend void read(std::istream &in, MultiArray &A)
Binary read.
Definition: MultiArray.h:406
const T & operator()(int x, int y, int z) const
Read access 3D alias.
Definition: MultiArray.h:360
iterator begin()
Begin iterator.
Definition: Array.h:231
Imagine++ namespace.
Definition: Array.h:7
iterator end()
End iterator.
Definition: Array.h:245
friend void write(std::ostream &out, const MultiArray &A)
Binary write.
Definition: MultiArray.h:393
int width() const
Size alias 0.
Definition: MultiArray.h:232
friend std::ostream & operator<<(std::ostream &out, const MultiArray &A)
ASCII write.
Definition: MultiArray.h:421
const T * const_iterator
Const iterator type.
Definition: MultiArray.h:47
CoordsIterator< dim > coordsBegin() const
Begin coords iterator.
Definition: MultiArray.h:376
MultiArray(int s0, int s1)
Constructor (2D shorcut).
Definition: MultiArray.h:70