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_SYMMETRIC_CXX 00022 00023 #include "Matrix_Symmetric.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_Symmetric<T, Prop, Storage, Allocator>::Matrix_Symmetric(): 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_Symmetric<T, Prop, Storage, Allocator> 00054 ::Matrix_Symmetric(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_Symmetric::Matrix_Symmetric(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_Symmetric::Matrix_Symmetric(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_Symmetric<T, Prop, Storage, Allocator> 00133 ::Matrix_Symmetric(const Matrix_Symmetric<T, Prop, Storage, Allocator>& A) 00134 : Matrix_Base<T, Allocator>() 00135 { 00136 this->m_ = 0; 00137 this->n_ = 0; 00138 this->data_ = NULL; 00139 this->me_ = NULL; 00140 00141 this->Copy(A); 00142 } 00143 00144 00145 /************** 00146 * DESTRUCTOR * 00147 **************/ 00148 00149 00151 template <class T, class Prop, class Storage, class Allocator> 00152 inline Matrix_Symmetric<T, Prop, Storage, Allocator>::~Matrix_Symmetric() 00153 { 00154 00155 #ifdef SELDON_CHECK_MEMORY 00156 try 00157 { 00158 #endif 00159 00160 if (this->data_ != NULL) 00161 { 00162 this->allocator_.deallocate(this->data_, this->m_ * this->n_); 00163 this->data_ = NULL; 00164 } 00165 00166 #ifdef SELDON_CHECK_MEMORY 00167 } 00168 catch (...) 00169 { 00170 this->data_ = NULL; 00171 } 00172 #endif 00173 00174 #ifdef SELDON_CHECK_MEMORY 00175 try 00176 { 00177 #endif 00178 00179 if (me_ != NULL) 00180 { 00181 free(me_); 00182 me_ = NULL; 00183 } 00184 00185 #ifdef SELDON_CHECK_MEMORY 00186 } 00187 catch (...) 00188 { 00189 this->m_ = 0; 00190 this->n_ = 0; 00191 me_ = NULL; 00192 } 00193 #endif 00194 00195 } 00196 00197 00199 00203 template <class T, class Prop, class Storage, class Allocator> 00204 inline void Matrix_Symmetric<T, Prop, Storage, Allocator>::Clear() 00205 { 00206 this->~Matrix_Symmetric(); 00207 this->m_ = 0; 00208 this->n_ = 0; 00209 } 00210 00211 00212 /******************* 00213 * BASIC FUNCTIONS * 00214 *******************/ 00215 00216 00218 00224 template <class T, class Prop, class Storage, class Allocator> 00225 int Matrix_Symmetric<T, Prop, Storage, Allocator>::GetDataSize() const 00226 { 00227 return this->m_ * this->n_; 00228 } 00229 00230 00231 /********************* 00232 * MEMORY MANAGEMENT * 00233 *********************/ 00234 00235 00237 00243 template <class T, class Prop, class Storage, class Allocator> 00244 inline void Matrix_Symmetric<T, Prop, Storage, Allocator> 00245 ::Reallocate(int i, int j) 00246 { 00247 00248 if (i != this->m_) 00249 { 00250 this->m_ = i; 00251 this->n_ = i; 00252 00253 #ifdef SELDON_CHECK_MEMORY 00254 try 00255 { 00256 #endif 00257 00258 me_ = reinterpret_cast<pointer*>( realloc(me_, 00259 i * sizeof(pointer)) ); 00260 00261 #ifdef SELDON_CHECK_MEMORY 00262 } 00263 catch (...) 00264 { 00265 this->m_ = 0; 00266 this->n_ = 0; 00267 me_ = NULL; 00268 this->data_ = NULL; 00269 } 00270 if (me_ == NULL) 00271 { 00272 this->m_ = 0; 00273 this->n_ = 0; 00274 this->data_ = NULL; 00275 } 00276 if (me_ == NULL && i != 0) 00277 throw NoMemory("Matrix_Symmetric::Reallocate(int, int)", 00278 string("Unable to reallocate memory") 00279 + " for a matrix of size " 00280 + to_str(static_cast<long int>(i) 00281 * static_cast<long int>(i) 00282 * static_cast<long int>(sizeof(T))) 00283 + " bytes (" + to_str(i) + " x " + to_str(i) 00284 + " elements)."); 00285 #endif 00286 00287 #ifdef SELDON_CHECK_MEMORY 00288 try 00289 { 00290 #endif 00291 00292 this->data_ = 00293 reinterpret_cast<pointer>(this->allocator_.reallocate(this->data_, 00294 i * i, 00295 this) ); 00296 00297 #ifdef SELDON_CHECK_MEMORY 00298 } 00299 catch (...) 00300 { 00301 this->m_ = 0; 00302 this->n_ = 0; 00303 free(me_); 00304 me_ = NULL; 00305 this->data_ = NULL; 00306 } 00307 if (this->data_ == NULL) 00308 { 00309 this->m_ = 0; 00310 this->n_ = 0; 00311 free(me_); 00312 me_ = NULL; 00313 } 00314 if (this->data_ == NULL && i != 0) 00315 throw NoMemory("Matrix_Symmetric::Reallocate(int, int)", 00316 string("Unable to reallocate memory") 00317 + " for a matrix of size " 00318 + to_str(static_cast<long int>(i) 00319 * static_cast<long int>(i) 00320 * static_cast<long int>(sizeof(T))) 00321 + " bytes (" + to_str(i) + " x " + to_str(i) 00322 + " elements)."); 00323 #endif 00324 00325 pointer ptr = this->data_; 00326 int lgth = Storage::GetSecond(i, i); 00327 for (int k = 0; k < Storage::GetFirst(i, i); k++, ptr += lgth) 00328 me_[k] = ptr; 00329 } 00330 } 00331 00332 00335 00349 template <class T, class Prop, class Storage, class Allocator> 00350 inline void Matrix_Symmetric<T, Prop, Storage, Allocator> 00351 ::SetData(int i, int j, 00352 typename Matrix_Symmetric<T, Prop, Storage, Allocator> 00353 ::pointer data) 00354 { 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_Symmetric<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_Symmetric<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_Symmetric<T, Prop, Storage, Allocator>::reference 00480 Matrix_Symmetric<T, Prop, Storage, Allocator>::operator() (int i, int j) 00481 { 00482 00483 #ifdef SELDON_CHECK_BOUNDS 00484 if (i < 0 || i >= this->m_) 00485 throw WrongRow("Matrix_Symmetric::operator()", 00486 string("Index should be in [0, ") + to_str(this->m_-1) 00487 + "], but is equal to " + to_str(i) + "."); 00488 if (j < 0 || j >= this->n_) 00489 throw WrongCol("Matrix_Symmetric::operator()", 00490 string("Index should be in [0, ") + to_str(this->n_-1) 00491 + "], but is equal to " + to_str(j) + "."); 00492 #endif 00493 00494 if (i > j) 00495 return me_[Storage::GetSecond(i, j)][Storage::GetFirst(i, j)]; 00496 else 00497 return me_[Storage::GetFirst(i, j)][Storage::GetSecond(i, j)]; 00498 } 00499 00500 00502 00508 template <class T, class Prop, class Storage, class Allocator> 00509 inline typename Matrix_Symmetric<T, Prop, Storage, Allocator> 00510 ::const_reference 00511 Matrix_Symmetric<T, Prop, Storage, Allocator> 00512 ::operator() (int i, int j) const 00513 { 00514 00515 #ifdef SELDON_CHECK_BOUNDS 00516 if (i < 0 || i >= this->m_) 00517 throw WrongRow("Matrix_Symmetric::operator() 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_Symmetric::operator() const", 00522 string("Index should be in [0, ") + to_str(this->n_-1) 00523 + "], but is equal to " + to_str(j) + "."); 00524 #endif 00525 00526 if (i > j) 00527 return me_[Storage::GetSecond(i, j)][Storage::GetFirst(i, j)]; 00528 else 00529 return me_[Storage::GetFirst(i, j)][Storage::GetSecond(i, j)]; 00530 } 00531 00532 00534 00540 template <class T, class Prop, class Storage, class Allocator> 00541 inline typename Matrix_Symmetric<T, Prop, Storage, Allocator> 00542 ::const_reference 00543 Matrix_Symmetric<T, Prop, Storage, Allocator>::Val(int i, int j) const 00544 { 00545 00546 #ifdef SELDON_CHECK_BOUNDS 00547 if (i < 0 || i >= this->m_) 00548 throw WrongRow("Matrix_Symmetric::Val(int, int) const", 00549 string("Index should be in [0, ") + to_str(this->m_-1) 00550 + "], but is equal to " + to_str(i) + "."); 00551 if (j < 0 || j >= this->n_) 00552 throw WrongCol("Matrix_Symmetric::Val(int, int) const", 00553 string("Index should be in [0, ") + to_str(this->n_-1) 00554 + "], but is equal to " + to_str(j) + "."); 00555 if (i > j) 00556 throw WrongRow("Matrix_Symmetric::Val(int, int)", 00557 string("Attempted to access to element (") 00558 + to_str(i) + ", " + to_str(j) 00559 + ") but row index should not be strictly" 00560 + " greater than column index."); 00561 #endif 00562 00563 return me_[Storage::GetFirst(i, j)][Storage::GetSecond(i, j)]; 00564 } 00565 00566 00568 00574 template <class T, class Prop, class Storage, class Allocator> 00575 inline typename Matrix_Symmetric<T, Prop, Storage, Allocator>::reference 00576 Matrix_Symmetric<T, Prop, Storage, Allocator>::Val(int i, int j) 00577 { 00578 00579 #ifdef SELDON_CHECK_BOUNDS 00580 if (i < 0 || i >= this->m_) 00581 throw WrongRow("Matrix_Symmetric::Val(int, int)", 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_Symmetric::Val(int, int)", 00586 string("Index should be in [0, ") + to_str(this->n_-1) 00587 + "], but is equal to " + to_str(j) + "."); 00588 if (i > j) 00589 throw WrongRow("Matrix_Symmetric::Val(int, int)", 00590 string("Attempted to access to element (") 00591 + to_str(i) + ", " + to_str(j) 00592 + ") but row index should not be strictly" 00593 + " greater than column index."); 00594 #endif 00595 00596 return me_[Storage::GetFirst(i, j)][Storage::GetSecond(i, j)]; 00597 } 00598 00599 00601 00607 template <class T, class Prop, class Storage, class Allocator> 00608 inline typename Matrix_Symmetric<T, Prop, Storage, Allocator>::reference 00609 Matrix_Symmetric<T, Prop, Storage, Allocator>::Get(int i, int j) 00610 { 00611 00612 #ifdef SELDON_CHECK_BOUNDS 00613 if (i < 0 || i >= this->m_) 00614 throw WrongRow("Matrix_Symmetric::Get(int, int)", 00615 string("Index should be in [0, ") + to_str(this->m_-1) 00616 + "], but is equal to " + to_str(i) + "."); 00617 if (j < 0 || j >= this->n_) 00618 throw WrongCol("Matrix_Symmetric::Get(int, int)", 00619 string("Index should be in [0, ") + to_str(this->n_-1) 00620 + "], but is equal to " + to_str(j) + "."); 00621 #endif 00622 00623 if (i > j) 00624 return me_[Storage::GetSecond(i, j)][Storage::GetFirst(i, j)]; 00625 else 00626 return me_[Storage::GetFirst(i, j)][Storage::GetSecond(i, j)]; 00627 } 00628 00629 00631 00637 template <class T, class Prop, class Storage, class Allocator> 00638 inline typename Matrix_Symmetric<T, Prop, Storage, Allocator> 00639 ::const_reference 00640 Matrix_Symmetric<T, Prop, Storage, Allocator> 00641 ::Get(int i, int j) const 00642 { 00643 00644 #ifdef SELDON_CHECK_BOUNDS 00645 if (i < 0 || i >= this->m_) 00646 throw WrongRow("Matrix_Symmetric::Get(int, int) const", 00647 string("Index should be in [0, ") + to_str(this->m_-1) 00648 + "], but is equal to " + to_str(i) + "."); 00649 if (j < 0 || j >= this->n_) 00650 throw WrongCol("Matrix_Symmetric::Get(int, int) const", 00651 string("Index should be in [0, ") + to_str(this->n_-1) 00652 + "], but is equal to " + to_str(j) + "."); 00653 #endif 00654 00655 if (i > j) 00656 return me_[Storage::GetSecond(i, j)][Storage::GetFirst(i, j)]; 00657 else 00658 return me_[Storage::GetFirst(i, j)][Storage::GetSecond(i, j)]; 00659 } 00660 00661 00663 00668 template <class T, class Prop, class Storage, class Allocator> 00669 inline typename Matrix_Symmetric<T, Prop, Storage, Allocator>::reference 00670 Matrix_Symmetric<T, Prop, Storage, Allocator>::operator[] (int i) 00671 { 00672 00673 #ifdef SELDON_CHECK_BOUNDS 00674 if (i < 0 || i >= this->GetDataSize()) 00675 throw WrongIndex("Matrix_Symmetric::operator[] (int)", 00676 string("Index should be in [0, ") 00677 + to_str(this->GetDataSize()-1) + "], but is equal to " 00678 + to_str(i) + "."); 00679 #endif 00680 00681 return this->data_[i]; 00682 } 00683 00684 00686 00691 template <class T, class Prop, class Storage, class Allocator> 00692 inline typename Matrix_Symmetric<T, Prop, Storage, Allocator> 00693 ::const_reference 00694 Matrix_Symmetric<T, Prop, Storage, Allocator>::operator[] (int i) const 00695 { 00696 00697 #ifdef SELDON_CHECK_BOUNDS 00698 if (i < 0 || i >= this->GetDataSize()) 00699 throw WrongIndex("Matrix_Symmetric::operator[] (int) const", 00700 string("Index should be in [0, ") 00701 + to_str(this->GetDataSize()-1) + "], but is equal to " 00702 + to_str(i) + "."); 00703 #endif 00704 00705 return this->data_[i]; 00706 } 00707 00708 00710 00715 template <class T, class Prop, class Storage, class Allocator> 00716 inline Matrix_Symmetric<T, Prop, Storage, Allocator>& 00717 Matrix_Symmetric<T, Prop, Storage, Allocator> 00718 ::operator= (const Matrix_Symmetric<T, Prop, Storage, Allocator>& A) 00719 { 00720 this->Copy(A); 00721 00722 return *this; 00723 } 00724 00725 00727 00732 template <class T, class Prop, class Storage, class Allocator> 00733 inline void Matrix_Symmetric<T, Prop, Storage, Allocator> 00734 ::Set(int i, int j, const T& x) 00735 { 00736 this->Get(i, j) = x; 00737 } 00738 00739 00741 00746 template <class T, class Prop, class Storage, class Allocator> 00747 inline void Matrix_Symmetric<T, Prop, Storage, Allocator> 00748 ::Copy(const Matrix_Symmetric<T, Prop, Storage, Allocator>& A) 00749 { 00750 this->Reallocate(A.GetM(), A.GetN()); 00751 00752 this->allocator_.memorycpy(this->data_, A.GetData(), this->GetDataSize()); 00753 } 00754 00755 00756 /************************ 00757 * CONVENIENT FUNCTIONS * 00758 ************************/ 00759 00760 00762 00766 template <class T, class Prop, class Storage, class Allocator> 00767 void Matrix_Symmetric<T, Prop, Storage, Allocator>::Zero() 00768 { 00769 this->allocator_.memoryset(this->data_, char(0), 00770 this->GetDataSize() * sizeof(value_type)); 00771 } 00772 00773 00775 template <class T, class Prop, class Storage, class Allocator> 00776 void Matrix_Symmetric<T, Prop, Storage, Allocator>::SetIdentity() 00777 { 00778 this->Fill(T(0)); 00779 00780 T one(1); 00781 for (int i = 0; i < min(this->m_, this->n_); i++) 00782 this->Val(i, i) = one; 00783 } 00784 00785 00787 00791 template <class T, class Prop, class Storage, class Allocator> 00792 void Matrix_Symmetric<T, Prop, Storage, Allocator>::Fill() 00793 { 00794 for (int i = 0; i < this->GetDataSize(); i++) 00795 this->data_[i] = i; 00796 } 00797 00798 00800 00803 template <class T, class Prop, class Storage, class Allocator> 00804 template <class T0> 00805 void Matrix_Symmetric<T, Prop, Storage, Allocator>::Fill(const T0& x) 00806 { 00807 for (int i = 0; i < this->GetDataSize(); i++) 00808 this->data_[i] = x; 00809 } 00810 00811 00813 00816 template <class T, class Prop, class Storage, class Allocator> 00817 template <class T0> 00818 Matrix_Symmetric<T, Prop, Storage, Allocator>& 00819 Matrix_Symmetric<T, Prop, Storage, Allocator>::operator= (const T0& x) 00820 { 00821 this->Fill(x); 00822 00823 return *this; 00824 } 00825 00826 00828 00831 template <class T, class Prop, class Storage, class Allocator> 00832 void Matrix_Symmetric<T, Prop, Storage, Allocator>::FillRand() 00833 { 00834 srand(time(NULL)); 00835 for (int i = 0; i < this->GetDataSize(); i++) 00836 this->data_[i] = rand(); 00837 } 00838 00839 00841 00846 template <class T, class Prop, class Storage, class Allocator> 00847 void Matrix_Symmetric<T, Prop, Storage, Allocator>::Print() const 00848 { 00849 for (int i = 0; i < this->m_; i++) 00850 { 00851 for (int j = 0; j < this->n_; j++) 00852 cout << (*this)(i, j) << "\t"; 00853 cout << endl; 00854 } 00855 } 00856 00857 00859 00870 template <class T, class Prop, class Storage, class Allocator> 00871 void Matrix_Symmetric<T, Prop, Storage, Allocator> 00872 ::Print(int a, int b, int m, int n) const 00873 { 00874 for (int i = a; i < min(this->m_, a + m); i++) 00875 { 00876 for (int j = b; j < min(this->n_, b + n); j++) 00877 cout << (*this)(i, j) << "\t"; 00878 cout << endl; 00879 } 00880 } 00881 00882 00884 00892 template <class T, class Prop, class Storage, class Allocator> 00893 void Matrix_Symmetric<T, Prop, Storage, Allocator>::Print(int l) const 00894 { 00895 Print(0, 0, l, l); 00896 } 00897 00898 00899 /************************** 00900 * INPUT/OUTPUT FUNCTIONS * 00901 **************************/ 00902 00903 00905 00912 template <class T, class Prop, class Storage, class Allocator> 00913 void Matrix_Symmetric<T, Prop, Storage, Allocator> 00914 ::Write(string FileName) const 00915 { 00916 ofstream FileStream; 00917 FileStream.open(FileName.c_str(), ofstream::binary); 00918 00919 #ifdef SELDON_CHECK_IO 00920 // Checks if the file was opened. 00921 if (!FileStream.is_open()) 00922 throw IOError("Matrix_Symmetric::Write(string FileName)", 00923 string("Unable to open file \"") + FileName + "\"."); 00924 #endif 00925 00926 this->Write(FileStream); 00927 00928 FileStream.close(); 00929 } 00930 00931 00933 00940 template <class T, class Prop, class Storage, class Allocator> 00941 void Matrix_Symmetric<T, Prop, Storage, Allocator> 00942 ::Write(ostream& FileStream) const 00943 { 00944 00945 #ifdef SELDON_CHECK_IO 00946 // Checks if the stream is ready. 00947 if (!FileStream.good()) 00948 throw IOError("Matrix_Symmetric::Write(ofstream& FileStream)", 00949 "Stream is not ready."); 00950 #endif 00951 00952 FileStream.write(reinterpret_cast<char*>(const_cast<int*>(&this->m_)), 00953 sizeof(int)); 00954 FileStream.write(reinterpret_cast<char*>(const_cast<int*>(&this->n_)), 00955 sizeof(int)); 00956 00957 FileStream.write(reinterpret_cast<char*>(this->data_), 00958 this->m_ * this->n_ * sizeof(value_type)); 00959 00960 #ifdef SELDON_CHECK_IO 00961 // Checks if data was written. 00962 if (!FileStream.good()) 00963 throw IOError("Matrix_Symmetric::Write(ofstream& FileStream)", 00964 string("Output operation failed.") 00965 + string(" The output file may have been removed") 00966 + " or there is no space left on device."); 00967 #endif 00968 00969 } 00970 00971 00973 00980 template <class T, class Prop, class Storage, class Allocator> 00981 void Matrix_Symmetric<T, Prop, Storage, Allocator> 00982 ::WriteText(string FileName) const 00983 { 00984 ofstream FileStream; 00985 FileStream.precision(cout.precision()); 00986 FileStream.flags(cout.flags()); 00987 FileStream.open(FileName.c_str()); 00988 00989 #ifdef SELDON_CHECK_IO 00990 // Checks if the file was opened. 00991 if (!FileStream.is_open()) 00992 throw IOError("Matrix_Symmetric::WriteText(string FileName)", 00993 string("Unable to open file \"") + FileName + "\"."); 00994 #endif 00995 00996 this->WriteText(FileStream); 00997 00998 FileStream.close(); 00999 } 01000 01001 01003 01010 template <class T, class Prop, class Storage, class Allocator> 01011 void Matrix_Symmetric<T, Prop, Storage, Allocator> 01012 ::WriteText(ostream& FileStream) const 01013 { 01014 01015 #ifdef SELDON_CHECK_IO 01016 // Checks if the file is ready. 01017 if (!FileStream.good()) 01018 throw IOError("Matrix_Symmetric::WriteText(ofstream& FileStream)", 01019 "Stream is not ready."); 01020 #endif 01021 01022 int i, j; 01023 for (i = 0; i < this->GetM(); i++) 01024 { 01025 for (j = 0; j < this->GetN(); j++) 01026 FileStream << (*this)(i, j) << '\t'; 01027 FileStream << endl; 01028 } 01029 01030 #ifdef SELDON_CHECK_IO 01031 // Checks if data was written. 01032 if (!FileStream.good()) 01033 throw IOError("Matrix_Symmetric::WriteText(ofstream& FileStream)", 01034 string("Output operation failed.") 01035 + string(" The output file may have been removed") 01036 + " or there is no space left on device."); 01037 #endif 01038 01039 } 01040 01041 01043 01050 template <class T, class Prop, class Storage, class Allocator> 01051 void Matrix_Symmetric<T, Prop, Storage, Allocator>::Read(string FileName) 01052 { 01053 ifstream FileStream; 01054 FileStream.open(FileName.c_str(), ifstream::binary); 01055 01056 #ifdef SELDON_CHECK_IO 01057 // Checks if the file was opened. 01058 if (!FileStream.is_open()) 01059 throw IOError("Matrix_Symmetric::Read(string FileName)", 01060 string("Unable to open file \"") + FileName + "\"."); 01061 #endif 01062 01063 this->Read(FileStream); 01064 01065 FileStream.close(); 01066 } 01067 01068 01070 01077 template <class T, class Prop, class Storage, class Allocator> 01078 void Matrix_Symmetric<T, Prop, Storage, Allocator> 01079 ::Read(istream& FileStream) 01080 { 01081 01082 #ifdef SELDON_CHECK_IO 01083 // Checks if the stream is ready. 01084 if (!FileStream.good()) 01085 throw IOError("Matrix_Symmetric::Read(ifstream& FileStream)", 01086 "Stream is not ready."); 01087 #endif 01088 01089 int new_m, new_n; 01090 FileStream.read(reinterpret_cast<char*>(&new_m), sizeof(int)); 01091 FileStream.read(reinterpret_cast<char*>(&new_n), sizeof(int)); 01092 this->Reallocate(new_m, new_n); 01093 01094 FileStream.read(reinterpret_cast<char*>(this->data_), 01095 new_m * new_n * sizeof(value_type)); 01096 01097 #ifdef SELDON_CHECK_IO 01098 // Checks if data was read. 01099 if (!FileStream.good()) 01100 throw IOError("Matrix_Symmetric::Read(ifstream& FileStream)", 01101 string("Input operation failed.") 01102 + string(" The input file may have been removed") 01103 + " or may not contain enough data."); 01104 #endif 01105 01106 } 01107 01108 01110 01114 template <class T, class Prop, class Storage, class Allocator> 01115 void Matrix_Symmetric<T, Prop, Storage, Allocator>::ReadText(string FileName) 01116 { 01117 ifstream FileStream; 01118 FileStream.open(FileName.c_str()); 01119 01120 #ifdef SELDON_CHECK_IO 01121 // Checks if the file was opened. 01122 if (!FileStream.is_open()) 01123 throw IOError("Matrix_Pointers::ReadText(string FileName)", 01124 string("Unable to open file \"") + FileName + "\"."); 01125 #endif 01126 01127 this->ReadText(FileStream); 01128 01129 FileStream.close(); 01130 } 01131 01132 01134 01138 template <class T, class Prop, class Storage, class Allocator> 01139 void Matrix_Symmetric<T, Prop, Storage, Allocator> 01140 ::ReadText(istream& FileStream) 01141 { 01142 // clears previous matrix 01143 Clear(); 01144 01145 #ifdef SELDON_CHECK_IO 01146 // Checks if the stream is ready. 01147 if (!FileStream.good()) 01148 throw IOError("Matrix_Pointers::ReadText(ifstream& FileStream)", 01149 "Stream is not ready."); 01150 #endif 01151 01152 // we read first line 01153 string line; 01154 getline(FileStream, line); 01155 01156 if (FileStream.fail()) 01157 { 01158 // empty file ? 01159 return; 01160 } 01161 01162 // converting first line into a vector 01163 istringstream line_stream(line); 01164 Vector<T> first_row; 01165 first_row.ReadText(line_stream); 01166 01167 // and now the other rows 01168 Vector<T> other_rows; 01169 other_rows.ReadText(FileStream); 01170 01171 // number of rows and columns 01172 int n = first_row.GetM(); 01173 int m = 1 + other_rows.GetM()/n; 01174 01175 #ifdef SELDON_CHECK_IO 01176 // Checking number of elements 01177 if (other_rows.GetM() != (m-1)*n) 01178 throw IOError("Matrix_Pointers::ReadText(ifstream& FileStream)", 01179 "The file should contain same number of columns."); 01180 #endif 01181 01182 this->Reallocate(m,n); 01183 // filling matrix 01184 for (int j = 0; j < n; j++) 01185 this->Val(0, j) = first_row(j); 01186 01187 int nb = 0; 01188 for (int i = 1; i < m; i++) 01189 { 01190 for (int j = 0; j < i; j++) 01191 nb++; 01192 01193 for (int j = i; j < n; j++) 01194 this->Val(i, j) = other_rows(nb++); 01195 } 01196 } 01197 01198 01199 01201 // MATRIX<COLSYM> // 01203 01204 01205 /**************** 01206 * CONSTRUCTORS * 01207 ****************/ 01208 01209 01211 01214 template <class T, class Prop, class Allocator> 01215 Matrix<T, Prop, ColSym, Allocator>::Matrix(): 01216 Matrix_Symmetric<T, Prop, ColSym, Allocator>() 01217 { 01218 } 01219 01220 01222 01226 template <class T, class Prop, class Allocator> 01227 Matrix<T, Prop, ColSym, Allocator>::Matrix(int i, int j): 01228 Matrix_Symmetric<T, Prop, ColSym, Allocator>(i, j) 01229 { 01230 } 01231 01232 01233 /***************** 01234 * OTHER METHODS * 01235 *****************/ 01236 01237 01239 01242 template <class T, class Prop, class Allocator> 01243 template <class T0> 01244 Matrix<T, Prop, ColSym, Allocator>& 01245 Matrix<T, Prop, ColSym, Allocator>::operator= (const T0& x) 01246 { 01247 this->Fill(x); 01248 01249 return *this; 01250 } 01251 01252 01254 01259 template <class T, class Prop, class Allocator> 01260 inline Matrix<T, Prop, ColSym, Allocator>& 01261 Matrix<T, Prop, ColSym, Allocator>::operator= (const Matrix<T, Prop, 01262 ColSym, 01263 Allocator>& A) 01264 { 01265 this->Copy(A); 01266 return *this; 01267 } 01268 01269 01271 01274 template <class T, class Prop, class Allocator> 01275 template <class T0> 01276 Matrix<T, Prop, ColSym, Allocator>& 01277 Matrix<T, Prop, ColSym, Allocator>::operator*= (const T0& x) 01278 { 01279 for (int i = 0; i < this->GetDataSize();i++) 01280 this->data_[i] *= x; 01281 01282 return *this; 01283 } 01284 01285 01287 // MATRIX<ROWSYM> // 01289 01290 01291 /**************** 01292 * CONSTRUCTORS * 01293 ****************/ 01294 01295 01297 01300 template <class T, class Prop, class Allocator> 01301 Matrix<T, Prop, RowSym, Allocator>::Matrix(): 01302 Matrix_Symmetric<T, Prop, RowSym, Allocator>() 01303 { 01304 } 01305 01306 01308 01312 template <class T, class Prop, class Allocator> 01313 Matrix<T, Prop, RowSym, Allocator>::Matrix(int i, int j): 01314 Matrix_Symmetric<T, Prop, RowSym, Allocator>(i, j) 01315 { 01316 } 01317 01318 01319 /***************** 01320 * OTHER METHODS * 01321 *****************/ 01322 01323 01325 01328 template <class T, class Prop, class Allocator> 01329 template <class T0> 01330 Matrix<T, Prop, RowSym, Allocator>& 01331 Matrix<T, Prop, RowSym, Allocator>::operator= (const T0& x) 01332 { 01333 this->Fill(x); 01334 01335 return *this; 01336 } 01337 01339 01344 template <class T, class Prop, class Allocator> 01345 inline Matrix<T, Prop, RowSym, Allocator>& 01346 Matrix<T, Prop, RowSym, Allocator>::operator= (const Matrix<T, Prop, 01347 RowSym, 01348 Allocator>& A) 01349 { 01350 this->Copy(A); 01351 return *this; 01352 } 01353 01354 01356 01359 template <class T, class Prop, class Allocator> 01360 template <class T0> 01361 Matrix<T, Prop, RowSym, Allocator>& 01362 Matrix<T, Prop, RowSym, Allocator>::operator*= (const T0& x) 01363 { 01364 for (int i = 0; i < this->GetDataSize();i++) 01365 this->data_[i] *= x; 01366 01367 return *this; 01368 } 01369 01370 } // namespace Seldon. 01371 01372 #define SELDON_FILE_MATRIX_SYMMETRIC_CXX 01373 #endif