Warning: this documentation for the development version is under construction.
00001 // Copyright (C) 2001-2009 Vivien Mallet 00002 // Copyright (C) 2003-2009 Marc Duruflé 00003 // 00004 // This file is part of the linear-algebra library Seldon, 00005 // http://seldon.sourceforge.net/. 00006 // 00007 // Seldon is free software; you can redistribute it and/or modify it under the 00008 // terms of the GNU Lesser General Public License as published by the Free 00009 // Software Foundation; either version 2.1 of the License, or (at your option) 00010 // any later version. 00011 // 00012 // Seldon is distributed in the hope that it will be useful, but WITHOUT ANY 00013 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 00014 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for 00015 // more details. 00016 // 00017 // You should have received a copy of the GNU Lesser General Public License 00018 // along with Seldon. If not, see http://www.gnu.org/licenses/. 00019 00020 00021 #ifndef SELDON_FILE_MATRIX_POINTERS_CXX 00022 00023 #include "Matrix_Pointers.hxx" 00024 00025 namespace Seldon 00026 { 00027 00028 00029 /**************** 00030 * CONSTRUCTORS * 00031 ****************/ 00032 00033 00035 00038 template <class T, class Prop, class Storage, class Allocator> 00039 inline Matrix_Pointers<T, Prop, Storage, Allocator>::Matrix_Pointers(): 00040 Matrix_Base<T, Allocator>() 00041 { 00042 me_ = NULL; 00043 } 00044 00045 00047 00051 template <class T, class Prop, class Storage, class Allocator> 00052 inline Matrix_Pointers<T, Prop, Storage, Allocator> 00053 ::Matrix_Pointers(int i, int j): Matrix_Base<T, Allocator>(i, j) 00054 { 00055 00056 #ifdef SELDON_CHECK_MEMORY 00057 try 00058 { 00059 #endif 00060 00061 me_ = reinterpret_cast<pointer*>( calloc(Storage::GetFirst(i, j), 00062 sizeof(pointer)) ); 00063 00064 #ifdef SELDON_CHECK_MEMORY 00065 } 00066 catch (...) 00067 { 00068 this->m_ = 0; 00069 this->n_ = 0; 00070 me_ = NULL; 00071 this->data_ = NULL; 00072 } 00073 if (me_ == NULL && i != 0 && j != 0) 00074 throw NoMemory("Matrix_Pointers::Matrix_Pointers(int, int)", 00075 string("Unable to allocate memory for a matrix of size ") 00076 + to_str(static_cast<long int>(i) 00077 * static_cast<long int>(j) 00078 * static_cast<long int>(sizeof(T))) 00079 + " bytes (" + to_str(i) + " x " + to_str(j) 00080 + " elements)."); 00081 #endif 00082 00083 #ifdef SELDON_CHECK_MEMORY 00084 try 00085 { 00086 #endif 00087 00088 this->data_ = this->allocator_.allocate(i * j, this); 00089 00090 #ifdef SELDON_CHECK_MEMORY 00091 } 00092 catch (...) 00093 { 00094 this->m_ = 0; 00095 this->n_ = 0; 00096 free(me_); 00097 me_ = NULL; 00098 this->data_ = NULL; 00099 } 00100 if (this->data_ == NULL && i != 0 && j != 0) 00101 throw NoMemory("Matrix_Pointers::Matrix_Pointers(int, int)", 00102 string("Unable to allocate memory for a matrix of size ") 00103 + to_str(static_cast<long int>(i) 00104 * static_cast<long int>(j) 00105 * static_cast<long int>(sizeof(T))) 00106 + " bytes (" + to_str(i) + " x " + to_str(j) 00107 + " elements)."); 00108 #endif 00109 00110 pointer ptr = this->data_; 00111 int lgth = Storage::GetSecond(i, j); 00112 for (int k = 0; k < Storage::GetFirst(i, j); k++, ptr += lgth) 00113 me_[k] = ptr; 00114 00115 } 00116 00117 00119 template <class T, class Prop, class Storage, class Allocator> 00120 inline Matrix_Pointers<T, Prop, Storage, Allocator> 00121 ::Matrix_Pointers(const Matrix_Pointers<T, Prop, Storage, Allocator>& A): 00122 Matrix_Base<T, Allocator>(A) 00123 { 00124 this->m_ = 0; 00125 this->n_ = 0; 00126 this->data_ = NULL; 00127 this->me_ = NULL; 00128 00129 this->Copy(A); 00130 } 00131 00132 00133 /************** 00134 * DESTRUCTOR * 00135 **************/ 00136 00137 00139 template <class T, class Prop, class Storage, class Allocator> 00140 inline Matrix_Pointers<T, Prop, Storage, Allocator>::~Matrix_Pointers() 00141 { 00142 00143 #ifdef SELDON_CHECK_MEMORY 00144 try 00145 { 00146 #endif 00147 00148 if (this->data_ != NULL) 00149 { 00150 this->allocator_.deallocate(this->data_, this->m_ * this->n_); 00151 this->data_ = NULL; 00152 } 00153 00154 #ifdef SELDON_CHECK_MEMORY 00155 } 00156 catch (...) 00157 { 00158 this->data_ = NULL; 00159 } 00160 #endif 00161 00162 #ifdef SELDON_CHECK_MEMORY 00163 try 00164 { 00165 #endif 00166 00167 if (me_ != NULL) 00168 { 00169 free(me_); 00170 me_ = NULL; 00171 } 00172 00173 #ifdef SELDON_CHECK_MEMORY 00174 } 00175 catch (...) 00176 { 00177 this->m_ = 0; 00178 this->n_ = 0; 00179 me_ = NULL; 00180 } 00181 #endif 00182 00183 } 00184 00185 00187 00191 template <class T, class Prop, class Storage, class Allocator> 00192 inline void Matrix_Pointers<T, Prop, Storage, Allocator>::Clear() 00193 { 00194 this->~Matrix_Pointers(); 00195 this->m_ = 0; 00196 this->n_ = 0; 00197 } 00198 00199 00200 /******************* 00201 * BASIC FUNCTIONS * 00202 *******************/ 00203 00204 00206 00212 template <class T, class Prop, class Storage, class Allocator> 00213 int Matrix_Pointers<T, Prop, Storage, Allocator>::GetDataSize() const 00214 { 00215 return this->m_ * this->n_; 00216 } 00217 00218 00220 00225 template <class T, class Prop, class Storage, class Allocator> 00226 typename 00227 Matrix_Pointers<T, Prop, Storage, Allocator>::pointer* 00228 Matrix_Pointers<T, Prop, Storage, Allocator>::GetMe() const 00229 { 00230 return me_; 00231 } 00232 00233 00234 /********************* 00235 * MEMORY MANAGEMENT * 00236 *********************/ 00237 00238 00240 00246 template <class T, class Prop, class Storage, class Allocator> 00247 inline void Matrix_Pointers<T, Prop, Storage, Allocator> 00248 ::Reallocate(int i, int j) 00249 { 00250 00251 if (i != this->m_ || j != this->n_) 00252 { 00253 this->m_ = i; 00254 this->n_ = j; 00255 00256 #ifdef SELDON_CHECK_MEMORY 00257 try 00258 { 00259 #endif 00260 00261 me_ = reinterpret_cast<pointer*>( realloc(me_, 00262 Storage::GetFirst(i, j) 00263 * sizeof(pointer)) ); 00264 00265 #ifdef SELDON_CHECK_MEMORY 00266 } 00267 catch (...) 00268 { 00269 this->m_ = 0; 00270 this->n_ = 0; 00271 me_ = NULL; 00272 this->data_ = NULL; 00273 } 00274 if (me_ == NULL && i != 0 && j != 0) 00275 throw NoMemory("Matrix_Pointers::Reallocate(int, int)", 00276 string("Unable to reallocate memory for") 00277 + " a matrix of size " 00278 + to_str(static_cast<long int>(i) 00279 * static_cast<long int>(j) 00280 * static_cast<long int>(sizeof(T))) 00281 + " bytes (" + to_str(i) + " x " + to_str(j) 00282 + " elements)."); 00283 #endif 00284 00285 #ifdef SELDON_CHECK_MEMORY 00286 try 00287 { 00288 #endif 00289 00290 this->data_ = 00291 reinterpret_cast<pointer>(this->allocator_ 00292 .reallocate(this->data_, i * j, 00293 this)); 00294 00295 #ifdef SELDON_CHECK_MEMORY 00296 } 00297 catch (...) 00298 { 00299 this->m_ = 0; 00300 this->n_ = 0; 00301 free(me_); 00302 me_ = NULL; 00303 this->data_ = NULL; 00304 } 00305 if (this->data_ == NULL && i != 0 && j != 0) 00306 throw NoMemory("Matrix_Pointers::Reallocate(int, int)", 00307 string("Unable to reallocate memory") 00308 + " for a matrix of size " 00309 + to_str(static_cast<long int>(i) 00310 * static_cast<long int>(j) 00311 * static_cast<long int>(sizeof(T))) 00312 + " bytes (" + to_str(i) + " x " + to_str(j) 00313 + " elements)."); 00314 #endif 00315 00316 pointer ptr = this->data_; 00317 int lgth = Storage::GetSecond(i, j); 00318 for (int k = 0; k < Storage::GetFirst(i, j); k++, ptr += lgth) 00319 me_[k] = ptr; 00320 } 00321 } 00322 00323 00326 00340 template <class T, class Prop, class Storage, class Allocator> 00341 inline void Matrix_Pointers<T, Prop, Storage, Allocator> 00342 ::SetData(int i, int j, 00343 typename Matrix_Pointers<T, Prop, Storage, Allocator> 00344 ::pointer data) 00345 { 00346 this->Clear(); 00347 00348 this->m_ = i; 00349 this->n_ = j; 00350 00351 #ifdef SELDON_CHECK_MEMORY 00352 try 00353 { 00354 #endif 00355 00356 me_ = reinterpret_cast<pointer*>( calloc(Storage::GetFirst(i, j), 00357 sizeof(pointer)) ); 00358 00359 #ifdef SELDON_CHECK_MEMORY 00360 } 00361 catch (...) 00362 { 00363 this->m_ = 0; 00364 this->n_ = 0; 00365 me_ = NULL; 00366 this->data_ = NULL; 00367 return; 00368 } 00369 if (me_ == NULL) 00370 { 00371 this->m_ = 0; 00372 this->n_ = 0; 00373 this->data_ = NULL; 00374 return; 00375 } 00376 #endif 00377 00378 this->data_ = data; 00379 00380 pointer ptr = this->data_; 00381 int lgth = Storage::GetSecond(i, j); 00382 for (int k = 0; k < Storage::GetFirst(i, j); k++, ptr += lgth) 00383 me_[k] = ptr; 00384 } 00385 00386 00388 00393 template <class T, class Prop, class Storage, class Allocator> 00394 inline void Matrix_Pointers<T, Prop, Storage, Allocator>::Nullify() 00395 { 00396 this->m_ = 0; 00397 this->n_ = 0; 00398 00399 #ifdef SELDON_CHECK_MEMORY 00400 try 00401 { 00402 #endif 00403 00404 if (me_ != NULL) 00405 { 00406 free(me_); 00407 me_ = NULL; 00408 } 00409 00410 #ifdef SELDON_CHECK_MEMORY 00411 } 00412 catch (...) 00413 { 00414 this->m_ = 0; 00415 this->n_ = 0; 00416 me_ = NULL; 00417 } 00418 #endif 00419 00420 this->data_ = NULL; 00421 } 00422 00423 00425 00432 template <class T, class Prop, class Storage, class Allocator> 00433 inline void Matrix_Pointers<T, Prop, Storage, Allocator> 00434 ::Resize(int i, int j) 00435 { 00436 00437 if (i == this->m_ && j == this->n_) 00438 return; 00439 00440 // Storing the old values of the matrix. 00441 int iold = Storage::GetFirst(this->m_, this->n_); 00442 int jold = Storage::GetSecond(this->m_, this->n_); 00443 Vector<value_type, VectFull, Allocator> xold(this->GetDataSize()); 00444 for (int k = 0; k < this->GetDataSize(); k++) 00445 xold(k) = this->data_[k]; 00446 00447 // Reallocation. 00448 int inew = Storage::GetFirst(i, j); 00449 int jnew = Storage::GetSecond(i, j); 00450 this->Reallocate(i,j); 00451 00452 // Filling the matrix with its old values. 00453 int imin = min(iold, inew), jmin = min(jold, jnew); 00454 for (int k = 0; k < imin; k++) 00455 for (int l = 0; l < jmin; l++) 00456 this->data_[k*jnew+l] = xold(l+jold*k); 00457 } 00458 00459 00460 /********************************** 00461 * ELEMENT ACCESS AND AFFECTATION * 00462 **********************************/ 00463 00464 00466 00472 template <class T, class Prop, class Storage, class Allocator> 00473 inline typename Matrix_Pointers<T, Prop, Storage, Allocator>::reference 00474 Matrix_Pointers<T, Prop, Storage, Allocator>::operator() (int i, int j) 00475 { 00476 00477 #ifdef SELDON_CHECK_BOUNDS 00478 if (i < 0 || i >= this->m_) 00479 throw WrongRow("Matrix_Pointers::operator()", 00480 string("Index should be in [0, ") 00481 + to_str(this->m_-1) + "], but is equal to " 00482 + to_str(i) + "."); 00483 if (j < 0 || j >= this->n_) 00484 throw WrongCol("Matrix_Pointers::operator()", 00485 string("Index should be in [0, ") 00486 + to_str(this->n_-1) + "], but is equal to " 00487 + to_str(j) + "."); 00488 #endif 00489 00490 return me_[Storage::GetFirst(i, j)][Storage::GetSecond(i, j)]; 00491 } 00492 00493 00495 00501 template <class T, class Prop, class Storage, class Allocator> 00502 inline typename Matrix_Pointers<T, Prop, Storage, Allocator> 00503 ::const_reference Matrix_Pointers<T, Prop, Storage, Allocator> 00504 ::operator() (int i, int j) const 00505 { 00506 00507 #ifdef SELDON_CHECK_BOUNDS 00508 if (i < 0 || i >= this->m_) 00509 throw WrongRow("Matrix_Pointers::operator()", 00510 string("Index should be in [0, ") 00511 + to_str(this->m_-1) + "], but is equal to " 00512 + to_str(i) + "."); 00513 if (j < 0 || j >= this->n_) 00514 throw WrongCol("Matrix_Pointers::operator()", 00515 string("Index should be in [0, ") 00516 + to_str(this->n_-1) + "], but is equal to " 00517 + to_str(j) + "."); 00518 #endif 00519 00520 return me_[Storage::GetFirst(i, j)][Storage::GetSecond(i, j)]; 00521 } 00522 00523 00525 00531 template <class T, class Prop, class Storage, class Allocator> 00532 inline typename Matrix_Pointers<T, Prop, Storage, Allocator>::reference 00533 Matrix_Pointers<T, Prop, Storage, Allocator>::Val(int i, int j) 00534 { 00535 00536 #ifdef SELDON_CHECK_BOUNDS 00537 if (i < 0 || i >= this->m_) 00538 throw WrongRow("Matrix_Pointers::Val(int, int)", 00539 string("Index should be in [0, ") + to_str(this->m_-1) 00540 + "], but is equal to " + to_str(i) + "."); 00541 if (j < 0 || j >= this->n_) 00542 throw WrongCol("Matrix_Pointers::Val(int, int)", 00543 string("Index should be in [0, ") + to_str(this->n_-1) 00544 + "], but is equal to " + to_str(j) + "."); 00545 #endif 00546 00547 return me_[Storage::GetFirst(i, j)][Storage::GetSecond(i, j)]; 00548 } 00549 00550 00552 00558 template <class T, class Prop, class Storage, class Allocator> 00559 inline typename Matrix_Pointers<T, Prop, Storage, Allocator>::reference 00560 Matrix_Pointers<T, Prop, Storage, Allocator>::Get(int i, int j) 00561 { 00562 return Val(i, j); 00563 } 00564 00565 00567 00573 template <class T, class Prop, class Storage, class Allocator> 00574 inline typename Matrix_Pointers<T, Prop, Storage, Allocator> 00575 ::const_reference 00576 Matrix_Pointers<T, Prop, Storage, Allocator>::Val(int i, int j) const 00577 { 00578 00579 #ifdef SELDON_CHECK_BOUNDS 00580 if (i < 0 || i >= this->m_) 00581 throw WrongRow("Matrix_Pointers::Val(int, int) const", 00582 string("Index should be in [0, ") + to_str(this->m_-1) 00583 + "], but is equal to " + to_str(i) + "."); 00584 if (j < 0 || j >= this->n_) 00585 throw WrongCol("Matrix_Pointers::Val(int, int) const", 00586 string("Index should be in [0, ") + to_str(this->n_-1) 00587 + "], but is equal to " + to_str(j) + "."); 00588 #endif 00589 00590 return me_[Storage::GetFirst(i, j)][Storage::GetSecond(i, j)]; 00591 } 00592 00593 00595 00601 template <class T, class Prop, class Storage, class Allocator> 00602 inline typename Matrix_Pointers<T, Prop, Storage, Allocator> 00603 ::const_reference 00604 Matrix_Pointers<T, Prop, Storage, Allocator>::Get(int i, int j) const 00605 { 00606 return Val(i, j); 00607 } 00608 00609 00611 00616 template <class T, class Prop, class Storage, class Allocator> 00617 inline typename Matrix_Pointers<T, Prop, Storage, Allocator>::reference 00618 Matrix_Pointers<T, Prop, Storage, Allocator>::operator[] (int i) 00619 { 00620 00621 #ifdef SELDON_CHECK_BOUNDS 00622 if (i < 0 || i >= this->GetDataSize()) 00623 throw WrongIndex("Matrix_Pointers::operator[] (int)", 00624 string("Index should be in [0, ") 00625 + to_str(this->GetDataSize()-1) + "], but is equal to " 00626 + to_str(i) + "."); 00627 #endif 00628 00629 return this->data_[i]; 00630 } 00631 00632 00634 00639 template <class T, class Prop, class Storage, class Allocator> 00640 inline typename Matrix_Pointers<T, Prop, Storage, Allocator> 00641 ::const_reference 00642 Matrix_Pointers<T, Prop, Storage, Allocator>::operator[] (int i) const 00643 { 00644 00645 #ifdef SELDON_CHECK_BOUNDS 00646 if (i < 0 || i >= this->GetDataSize()) 00647 throw WrongIndex("Matrix_Pointers::operator[] (int) const", 00648 string("Index should be in [0, ") 00649 + to_str(this->GetDataSize()-1) + "], but is equal to " 00650 + to_str(i) + "."); 00651 #endif 00652 00653 return this->data_[i]; 00654 } 00655 00656 00658 00663 template <class T, class Prop, class Storage, class Allocator> 00664 inline void Matrix_Pointers<T, Prop, Storage, Allocator> 00665 ::Set(int i, int j, const T& val) 00666 { 00667 this->Val(i, j) = val; 00668 } 00669 00670 00672 00677 template <class T, class Prop, class Storage, class Allocator> 00678 inline Matrix_Pointers<T, Prop, Storage, Allocator>& 00679 Matrix_Pointers<T, Prop, Storage, Allocator> 00680 ::operator= (const Matrix_Pointers<T, Prop, Storage, Allocator>& A) 00681 { 00682 this->Copy(A); 00683 00684 return *this; 00685 } 00686 00687 00689 00694 template <class T, class Prop, class Storage, class Allocator> 00695 inline void Matrix_Pointers<T, Prop, Storage, Allocator> 00696 ::Copy(const Matrix_Pointers<T, Prop, Storage, Allocator>& A) 00697 { 00698 this->Reallocate(A.GetM(), A.GetN()); 00699 00700 this->allocator_.memorycpy(this->data_, A.GetData(), this->GetDataSize()); 00701 } 00702 00703 00704 /************************ 00705 * CONVENIENT FUNCTIONS * 00706 ************************/ 00707 00708 00710 00713 template <class T, class Prop, class Storage, class Allocator> 00714 int Matrix_Pointers<T, Prop, Storage, Allocator>::GetLD() const 00715 { 00716 return Storage::GetSecond(this->m_, this->n_); 00717 } 00718 00719 00721 00725 template <class T, class Prop, class Storage, class Allocator> 00726 void Matrix_Pointers<T, Prop, Storage, Allocator>::Zero() 00727 { 00728 this->allocator_.memoryset(this->data_, char(0), 00729 this->GetDataSize() * sizeof(value_type)); 00730 } 00731 00732 00734 template <class T, class Prop, class Storage, class Allocator> 00735 void Matrix_Pointers<T, Prop, Storage, Allocator>::SetIdentity() 00736 { 00737 Fill(T(0)); 00738 00739 T one(1); 00740 for (int i = 0; i < min(this->m_, this->n_); i++) 00741 (*this)(i,i) = one; 00742 } 00743 00744 00746 00750 template <class T, class Prop, class Storage, class Allocator> 00751 void Matrix_Pointers<T, Prop, Storage, Allocator>::Fill() 00752 { 00753 for (int i = 0; i < this->GetDataSize(); i++) 00754 this->data_[i] = i; 00755 } 00756 00757 00759 00762 template <class T, class Prop, class Storage, class Allocator> 00763 template <class T0> 00764 void Matrix_Pointers<T, Prop, Storage, Allocator>::Fill(const T0& x) 00765 { 00766 for (int i = 0; i < this->GetDataSize(); i++) 00767 this->data_[i] = x; 00768 } 00769 00770 00772 00775 template <class T, class Prop, class Storage, class Allocator> 00776 template <class T0> 00777 Matrix_Pointers<T, Prop, Storage, Allocator>& 00778 Matrix_Pointers<T, Prop, Storage, Allocator>::operator= (const T0& x) 00779 { 00780 this->Fill(x); 00781 00782 return *this; 00783 } 00784 00785 00787 00790 template <class T, class Prop, class Storage, class Allocator> 00791 void Matrix_Pointers<T, Prop, Storage, Allocator>::FillRand() 00792 { 00793 srand(time(NULL)); 00794 for (int i = 0; i < this->GetDataSize(); i++) 00795 this->data_[i] = rand(); 00796 } 00797 00798 00800 00805 template <class T, class Prop, class Storage, class Allocator> 00806 void Matrix_Pointers<T, Prop, Storage, Allocator>::Print() const 00807 { 00808 for (int i = 0; i < this->m_; i++) 00809 { 00810 for (int j = 0; j < this->n_; j++) 00811 cout << (*this)(i, j) << "\t"; 00812 cout << endl; 00813 } 00814 } 00815 00816 00818 00829 template <class T, class Prop, class Storage, class Allocator> 00830 void Matrix_Pointers<T, Prop, Storage, Allocator>::Print(int a, int b, 00831 int m, int n) const 00832 { 00833 for (int i = a; i < min(this->m_, a+m); i++) 00834 { 00835 for (int j = b; j < min(this->n_, b+n); j++) 00836 cout << (*this)(i, j) << "\t"; 00837 cout << endl; 00838 } 00839 } 00840 00841 00843 00851 template <class T, class Prop, class Storage, class Allocator> 00852 void Matrix_Pointers<T, Prop, Storage, Allocator>::Print(int l) const 00853 { 00854 Print(0, 0, l, l); 00855 } 00856 00857 00858 /************************** 00859 * INPUT/OUTPUT FUNCTIONS * 00860 **************************/ 00861 00862 #ifdef SELDON_WITH_HDF5 00863 00864 00871 template <class T, class Prop, class Storage, class Allocator> 00872 void Matrix_Pointers<T, Prop, Storage, Allocator> 00873 ::WriteHDF5(string FileName, string group_name, string dataset_name) const 00874 { 00875 throw IOError("Matrix_Pointers::WriteHDF5(string FileName)", 00876 string("Unable to write matrix in \"") + FileName + "\"."); 00877 } 00878 #endif 00879 00880 00882 00891 template <class T, class Prop, class Storage, class Allocator> 00892 void Matrix_Pointers<T, Prop, Storage, Allocator> 00893 ::Write(string FileName, bool with_size) const 00894 { 00895 ofstream FileStream; 00896 FileStream.open(FileName.c_str(), ofstream::binary); 00897 00898 #ifdef SELDON_CHECK_IO 00899 // Checks if the file was opened. 00900 if (!FileStream.is_open()) 00901 throw IOError("Matrix_Pointers::Write(string FileName)", 00902 string("Unable to open file \"") + FileName + "\"."); 00903 #endif 00904 00905 this->Write(FileStream, with_size); 00906 00907 FileStream.close(); 00908 } 00909 00910 00912 00921 template <class T, class Prop, class Storage, class Allocator> 00922 void Matrix_Pointers<T, Prop, Storage, Allocator> 00923 ::Write(ostream& FileStream, bool with_size) const 00924 { 00925 00926 #ifdef SELDON_CHECK_IO 00927 // Checks if the stream is ready. 00928 if (!FileStream.good()) 00929 throw IOError("Matrix_Pointers::Write(ostream& FileStream)", 00930 "The stream is not ready."); 00931 #endif 00932 00933 if (with_size) 00934 { 00935 FileStream.write(reinterpret_cast<char*>(const_cast<int*>(&this->m_)), 00936 sizeof(int)); 00937 FileStream.write(reinterpret_cast<char*>(const_cast<int*>(&this->n_)), 00938 sizeof(int)); 00939 } 00940 00941 FileStream.write(reinterpret_cast<char*>(this->data_), 00942 this->m_ * this->n_ * sizeof(value_type)); 00943 00944 #ifdef SELDON_CHECK_IO 00945 // Checks if data was written. 00946 if (!FileStream.good()) 00947 throw IOError("Matrix_Pointers::Write(ostream& FileStream)", 00948 "Output operation failed."); 00949 #endif 00950 00951 } 00952 00953 00955 00962 template <class T, class Prop, class Storage, class Allocator> 00963 void Matrix_Pointers<T, Prop, Storage, Allocator> 00964 ::WriteText(string FileName) const 00965 { 00966 ofstream FileStream; 00967 FileStream.precision(cout.precision()); 00968 FileStream.flags(cout.flags()); 00969 FileStream.open(FileName.c_str()); 00970 00971 #ifdef SELDON_CHECK_IO 00972 // Checks if the file was opened. 00973 if (!FileStream.is_open()) 00974 throw IOError("Matrix_Pointers::WriteText(string FileName)", 00975 string("Unable to open file \"") + FileName + "\"."); 00976 #endif 00977 00978 this->WriteText(FileStream); 00979 00980 FileStream.close(); 00981 } 00982 00983 00985 00992 template <class T, class Prop, class Storage, class Allocator> 00993 void Matrix_Pointers<T, Prop, Storage, Allocator> 00994 ::WriteText(ostream& FileStream) const 00995 { 00996 00997 #ifdef SELDON_CHECK_IO 00998 // Checks if the file is ready. 00999 if (!FileStream.good()) 01000 throw IOError("Matrix_Pointers::WriteText(ostream& FileStream)", 01001 "The stream is not ready."); 01002 #endif 01003 01004 int i, j; 01005 for (i = 0; i < this->GetM(); i++) 01006 { 01007 for (j = 0; j < this->GetN(); j++) 01008 FileStream << (*this)(i, j) << '\t'; 01009 FileStream << endl; 01010 } 01011 01012 #ifdef SELDON_CHECK_IO 01013 // Checks if data was written. 01014 if (!FileStream.good()) 01015 throw IOError("Matrix_Pointers::WriteText(ostream& FileStream)", 01016 "Output operation failed."); 01017 #endif 01018 01019 } 01020 01021 01023 01033 template <class T, class Prop, class Storage, class Allocator> 01034 void Matrix_Pointers<T, Prop, Storage, Allocator> 01035 ::Read(string FileName, bool with_size) 01036 { 01037 ifstream FileStream; 01038 FileStream.open(FileName.c_str(), ifstream::binary); 01039 01040 #ifdef SELDON_CHECK_IO 01041 // Checks if the file was opened. 01042 if (!FileStream.is_open()) 01043 throw IOError("Matrix_Pointers::Read(string FileName)", 01044 string("Unable to open file \"") + FileName + "\"."); 01045 #endif 01046 01047 this->Read(FileStream, with_size); 01048 01049 FileStream.close(); 01050 } 01051 01052 01054 01064 template <class T, class Prop, class Storage, class Allocator> 01065 void Matrix_Pointers<T, Prop, Storage, Allocator> 01066 ::Read(istream& FileStream, bool with_size) 01067 { 01068 01069 #ifdef SELDON_CHECK_IO 01070 // Checks if the stream is ready. 01071 if (!FileStream.good()) 01072 throw IOError("Matrix_Pointers::Read(istream& FileStream)", 01073 "The stream is not ready."); 01074 #endif 01075 01076 if (with_size) 01077 { 01078 int new_m, new_n; 01079 FileStream.read(reinterpret_cast<char*>(&new_m), sizeof(int)); 01080 FileStream.read(reinterpret_cast<char*>(&new_n), sizeof(int)); 01081 this->Reallocate(new_m, new_n); 01082 } 01083 01084 FileStream.read(reinterpret_cast<char*>(this->data_), 01085 this->GetM() * this->GetN() * sizeof(value_type)); 01086 01087 #ifdef SELDON_CHECK_IO 01088 // Checks if data was read. 01089 if (!FileStream.good()) 01090 throw IOError("Matrix_Pointers::Read(istream& FileStream)", 01091 "Input operation failed."); 01092 #endif 01093 01094 } 01095 01096 01098 01102 template <class T, class Prop, class Storage, class Allocator> 01103 void Matrix_Pointers<T, Prop, Storage, Allocator>::ReadText(string FileName) 01104 { 01105 ifstream FileStream; 01106 FileStream.open(FileName.c_str()); 01107 01108 #ifdef SELDON_CHECK_IO 01109 // Checks if the file was opened. 01110 if (!FileStream.is_open()) 01111 throw IOError("Matrix_Pointers::ReadText(string FileName)", 01112 string("Unable to open file \"") + FileName + "\"."); 01113 #endif 01114 01115 this->ReadText(FileStream); 01116 01117 FileStream.close(); 01118 } 01119 01120 01122 01126 template <class T, class Prop, class Storage, class Allocator> 01127 void Matrix_Pointers<T, Prop, Storage, Allocator> 01128 ::ReadText(istream& FileStream) 01129 { 01130 // Clears the matrix. 01131 Clear(); 01132 01133 #ifdef SELDON_CHECK_IO 01134 // Checks if the stream is ready. 01135 if (!FileStream.good()) 01136 throw IOError("Matrix_Pointers::ReadText(istream& FileStream)", 01137 "The stream is not ready."); 01138 #endif 01139 01140 // Reads the first line. 01141 string line; 01142 getline(FileStream, line); 01143 if (FileStream.fail()) 01144 // Is the file empty? 01145 return; 01146 01147 // Converts the first line into a vector. 01148 istringstream line_stream(line); 01149 Vector<T> first_row; 01150 first_row.ReadText(line_stream); 01151 01152 // Now reads all other rows, and puts them in a single vector. 01153 Vector<T> other_row; 01154 other_row.ReadText(FileStream); 01155 01156 // Number of rows and columns. 01157 int n = first_row.GetM(); 01158 int m = 1 + other_row.GetM() / n; 01159 01160 #ifdef SELDON_CHECK_IO 01161 // Checks that enough elements were read. 01162 if (other_row.GetM() != (m - 1) * n) 01163 throw IOError("Matrix_Pointers::ReadText(istream& FileStream)", 01164 "Not all rows have the same number of columns."); 01165 #endif 01166 01167 this->Reallocate(m, n); 01168 // Fills the matrix. 01169 for (int j = 0; j < n; j++) 01170 this->Val(0, j) = first_row(j); 01171 01172 int k = 0; 01173 for (int i = 1; i < m; i++) 01174 for (int j = 0; j < n; j++) 01175 this->Val(i, j) = other_row(k++); 01176 } 01177 01178 01180 // MATRIX<COLMAJOR> // 01182 01183 01184 /**************** 01185 * CONSTRUCTORS * 01186 ****************/ 01187 01188 01190 01193 template <class T, class Prop, class Allocator> 01194 Matrix<T, Prop, ColMajor, Allocator>::Matrix(): 01195 Matrix_Pointers<T, Prop, ColMajor, Allocator>() 01196 { 01197 } 01198 01199 01201 01205 template <class T, class Prop, class Allocator> 01206 Matrix<T, Prop, ColMajor, Allocator>::Matrix(int i, int j): 01207 Matrix_Pointers<T, Prop, ColMajor, Allocator>(i, j) 01208 { 01209 } 01210 01211 01213 template <class T, class Prop, class Allocator> 01214 Matrix<T, Prop, ColMajor, Allocator> 01215 ::Matrix(const Matrix<T, Prop, ColMajor, Allocator>& A): 01216 Matrix_Pointers<T, Prop, ColMajor, Allocator>(A) 01217 { 01218 } 01219 01220 01221 /***************** 01222 * OTHER METHODS * 01223 *****************/ 01224 01225 01227 01230 template <class T, class Prop, class Allocator> 01231 template <class T0> 01232 Matrix<T, Prop, ColMajor, Allocator>& 01233 Matrix<T, Prop, ColMajor, Allocator>::operator= (const T0& x) 01234 { 01235 this->Fill(x); 01236 01237 return *this; 01238 } 01239 01240 01242 01247 template <class T, class Prop, class Allocator> 01248 inline Matrix<T, Prop, ColMajor, Allocator>& 01249 Matrix<T, Prop, ColMajor, Allocator> 01250 ::operator= (const Matrix<T, Prop, ColMajor, Allocator>& A) 01251 { 01252 this->Copy(A); 01253 01254 return *this; 01255 } 01256 01257 01259 01262 template <class T, class Prop, class Allocator> template<class T0> 01263 inline Matrix<T, Prop, ColMajor, Allocator>& 01264 Matrix<T, Prop, ColMajor, Allocator>::operator*= (const T0& alpha) 01265 { 01266 for (int i = 0; i < this->m_ * this->n_; i++) 01267 this->data_[i] *= alpha; 01268 01269 return *this; 01270 } 01271 01272 01274 // MATRIX<ROWMAJOR> // 01276 01277 01278 /**************** 01279 * CONSTRUCTORS * 01280 ****************/ 01281 01282 01284 01287 template <class T, class Prop, class Allocator> 01288 Matrix<T, Prop, RowMajor, Allocator>::Matrix(): 01289 Matrix_Pointers<T, Prop, RowMajor, Allocator>() 01290 { 01291 } 01292 01293 01295 01299 template <class T, class Prop, class Allocator> 01300 Matrix<T, Prop, RowMajor, Allocator>::Matrix(int i, int j): 01301 Matrix_Pointers<T, Prop, RowMajor, Allocator>(i, j) 01302 { 01303 } 01304 01305 01307 template <class T, class Prop, class Allocator> 01308 Matrix<T, Prop, RowMajor, Allocator> 01309 ::Matrix(const Matrix<T, Prop, RowMajor, Allocator>& A): 01310 Matrix_Pointers<T, Prop, RowMajor, Allocator>(A) 01311 { 01312 } 01313 01314 01315 /***************** 01316 * OTHER METHODS * 01317 *****************/ 01318 01319 01321 01324 template <class T, class Prop, class Allocator> 01325 template <class T0> 01326 Matrix<T, Prop, RowMajor, Allocator>& 01327 Matrix<T, Prop, RowMajor, Allocator>::operator= (const T0& x) 01328 { 01329 this->Fill(x); 01330 01331 return *this; 01332 } 01333 01334 01336 01341 template <class T, class Prop, class Allocator> 01342 inline Matrix<T, Prop, RowMajor, Allocator>& 01343 Matrix<T, Prop, RowMajor, Allocator> 01344 ::operator= (const Matrix<T, Prop, RowMajor, Allocator>& A) 01345 { 01346 this->Copy(A); 01347 01348 return *this; 01349 } 01350 01351 01353 01356 template <class T, class Prop, class Allocator> template<class T0> 01357 inline Matrix<T, Prop, RowMajor, Allocator>& 01358 Matrix<T, Prop, RowMajor, Allocator>::operator*= (const T0& alpha) 01359 { 01360 for (int i = 0; i < this->m_*this->n_; i++) 01361 this->data_[i] *= alpha; 01362 01363 return *this; 01364 } 01365 01366 01367 } // namespace Seldon. 01368 01369 #define SELDON_FILE_MATRIX_POINTERS_CXX 01370 #endif