Array4D.cxx
1 // Copyright (C) 2010 Lin Wu
2 // Copyright (C) 2001-2009 Vivien Mallet
3 // Copyright (C) 2003-2009 Marc DuruflĂ©
4 //
5 // This file is part of the linear-algebra library Seldon,
6 // http://seldon.sourceforge.net/.
7 //
8 // Seldon is free software; you can redistribute it and/or modify it under the
9 // terms of the GNU Lesser General Public License as published by the Free
10 // Software Foundation; either version 2.1 of the License, or (at your option)
11 // any later version.
12 //
13 // Seldon is distributed in the hope that it will be useful, but WITHOUT ANY
14 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
16 // more details.
17 //
18 // You should have received a copy of the GNU Lesser General Public License
19 // along with Seldon. If not, see http://www.gnu.org/licenses/.
20 
21 
22 #ifndef SELDON_FILE_ARRAY4D_CXX
23 
24 #include "Array4D.hxx"
25 
26 namespace Seldon
27 {
28 
29  /****************
30  * CONSTRUCTORS *
31  ****************/
32 
33 
35 
38  template <class T, class Allocator>
40  {
41  length1_ = 0;
42  length2_ = 0;
43  length3_ = 0;
44  length4_ = 0;
45 
46  length34_ = 0;
47  length234_ = 0;
48 
49  data_ = NULL;
50  }
51 
52 
54 
60  template <class T, class Allocator>
61  Array4D<T, Allocator>::Array4D(int i, int j, int k, int l)
62  {
63  length1_ = i;
64  length2_ = j;
65  length3_ = k;
66  length4_ = l;
67 
68  length34_ = long(length3_) * long(length4_);
69  length234_ = long(length2_) * long(length3_) * long(length4_);
70  int nb_elt = long(i) * long(j) * long(k) * long(l);
71 
72 #ifdef SELDON_CHECK_MEMORY
73  try
74  {
75 #endif
76 
77  data_ = Allocator::allocate(nb_elt, this);
78 
79 #ifdef SELDON_CHECK_MEMORY
80  }
81  catch (...)
82  {
83  length1_ = 0;
84  length2_ = 0;
85  length3_ = 0;
86  length4_ = 0;
87  length34_ = 0;
88  length234_ = 0;
89  data_ = NULL;
90  }
91  if (data_ == NULL && i != 0 && j != 0 && k != 0 && l != 0)
92  throw NoMemory("Array4D::Array4D(int, int, int, int)",
93  string("Unable to allocate memory for an array of size ")
94  + to_str(static_cast<long int>(i)
95  * static_cast<long int>(j)
96  * static_cast<long int>(k)
97  * static_cast<long int>(l)
98  * static_cast<long int>(sizeof(T)))
99  + " bytes (" + to_str(i) + " x " + to_str(j)
100  + " x " + to_str(k) + " x " + to_str(l) + " elements).");
101 #endif
102 
103  }
104 
105 
107  template <class T, class Allocator>
109  {
110  length1_ = 0;
111  length2_ = 0;
112  length3_ = 0;
113  length4_ = 0;
114 
115  length34_ = 0;
116  length234_ = 0;
117 
118  data_ = NULL;
119 
120  Copy(A);
121  }
122 
123 
124  /*********************
125  * MEMORY MANAGEMENT *
126  *********************/
127 
128 
130 
138  template <class T, class Allocator>
139  void Array4D<T, Allocator>::Reallocate(int i, int j, int k, int l)
140  {
141  if (i != length1_ || j != length2_ || k != length3_ || l != length4_)
142  {
143  length1_ = i;
144  length2_ = j;
145  length3_ = k;
146  length4_ = l;
147 
148  length34_ = long(k) * long(l);
149  length234_ = long(j) * long(k) * long(l);
150  int nb_elt = long(i) * long(j) * long(k) * long(l);
151 
152 #ifdef SELDON_CHECK_MEMORY
153  try
154  {
155 #endif
156 
157  data_ =
158  reinterpret_cast<pointer>(Allocator::reallocate(data_,
159  nb_elt, this));
160 
161 #ifdef SELDON_CHECK_MEMORY
162  }
163  catch (...)
164  {
165  length1_ = 0;
166  length2_ = 0;
167  length3_ = 0;
168  length4_ = 0;
169  length34_ = 0;
170  length234_ = 0;
171  data_ = NULL;
172  }
173  if (data_ == NULL && i != 0 && j != 0 && k != 0 && l != 0)
174  throw NoMemory("Array4D::Reallocate(int, int, int, int)",
175  string("Unable to reallocate memory")
176  + " for an array of size "
177  + to_str(static_cast<long int>(i)
178  * static_cast<long int>(j)
179  * static_cast<long int>(k)
180  * static_cast<long int>(l)
181  * static_cast<long int>(sizeof(T)))
182  + " bytes (" + to_str(i) + " x " + to_str(j) + " x "
183  + to_str(k) + " x " + to_str(l) + " elements).");
184 #endif
185 
186  }
187  }
188 
189 
191 
195  template <class T, class Allocator>
197  {
198  length1_ = 0;
199  length2_ = 0;
200  length3_ = 0;
201  length4_ = 0;
202  length34_ = 0;
203  length234_ = 0;
204 
205 #ifdef SELDON_CHECK_MEMORY
206  try
207  {
208 #endif
209 
210  if (data_ != NULL)
211  {
212  Allocator::deallocate(data_, length1_ * length234_);
213  data_ = NULL;
214  }
215 
216 #ifdef SELDON_CHECK_MEMORY
217  }
218  catch (...)
219  {
220  data_ = NULL;
221  }
222 #endif
223 
224  this->length1_ = 0;
225  this->length2_ = 0;
226  this->length3_ = 0;
227  this->length4_ = 0;
228  }
229 
230 
231  /************************
232  * CONVENIENT FUNCTIONS *
233  ************************/
234 
235 
237 
241  template <class T, class Allocator>
243  {
244  return sizeof(*this) + size_t(sizeof(T))*GetDataSize();
245  }
246 
247 
249 
253  template <class T, class Allocator>
255  {
256  Allocator::memoryset(data_, char(0),
257  GetDataSize()*sizeof(value_type));
258  }
259 
260 
262 
266  template <class T, class Allocator>
268  {
269  long taille = this->GetDataSize();
270  for (long i = 0; i < taille; i++)
271  SetComplexReal(i, data_[i]);
272  }
273 
274 
276 
280  template <class T, class Allocator>
281  template <class T0>
282  void Array4D<T, Allocator>::Fill(const T0& x)
283  {
284  T x_; long taille = this->GetDataSize();
285  SetComplexReal(x, x_);
286  for (long i = 0; i < taille; i++)
287  data_[i] = x_;
288  }
289 
290 
292 
295  template <class T, class Allocator>
297  {
298 #ifndef SELDON_WITHOUT_REINIT_RANDOM
299  srand(time(NULL));
300 #endif
301  long taille = this->GetDataSize();
302  for (long i = 0; i < taille; i++)
303  SetComplexReal(rand(), this->data_[i]);
304  }
305 
306 
308 
311  template <class T, class Allocator>
313  {
314  int i, j, k, l;
315 
316  for (i = 0; i < GetLength1(); i++)
317  {
318  for (j = 0; j < GetLength2(); j++)
319  {
320  for (k = 0; k < GetLength3(); k++)
321  {
322  for (l = 0; l < GetLength4(); l++)
323  cout << (*this)(i, j, k, l) << '\t';
324  cout << endl;
325  }
326  cout << endl;
327  }
328  cout << endl;
329  }
330  }
331 
332 
333  /**************************
334  * INPUT/OUTPUT FUNCTIONS *
335  **************************/
336 
337 
339 
346  template <class T, class Allocator> void Array4D<T, Allocator>
347  ::Write(string FileName, bool with_size) const
348  {
349  ofstream FileStream;
350  FileStream.open(FileName.c_str(), ofstream::binary);
351 
352 #ifdef SELDON_CHECK_IO
353  // Checks if the file was opened.
354  if (!FileStream.is_open())
355  throw IOError("Array4D::Write(string FileName)",
356  string("Unable to open file \"") + FileName + "\".");
357 #endif
358 
359  Write(FileStream, with_size);
360 
361  FileStream.close();
362  }
363 
364 
366 
373  template <class T, class Allocator> void Array4D<T, Allocator>
374  ::Write(ofstream& FileStream, bool with_size) const
375  {
376 
377 #ifdef SELDON_CHECK_IO
378  // Checks if the stream is ready.
379  if (!FileStream.good())
380  throw IOError("Array4D::Write(ofstream& FileStream)",
381  "Stream is not ready.");
382 #endif
383 
384  if (with_size)
385  {
386  FileStream.write(reinterpret_cast<char*>(const_cast<int*>(&length1_)),
387  sizeof(int));
388  FileStream.write(reinterpret_cast<char*>(const_cast<int*>(&length2_)),
389  sizeof(int));
390  FileStream.write(reinterpret_cast<char*>(const_cast<int*>(&length3_)),
391  sizeof(int));
392  FileStream.write(reinterpret_cast<char*>(const_cast<int*>(&length4_)),
393  sizeof(int));
394  }
395 
396  FileStream.write(reinterpret_cast<char*>(data_),
397  length234_ * length1_ * sizeof(value_type));
398 
399 #ifdef SELDON_CHECK_IO
400  // Checks if data was written.
401  if (!FileStream.good())
402  throw IOError("Array4D::Write(ofstream& FileStream)",
403  string("Output operation failed.")
404  + string(" The output file may have been removed")
405  + " or there is no space left on device.");
406 #endif
407 
408  }
409 
410 
412 
419  template <class T, class Allocator>
420  void Array4D<T, Allocator>::Read(string FileName, bool with_size)
421  {
422  ifstream FileStream;
423  FileStream.open(FileName.c_str(), ifstream::binary);
424 
425 #ifdef SELDON_CHECK_IO
426  // Checks if the file was opened.
427  if (!FileStream.is_open())
428  throw IOError("Array4D::Read(string FileName)",
429  string("Unable to open file \"") + FileName + "\".");
430 #endif
431 
432  Read(FileStream, with_size);
433 
434  FileStream.close();
435  }
436 
437 
439 
446  template <class T, class Allocator>
448  ::Read(ifstream& FileStream, bool with_size)
449  {
450 
451 #ifdef SELDON_CHECK_IO
452  // Checks if the stream is ready.
453  if (!FileStream.good())
454  throw IOError("Matrix_Pointers::Read(ifstream& FileStream)",
455  "Stream is not ready.");
456 #endif
457 
458  if (with_size)
459  {
460  int new_l1, new_l2, new_l3, new_l4;
461  FileStream.read(reinterpret_cast<char*>(&new_l1), sizeof(int));
462  FileStream.read(reinterpret_cast<char*>(&new_l2), sizeof(int));
463  FileStream.read(reinterpret_cast<char*>(&new_l3), sizeof(int));
464  FileStream.read(reinterpret_cast<char*>(&new_l4), sizeof(int));
465  Reallocate(new_l1, new_l2, new_l3, new_l4);
466  }
467 
468  FileStream.read(reinterpret_cast<char*>(data_),
469  length234_ * length1_ * sizeof(value_type));
470 
471 #ifdef SELDON_CHECK_IO
472  // Checks if data was read.
473  if (!FileStream.good())
474  throw IOError("Array4D::Read(ifstream& FileStream)",
475  string("Output operation failed.")
476  + string(" The intput file may have been removed")
477  + " or may not contain enough data.");
478 #endif
479 
480  }
481 
482 
484 
489  template <class T, class Allocator>
490  ostream& operator << (ostream& out,
491  const Array4D<T, Allocator>& A)
492  {
493  int i, j, k, l;
494 
495  for (i = 0; i < A.GetLength1(); i++)
496  {
497  for (j = 0; j < A.GetLength2(); j++)
498  {
499  for (k = 0; k < A.GetLength3(); k++)
500  {
501  for (l = 0; l < A.GetLength4(); l++)
502  out << A(i, j, k, l) << '\t';
503  out << endl;
504  }
505  out << endl;
506  }
507  out << endl;
508  }
509 
510  return out;
511  }
512 
513 } // namespace Seldon.
514 
515 #define SELDON_FILE_ARRAY4D_CXX
516 #endif
Seldon::Array4D::Zero
void Zero()
Sets all elements to zero.
Definition: Array4D.cxx:254
Seldon::Array4D::Array4D
Array4D()
Default constructor.
Definition: Array4D.cxx:39
Seldon::to_str
std::string to_str(const T &input)
Converts most types to string.
Definition: CommonInline.cxx:137
Seldon::Array4D::GetLength3
int GetLength3() const
Returns the length in dimension #3.
Definition: Array4D_Inline.cxx:74
Seldon::Array4D::GetLength1
int GetLength1() const
Returns the length in dimension #1.
Definition: Array4D_Inline.cxx:52
Seldon::Array4D::Print
void Print() const
Displays the array on the standard output.
Definition: Array4D.cxx:312
Seldon::Array4D::Reallocate
void Reallocate(int i, int j, int k, int l)
Reallocates memory to resize the 4D array.
Definition: Array4D.cxx:139
Seldon::Array4D::Fill
void Fill()
Fills the array.
Definition: Array4D.cxx:267
Seldon::Array4D::GetMemorySize
size_t GetMemorySize() const
Returns the memory used by the object in bytes.
Definition: Array4D.cxx:242
Seldon::Array4D::GetLength4
int GetLength4() const
Returns the length in dimension #4.
Definition: Array4D_Inline.cxx:85
Seldon::Array4D::GetLength2
int GetLength2() const
Returns the length in dimension #2.
Definition: Array4D_Inline.cxx:63
Seldon::Array4D
4D array.
Definition: Array4D.hxx:39
Seldon::Array4D::Write
void Write(string FileName, bool with_size=true) const
Writes the 4D array in a file.
Definition: Array4D.cxx:347
Seldon::Array4D::Read
void Read(string FileName, bool with_size=true)
Reads the 4D array from a file.
Definition: Array4D.cxx:420
Seldon
Seldon namespace.
Definition: Array.cxx:24
Seldon::operator<<
ostream & operator<<(ostream &out, const Array< T, N, Allocator > &A)
operator<< overloaded for a 3D array.
Definition: Array.cxx:1617
Seldon::IOError
Definition: Errors.hxx:150
Seldon::NoMemory
Definition: Errors.hxx:90
Seldon::Array4D::Clear
void Clear()
Clears the array.
Definition: Array4D.cxx:196
Seldon::Array4D::FillRand
void FillRand()
Fills the 4D array randomly.
Definition: Array4D.cxx:296
Seldon::SetComplexReal
void SetComplexReal(int n, std::complex< T > &number)
Sets a complex number to (n, 0).
Definition: CommonInline.cxx:234