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_TRIANGULAR_CXX 00022 00023 #include "Matrix_Triangular.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_Triangular<T, Prop, Storage, Allocator>::Matrix_Triangular(): 00040 Matrix_Base<T, Allocator>() 00041 { 00042 me_ = NULL; 00043 } 00044 00045 00047 00052 template <class T, class Prop, class Storage, class Allocator> 00053 inline Matrix_Triangular<T, Prop, Storage, Allocator> 00054 ::Matrix_Triangular(int i, int j): Matrix_Base<T, Allocator>(i, i) 00055 { 00056 00057 #ifdef SELDON_CHECK_MEMORY 00058 try 00059 { 00060 #endif 00061 00062 me_ = reinterpret_cast<pointer*>( calloc(i, 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) 00074 { 00075 this->m_ = 0; 00076 this->n_ = 0; 00077 this->data_ = NULL; 00078 } 00079 if (me_ == NULL && i != 0) 00080 throw NoMemory("Matrix_Triangular::Matrix_Triangular(int, int)", 00081 string("Unable to allocate memory for a matrix of size ") 00082 + to_str(static_cast<long int>(i) 00083 * static_cast<long int>(i) 00084 * static_cast<long int>(sizeof(T))) 00085 + " bytes (" + to_str(i) + " x " + to_str(i) 00086 + " elements)."); 00087 #endif 00088 00089 #ifdef SELDON_CHECK_MEMORY 00090 try 00091 { 00092 #endif 00093 00094 this->data_ = this->allocator_.allocate(i * i, this); 00095 00096 #ifdef SELDON_CHECK_MEMORY 00097 } 00098 catch (...) 00099 { 00100 this->m_ = 0; 00101 this->n_ = 0; 00102 free(me_); 00103 me_ = NULL; 00104 this->data_ = NULL; 00105 } 00106 if (this->data_ == NULL) 00107 { 00108 this->m_ = 0; 00109 this->n_ = 0; 00110 free(me_); 00111 me_ = NULL; 00112 } 00113 if (this->data_ == NULL && i != 0) 00114 throw NoMemory("Matrix_Triangular::Matrix_Triangular(int, int)", 00115 string("Unable to allocate memory for a matrix of size ") 00116 + to_str(static_cast<long int>(i) 00117 * static_cast<long int>(i) 00118 * static_cast<long int>(sizeof(T))) 00119 + " bytes (" + to_str(i) + " x " + to_str(i) 00120 + " elements)."); 00121 #endif 00122 00123 pointer ptr = this->data_; 00124 int lgth = i; 00125 for (int k = 0; k < i; k++, ptr += lgth) 00126 me_[k] = ptr; 00127 } 00128 00129 00131 template <class T, class Prop, class Storage, class Allocator> 00132 inline Matrix_Triangular<T, Prop, Storage, Allocator> 00133 ::Matrix_Triangular(const Matrix_Triangular<T, Prop, 00134 Storage, Allocator>& A) 00135 : Matrix_Base<T, Allocator>() 00136 { 00137 this->m_ = 0; 00138 this->n_ = 0; 00139 this->data_ = NULL; 00140 this->me_ = NULL; 00141 00142 this->Copy(A); 00143 } 00144 00145 00146 /************** 00147 * DESTRUCTOR * 00148 **************/ 00149 00150 00152 template <class T, class Prop, class Storage, class Allocator> 00153 inline Matrix_Triangular<T, Prop, Storage, Allocator>::~Matrix_Triangular() 00154 { 00155 00156 #ifdef SELDON_CHECK_MEMORY 00157 try 00158 { 00159 #endif 00160 00161 if (this->data_ != NULL) 00162 { 00163 this->allocator_.deallocate(this->data_, this->m_ * this->n_); 00164 this->data_ = NULL; 00165 } 00166 00167 #ifdef SELDON_CHECK_MEMORY 00168 } 00169 catch (...) 00170 { 00171 this->data_ = NULL; 00172 } 00173 #endif 00174 00175 #ifdef SELDON_CHECK_MEMORY 00176 try 00177 { 00178 #endif 00179 00180 if (me_ != NULL) 00181 { 00182 free(me_); 00183 me_ = NULL; 00184 } 00185 00186 #ifdef SELDON_CHECK_MEMORY 00187 } 00188 catch (...) 00189 { 00190 this->m_ = 0; 00191 this->n_ = 0; 00192 me_ = NULL; 00193 } 00194 #endif 00195 00196 } 00197 00198 00200 00204 template <class T, class Prop, class Storage, class Allocator> 00205 inline void Matrix_Triangular<T, Prop, Storage, Allocator>::Clear() 00206 { 00207 this->~Matrix_Triangular(); 00208 this->m_ = 0; 00209 this->n_ = 0; 00210 } 00211 00212 00213 /******************* 00214 * BASIC FUNCTIONS * 00215 *******************/ 00216 00217 00219 00225 template <class T, class Prop, class Storage, class Allocator> 00226 int Matrix_Triangular<T, Prop, Storage, Allocator>::GetDataSize() const 00227 { 00228 return this->m_ * this->n_; 00229 } 00230 00231 00232 /********************* 00233 * MEMORY MANAGEMENT * 00234 *********************/ 00235 00236 00238 00244 template <class T, class Prop, class Storage, class Allocator> 00245 inline void Matrix_Triangular<T, Prop, Storage, Allocator> 00246 ::Reallocate(int i, int j) 00247 { 00248 00249 if (i != this->m_) 00250 { 00251 this->m_ = i; 00252 this->n_ = i; 00253 00254 #ifdef SELDON_CHECK_MEMORY 00255 try 00256 { 00257 #endif 00258 00259 me_ = reinterpret_cast<pointer*>( realloc(me_, 00260 i * sizeof(pointer)) ); 00261 00262 #ifdef SELDON_CHECK_MEMORY 00263 } 00264 catch (...) 00265 { 00266 this->m_ = 0; 00267 this->n_ = 0; 00268 me_ = NULL; 00269 this->data_ = NULL; 00270 } 00271 if (me_ == NULL) 00272 { 00273 this->m_ = 0; 00274 this->n_ = 0; 00275 this->data_ = NULL; 00276 } 00277 if (me_ == NULL && i != 0) 00278 throw NoMemory("Matrix_Triangular::Reallocate(int, int)", 00279 string("Unable to reallocate memory") 00280 + " for a matrix of size " 00281 + to_str(static_cast<long int>(i) 00282 * static_cast<long int>(i) 00283 * static_cast<long int>(sizeof(T))) 00284 + " bytes (" + to_str(i) + " x " + to_str(i) 00285 + " elements)."); 00286 #endif 00287 00288 #ifdef SELDON_CHECK_MEMORY 00289 try 00290 { 00291 #endif 00292 00293 this->data_ = 00294 reinterpret_cast<pointer>(this->allocator_.reallocate(this->data_, 00295 i * i, 00296 this) ); 00297 00298 #ifdef SELDON_CHECK_MEMORY 00299 } 00300 catch (...) 00301 { 00302 this->m_ = 0; 00303 this->n_ = 0; 00304 free(me_); 00305 me_ = NULL; 00306 this->data_ = NULL; 00307 } 00308 if (this->data_ == NULL) 00309 { 00310 this->m_ = 0; 00311 this->n_ = 0; 00312 free(me_); 00313 me_ = NULL; 00314 } 00315 if (this->data_ == NULL && i != 0) 00316 throw NoMemory("Matrix_Triangular::Reallocate(int, int)", 00317 string("Unable to reallocate memory") 00318 + " for a matrix of size " 00319 + to_str(static_cast<long int>(i) 00320 * static_cast<long int>(i) 00321 * static_cast<long int>(sizeof(T))) 00322 + " bytes (" + to_str(i) + " x " + to_str(i) 00323 + " elements)."); 00324 #endif 00325 00326 pointer ptr = this->data_; 00327 int lgth = Storage::GetSecond(i, i); 00328 for (int k = 0; k < Storage::GetFirst(i, i); k++, ptr += lgth) 00329 me_[k] = ptr; 00330 } 00331 } 00332 00333 00335 00342 template <class T, class Prop, class Storage, class Allocator> 00343 inline void Matrix_Triangular<T, Prop, Storage, Allocator> 00344 ::Resize(int i, int j) 00345 { 00346 00347 if (i != this->m_) 00348 { 00349 // Storing the previous values of the matrix. 00350 int iold = this->m_; 00351 Vector<value_type, VectFull, Allocator> xold(this->GetDataSize()); 00352 for (int k = 0; k < this->GetDataSize(); k++) 00353 xold(k) = this->data_[k]; 00354 00355 // Reallocation. 00356 this->Reallocate(i, i); 00357 00358 // Filling the matrix with its previous values. 00359 int imin = min(iold, i); 00360 for (int k = 0; k < imin; k++) 00361 for (int l = 0; l < imin; l++) 00362 this->data_[k*i + l] = xold(k*iold + l); 00363 } 00364 } 00365 00366 00369 00383 template <class T, class Prop, class Storage, class Allocator> 00384 inline void Matrix_Triangular<T, Prop, Storage, Allocator> 00385 ::SetData(int i, int j, 00386 typename Matrix_Triangular<T, Prop, Storage, Allocator> 00387 ::pointer data) 00388 { 00389 00390 this->Clear(); 00391 00392 this->m_ = i; 00393 this->n_ = i; 00394 00395 #ifdef SELDON_CHECK_MEMORY 00396 try 00397 { 00398 #endif 00399 00400 me_ = reinterpret_cast<pointer*>( calloc(i, sizeof(pointer)) ); 00401 00402 #ifdef SELDON_CHECK_MEMORY 00403 } 00404 catch (...) 00405 { 00406 this->m_ = 0; 00407 this->n_ = 0; 00408 me_ = NULL; 00409 this->data_ = NULL; 00410 return; 00411 } 00412 if (me_ == NULL) 00413 { 00414 this->m_ = 0; 00415 this->n_ = 0; 00416 this->data_ = NULL; 00417 return; 00418 } 00419 #endif 00420 00421 this->data_ = data; 00422 00423 pointer ptr = this->data_; 00424 int lgth = i; 00425 for (int k = 0; k < i; k++, ptr += lgth) 00426 me_[k] = ptr; 00427 } 00428 00429 00431 00436 template <class T, class Prop, class Storage, class Allocator> 00437 inline void Matrix_Triangular<T, Prop, Storage, Allocator>::Nullify() 00438 { 00439 this->m_ = 0; 00440 this->n_ = 0; 00441 00442 #ifdef SELDON_CHECK_MEMORY 00443 try 00444 { 00445 #endif 00446 00447 if (me_ != NULL) 00448 { 00449 free(me_); 00450 me_ = NULL; 00451 } 00452 00453 #ifdef SELDON_CHECK_MEMORY 00454 } 00455 catch (...) 00456 { 00457 this->m_ = 0; 00458 this->n_ = 0; 00459 me_ = NULL; 00460 } 00461 #endif 00462 00463 this->data_ = NULL; 00464 } 00465 00466 00467 /********************************** 00468 * ELEMENT ACCESS AND AFFECTATION * 00469 **********************************/ 00470 00471 00473 00479 template <class T, class Prop, class Storage, class Allocator> 00480 inline typename Matrix_Triangular<T, Prop, Storage, Allocator>::value_type 00481 Matrix_Triangular<T, Prop, Storage, Allocator> 00482 ::operator() (int i, int j) const 00483 { 00484 00485 #ifdef SELDON_CHECK_BOUNDS 00486 if (i < 0 || i >= this->m_) 00487 throw WrongRow("Matrix_Triangular::operator() const", 00488 string("Index should be in [0, ") + to_str(this->m_-1) 00489 + "], but is equal to " + to_str(i) + "."); 00490 if (j < 0 || j >= this->n_) 00491 throw WrongCol("Matrix_Triangular::operator() const", 00492 string("Index should be in [0, ") + to_str(this->n_-1) 00493 + "], but is equal to " + to_str(j) + "."); 00494 #endif 00495 00496 if (Storage::UpLo()) 00497 { 00498 if (i > j) 00499 return T(0); 00500 else 00501 return me_[Storage::GetFirst(i, j)][Storage::GetSecond(i, j)]; 00502 } 00503 else 00504 { 00505 if (i < j) 00506 return T(0); 00507 else 00508 return me_[Storage::GetFirst(i, j)][Storage::GetSecond(i, j)]; 00509 } 00510 } 00511 00512 00514 00523 template <class T, class Prop, class Storage, class Allocator> 00524 inline typename Matrix_Triangular<T, Prop, Storage, Allocator> 00525 ::const_reference 00526 Matrix_Triangular<T, Prop, Storage, Allocator>::Val(int i, int j) const 00527 { 00528 00529 #ifdef SELDON_CHECK_BOUNDS 00530 if (i < 0 || i >= this->m_) 00531 throw WrongRow("Matrix_Triangular::Val(int, int) const", 00532 string("Index should be in [0, ") + to_str(this->m_-1) 00533 + "], but is equal to " + to_str(i) + "."); 00534 if (j < 0 || j >= this->n_) 00535 throw WrongCol("Matrix_Triangular::Val(int, int) const", 00536 string("Index should be in [0, ") + to_str(this->n_-1) 00537 + "], but is equal to " + to_str(j) + "."); 00538 if ( (Storage::UpLo() && (i > j)) || (!Storage::UpLo() && (i < j)) ) 00539 throw WrongRow("Matrix_Triangular::Val(int, int)", 00540 string("Attempted to access to element (") 00541 + to_str(i) + ", " + to_str(j) 00542 + ") but this element is null."); 00543 #endif 00544 00545 return me_[Storage::GetFirst(i, j)][Storage::GetSecond(i, j)]; 00546 } 00547 00548 00550 00559 template <class T, class Prop, class Storage, class Allocator> 00560 inline typename Matrix_Triangular<T, Prop, Storage, Allocator>::reference 00561 Matrix_Triangular<T, Prop, Storage, Allocator>::Val(int i, int j) 00562 { 00563 00564 #ifdef SELDON_CHECK_BOUNDS 00565 if (i < 0 || i >= this->m_) 00566 throw WrongRow("Matrix_Triangular::Val(int, int)", 00567 string("Index should be in [0, ") + to_str(this->m_-1) 00568 + "], but is equal to " + to_str(i) + "."); 00569 if (j < 0 || j >= this->n_) 00570 throw WrongCol("Matrix_Triangular::Val(int, int)", 00571 string("Index should be in [0, ") + to_str(this->n_-1) 00572 + "], but is equal to " + to_str(j) + "."); 00573 if ( (Storage::UpLo() && (i > j)) || (!Storage::UpLo() && (i < j)) ) 00574 throw WrongRow("Matrix_Triangular::Val(int, int)", 00575 string("Attempted to access to element (") 00576 + to_str(i) + ", " + to_str(j) 00577 + ") but this element is null."); 00578 #endif 00579 00580 return me_[Storage::GetFirst(i, j)][Storage::GetSecond(i, j)]; 00581 } 00582 00583 00585 00591 template <class T, class Prop, class Storage, class Allocator> 00592 inline typename Matrix_Triangular<T, Prop, Storage, Allocator> 00593 ::const_reference 00594 Matrix_Triangular<T, Prop, Storage, Allocator>::Get(int i, int j) const 00595 { 00596 return this->Val(i, j); 00597 } 00598 00599 00601 00607 template <class T, class Prop, class Storage, class Allocator> 00608 inline typename Matrix_Triangular<T, Prop, Storage, Allocator>::reference 00609 Matrix_Triangular<T, Prop, Storage, Allocator>::Get(int i, int j) 00610 { 00611 return this->Val(i, j); 00612 } 00613 00614 00616 00621 template <class T, class Prop, class Storage, class Allocator> 00622 inline typename Matrix_Triangular<T, Prop, Storage, Allocator>::reference 00623 Matrix_Triangular<T, Prop, Storage, Allocator>::operator[] (int i) 00624 { 00625 00626 #ifdef SELDON_CHECK_BOUNDS 00627 if (i < 0 || i >= this->GetDataSize()) 00628 throw WrongIndex("Matrix_Triangular::operator[] (int)", 00629 string("Index should be in [0, ") 00630 + to_str(this->GetDataSize()-1) + "], but is equal to " 00631 + to_str(i) + "."); 00632 #endif 00633 00634 return this->data_[i]; 00635 } 00636 00637 00639 00644 template <class T, class Prop, class Storage, class Allocator> 00645 inline typename Matrix_Triangular<T, Prop, Storage, Allocator> 00646 ::const_reference 00647 Matrix_Triangular<T, Prop, Storage, Allocator>::operator[] (int i) const 00648 { 00649 00650 #ifdef SELDON_CHECK_BOUNDS 00651 if (i < 0 || i >= this->GetDataSize()) 00652 throw WrongIndex("Matrix_Triangular::operator[] (int) const", 00653 string("Index should be in [0, ") 00654 + to_str(this->GetDataSize()-1) + "], but is equal to " 00655 + to_str(i) + "."); 00656 #endif 00657 00658 return this->data_[i]; 00659 } 00660 00661 00663 00668 template <class T, class Prop, class Storage, class Allocator> 00669 inline Matrix_Triangular<T, Prop, Storage, Allocator>& 00670 Matrix_Triangular<T, Prop, Storage, Allocator> 00671 ::operator= (const Matrix_Triangular<T, Prop, Storage, Allocator>& A) 00672 { 00673 this->Copy(A); 00674 00675 return *this; 00676 } 00677 00678 00680 00685 template <class T, class Prop, class Storage, class Allocator> 00686 inline void Matrix_Triangular<T, Prop, Storage, Allocator> 00687 ::Set(int i, int j, const T& x) 00688 { 00689 this->Val(i, j) = x; 00690 } 00691 00692 00694 00699 template <class T, class Prop, class Storage, class Allocator> 00700 inline void Matrix_Triangular<T, Prop, Storage, Allocator> 00701 ::Copy(const Matrix_Triangular<T, Prop, Storage, Allocator>& A) 00702 { 00703 this->Reallocate(A.GetM(), A.GetN()); 00704 00705 this->allocator_.memorycpy(this->data_, A.GetData(), this->GetDataSize()); 00706 } 00707 00708 00709 /************************ 00710 * CONVENIENT FUNCTIONS * 00711 ************************/ 00712 00713 00715 00719 template <class T, class Prop, class Storage, class Allocator> 00720 void Matrix_Triangular<T, Prop, Storage, Allocator>::Zero() 00721 { 00722 this->allocator_.memoryset(this->data_, char(0), 00723 this->GetDataSize() * sizeof(value_type)); 00724 } 00725 00726 00728 template <class T, class Prop, class Storage, class Allocator> 00729 void Matrix_Triangular<T, Prop, Storage, Allocator>::SetIdentity() 00730 { 00731 this->Fill(T(0)); 00732 00733 T one(1); 00734 for (int i = 0; i < min(this->m_, this->n_); i++) 00735 this->Val(i, i) = one; 00736 } 00737 00738 00740 00744 template <class T, class Prop, class Storage, class Allocator> 00745 void Matrix_Triangular<T, Prop, Storage, Allocator>::Fill() 00746 { 00747 for (int i = 0; i < this->GetDataSize(); i++) 00748 this->data_[i] = i; 00749 } 00750 00751 00753 00757 template <class T, class Prop, class Storage, class Allocator> 00758 template <class T0> 00759 void Matrix_Triangular<T, Prop, Storage, Allocator>::Fill(const T0& x) 00760 { 00761 for (int i = 0; i < this->GetDataSize(); i++) 00762 this->data_[i] = x; 00763 } 00764 00765 00767 00771 template <class T, class Prop, class Storage, class Allocator> 00772 template <class T0> 00773 Matrix_Triangular<T, Prop, Storage, Allocator>& 00774 Matrix_Triangular<T, Prop, Storage, Allocator>::operator= (const T0& x) 00775 { 00776 this->Fill(x); 00777 00778 return *this; 00779 } 00780 00781 00783 00786 template <class T, class Prop, class Storage, class Allocator> 00787 void Matrix_Triangular<T, Prop, Storage, Allocator>::FillRand() 00788 { 00789 srand(time(NULL)); 00790 for (int i = 0; i < this->GetDataSize(); i++) 00791 this->data_[i] = rand(); 00792 } 00793 00794 00796 00801 template <class T, class Prop, class Storage, class Allocator> 00802 void Matrix_Triangular<T, Prop, Storage, Allocator>::Print() const 00803 { 00804 for (int i = 0; i < this->m_; i++) 00805 { 00806 for (int j = 0; j < this->n_; j++) 00807 cout << (*this)(i, j) << "\t"; 00808 cout << endl; 00809 } 00810 } 00811 00812 00814 00825 template <class T, class Prop, class Storage, class Allocator> 00826 void Matrix_Triangular<T, Prop, Storage, Allocator> 00827 ::Print(int a, int b, int m, int n) const 00828 { 00829 for (int i = a; i < min(this->m_, a + m); i++) 00830 { 00831 for (int j = b; j < min(this->n_, b + n); j++) 00832 cout << (*this)(i, j) << "\t"; 00833 cout << endl; 00834 } 00835 } 00836 00837 00839 00847 template <class T, class Prop, class Storage, class Allocator> 00848 void Matrix_Triangular<T, Prop, Storage, Allocator>::Print(int l) const 00849 { 00850 Print(0, 0, l, l); 00851 } 00852 00853 00854 /************************** 00855 * INPUT/OUTPUT FUNCTIONS * 00856 **************************/ 00857 00858 00860 00867 template <class T, class Prop, class Storage, class Allocator> 00868 void Matrix_Triangular<T, Prop, Storage, Allocator> 00869 ::Write(string FileName) const 00870 { 00871 ofstream FileStream; 00872 FileStream.open(FileName.c_str(), ofstream::binary); 00873 00874 #ifdef SELDON_CHECK_IO 00875 // Checks if the file was opened. 00876 if (!FileStream.is_open()) 00877 throw IOError("Matrix_Triangular::Write(string FileName)", 00878 string("Unable to open file \"") + FileName + "\"."); 00879 #endif 00880 00881 this->Write(FileStream); 00882 00883 FileStream.close(); 00884 } 00885 00886 00888 00895 template <class T, class Prop, class Storage, class Allocator> 00896 void Matrix_Triangular<T, Prop, Storage, Allocator> 00897 ::Write(ostream& FileStream) const 00898 { 00899 00900 #ifdef SELDON_CHECK_IO 00901 // Checks if the stream is ready. 00902 if (!FileStream.good()) 00903 throw IOError("Matrix_Triangular::Write(ofstream& FileStream)", 00904 "Stream is not ready."); 00905 #endif 00906 00907 FileStream.write(reinterpret_cast<char*>(const_cast<int*>(&this->m_)), 00908 sizeof(int)); 00909 FileStream.write(reinterpret_cast<char*>(const_cast<int*>(&this->n_)), 00910 sizeof(int)); 00911 00912 FileStream.write(reinterpret_cast<char*>(this->data_), 00913 this->m_ * this->n_ * sizeof(value_type)); 00914 00915 #ifdef SELDON_CHECK_IO 00916 // Checks if data was written. 00917 if (!FileStream.good()) 00918 throw IOError("Matrix_Triangular::Write(ofstream& FileStream)", 00919 string("Output operation failed.") 00920 + string(" The output file may have been removed") 00921 + " or there is no space left on device."); 00922 #endif 00923 00924 } 00925 00926 00928 00935 template <class T, class Prop, class Storage, class Allocator> 00936 void Matrix_Triangular<T, Prop, Storage, Allocator> 00937 ::WriteText(string FileName) const 00938 { 00939 ofstream FileStream; 00940 FileStream.precision(cout.precision()); 00941 FileStream.flags(cout.flags()); 00942 FileStream.open(FileName.c_str()); 00943 00944 #ifdef SELDON_CHECK_IO 00945 // Checks if the file was opened. 00946 if (!FileStream.is_open()) 00947 throw IOError("Matrix_Triangular::WriteText(string FileName)", 00948 string("Unable to open file \"") + FileName + "\"."); 00949 #endif 00950 00951 this->WriteText(FileStream); 00952 00953 FileStream.close(); 00954 } 00955 00956 00958 00965 template <class T, class Prop, class Storage, class Allocator> 00966 void Matrix_Triangular<T, Prop, Storage, Allocator> 00967 ::WriteText(ostream& FileStream) const 00968 { 00969 00970 #ifdef SELDON_CHECK_IO 00971 // Checks if the file is ready. 00972 if (!FileStream.good()) 00973 throw IOError("Matrix_Triangular::WriteText(ofstream& FileStream)", 00974 "Stream is not ready."); 00975 #endif 00976 00977 int i, j; 00978 for (i = 0; i < this->GetM(); i++) 00979 { 00980 for (j = 0; j < this->GetN(); j++) 00981 FileStream << (*this)(i, j) << '\t'; 00982 FileStream << endl; 00983 } 00984 00985 #ifdef SELDON_CHECK_IO 00986 // Checks if data was written. 00987 if (!FileStream.good()) 00988 throw IOError("Matrix_Triangular::WriteText(ofstream& FileStream)", 00989 string("Output operation failed.") 00990 + string(" The output file may have been removed") 00991 + " or there is no space left on device."); 00992 #endif 00993 00994 } 00995 00996 00998 01005 template <class T, class Prop, class Storage, class Allocator> 01006 void Matrix_Triangular<T, Prop, Storage, Allocator>::Read(string FileName) 01007 { 01008 ifstream FileStream; 01009 FileStream.open(FileName.c_str(), ifstream::binary); 01010 01011 #ifdef SELDON_CHECK_IO 01012 // Checks if the file was opened. 01013 if (!FileStream.is_open()) 01014 throw IOError("Matrix_Triangular::Read(string FileName)", 01015 string("Unable to open file \"") + FileName + "\"."); 01016 #endif 01017 01018 this->Read(FileStream); 01019 01020 FileStream.close(); 01021 } 01022 01023 01025 01032 template <class T, class Prop, class Storage, class Allocator> 01033 void Matrix_Triangular<T, Prop, Storage, Allocator> 01034 ::Read(istream& FileStream) 01035 { 01036 01037 #ifdef SELDON_CHECK_IO 01038 // Checks if the stream is ready. 01039 if (!FileStream.good()) 01040 throw IOError("Matrix_Triangular::Read(ifstream& FileStream)", 01041 "Stream is not ready."); 01042 #endif 01043 01044 int new_m, new_n; 01045 FileStream.read(reinterpret_cast<char*>(&new_m), sizeof(int)); 01046 FileStream.read(reinterpret_cast<char*>(&new_n), sizeof(int)); 01047 this->Reallocate(new_m, new_n); 01048 01049 FileStream.read(reinterpret_cast<char*>(this->data_), 01050 new_m * new_n * sizeof(value_type)); 01051 01052 #ifdef SELDON_CHECK_IO 01053 // Checks if data was read. 01054 if (!FileStream.good()) 01055 throw IOError("Matrix_Triangular::Read(ifstream& FileStream)", 01056 string("Input operation failed.") 01057 + string(" The input file may have been removed") 01058 + " or may not contain enough data."); 01059 #endif 01060 01061 } 01062 01063 01065 01069 template <class T, class Prop, class Storage, class Allocator> 01070 void Matrix_Triangular<T, Prop, Storage, Allocator>::ReadText(string FileName) 01071 { 01072 ifstream FileStream; 01073 FileStream.open(FileName.c_str()); 01074 01075 #ifdef SELDON_CHECK_IO 01076 // Checks if the file was opened. 01077 if (!FileStream.is_open()) 01078 throw IOError("Matrix_Pointers::ReadText(string FileName)", 01079 string("Unable to open file \"") + FileName + "\"."); 01080 #endif 01081 01082 this->ReadText(FileStream); 01083 01084 FileStream.close(); 01085 } 01086 01087 01089 01093 template <class T, class Prop, class Storage, class Allocator> 01094 void Matrix_Triangular<T, Prop, Storage, Allocator> 01095 ::ReadText(istream& FileStream) 01096 { 01097 // clears previous matrix 01098 Clear(); 01099 01100 #ifdef SELDON_CHECK_IO 01101 // Checks if the stream is ready. 01102 if (!FileStream.good()) 01103 throw IOError("Matrix_Pointers::ReadText(ifstream& FileStream)", 01104 "Stream is not ready."); 01105 #endif 01106 01107 // we read first line 01108 string line; 01109 getline(FileStream, line); 01110 01111 if (FileStream.fail()) 01112 { 01113 // empty file ? 01114 return; 01115 } 01116 01117 // converting first line into a vector 01118 istringstream line_stream(line); 01119 Vector<T> first_row; 01120 first_row.ReadText(line_stream); 01121 01122 // and now the other rows 01123 Vector<T> other_rows; 01124 other_rows.ReadText(FileStream); 01125 01126 // number of rows and columns 01127 int n = first_row.GetM(); 01128 int m = 1 + other_rows.GetM()/n; 01129 01130 #ifdef SELDON_CHECK_IO 01131 // Checking number of elements 01132 if (other_rows.GetM() != (m-1)*n) 01133 throw IOError("Matrix_Pointers::ReadText(ifstream& FileStream)", 01134 "The file should contain same number of columns."); 01135 #endif 01136 01137 this->Reallocate(m,n); 01138 // filling matrix 01139 if (Storage::UpLo()) 01140 for (int j = 0; j < n; j++) 01141 this->Val(0, j) = first_row(j); 01142 else 01143 this->Val(0, 0) = first_row(0); 01144 01145 int nb = 0; 01146 if (Storage::UpLo()) 01147 for (int i = 1; i < m; i++) 01148 { 01149 for (int j = 0; j < i; j++) 01150 nb++; 01151 01152 for (int j = i; j < n; j++) 01153 this->Val(i, j) = other_rows(nb++); 01154 } 01155 else 01156 for (int i = 1; i < m; i++) 01157 { 01158 for (int j = 0; j <= i; j++) 01159 this->Val(i, j) = other_rows(nb++); 01160 01161 for (int j = i+1; j < n; j++) 01162 nb++; 01163 } 01164 } 01165 01166 01167 01169 // MATRIX<COLUPTRIANG> // 01171 01172 01173 /**************** 01174 * CONSTRUCTORS * 01175 ****************/ 01176 01177 01179 01182 template <class T, class Prop, class Allocator> 01183 Matrix<T, Prop, ColUpTriang, Allocator>::Matrix(): 01184 Matrix_Triangular<T, Prop, ColUpTriang, Allocator>() 01185 { 01186 } 01187 01188 01190 01194 template <class T, class Prop, class Allocator> 01195 Matrix<T, Prop, ColUpTriang, Allocator>::Matrix(int i, int j): 01196 Matrix_Triangular<T, Prop, ColUpTriang, Allocator>(i, j) 01197 { 01198 } 01199 01200 01201 /***************** 01202 * OTHER METHODS * 01203 *****************/ 01204 01205 01207 01211 template <class T, class Prop, class Allocator> 01212 template <class T0> 01213 Matrix<T, Prop, ColUpTriang, Allocator>& 01214 Matrix<T, Prop, ColUpTriang, Allocator>::operator= (const T0& x) 01215 { 01216 this->Fill(x); 01217 01218 return *this; 01219 } 01220 01221 01223 01228 template <class T, class Prop, class Allocator> 01229 inline Matrix<T, Prop, ColUpTriang, Allocator>& 01230 Matrix<T, Prop, ColUpTriang, Allocator>::operator= 01231 (const Matrix<T, Prop, ColUpTriang, Allocator>& A) 01232 { 01233 this->Copy(A); 01234 return *this; 01235 } 01236 01237 01239 01242 template <class T, class Prop, class Allocator> 01243 template <class T0> 01244 Matrix<T, Prop, ColUpTriang, Allocator>& 01245 Matrix<T, Prop, ColUpTriang, Allocator>::operator*= (const T0& x) 01246 { 01247 for (int i = 0; i < this->GetDataSize();i++) 01248 this->data_[i] *= x; 01249 01250 return *this; 01251 } 01252 01253 01254 01256 // MATRIX<COLLOTRIANG> // 01258 01259 01260 /**************** 01261 * CONSTRUCTORS * 01262 ****************/ 01263 01264 01266 01269 template <class T, class Prop, class Allocator> 01270 Matrix<T, Prop, ColLoTriang, Allocator>::Matrix(): 01271 Matrix_Triangular<T, Prop, ColLoTriang, Allocator>() 01272 { 01273 } 01274 01275 01277 01281 template <class T, class Prop, class Allocator> 01282 Matrix<T, Prop, ColLoTriang, Allocator>::Matrix(int i, int j): 01283 Matrix_Triangular<T, Prop, ColLoTriang, Allocator>(i, j) 01284 { 01285 } 01286 01287 01288 /***************** 01289 * OTHER METHODS * 01290 *****************/ 01291 01292 01294 01298 template <class T, class Prop, class Allocator> 01299 template <class T0> 01300 Matrix<T, Prop, ColLoTriang, Allocator>& 01301 Matrix<T, Prop, ColLoTriang, Allocator>::operator= (const T0& x) 01302 { 01303 this->Fill(x); 01304 01305 return *this; 01306 } 01307 01308 01310 01315 template <class T, class Prop, class Allocator> 01316 inline Matrix<T, Prop, ColLoTriang, Allocator>& 01317 Matrix<T, Prop, ColLoTriang, Allocator>::operator= 01318 (const Matrix<T, Prop, ColLoTriang, Allocator>& A) 01319 { 01320 this->Copy(A); 01321 return *this; 01322 } 01323 01324 01326 01329 template <class T, class Prop, class Allocator> 01330 template <class T0> 01331 Matrix<T, Prop, ColLoTriang, Allocator>& 01332 Matrix<T, Prop, ColLoTriang, Allocator>::operator*= (const T0& x) 01333 { 01334 for (int i = 0; i < this->GetDataSize();i++) 01335 this->data_[i] *= x; 01336 01337 return *this; 01338 } 01339 01340 01341 01343 // MATRIX<ROWUPTRIANG> // 01345 01346 01347 /**************** 01348 * CONSTRUCTORS * 01349 ****************/ 01350 01351 01353 01356 template <class T, class Prop, class Allocator> 01357 Matrix<T, Prop, RowUpTriang, Allocator>::Matrix(): 01358 Matrix_Triangular<T, Prop, RowUpTriang, Allocator>() 01359 { 01360 } 01361 01362 01364 01368 template <class T, class Prop, class Allocator> 01369 Matrix<T, Prop, RowUpTriang, Allocator>::Matrix(int i, int j): 01370 Matrix_Triangular<T, Prop, RowUpTriang, Allocator>(i, j) 01371 { 01372 } 01373 01374 01375 /***************** 01376 * OTHER METHODS * 01377 *****************/ 01378 01379 01381 01385 template <class T, class Prop, class Allocator> 01386 template <class T0> 01387 Matrix<T, Prop, RowUpTriang, Allocator>& 01388 Matrix<T, Prop, RowUpTriang, Allocator>::operator= (const T0& x) 01389 { 01390 this->Fill(x); 01391 01392 return *this; 01393 } 01394 01395 01397 01402 template <class T, class Prop, class Allocator> 01403 inline Matrix<T, Prop, RowUpTriang, Allocator>& 01404 Matrix<T, Prop, RowUpTriang, Allocator>::operator= 01405 (const Matrix<T, Prop, RowUpTriang, Allocator>& A) 01406 { 01407 this->Copy(A); 01408 return *this; 01409 } 01410 01411 01413 01416 template <class T, class Prop, class Allocator> 01417 template <class T0> 01418 Matrix<T, Prop, RowUpTriang, Allocator>& 01419 Matrix<T, Prop, RowUpTriang, Allocator>::operator*= (const T0& x) 01420 { 01421 for (int i = 0; i < this->GetDataSize();i++) 01422 this->data_[i] *= x; 01423 01424 return *this; 01425 } 01426 01427 01428 01430 // MATRIX<ROWLOTRIANG> // 01432 01433 01434 /**************** 01435 * CONSTRUCTORS * 01436 ****************/ 01437 01438 01440 01443 template <class T, class Prop, class Allocator> 01444 Matrix<T, Prop, RowLoTriang, Allocator>::Matrix(): 01445 Matrix_Triangular<T, Prop, RowLoTriang, Allocator>() 01446 { 01447 } 01448 01449 01451 01455 template <class T, class Prop, class Allocator> 01456 Matrix<T, Prop, RowLoTriang, Allocator>::Matrix(int i, int j): 01457 Matrix_Triangular<T, Prop, RowLoTriang, Allocator>(i, j) 01458 { 01459 } 01460 01461 01462 /***************** 01463 * OTHER METHODS * 01464 *****************/ 01465 01466 01468 01472 template <class T, class Prop, class Allocator> 01473 template <class T0> 01474 Matrix<T, Prop, RowLoTriang, Allocator>& 01475 Matrix<T, Prop, RowLoTriang, Allocator>::operator= (const T0& x) 01476 { 01477 this->Fill(x); 01478 01479 return *this; 01480 } 01481 01482 01484 01489 template <class T, class Prop, class Allocator> 01490 inline Matrix<T, Prop, RowLoTriang, Allocator>& 01491 Matrix<T, Prop, RowLoTriang, Allocator>::operator= 01492 (const Matrix<T, Prop, RowLoTriang, Allocator>& A) 01493 { 01494 this->Copy(A); 01495 return *this; 01496 } 01497 01498 01500 01503 template <class T, class Prop, class Allocator> 01504 template <class T0> 01505 Matrix<T, Prop, RowLoTriang, Allocator>& 01506 Matrix<T, Prop, RowLoTriang, Allocator>::operator*= (const T0& x) 01507 { 01508 for (int i = 0; i < this->GetDataSize();i++) 01509 this->data_[i] *= x; 01510 01511 return *this; 01512 } 01513 01514 } // namespace Seldon. 01515 01516 #define SELDON_FILE_MATRIX_TRIANGULAR_CXX 01517 #endif