00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef SELDON_FILE_MATRIX_SYMMETRIC_CXX
00022
00023 #include "Matrix_Symmetric.hxx"
00024
00025 namespace Seldon
00026 {
00027
00028
00029
00030
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
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
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
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
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
00454 int inew = Storage::GetFirst(i, j);
00455 int jnew = Storage::GetSecond(i, j);
00456 this->Reallocate(i, j);
00457
00458
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
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
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
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
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
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
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
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
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
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
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
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
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
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
01143 Clear();
01144
01145 #ifdef SELDON_CHECK_IO
01146
01147 if (!FileStream.good())
01148 throw IOError("Matrix_Pointers::ReadText(ifstream& FileStream)",
01149 "Stream is not ready.");
01150 #endif
01151
01152
01153 string line;
01154 getline(FileStream, line);
01155
01156 if (FileStream.fail())
01157 {
01158
01159 return;
01160 }
01161
01162
01163 istringstream line_stream(line);
01164 Vector<T> first_row;
01165 first_row.ReadText(line_stream);
01166
01167
01168 Vector<T> other_rows;
01169 other_rows.ReadText(FileStream);
01170
01171
01172 int n = first_row.GetM();
01173 int m = 1 + other_rows.GetM()/n;
01174
01175 #ifdef SELDON_CHECK_IO
01176
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
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
01203
01204
01205
01206
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
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
01289
01290
01291
01292
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
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 }
01371
01372 #define SELDON_FILE_MATRIX_SYMMETRIC_CXX
01373 #endif