Array3D.cxx
1 // Copyright (C) 2001-2009 Vivien Mallet
2 // Copyright (C) 2003-2009 Marc DuruflĂ©
3 //
4 // This file is part of the linear-algebra library Seldon,
5 // http://seldon.sourceforge.net/.
6 //
7 // Seldon is free software; you can redistribute it and/or modify it under the
8 // terms of the GNU Lesser General Public License as published by the Free
9 // Software Foundation; either version 2.1 of the License, or (at your option)
10 // any later version.
11 //
12 // Seldon is distributed in the hope that it will be useful, but WITHOUT ANY
13 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
15 // more details.
16 //
17 // You should have received a copy of the GNU Lesser General Public License
18 // along with Seldon. If not, see http://www.gnu.org/licenses/.
19 
20 
21 #ifndef SELDON_FILE_ARRAY3D_CXX
22 
23 #include "Array3D.hxx"
24 
25 namespace Seldon
26 {
27 
28  /****************
29  * CONSTRUCTORS *
30  ****************/
31 
32 
34 
37  template <class T, class Allocator>
39  {
40  length1_ = 0;
41  length2_ = 0;
42  length3_ = 0;
43 
44  length23_ = 0;
45 
46  data_ = NULL;
47  }
48 
49 
51 
56  template <class T, class Allocator>
57  Array3D<T, Allocator>::Array3D(int i, int j, int k)
58  {
59  length1_ = i;
60  length2_ = j;
61  length3_ = k;
62 
63  length23_ = long(length2_) * long(length3_);
64  int nb_elt = long(i)*long(j)*long(k);
65 
66 #ifdef SELDON_CHECK_MEMORY
67  try
68  {
69 #endif
70 
71  data_ = Allocator::allocate(nb_elt, this);
72 
73 #ifdef SELDON_CHECK_MEMORY
74  }
75  catch (...)
76  {
77  length1_ = 0;
78  length2_ = 0;
79  length3_ = 0;
80  length23_ = 0;
81  data_ = NULL;
82  }
83  if (data_ == NULL && i != 0 && j != 0 && k != 0)
84  throw NoMemory("Array3D::Array3D(int, int, int)",
85  string("Unable to allocate memory for an array of size ")
86  + to_str(static_cast<long int>(i)
87  * static_cast<long int>(j)
88  * static_cast<long int>(k)
89  * static_cast<long int>(sizeof(T)))
90  + " bytes (" + to_str(i) + " x " + to_str(j)
91  + " x " + to_str(k) + " elements).");
92 #endif
93 
94  }
95 
96 
98  template <class T, class Allocator>
100  {
101  length1_ = 0;
102  length2_ = 0;
103  length3_ = 0;
104 
105  length23_ = 0;
106 
107  data_ = NULL;
108 
109  Copy(A);
110  }
111 
112 
113  /*********************
114  * MEMORY MANAGEMENT *
115  *********************/
116 
117 
119 
126  template <class T, class Allocator>
127  void Array3D<T, Allocator>::Reallocate(int i, int j, int k)
128  {
129  if (i != length1_ || j != length2_ || k != length3_)
130  {
131  length1_ = i;
132  length2_ = j;
133  length3_ = k;
134 
135  length23_ = long(j) * long(k);
136  int nb_elt = long(i)*long(j)*long(k);
137 
138 #ifdef SELDON_CHECK_MEMORY
139  try
140  {
141 #endif
142 
143  data_ =
144  reinterpret_cast<pointer>(Allocator::reallocate(data_,
145  nb_elt, this));
146 
147 #ifdef SELDON_CHECK_MEMORY
148  }
149  catch (...)
150  {
151  length1_ = 0;
152  length2_ = 0;
153  length3_ = 0;
154  length23_ = 0;
155  data_ = NULL;
156  }
157  if (data_ == NULL && i != 0 && j != 0 && k != 0)
158  throw NoMemory("Array3D::Reallocate(int, int, int)",
159  string("Unable to reallocate memory")
160  + " for an array of size "
161  + to_str(static_cast<long int>(i)
162  * static_cast<long int>(j)
163  * static_cast<long int>(k)
164  * static_cast<long int>(sizeof(T)))
165  + " bytes (" + to_str(i) + " x " + to_str(j)
166  + " x " + to_str(k) + " elements).");
167 #endif
168 
169  }
170  }
171 
172 
175 
191  template <class T, class Allocator>
192  void Array3D<T, Allocator>::SetData(int i, int j, int k,
193  typename Array3D<T, Allocator>
194  ::pointer data)
195  {
196  Clear();
197 
198  length1_ = i;
199  length2_ = j;
200  length3_ = k;
201  length23_ = long(j) * long(k);
202  data_ = data;
203  }
204 
205 
207 
211  template <class T, class Allocator>
213  {
214  length1_ = 0;
215  length2_ = 0;
216  length3_ = 0;
217  length23_ = 0;
218  data_ = NULL;
219  }
220 
221 
223 
227  template <class T, class Allocator>
229  {
230  length1_ = 0;
231  length2_ = 0;
232  length3_ = 0;
233  length23_ = 0;
234 
235 #ifdef SELDON_CHECK_MEMORY
236  try
237  {
238 #endif
239 
240  if (data_ != NULL)
241  {
242  Allocator::deallocate(data_, length1_ * length23_);
243  data_ = NULL;
244  }
245 
246 #ifdef SELDON_CHECK_MEMORY
247  }
248  catch (...)
249  {
250  data_ = NULL;
251  }
252 #endif
253 
254  this->length1_ = 0;
255  this->length2_ = 0;
256  this->length3_ = 0;
257  }
258 
259 
260  /************************
261  * CONVENIENT FUNCTIONS *
262  ************************/
263 
264 
266 
270  template <class T, class Allocator>
272  {
273  return sizeof(*this) + size_t(sizeof(T))*GetDataSize();
274  }
275 
276 
278 
282  template <class T, class Allocator>
284  {
285  Allocator::memoryset(data_, char(0),
286  GetDataSize()*sizeof(value_type));
287  }
288 
289 
291 
295  template <class T, class Allocator>
297  {
298  long taille = this->GetDataSize();
299  for (long i = 0; i < taille; i++)
300  SetComplexReal(i, data_[i]);
301  }
302 
303 
305 
309  template <class T, class Allocator>
310  template <class T0>
311  void Array3D<T, Allocator>::Fill(const T0& x)
312  {
313  long taille = this->GetDataSize();
314  T x_;
315  SetComplexReal(x, x_);
316  for (long i = 0; i < taille; i++)
317  data_[i] = x_;
318  }
319 
320 
322 
325  template <class T, class Allocator>
327  {
328 #ifndef SELDON_WITHOUT_REINIT_RANDOM
329  srand(time(NULL));
330 #endif
331  long taille = this->GetDataSize();
332  for (long i = 0; i < taille; i++)
333  SetComplexReal(rand(), this->data_[i]);
334  }
335 
336 
338 
341  template <class T, class Allocator>
343  {
344  int i, j, k;
345 
346  for (i = 0; i < GetLength1(); i++)
347  {
348  for (j = 0; j < GetLength2(); j++)
349  {
350  for (k = 0; k < GetLength3(); k++)
351  cout << (*this)(i, j, k) << '\t';
352  cout << endl;
353  }
354  cout << endl;
355  }
356  }
357 
358 
359  /**************************
360  * INPUT/OUTPUT FUNCTIONS *
361  **************************/
362 
363 
365 
372  template <class T, class Allocator> void Array3D<T, Allocator>
373  ::Write(string FileName, bool with_size) const
374  {
375  ofstream FileStream;
376  FileStream.open(FileName.c_str(), ofstream::binary);
377 
378 #ifdef SELDON_CHECK_IO
379  // Checks if the file was opened.
380  if (!FileStream.is_open())
381  throw IOError("Array3D::Write(string FileName)",
382  string("Unable to open file \"") + FileName + "\".");
383 #endif
384 
385  Write(FileStream, with_size);
386 
387  FileStream.close();
388  }
389 
390 
392 
399  template <class T, class Allocator> void Array3D<T, Allocator>
400  ::Write(ofstream& FileStream, bool with_size) const
401  {
402 
403 #ifdef SELDON_CHECK_IO
404  // Checks if the stream is ready.
405  if (!FileStream.good())
406  throw IOError("Array3D::Write(ofstream& FileStream)",
407  "Stream is not ready.");
408 #endif
409 
410  if (with_size)
411  {
412  FileStream.write(reinterpret_cast<char*>(const_cast<int*>(&length1_)),
413  sizeof(int));
414  FileStream.write(reinterpret_cast<char*>(const_cast<int*>(&length2_)),
415  sizeof(int));
416  FileStream.write(reinterpret_cast<char*>(const_cast<int*>(&length3_)),
417  sizeof(int));
418  }
419 
420  FileStream.write(reinterpret_cast<char*>(data_),
421  length23_ * length1_ * sizeof(value_type));
422 
423 #ifdef SELDON_CHECK_IO
424  // Checks if data was written.
425  if (!FileStream.good())
426  throw IOError("Array3D::Write(ofstream& FileStream)",
427  string("Output operation failed.")
428  + string(" The output file may have been removed")
429  + " or there is no space left on device.");
430 #endif
431 
432  }
433 
434 
436 
443  template <class T, class Allocator>
444  void Array3D<T, Allocator>::Read(string FileName, bool with_size)
445  {
446  ifstream FileStream;
447  FileStream.open(FileName.c_str(), ifstream::binary);
448 
449 #ifdef SELDON_CHECK_IO
450  // Checks if the file was opened.
451  if (!FileStream.is_open())
452  throw IOError("Array3D::Read(string FileName)",
453  string("Unable to open file \"") + FileName + "\".");
454 #endif
455 
456  Read(FileStream, with_size);
457 
458  FileStream.close();
459  }
460 
461 
463 
470  template <class T, class Allocator>
472  ::Read(ifstream& FileStream, bool with_size)
473  {
474 
475 #ifdef SELDON_CHECK_IO
476  // Checks if the stream is ready.
477  if (!FileStream.good())
478  throw IOError("Matrix_Pointers::Read(ifstream& FileStream)",
479  "Stream is not ready.");
480 #endif
481 
482  if (with_size)
483  {
484  int new_l1, new_l2, new_l3;
485  FileStream.read(reinterpret_cast<char*>(&new_l1), sizeof(int));
486  FileStream.read(reinterpret_cast<char*>(&new_l2), sizeof(int));
487  FileStream.read(reinterpret_cast<char*>(&new_l3), sizeof(int));
488  Reallocate(new_l1, new_l2, new_l3);
489  }
490 
491  FileStream.read(reinterpret_cast<char*>(data_),
492  length23_ * length1_ * sizeof(value_type));
493 
494 #ifdef SELDON_CHECK_IO
495  // Checks if data was read.
496  if (!FileStream.good())
497  throw IOError("Array3D::Read(ifstream& FileStream)",
498  string("Output operation failed.")
499  + string(" The intput file may have been removed")
500  + " or may not contain enough data.");
501 #endif
502 
503  }
504 
505 
507 
512  template <class T, class Allocator>
513  ostream& operator << (ostream& out,
514  const Array3D<T, Allocator>& A)
515  {
516  int i, j, k;
517 
518  for (i = 0; i < A.GetLength1(); i++)
519  {
520  for (j = 0; j < A.GetLength2(); j++)
521  {
522  for (k = 0; k < A.GetLength3(); k++)
523  out << A(i, j, k) << '\t';
524  out << endl;
525  }
526  out << endl;
527  }
528 
529  return out;
530  }
531 
532 
534 
538  template <class T0, class T, class Allocator>
539  void MltScalar(const T0& alpha, Array3D<T, Allocator>& A)
540  {
541  T* data = A.GetData();
542  long taille = A.GetDataSize();
543  for (long i = 0; i < taille; i++)
544  data[i] *= alpha;
545  }
546 
547 } // namespace Seldon.
548 
549 #define SELDON_FILE_ARRAY3D_CXX
550 #endif
Seldon::Array3D::Clear
void Clear()
Clears the array.
Definition: Array3D.cxx:228
Seldon::Array3D::Array3D
Array3D()
Default constructor.
Definition: Array3D.cxx:38
Seldon::Array3D::GetLength2
int GetLength2() const
Returns the length in dimension #2.
Definition: Array3D_Inline.cxx:62
Seldon::MltScalar
void MltScalar(const T0 &alpha, Array3D< T, Allocator > &A)
Multiplication of all elements of a 3D array by a scalar.
Definition: Array3D.cxx:539
Seldon::to_str
std::string to_str(const T &input)
Converts most types to string.
Definition: CommonInline.cxx:137
Seldon::Array3D::SetData
void SetData(int i, int j, int k, pointer data)
Changes the size of the array and sets its data array (low level method).
Definition: Array3D.cxx:192
Seldon::Array3D::Write
void Write(string FileName, bool with_size=true) const
Writes the 3D array in a file.
Definition: Array3D.cxx:373
Seldon::Array3D::GetLength1
int GetLength1() const
Returns the length in dimension #1.
Definition: Array3D_Inline.cxx:51
Seldon::Array3D::GetLength3
int GetLength3() const
Returns the length in dimension #3.
Definition: Array3D_Inline.cxx:73
Seldon::Array3D::Print
void Print() const
Displays the array on the standard output.
Definition: Array3D.cxx:342
Seldon::Array3D::Reallocate
void Reallocate(int i, int j, int k)
Reallocates memory to resize the 3D array.
Definition: Array3D.cxx:127
Seldon::Array3D::GetDataSize
long GetDataSize() const
Returns the number of elements stored in memory.
Definition: Array3D_Inline.cxx:100
Seldon::Array3D::Nullify
void Nullify()
Clears the 3D array without releasing memory.
Definition: Array3D.cxx:212
Seldon::Array3D::Zero
void Zero()
Sets all elements to zero.
Definition: Array3D.cxx:283
Seldon::Array3D::GetData
pointer GetData() const
Returns a pointer to the data array.
Definition: Array3D_Inline.cxx:114
Seldon::Array3D::Fill
void Fill()
Fills the array.
Definition: Array3D.cxx:296
Seldon::Array3D
3D array.
Definition: Array3D.hxx:38
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::Array3D::GetMemorySize
size_t GetMemorySize() const
Returns the memory used by the object in bytes.
Definition: Array3D.cxx:271
Seldon::SetComplexReal
void SetComplexReal(int n, std::complex< T > &number)
Sets a complex number to (n, 0).
Definition: CommonInline.cxx:234
Seldon::Array3D::FillRand
void FillRand()
Fills the 3D array randomly.
Definition: Array3D.cxx:326
Seldon::Array3D::Read
void Read(string FileName, bool with_size=true)
Reads the 3D array from a file.
Definition: Array3D.cxx:444