00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef SELDON_FILE_ARRAY3D_CXX
00022
00023 #include "Array3D.hxx"
00024
00025 namespace Seldon
00026 {
00027
00028
00029
00030
00031
00032
00033
00035
00038 template <class T, class Allocator>
00039 inline Array3D<T, Allocator>::Array3D()
00040 {
00041 length1_ = 0;
00042 length2_ = 0;
00043 length3_ = 0;
00044
00045 length23_ = 0;
00046
00047 data_ = NULL;
00048 }
00049
00050
00052
00057 template <class T, class Allocator>
00058 inline Array3D<T, Allocator>::Array3D(int i, int j, int k)
00059 {
00060 length1_ = i;
00061 length2_ = j;
00062 length3_ = k;
00063
00064 length23_ = length2_ * length3_;
00065
00066 #ifdef SELDON_CHECK_MEMORY
00067 try
00068 {
00069 #endif
00070
00071 data_ = array3D_allocator_.allocate(i*j*k, this);
00072
00073 #ifdef SELDON_CHECK_MEMORY
00074 }
00075 catch (...)
00076 {
00077 length1_ = 0;
00078 length2_ = 0;
00079 length3_ = 0;
00080 length23_ = 0;
00081 data_ = NULL;
00082 }
00083 if (data_ == NULL && i != 0 && j != 0 && k != 0)
00084 throw NoMemory("Array3D::Array3D(int, int, int)",
00085 string("Unable to allocate memory for an array of size ")
00086 + to_str(static_cast<long int>(i)
00087 * static_cast<long int>(j)
00088 * static_cast<long int>(k)
00089 * static_cast<long int>(sizeof(T)))
00090 + " bytes (" + to_str(i) + " x " + to_str(j)
00091 + " x " + to_str(k) + " elements).");
00092 #endif
00093
00094 }
00095
00096
00098 template <class T, class Allocator>
00099 Array3D<T, Allocator>::Array3D(const Array3D<T, Allocator>& A)
00100 {
00101 length1_ = 0;
00102 length2_ = 0;
00103 length3_ = 0;
00104
00105 length23_ = 0;
00106
00107 data_ = NULL;
00108
00109 Copy(A);
00110 }
00111
00112
00113
00114
00115
00116
00117
00119 template <class T, class Allocator>
00120 inline Array3D<T, Allocator>::~Array3D()
00121 {
00122 length1_ = 0;
00123 length2_ = 0;
00124 length3_ = 0;
00125 length23_ = 0;
00126
00127 #ifdef SELDON_CHECK_MEMORY
00128 try
00129 {
00130 #endif
00131
00132 if (data_ != NULL)
00133 {
00134 array3D_allocator_.deallocate(data_, length1_ * length23_);
00135 data_ = NULL;
00136 }
00137
00138 #ifdef SELDON_CHECK_MEMORY
00139 }
00140 catch (...)
00141 {
00142 data_ = NULL;
00143 }
00144 #endif
00145
00146 }
00147
00148
00149
00150
00151
00152
00153
00155
00162 template <class T, class Allocator>
00163 inline void Array3D<T, Allocator>::Reallocate(int i, int j, int k)
00164 {
00165 if (i != length1_ || j != length2_ || k != length3_)
00166 {
00167 length1_ = i;
00168 length2_ = j;
00169 length3_ = k;
00170
00171 length23_ = j * k;
00172
00173 #ifdef SELDON_CHECK_MEMORY
00174 try
00175 {
00176 #endif
00177
00178 data_ =
00179 reinterpret_cast<pointer>(array3D_allocator_.reallocate(data_,
00180 i*j*k,
00181 this));
00182
00183 #ifdef SELDON_CHECK_MEMORY
00184 }
00185 catch (...)
00186 {
00187 length1_ = 0;
00188 length2_ = 0;
00189 length3_ = 0;
00190 length23_ = 0;
00191 data_ = NULL;
00192 }
00193 if (data_ == NULL && i != 0 && j != 0 && k != 0)
00194 throw NoMemory("Array3D::Reallocate(int, int, int)",
00195 string("Unable to reallocate memory")
00196 + " for an array of size "
00197 + to_str(static_cast<long int>(i)
00198 * static_cast<long int>(j)
00199 * static_cast<long int>(k)
00200 * static_cast<long int>(sizeof(T)))
00201 + " bytes (" + to_str(i) + " x " + to_str(j)
00202 + " x " + to_str(k) + " elements).");
00203 #endif
00204
00205 }
00206 }
00207
00208
00210
00214 template <class T, class Allocator>
00215 inline void Array3D<T, Allocator>::Clear()
00216 {
00217 this->~Array3D();
00218 this->length1_ = 0;
00219 this->length2_ = 0;
00220 this->length3_ = 0;
00221 }
00222
00223
00224
00225
00226
00227
00228
00230
00233 template <class T, class Allocator>
00234 int Array3D<T, Allocator>::GetLength1() const
00235 {
00236 return length1_;
00237 }
00238
00239
00241
00244 template <class T, class Allocator>
00245 int Array3D<T, Allocator>::GetLength2() const
00246 {
00247 return length2_;
00248 }
00249
00250
00252
00255 template <class T, class Allocator>
00256 int Array3D<T, Allocator>::GetLength3() const
00257 {
00258 return length3_;
00259 }
00260
00261
00263
00268 template <class T, class Allocator>
00269 int Array3D<T, Allocator>::GetSize() const
00270 {
00271 return length1_ * length23_;
00272 }
00273
00274
00276
00282 template <class T, class Allocator>
00283 int Array3D<T, Allocator>::GetDataSize() const
00284 {
00285 return length1_ * length23_;
00286 }
00287
00288
00290
00295 template <class T, class Allocator>
00296 typename Array3D<T, Allocator>::pointer Array3D<T, Allocator>
00297 ::GetData() const
00298 {
00299 return data_;
00300 }
00301
00302
00303
00304
00305
00306
00307
00309
00316 template <class T, class Allocator>
00317 inline typename Array3D<T, Allocator>::reference
00318 Array3D<T, Allocator>::operator() (int i, int j, int k)
00319 {
00320
00321 #ifdef SELDON_CHECK_BOUNDS
00322 if (i < 0 || i >= length1_)
00323 throw WrongIndex("Array3D::operator()",
00324 string("Index along dimension #1 should be in [0, ")
00325 + to_str(length1_-1) + "], but is equal to "
00326 + to_str(i) + ".");
00327 if (j < 0 || j >= length2_)
00328 throw WrongIndex("Array3D::operator()",
00329 string("Index along dimension #2 should be in [0, ")
00330 + to_str(length2_-1) + "], but is equal to "
00331 + to_str(j) + ".");
00332 if (k < 0 || k >= length3_)
00333 throw WrongIndex("Array3D::operator()",
00334 string("Index along dimension #3 should be in [0, ")
00335 + to_str(length3_-1) + "], but is equal to "
00336 + to_str(k) + ".");
00337 #endif
00338
00339 return data_[i * length23_ + j * length3_ + k];
00340 }
00341
00342
00344
00351 template <class T, class Allocator>
00352 inline typename Array3D<T, Allocator>::const_reference
00353 Array3D<T, Allocator>::operator() (int i, int j, int k) const
00354 {
00355
00356 #ifdef SELDON_CHECK_BOUNDS
00357 if (i < 0 || i >= length1_)
00358 throw WrongIndex("Array3D::operator()",
00359 string("Index along dimension #1 should be in [0, ")
00360 + to_str(length1_-1) + "], but is equal to "
00361 + to_str(i) + ".");
00362 if (j < 0 || j >= length2_)
00363 throw WrongIndex("Array3D::operator()",
00364 string("Index along dimension #2 should be in [0, ")
00365 + to_str(length2_-1) + "], but is equal to "
00366 + to_str(j) + ".");
00367 if (k < 0 || k >= length3_)
00368 throw WrongIndex("Array3D::operator()",
00369 string("Index along dimension #3 should be in [0, ")
00370 + to_str(length3_-1) + "], but is equal to "
00371 + to_str(k) + ".");
00372 #endif
00373
00374 return data_[i*length23_ + j*length3_ + k];
00375 }
00376
00378
00383 template <class T, class Allocator>
00384 inline Array3D<T, Allocator>& Array3D<T, Allocator>::operator=
00385 (const Array3D<T, Allocator>& A)
00386 {
00387 Copy(A);
00388
00389 return *this;
00390 }
00391
00393
00398 template <class T, class Allocator>
00399 inline void Array3D<T, Allocator>::Copy(const Array3D<T, Allocator>& A)
00400 {
00401 Reallocate(A.GetLength1(), A.GetLength2(), A.GetLength3());
00402
00403 array3D_allocator_.memorycpy(data_, A.GetData(), GetDataSize());
00404 }
00405
00406
00407
00408
00409
00410
00411
00413
00417 template <class T, class Allocator>
00418 void Array3D<T, Allocator>::Zero()
00419 {
00420 array3D_allocator_.memoryset(data_, char(0),
00421 GetDataSize()*sizeof(value_type));
00422 }
00423
00424
00426
00430 template <class T, class Allocator>
00431 void Array3D<T, Allocator>::Fill()
00432 {
00433 for (int i = 0; i < GetDataSize(); i++)
00434 data_[i] = i;
00435 }
00436
00437
00439
00443 template <class T, class Allocator>
00444 template <class T0>
00445 void Array3D<T, Allocator>::Fill(const T0& x)
00446 {
00447 for (int i = 0; i < GetDataSize(); i++)
00448 data_[i] = x;
00449 }
00450
00451
00453
00456 template <class T, class Allocator>
00457 void Array3D<T, Allocator>::FillRand()
00458 {
00459 srand(time(NULL));
00460 for (int i = 0; i < GetDataSize(); i++)
00461 data_[i] = rand();
00462 }
00463
00464
00466
00469 template <class T, class Allocator>
00470 void Array3D<T, Allocator>::Print() const
00471 {
00472 int i, j, k;
00473
00474 for (i = 0; i < GetLength1(); i++)
00475 {
00476 for (j = 0; j < GetLength2(); j++)
00477 {
00478 for (k = 0; k < GetLength3(); k++)
00479 cout << (*this)(i, j, k) << '\t';
00480 cout << endl;
00481 }
00482 cout << endl;
00483 }
00484 }
00485
00486
00487
00488
00489
00490
00491
00493
00500 template <class T, class Allocator> void Array3D<T, Allocator>
00501 ::Write(string FileName) const
00502 {
00503 ofstream FileStream;
00504 FileStream.open(FileName.c_str(), ofstream::binary);
00505
00506 #ifdef SELDON_CHECK_IO
00507
00508 if (!FileStream.is_open())
00509 throw IOError("Array3D::Write(string FileName)",
00510 string("Unable to open file \"") + FileName + "\".");
00511 #endif
00512
00513 Write(FileStream);
00514
00515 FileStream.close();
00516 }
00517
00518
00520
00527 template <class T, class Allocator> void Array3D<T, Allocator>
00528 ::Write(ofstream& FileStream) const
00529 {
00530
00531 #ifdef SELDON_CHECK_IO
00532
00533 if (!FileStream.good())
00534 throw IOError("Array3D::Write(ofstream& FileStream)",
00535 "Stream is not ready.");
00536 #endif
00537
00538 FileStream.write(reinterpret_cast<char*>(const_cast<int*>(&length1_)),
00539 sizeof(int));
00540 FileStream.write(reinterpret_cast<char*>(const_cast<int*>(&length2_)),
00541 sizeof(int));
00542 FileStream.write(reinterpret_cast<char*>(const_cast<int*>(&length3_)),
00543 sizeof(int));
00544
00545 FileStream.write(reinterpret_cast<char*>(data_),
00546 length23_ * length1_ * sizeof(value_type));
00547
00548 #ifdef SELDON_CHECK_IO
00549
00550 if (!FileStream.good())
00551 throw IOError("Array3D::Write(ofstream& FileStream)",
00552 string("Output operation failed.")
00553 + string(" The output file may have been removed")
00554 + " or there is no space left on device.");
00555 #endif
00556
00557 }
00558
00559
00561
00568 template <class T, class Allocator>
00569 void Array3D<T, Allocator>::Read(string FileName)
00570 {
00571 ifstream FileStream;
00572 FileStream.open(FileName.c_str(), ifstream::binary);
00573
00574 #ifdef SELDON_CHECK_IO
00575
00576 if (!FileStream.is_open())
00577 throw IOError("Array3D::Read(string FileName)",
00578 string("Unable to open file \"") + FileName + "\".");
00579 #endif
00580
00581 Read(FileStream);
00582
00583 FileStream.close();
00584 }
00585
00586
00588
00595 template <class T, class Allocator>
00596 void Array3D<T, Allocator>
00597 ::Read(ifstream& FileStream)
00598 {
00599
00600 #ifdef SELDON_CHECK_IO
00601
00602 if (!FileStream.good())
00603 throw IOError("Matrix_Pointers::Read(ifstream& FileStream)",
00604 "Stream is not ready.");
00605 #endif
00606
00607 int new_l1, new_l2, new_l3;
00608 FileStream.read(reinterpret_cast<char*>(&new_l1), sizeof(int));
00609 FileStream.read(reinterpret_cast<char*>(&new_l2), sizeof(int));
00610 FileStream.read(reinterpret_cast<char*>(&new_l3), sizeof(int));
00611 Reallocate(new_l1, new_l2, new_l3);
00612
00613 FileStream.read(reinterpret_cast<char*>(data_),
00614 length23_ * length1_ * sizeof(value_type));
00615
00616 #ifdef SELDON_CHECK_IO
00617
00618 if (!FileStream.good())
00619 throw IOError("Array3D::Read(ifstream& FileStream)",
00620 string("Input operation failed.")
00621 + string(" The input file may have been removed")
00622 + " or may not contain enough data.");
00623 #endif
00624
00625 }
00626
00627
00629
00634 template <class T, class Allocator>
00635 ostream& operator << (ostream& out,
00636 const Array3D<T, Allocator>& A)
00637 {
00638 int i, j, k;
00639
00640 for (i = 0; i < A.GetLength1(); i++)
00641 {
00642 for (j = 0; j < A.GetLength2(); j++)
00643 {
00644 for (k = 0; k < A.GetLength3(); k++)
00645 out << A(i, j, k) << '\t';
00646 out << endl;
00647 }
00648 out << endl;
00649 }
00650
00651 return out;
00652 }
00653
00654
00656
00660 template <class T0, class T, class Allocator>
00661 void Mlt(const T0& alpha, Array3D<T, Allocator>& A)
00662 {
00663 T* data = A.GetData();
00664 for (int i = 0; i < A.GetDataSize(); i++)
00665 data[i] *= alpha;
00666 }
00667
00668
00669 }
00670
00671 #define SELDON_FILE_ARRAY3D_CXX
00672 #endif