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_HERMITIAN_CXX 00022 00023 #include "Matrix_Hermitian.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_Hermitian<T, Prop, Storage, Allocator>::Matrix_Hermitian(): 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_Hermitian<T, Prop, Storage, Allocator> 00054 ::Matrix_Hermitian(int i, int j): 00055 Matrix_Base<T, Allocator>(i, i) 00056 { 00057 00058 #ifdef SELDON_CHECK_MEMORY 00059 try 00060 { 00061 #endif 00062 00063 me_ = reinterpret_cast<pointer*>(calloc(i, sizeof(pointer))); 00064 00065 #ifdef SELDON_CHECK_MEMORY 00066 } 00067 catch (...) 00068 { 00069 this->m_ = 0; 00070 this->n_ = 0; 00071 me_ = NULL; 00072 this->data_ = NULL; 00073 } 00074 if (me_ == NULL) 00075 { 00076 this->m_ = 0; 00077 this->n_ = 0; 00078 this->data_ = NULL; 00079 } 00080 if ((me_ == NULL) && (i != 0)) 00081 throw NoMemory("Matrix_Hermitian::Matrix_Hermitian(int, int)", 00082 string("Unable to allocate memory for a matrix of size ") 00083 + to_str(static_cast<long int>(i) 00084 * static_cast<long int>(i) 00085 * static_cast<long int>(sizeof(T))) 00086 + " bytes (" + to_str(i) + " x " + to_str(i) 00087 + " elements)."); 00088 #endif 00089 00090 #ifdef SELDON_CHECK_MEMORY 00091 try 00092 { 00093 #endif 00094 00095 this->data_ = this->allocator_.allocate(i * i, this); 00096 00097 #ifdef SELDON_CHECK_MEMORY 00098 } 00099 catch (...) 00100 { 00101 this->m_ = 0; 00102 this->n_ = 0; 00103 free(me_); 00104 me_ = NULL; 00105 this->data_ = NULL; 00106 } 00107 if (this->data_ == NULL) 00108 { 00109 this->m_ = 0; 00110 this->n_ = 0; 00111 free(me_); 00112 me_ = NULL; 00113 } 00114 if (this->data_ == NULL && i != 0) 00115 throw NoMemory("Matrix_Hermitian::Matrix_Hermitian(int, int)", 00116 string("Unable to allocate memory for a matrix of size ") 00117 + to_str(static_cast<long int>(i) 00118 * static_cast<long int>(i) 00119 * static_cast<long int>(sizeof(T))) 00120 + " bytes (" + to_str(i) + " x " + to_str(i) 00121 + " elements)."); 00122 #endif 00123 00124 pointer ptr = this->data_; 00125 int lgth = i; 00126 for (int k = 0; k < i; k++, ptr += lgth) 00127 me_[k] = ptr; 00128 } 00129 00130 00132 template <class T, class Prop, class Storage, class Allocator> 00133 inline Matrix_Hermitian<T, Prop, Storage, Allocator> 00134 ::Matrix_Hermitian(const Matrix_Hermitian<T, Prop, 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_Hermitian<T, Prop, Storage, Allocator>::~Matrix_Hermitian() 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_Hermitian<T, Prop, Storage, Allocator>::Clear() 00206 { 00207 this->~Matrix_Hermitian(); 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_Hermitian<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_Hermitian<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_Hermitian::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_Hermitian::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 00336 00350 template <class T, class Prop, class Storage, class Allocator> 00351 inline void Matrix_Hermitian<T, Prop, Storage, Allocator> 00352 ::SetData(int i, int j, 00353 typename Matrix_Hermitian<T, Prop, Storage, Allocator> 00354 ::pointer data) 00355 { 00356 this->Clear(); 00357 00358 this->m_ = i; 00359 this->n_ = i; 00360 00361 #ifdef SELDON_CHECK_MEMORY 00362 try 00363 { 00364 #endif 00365 00366 me_ = reinterpret_cast<pointer*>(calloc(i, sizeof(pointer))); 00367 00368 #ifdef SELDON_CHECK_MEMORY 00369 } 00370 catch (...) 00371 { 00372 this->m_ = 0; 00373 this->n_ = 0; 00374 me_ = NULL; 00375 this->data_ = NULL; 00376 return; 00377 } 00378 if (me_ == NULL) 00379 { 00380 this->m_ = 0; 00381 this->n_ = 0; 00382 this->data_ = NULL; 00383 return; 00384 } 00385 #endif 00386 00387 this->data_ = data; 00388 00389 pointer ptr = this->data_; 00390 int lgth = i; 00391 for (int k = 0; k < i; k++, ptr += lgth) 00392 me_[k] = ptr; 00393 } 00394 00395 00397 00402 template <class T, class Prop, class Storage, class Allocator> 00403 inline void Matrix_Hermitian<T, Prop, Storage, Allocator>::Nullify() 00404 { 00405 this->m_ = 0; 00406 this->n_ = 0; 00407 00408 #ifdef SELDON_CHECK_MEMORY 00409 try 00410 { 00411 #endif 00412 00413 if (me_ != NULL) 00414 { 00415 free(me_); 00416 me_ = NULL; 00417 } 00418 00419 #ifdef SELDON_CHECK_MEMORY 00420 } 00421 catch (...) 00422 { 00423 this->m_ = 0; 00424 this->n_ = 0; 00425 me_ = NULL; 00426 } 00427 #endif 00428 00429 this->data_ = NULL; 00430 } 00431 00432 00434 00441 template <class T, class Prop, class Storage, class Allocator> 00442 inline void Matrix_Hermitian<T, Prop, Storage, Allocator> 00443 ::Resize(int i, int j) 00444 { 00445 00446 // Storing the old values of the matrix. 00447 int iold = Storage::GetFirst(this->m_, this->n_); 00448 int jold = Storage::GetSecond(this->m_, this->n_); 00449 Vector<value_type, VectFull, Allocator> xold(this->GetDataSize()); 00450 for (int k = 0; k < this->GetDataSize(); k++) 00451 xold(k) = this->data_[k]; 00452 00453 // Reallocation. 00454 int inew = Storage::GetFirst(i, j); 00455 int jnew = Storage::GetSecond(i, j); 00456 this->Reallocate(i, j); 00457 00458 // Filling the matrix with its old values. 00459 int imin = min(iold, inew), jmin = min(jold, jnew); 00460 for (int k = 0; k < imin; k++) 00461 for (int l = 0; l < jmin; l++) 00462 this->data_[k*jnew+l] = xold(l+jold*k); 00463 } 00464 00465 00466 /********************************** 00467 * ELEMENT ACCESS AND AFFECTATION * 00468 **********************************/ 00469 00470 00472 00478 template <class T, class Prop, class Storage, class Allocator> 00479 inline typename Matrix_Hermitian<T, Prop, Storage, Allocator>::value_type 00480 Matrix_Hermitian<T, Prop, Storage, Allocator> 00481 ::operator() (int i, int j) const 00482 { 00483 00484 #ifdef SELDON_CHECK_BOUNDS 00485 if (i < 0 || i >= this->m_) 00486 throw WrongRow("Matrix_Hermitian::operator() const", 00487 string("Index should be in [0, ") + to_str(this->m_-1) 00488 + "], but is equal to " + to_str(i) + "."); 00489 if (j < 0 || j >= this->n_) 00490 throw WrongCol("Matrix_Hermitian::operator() const", 00491 string("Index should be in [0, ") + to_str(this->n_-1) 00492 + "], but is equal to " + to_str(j) + "."); 00493 #endif 00494 00495 if (i > j) 00496 return conj(me_[Storage::GetSecond(i, j)][Storage::GetFirst(i, j)]); 00497 else 00498 return me_[Storage::GetFirst(i, j)][Storage::GetSecond(i, j)]; 00499 } 00500 00501 00503 00509 template <class T, class Prop, class Storage, class Allocator> 00510 inline typename Matrix_Hermitian<T, Prop, Storage, Allocator> 00511 ::const_reference 00512 Matrix_Hermitian<T, Prop, Storage, Allocator>::Val(int i, int j) const 00513 { 00514 00515 #ifdef SELDON_CHECK_BOUNDS 00516 if (i < 0 || i >= this->m_) 00517 throw WrongRow("Matrix_Hermitian::Val(int, int) const", 00518 string("Index should be in [0, ") + to_str(this->m_-1) 00519 + "], but is equal to " + to_str(i) + "."); 00520 if (j < 0 || j >= this->n_) 00521 throw WrongCol("Matrix_Hermitian::Val(int, int) const", 00522 string("Index should be in [0, ") + to_str(this->n_-1) 00523 + "], but is equal to " + to_str(j) + "."); 00524 if (i > j) 00525 throw WrongRow("Matrix_Hermitian::Val(int, int)", 00526 string("Attempted to access to element (") 00527 + to_str(i) + ", " + to_str(j) 00528 + ") but row index should not be strictly" 00529 + " greater than column index."); 00530 #endif 00531 00532 return me_[Storage::GetFirst(i, j)][Storage::GetSecond(i, j)]; 00533 } 00534 00535 00537 00543 template <class T, class Prop, class Storage, class Allocator> 00544 inline typename Matrix_Hermitian<T, Prop, Storage, Allocator>::reference 00545 Matrix_Hermitian<T, Prop, Storage, Allocator>::Val(int i, int j) 00546 { 00547 00548 #ifdef SELDON_CHECK_BOUNDS 00549 if (i < 0 || i >= this->m_) 00550 throw WrongRow("Matrix_Hermitian::Val(int, int)", 00551 string("Index should be in [0, ") + to_str(this->m_-1) 00552 + "], but is equal to " + to_str(i) + "."); 00553 if (j < 0 || j >= this->n_) 00554 throw WrongCol("Matrix_Hermitian::Val(int, int)", 00555 string("Index should be in [0, ") + to_str(this->n_-1) 00556 + "], but is equal to " + to_str(j) + "."); 00557 if (i > j) 00558 throw WrongRow("Matrix_Hermitian::Val(int, int)", 00559 string("Attempted to access to element (") 00560 + to_str(i) + ", " + to_str(j) 00561 + ") but row index should not be strictly" 00562 + " greater than column index."); 00563 #endif 00564 00565 return me_[Storage::GetFirst(i, j)][Storage::GetSecond(i, j)]; 00566 } 00567 00568 00570 00576 template <class T, class Prop, class Storage, class Allocator> 00577 inline typename Matrix_Hermitian<T, Prop, Storage, Allocator> 00578 ::const_reference 00579 Matrix_Hermitian<T, Prop, Storage, Allocator>::Get(int i, int j) const 00580 { 00581 00582 #ifdef SELDON_CHECK_BOUNDS 00583 if (i < 0 || i >= this->m_) 00584 throw WrongRow("Matrix_Hermitian::Val(int, int) const", 00585 string("Index should be in [0, ") + to_str(this->m_-1) 00586 + "], but is equal to " + to_str(i) + "."); 00587 if (j < 0 || j >= this->n_) 00588 throw WrongCol("Matrix_Hermitian::Val(int, int) const", 00589 string("Index should be in [0, ") + to_str(this->n_-1) 00590 + "], but is equal to " + to_str(j) + "."); 00591 if (i > j) 00592 throw WrongRow("Matrix_Hermitian::Get(int, int)", 00593 string("Attempted to access to element (") 00594 + to_str(i) + ", " + to_str(j) 00595 + ") but row index should not be strictly" 00596 + " greater than column index."); 00597 #endif 00598 00599 return me_[Storage::GetFirst(i, j)][Storage::GetSecond(i, j)]; 00600 } 00601 00602 00604 00610 template <class T, class Prop, class Storage, class Allocator> 00611 inline typename Matrix_Hermitian<T, Prop, Storage, Allocator>::reference 00612 Matrix_Hermitian<T, Prop, Storage, Allocator>::Get(int i, int j) 00613 { 00614 00615 #ifdef SELDON_CHECK_BOUNDS 00616 if (i < 0 || i >= this->m_) 00617 throw WrongRow("Matrix_Hermitian::Val(int, int)", 00618 string("Index should be in [0, ") + to_str(this->m_-1) 00619 + "], but is equal to " + to_str(i) + "."); 00620 if (j < 0 || j >= this->n_) 00621 throw WrongCol("Matrix_Hermitian::Val(int, int)", 00622 string("Index should be in [0, ") + to_str(this->n_-1) 00623 + "], but is equal to " + to_str(j) + "."); 00624 if (i > j) 00625 throw WrongRow("Matrix_Hermitian::Val(int, int)", 00626 string("Attempted to access to element (") 00627 + to_str(i) + ", " + to_str(j) 00628 + ") but row index should not be strictly" 00629 + " greater than column index."); 00630 #endif 00631 00632 return me_[Storage::GetFirst(i, j)][Storage::GetSecond(i, j)]; 00633 } 00634 00635 00637 00642 template <class T, class Prop, class Storage, class Allocator> 00643 inline typename Matrix_Hermitian<T, Prop, Storage, Allocator>::reference 00644 Matrix_Hermitian<T, Prop, Storage, Allocator>::operator[] (int i) 00645 { 00646 00647 #ifdef SELDON_CHECK_BOUNDS 00648 if (i < 0 || i >= this->GetDataSize()) 00649 throw WrongIndex("Matrix_Hermitian::operator[] (int)", 00650 string("Index should be in [0, ") 00651 + to_str(this->GetDataSize()-1) + "], but is equal to " 00652 + to_str(i) + "."); 00653 #endif 00654 00655 return this->data_[i]; 00656 } 00657 00658 00660 00665 template <class T, class Prop, class Storage, class Allocator> 00666 inline typename Matrix_Hermitian<T, Prop, Storage, Allocator> 00667 ::const_reference 00668 Matrix_Hermitian<T, Prop, Storage, Allocator>::operator[] (int i) const 00669 { 00670 00671 #ifdef SELDON_CHECK_BOUNDS 00672 if (i < 0 || i >= this->GetDataSize()) 00673 throw WrongIndex("Matrix_Hermitian::operator[] (int) const", 00674 string("Index should be in [0, ") 00675 + to_str(this->GetDataSize()-1) + "], but is equal to " 00676 + to_str(i) + "."); 00677 #endif 00678 00679 return this->data_[i]; 00680 } 00681 00682 00684 00689 template <class T, class Prop, class Storage, class Allocator> 00690 inline void Matrix_Hermitian<T, Prop, Storage, Allocator> 00691 ::Set(int i, int j, const T& x) 00692 { 00693 if (i > j) 00694 this->Val(j, i) = conj(x); 00695 else 00696 this->Val(i, j) = x; 00697 } 00698 00699 00701 00706 template <class T, class Prop, class Storage, class Allocator> 00707 inline Matrix_Hermitian<T, Prop, Storage, Allocator>& 00708 Matrix_Hermitian<T, Prop, Storage, Allocator> 00709 ::operator=(const Matrix_Hermitian<T, Prop, Storage, Allocator>& A) 00710 { 00711 this->Copy(A); 00712 00713 return *this; 00714 } 00715 00716 00718 00723 template <class T, class Prop, class Storage, class Allocator> 00724 inline void Matrix_Hermitian<T, Prop, Storage, Allocator> 00725 ::Copy(const Matrix_Hermitian<T, Prop, Storage, Allocator>& A) 00726 { 00727 this->Reallocate(A.GetM(), A.GetN()); 00728 00729 this->allocator_.memorycpy(this->data_, A.GetData(), this->GetDataSize()); 00730 } 00731 00732 00733 /************************ 00734 * CONVENIENT FUNCTIONS * 00735 ************************/ 00736 00737 00739 00743 template <class T, class Prop, class Storage, class Allocator> 00744 void Matrix_Hermitian<T, Prop, Storage, Allocator>::Zero() 00745 { 00746 this->allocator_.memoryset(this->data_, char(0), 00747 this->GetDataSize() * sizeof(value_type)); 00748 } 00749 00750 00752 00756 template <class T, class Prop, class Storage, class Allocator> 00757 void Matrix_Hermitian<T, Prop, Storage, Allocator>::SetIdentity() 00758 { 00759 this->Fill(T(0)); 00760 00761 T one; 00762 SetComplexOne(one); 00763 for (int i = 0; i < min(this->m_, this->n_); i++) 00764 this->Val(i, i) = one; 00765 } 00766 00767 00769 00773 template <class T, class Prop, class Storage, class Allocator> 00774 void Matrix_Hermitian<T, Prop, Storage, Allocator>::Fill() 00775 { 00776 for (int i = 0; i < this->GetDataSize(); i++) 00777 this->data_[i] = i; 00778 } 00779 00780 00782 00787 template <class T, class Prop, class Storage, class Allocator> 00788 template <class T0> 00789 void Matrix_Hermitian<T, Prop, Storage, Allocator>::Fill(const T0& x) 00790 { 00791 for (int i = 0; i < this->GetDataSize(); i++) 00792 this->data_[i] = x; 00793 } 00794 00795 00797 00802 template <class T, class Prop, class Storage, class Allocator> 00803 template <class T0> 00804 Matrix_Hermitian<T, Prop, Storage, Allocator>& 00805 Matrix_Hermitian<T, Prop, Storage, Allocator>::operator= (const T0& x) 00806 { 00807 this->Fill(x); 00808 00809 return *this; 00810 } 00811 00812 00814 00817 template <class T, class Prop, class Storage, class Allocator> 00818 void Matrix_Hermitian<T, Prop, Storage, Allocator>::FillRand() 00819 { 00820 srand(time(NULL)); 00821 for (int i = 0; i < this->GetDataSize(); i++) 00822 this->data_[i] = rand(); 00823 } 00824 00825 00827 00832 template <class T, class Prop, class Storage, class Allocator> 00833 void Matrix_Hermitian<T, Prop, Storage, Allocator>::Print() const 00834 { 00835 for (int i = 0; i < this->m_; i++) 00836 { 00837 for (int j = 0; j < this->n_; j++) 00838 cout << (*this)(i, j) << "\t"; 00839 cout << endl; 00840 } 00841 } 00842 00843 00845 00856 template <class T, class Prop, class Storage, class Allocator> 00857 void Matrix_Hermitian<T, Prop, Storage, Allocator> 00858 ::Print(int a, int b, int m, int n) const 00859 { 00860 for (int i = a; i < min(this->m_, a+m); i++) 00861 { 00862 for (int j = b; j < min(this->n_, b+n); j++) 00863 cout << (*this)(i, j) << "\t"; 00864 cout << endl; 00865 } 00866 } 00867 00868 00870 00878 template <class T, class Prop, class Storage, class Allocator> 00879 void Matrix_Hermitian<T, Prop, Storage, Allocator>::Print(int l) const 00880 { 00881 Print(0, 0, l, l); 00882 } 00883 00884 00885 /************************** 00886 * INPUT/OUTPUT FUNCTIONS * 00887 **************************/ 00888 00889 00891 00898 template <class T, class Prop, class Storage, class Allocator> 00899 void Matrix_Hermitian<T, Prop, Storage, Allocator> 00900 ::Write(string FileName) const 00901 { 00902 ofstream FileStream; 00903 FileStream.open(FileName.c_str(), ofstream::binary); 00904 00905 #ifdef SELDON_CHECK_IO 00906 // Checks if the file was opened. 00907 if (!FileStream.is_open()) 00908 throw IOError("Matrix_Hermitian::Write(string FileName)", 00909 string("Unable to open file \"") + FileName + "\"."); 00910 #endif 00911 00912 this->Write(FileStream); 00913 00914 FileStream.close(); 00915 } 00916 00917 00919 00926 template <class T, class Prop, class Storage, class Allocator> 00927 void Matrix_Hermitian<T, Prop, Storage, Allocator> 00928 ::Write(ostream& FileStream) const 00929 { 00930 00931 #ifdef SELDON_CHECK_IO 00932 // Checks if the stream is ready. 00933 if (!FileStream.good()) 00934 throw IOError("Matrix_Hermitian::Write(ofstream& FileStream)", 00935 "Stream is not ready."); 00936 #endif 00937 00938 FileStream.write(reinterpret_cast<char*>(const_cast<int*>(&this->m_)), 00939 sizeof(int)); 00940 FileStream.write(reinterpret_cast<char*>(const_cast<int*>(&this->n_)), 00941 sizeof(int)); 00942 00943 FileStream.write(reinterpret_cast<char*>(this->data_), 00944 this->m_ * this->n_ * sizeof(value_type)); 00945 00946 #ifdef SELDON_CHECK_IO 00947 // Checks if data was written. 00948 if (!FileStream.good()) 00949 throw IOError("Matrix_Hermitian::Write(ofstream& FileStream)", 00950 string("Output operation failed.") 00951 + string(" The output file may have been removed") 00952 + " or there is no space left on device."); 00953 #endif 00954 00955 } 00956 00957 00959 00966 template <class T, class Prop, class Storage, class Allocator> 00967 void Matrix_Hermitian<T, Prop, Storage, Allocator> 00968 ::WriteText(string FileName) const 00969 { 00970 ofstream FileStream; 00971 FileStream.precision(cout.precision()); 00972 FileStream.flags(cout.flags()); 00973 FileStream.open(FileName.c_str()); 00974 00975 #ifdef SELDON_CHECK_IO 00976 // Checks if the file was opened. 00977 if (!FileStream.is_open()) 00978 throw IOError("Matrix_Hermitian::WriteText(string FileName)", 00979 string("Unable to open file \"") + FileName + "\"."); 00980 #endif 00981 00982 this->WriteText(FileStream); 00983 00984 FileStream.close(); 00985 } 00986 00987 00989 00996 template <class T, class Prop, class Storage, class Allocator> 00997 void Matrix_Hermitian<T, Prop, Storage, Allocator> 00998 ::WriteText(ostream& FileStream) const 00999 { 01000 01001 #ifdef SELDON_CHECK_IO 01002 // Checks if the file is ready. 01003 if (!FileStream.good()) 01004 throw IOError("Matrix_Hermitian::WriteText(ofstream& FileStream)", 01005 "Stream is not ready."); 01006 #endif 01007 01008 int i, j; 01009 for (i = 0; i < this->GetM(); i++) 01010 { 01011 for (j = 0; j < this->GetN(); j++) 01012 FileStream << (*this)(i, j) << '\t'; 01013 FileStream << endl; 01014 } 01015 01016 #ifdef SELDON_CHECK_IO 01017 // Checks if data was written. 01018 if (!FileStream.good()) 01019 throw IOError("Matrix_Hermitian::WriteText(ofstream& FileStream)", 01020 string("Output operation failed.") 01021 + string(" The output file may have been removed") 01022 + " or there is no space left on device."); 01023 #endif 01024 01025 } 01026 01027 01029 01036 template <class T, class Prop, class Storage, class Allocator> 01037 void Matrix_Hermitian<T, Prop, Storage, Allocator>::Read(string FileName) 01038 { 01039 ifstream FileStream; 01040 FileStream.open(FileName.c_str(), ifstream::binary); 01041 01042 #ifdef SELDON_CHECK_IO 01043 // Checks if the file was opened. 01044 if (!FileStream.is_open()) 01045 throw IOError("Matrix_Hermitian::Read(string FileName)", 01046 string("Unable to open file \"") + FileName + "\"."); 01047 #endif 01048 01049 this->Read(FileStream); 01050 01051 FileStream.close(); 01052 } 01053 01054 01056 01063 template <class T, class Prop, class Storage, class Allocator> 01064 void Matrix_Hermitian<T, Prop, Storage, Allocator> 01065 ::Read(istream& FileStream) 01066 { 01067 01068 #ifdef SELDON_CHECK_IO 01069 // Checks if the stream is ready. 01070 if (!FileStream.good()) 01071 throw IOError("Matrix_Hermitian::Read(ifstream& FileStream)", 01072 "Stream is not ready."); 01073 #endif 01074 01075 int new_m, new_n; 01076 FileStream.read(reinterpret_cast<char*>(&new_m), sizeof(int)); 01077 FileStream.read(reinterpret_cast<char*>(&new_n), sizeof(int)); 01078 this->Reallocate(new_m, new_n); 01079 01080 FileStream.read(reinterpret_cast<char*>(this->data_), 01081 new_m * new_n * sizeof(value_type)); 01082 01083 #ifdef SELDON_CHECK_IO 01084 // Checks if data was read. 01085 if (!FileStream.good()) 01086 throw IOError("Matrix_Hermitian::Read(ifstream& FileStream)", 01087 string("Input operation failed.") 01088 + string(" The input file may have been removed") 01089 + " or may not contain enough data."); 01090 #endif 01091 01092 } 01093 01094 01096 01100 template <class T, class Prop, class Storage, class Allocator> 01101 void Matrix_Hermitian<T, Prop, Storage, Allocator>::ReadText(string FileName) 01102 { 01103 ifstream FileStream; 01104 FileStream.open(FileName.c_str()); 01105 01106 #ifdef SELDON_CHECK_IO 01107 // Checks if the file was opened. 01108 if (!FileStream.is_open()) 01109 throw IOError("Matrix_Pointers::ReadText(string FileName)", 01110 string("Unable to open file \"") + FileName + "\"."); 01111 #endif 01112 01113 this->ReadText(FileStream); 01114 01115 FileStream.close(); 01116 } 01117 01118 01120 01124 template <class T, class Prop, class Storage, class Allocator> 01125 void Matrix_Hermitian<T, Prop, Storage, Allocator> 01126 ::ReadText(istream& FileStream) 01127 { 01128 // clears previous matrix 01129 Clear(); 01130 01131 #ifdef SELDON_CHECK_IO 01132 // Checks if the stream is ready. 01133 if (!FileStream.good()) 01134 throw IOError("Matrix_Pointers::ReadText(ifstream& FileStream)", 01135 "Stream is not ready."); 01136 #endif 01137 01138 // we read first line 01139 string line; 01140 getline(FileStream, line); 01141 01142 if (FileStream.fail()) 01143 { 01144 // empty file ? 01145 return; 01146 } 01147 01148 // converting first line into a vector 01149 istringstream line_stream(line); 01150 Vector<T> first_row; 01151 first_row.ReadText(line_stream); 01152 01153 // and now the other rows 01154 Vector<T> other_rows; 01155 other_rows.ReadText(FileStream); 01156 01157 // number of rows and columns 01158 int n = first_row.GetM(); 01159 int m = 1 + other_rows.GetM()/n; 01160 01161 #ifdef SELDON_CHECK_IO 01162 // Checking number of elements 01163 if (other_rows.GetM() != (m-1)*n) 01164 throw IOError("Matrix_Pointers::ReadText(ifstream& FileStream)", 01165 "The file should contain same number of columns."); 01166 #endif 01167 01168 this->Reallocate(m,n); 01169 // filling matrix 01170 for (int j = 0; j < n; j++) 01171 this->Val(0, j) = first_row(j); 01172 01173 int nb = 0; 01174 for (int i = 1; i < m; i++) 01175 { 01176 for (int j = 0; j < i; j++) 01177 nb++; 01178 01179 for (int j = i; j < n; j++) 01180 this->Val(i, j) = other_rows(nb++); 01181 } 01182 } 01183 01184 01185 01187 // MATRIX<COLHERM> // 01189 01190 01191 /**************** 01192 * CONSTRUCTORS * 01193 ****************/ 01194 01195 01197 01200 template <class T, class Prop, class Allocator> 01201 Matrix<T, Prop, ColHerm, Allocator>::Matrix(): 01202 Matrix_Hermitian<T, Prop, ColHerm, Allocator>() 01203 { 01204 } 01205 01206 01208 01212 template <class T, class Prop, class Allocator> 01213 Matrix<T, Prop, ColHerm, Allocator>::Matrix(int i, int j): 01214 Matrix_Hermitian<T, Prop, ColHerm, Allocator>(i, j) 01215 { 01216 } 01217 01218 01219 /***************** 01220 * OTHER METHODS * 01221 *****************/ 01222 01223 01225 01228 template <class T, class Prop, class Allocator> 01229 template <class T0> 01230 Matrix<T, Prop, ColHerm, Allocator>& 01231 Matrix<T, Prop, ColHerm, Allocator>::operator= (const T0& x) 01232 { 01233 this->Fill(x); 01234 01235 return *this; 01236 } 01237 01239 01244 template <class T, class Prop, class Allocator> 01245 inline Matrix<T, Prop, ColHerm, Allocator>& 01246 Matrix<T, Prop, ColHerm, Allocator>::operator= (const Matrix<T, Prop, 01247 ColHerm, 01248 Allocator>& A) 01249 { 01250 this->Copy(A); 01251 return *this; 01252 } 01253 01254 01256 01261 template <class T, class Prop, class Allocator> 01262 template <class T0> 01263 Matrix<T, Prop, ColHerm, Allocator>& 01264 Matrix<T, Prop, ColHerm, Allocator>::operator*= (const T0& x) 01265 { 01266 for (int i = 0; i < this->GetDataSize();i++) 01267 this->data_[i] *= x; 01268 01269 return *this; 01270 } 01271 01272 01273 01275 // MATRIX<ROWHERM> // 01277 01278 01279 /**************** 01280 * CONSTRUCTORS * 01281 ****************/ 01282 01283 01285 01288 template <class T, class Prop, class Allocator> 01289 Matrix<T, Prop, RowHerm, Allocator>::Matrix(): 01290 Matrix_Hermitian<T, Prop, RowHerm, Allocator>() 01291 { 01292 } 01293 01294 01296 01300 template <class T, class Prop, class Allocator> 01301 Matrix<T, Prop, RowHerm, Allocator>::Matrix(int i, int j): 01302 Matrix_Hermitian<T, Prop, RowHerm, Allocator>(i, j) 01303 { 01304 } 01305 01306 01307 /***************** 01308 * OTHER METHODS * 01309 *****************/ 01310 01311 01313 01316 template <class T, class Prop, class Allocator> 01317 template <class T0> 01318 Matrix<T, Prop, RowHerm, Allocator>& 01319 Matrix<T, Prop, RowHerm, Allocator>::operator= (const T0& x) 01320 { 01321 this->Fill(x); 01322 01323 return *this; 01324 } 01325 01327 01332 template <class T, class Prop, class Allocator> 01333 inline Matrix<T, Prop, RowHerm, Allocator>& 01334 Matrix<T, Prop, RowHerm, Allocator>::operator= (const Matrix<T, Prop, 01335 RowHerm, 01336 Allocator>& A) 01337 { 01338 this->Copy(A); 01339 return *this; 01340 } 01341 01342 01344 01347 template <class T, class Prop, class Allocator> 01348 template <class T0> 01349 Matrix<T, Prop, RowHerm, Allocator>& 01350 Matrix<T, Prop, RowHerm, Allocator>::operator*= (const T0& x) 01351 { 01352 for (int i = 0; i < this->GetDataSize();i++) 01353 this->data_[i] *= x; 01354 01355 return *this; 01356 } 01357 01358 } // namespace Seldon. 01359 01360 #define SELDON_FILE_MATRIX_HERMITIAN_CXX 01361 #endif