1 /*
2 
3 Copyright (C) 2007 Lucas K. Wagner
4  extension of Arrays written by Burkhard Militzer
5 
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10 
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15 
16 You should have received a copy of the GNU General Public License along
17 with this program; if not, write to the Free Software Foundation, Inc.,
18 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 
20 */
21 //--------------------------------------------------------------------------
22 // include/Array45.h
23 //
24 //
25 #ifndef ARRAY45_H_INCLUDED
26 #define ARRAY45_H_INCLUDED
27 
28 //This is somewhat hacked.  Use with caution.
29 #include "Array.h"
30 
31 template <class T>
32 class Array4 : public Array <T>
33 {
34 public:
35   int step1, step2, step3;
36   int size;
37   const int rank;
38   int dim[4];
39   T* v;
40 
Array4()41   Array4():step1(0),step2(0),step3(0),size(0),rank(4),v(0)
42   {
43     dim[0]=dim[1]=dim[2]=dim[3]=0;
44   }
45 
~Array4()46   ~Array4()
47   {
48     if (v)
49       delete[] v;
50   }
51 
Array4(int n1,int n2,int n3,int n4)52   Array4(int n1, int n2, int n3, int n4):           // Create without initialization
53       step1(n2*n3*n4),
54       step2(n3*n4),
55       step3(n4),
56       size(n1*step1),
57       rank(4),
58       v(new T[size])
59   {
60     dim[0] = n1;
61     dim[1] = n2;
62     dim[2] = n3;
63     dim[3]=n4;
64   }
65 
Array4(int n1,int n2,int n3,int n4,const T vv)66   Array4(int n1, int n2, int n3, int n4, const T vv):size(0),rank(4),v(0)
67   {    // Create with initialization
68     Resize(n1,n2,n3,n4);
69     for(int i=0;i<size;++i)
70       v[i]=vv;
71   }
72 
operator()73   const T& operator() (int n1, int n2, int n3, int n4) const
74   { // Read element
75     Limits(n1,dim[0]);
76     Limits(n2,dim[1]);
77     Limits(n3,dim[2]);
78     Limits(n4,dim[3]);
79     return v[n1*step1+n2*step2+n3*step3+n4];
80   }
81 
operator()82   T& operator() (int n1, int n2, int n3, int n4)
83   {       // Access element
84     Limits(n1,dim[0]);
85     Limits(n2,dim[1]);
86     Limits(n3,dim[2]);
87     Limits(n4,dim[3]);
88     return v[n1*step1+n2*step2+n3*step3+n4];
89   }
90 
91   /*
92   Array1 <T> operator() (const int n1,const int n2, const int n3)
93   {        // Access 1D sub-array
94     //    cout << "Reference sub-array\n";
95     Limits(n1,dim[0]);
96     Limits(n2,dim[1]);
97     Limits(n3,dim[2]);
98     return Array1 <T> (dim[2],v+n1*step1+n2*step2+n3*step3);
99   };
100 
101   Array2 <T> operator
102   () (const int n1, const int n2)
103   {        // Access 2D sub-array
104     //    cout << "Reference sub-array\n";
105     Limits(n1,dim[0]);
106     Limits(n2,dim[1]);
107     return Array2 <T> (dim[1],dim[2],v+n1*step1);
108   };
109 
110   Array3 <T> operator
111   () (const int n1)
112   {        // Access 3D sub-array
113     //    cout << "Reference sub-array\n";
114     Limits(n1,dim[0]);
115     return Array3 <T> (dim[1],dim[2],dim[3],v+n1*step1);
116   };
117 */
118 
119   /*
120   T* operator() (const int n1, const int n2) {   // Access sub-array
121     Limits(n1,dim[0]); Limits(n2,dim[1]);
122     return v+n1*step1+n2*step2;
123   }
124   */
125 
126   Array4 operator=(const Array4 x)
127   {     // Copy array like 1D
128     Resize(x.dim[0],x.dim[1],x.dim[2],x.dim[3]);
129     for(int i=0;i<size;++i)
130       v[i]=x.v[i];
131     return *this;
132   }
133 
134   Array4 & operator=(const T x)
135   {        // Fill with one element
136     for(int i=0;i<size;++i)
137       v[i]=x;
138     return *this;
139   }
140 
Resize(int n1,int n2,int n3,int n4)141   void Resize(int n1, int n2, int n3, int n4)
142   {
143     int sizen= n1*n2*n3*n4;
144 
145     if (sizen>size)
146     {
147       if (v)
148         delete[] v;
149       size=sizen;
150       v = new T[size];
151     }
152     dim[0] = n1;
153     dim[1] = n2;
154     dim[2] = n3;
155     dim[3]=n4;
156     step3=n4;
157     step2=step3*n3;
158     step1=step2*n2;
159   }
160 
GetDim(const int d)161   virtual int GetDim(const int d) const
162   {
163     Limits(d,rank);
164     return dim[d];
165   }
GetDims()166   virtual int* GetDims() const
167   {
168     return (int*)dim;
169   }
GetRank()170   virtual int GetRank() const
171   {
172     return rank;
173   }
GetSize()174   inline int GetSize() const
175   {
176     return size;
177   }
Size()178   inline int Size() const
179   {
180     return size;
181   }
Read(istream & is)182   virtual void Read(istream& is)
183   {
184     error("Cannot read standard Array4\nNeed specialization of template");
185   }
186 };
187 
188 template <class T>
189 class Array5 : public Array <T>
190 {
191 public:
192   int step1, step2, step3, step4;
193   int size;
194   const int rank;
195   int dim[5];
196   T* v;
197 
Array5()198   Array5():step1(0),step2(0),step3(0),step4(0),size(0),rank(4),v(0)
199   {
200     dim[0]=dim[1]=dim[2]=dim[3]=0;
201   }
202 
~Array5()203   ~Array5()
204   {
205     if (v)
206       delete[] v;
207   }
208 
Array5(int n1,int n2,int n3,int n4,int n5)209   Array5(int n1, int n2, int n3, int n4, int n5):           // Create without initialization
210       step1(n2*n3*n4*n5),
211       step2(n3*n4*n5),
212       step3(n4*n5),
213       step4(n5),
214       size(n1*step1),
215       rank(5),
216       v(new T[size])
217   {
218     dim[0] = n1;
219     dim[1] = n2;
220     dim[2] = n3;
221     dim[3]=n4;
222     dim[4]=n5;
223   }
224 
Array5(int n1,int n2,int n3,int n4,int n5,const T vv)225   Array5(int n1, int n2, int n3, int n4, int n5, const T vv):size(0),rank(5),v(0)
226   {    // Create with initialization
227     Resize(n1,n2,n3,n4,n5);
228     for(int i=0;i<size;++i)
229       v[i]=vv;
230   }
231 
operator()232   const T& operator() (int n1, int n2, int n3, int n4, int n5) const
233   { // Read element
234     Limits(n1,dim[0]);
235     Limits(n2,dim[1]);
236     Limits(n3,dim[2]);
237     Limits(n4,dim[3]);
238     Limits(n5, dim[4]);
239     return v[n1*step1+n2*step2+n3*step3+n4*step4+n5];
240   }
241 
operator()242   T& operator() (int n1, int n2, int n3, int n4, int n5)
243   {       // Access element
244     Limits(n1,dim[0]);
245     Limits(n2,dim[1]);
246     Limits(n3,dim[2]);
247     Limits(n4,dim[3]);
248     Limits(n5, dim[4]);
249     return v[n1*step1+n2*step2+n3*step3+n4*step4+n5];
250   }
251 
operator()252   Array1 <T> operator() (const int n1,const int n2, const int n3, const int n4)
253   {        // Access 1D sub-array
254     //    cout << "Reference sub-array\n";
255     Limits(n1,dim[0]);
256     Limits(n2,dim[1]);
257     Limits(n3,dim[2]);
258     Limits(n4, dim[3]);
259     return Array1 <T> (dim[4],v+n1*step1+n2*step2+n3*step3+n4*step4);
260   };
261 
operator()262   Array2 <T> operator
263   () (const int n1, const int n2, const int n3)
264   {        // Access 2D sub-array
265     //    cout << "Reference sub-array\n";
266     Limits(n1,dim[0]);
267     Limits(n2,dim[1]);
268     Limits(n3,dim[2]);
269     return Array2 <T> (dim[3],dim[4],v+n1*step1+n2*step2+n3*step3);
270   };
271 
operator()272   Array3 <T>  operator() (const int n1, const int n2)
273   {
274     Limits(n1, dim[0]);
275     Limits(n2, dim[1]);
276     return Array3 <T> (dim[2], dim[3], dim[4], v+n1*step1+n2*step2);
277   }
278 
279   /*
280   T* operator() (const int n1, const int n2) {   // Access sub-array
281     Limits(n1,dim[0]); Limits(n2,dim[1]);
282     return v+n1*step1+n2*step2;
283   }
284   */
285 
286   Array5 operator=(const Array5 x)
287   {     // Copy array like 1D
288     Resize(x.dim[0],x.dim[1],x.dim[2],x.dim[3], x.dim[4]);
289     for(int i=0;i<size;++i)
290       v[i]=x.v[i];
291     return *this;
292   }
293 
294   Array5 & operator=(const T x)
295   {        // Fill with one element
296     for(int i=0;i<size;++i)
297       v[i]=x;
298     return *this;
299   }
300 
Resize(int n1,int n2,int n3,int n4,int n5)301   void Resize(int n1, int n2, int n3, int n4, int n5)
302   {
303     int sizen= n1*n2*n3*n4*n5;
304     //    cout << "Resize dd " << sizen << " " << size << endl;
305     if (sizen>size)
306     {
307       if (v)
308         delete[] v;
309       size=sizen;
310       v = new T[size];
311     }
312     dim[0] = n1;
313     dim[1] = n2;
314     dim[2] = n3;
315     dim[3]=n4;
316     dim[4]=n5;
317     step4=n5;
318     step3=step4*n4;
319     step2=step3*n3;
320     step1 = step2*n2;
321   }
322 
GetDim(const int d)323   virtual int GetDim(const int d) const
324   {
325     Limits(d,rank);
326     return dim[d];
327   }
GetDims()328   virtual int* GetDims() const
329   {
330     return (int*)dim;
331   }
GetRank()332   virtual int GetRank() const
333   {
334     return rank;
335   }
GetSize()336   virtual int GetSize() const
337   {
338     return size;
339   }
Size()340   inline int Size() const
341   {
342     return size;
343   }
Read(istream & is)344   virtual void Read(istream& is)
345   {
346     error("Cannot read standard Array5\nNeed specialization of template");
347   }
348 };
349 
350 
351 #endif // ARRAY45_H_INCLUDED
352 //--------------------------------------------------------------------------
353