matrix/Matrix_Hermitian.cxx

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>::operator() (int i, int j)
00481   {
00482 
00483 #ifdef SELDON_CHECK_BOUNDS
00484     if (i < 0 || i >= this->m_)
00485       throw WrongRow("Matrix_Hermitian::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_Hermitian::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 conj(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_Hermitian<T, Prop, Storage, Allocator>::value_type
00510   Matrix_Hermitian<T, Prop, Storage, Allocator>
00511   ::operator() (int i, int j) const
00512   {
00513 
00514 #ifdef SELDON_CHECK_BOUNDS
00515     if (i < 0 || i >= this->m_)
00516       throw WrongRow("Matrix_Hermitian::operator() const",
00517                      string("Index should be in [0, ") + to_str(this->m_-1)
00518                      + "], but is equal to " + to_str(i) + ".");
00519     if (j < 0 || j >= this->n_)
00520       throw WrongCol("Matrix_Hermitian::operator() const",
00521                      string("Index should be in [0, ") + to_str(this->n_-1)
00522                      + "], but is equal to " + to_str(j) + ".");
00523 #endif
00524 
00525     if (i > j)
00526       return conj(me_[Storage::GetSecond(i, j)][Storage::GetFirst(i, j)]);
00527     else
00528       return me_[Storage::GetFirst(i, j)][Storage::GetSecond(i, j)];
00529 
00530   }
00531 
00532 
00534 
00540   template <class T, class Prop, class Storage, class Allocator>
00541   inline typename Matrix_Hermitian<T, Prop, Storage, Allocator>
00542   ::const_reference
00543   Matrix_Hermitian<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_Hermitian::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_Hermitian::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 #endif
00556 
00557     return me_[Storage::GetFirst(i, j)][Storage::GetSecond(i, j)];
00558   }
00559 
00560 
00562 
00568   template <class T, class Prop, class Storage, class Allocator>
00569   inline typename Matrix_Hermitian<T, Prop, Storage, Allocator>::reference
00570   Matrix_Hermitian<T, Prop, Storage, Allocator>::Val(int i, int j)
00571   {
00572 
00573 #ifdef SELDON_CHECK_BOUNDS
00574     if (i < 0 || i >= this->m_)
00575       throw WrongRow("Matrix_Hermitian::Val(int, int)",
00576                      string("Index should be in [0, ") + to_str(this->m_-1)
00577                      + "], but is equal to " + to_str(i) + ".");
00578     if (j < 0 || j >= this->n_)
00579       throw WrongCol("Matrix_Hermitian::Val(int, int)",
00580                      string("Index should be in [0, ") + to_str(this->n_-1)
00581                      + "], but is equal to " + to_str(j) + ".");
00582 #endif
00583 
00584     return me_[Storage::GetFirst(i, j)][Storage::GetSecond(i, j)];
00585   }
00586 
00587 
00589 
00594   template <class T, class Prop, class Storage, class Allocator>
00595   inline typename Matrix_Hermitian<T, Prop, Storage, Allocator>::reference
00596   Matrix_Hermitian<T, Prop, Storage, Allocator>::operator[] (int i)
00597   {
00598 
00599 #ifdef SELDON_CHECK_BOUNDS
00600     if (i < 0 || i >= this->GetDataSize())
00601       throw WrongIndex("Matrix_Hermitian::operator[] (int)",
00602                        string("Index should be in [0, ")
00603                        + to_str(this->GetDataSize()-1) + "], but is equal to "
00604                        + to_str(i) + ".");
00605 #endif
00606 
00607     return this->data_[i];
00608   }
00609 
00610 
00612 
00617   template <class T, class Prop, class Storage, class Allocator>
00618   inline typename Matrix_Hermitian<T, Prop, Storage, Allocator>
00619   ::const_reference
00620   Matrix_Hermitian<T, Prop, Storage, Allocator>::operator[] (int i) const
00621   {
00622 
00623 #ifdef SELDON_CHECK_BOUNDS
00624     if (i < 0 || i >= this->GetDataSize())
00625       throw WrongIndex("Matrix_Hermitian::operator[] (int) const",
00626                        string("Index should be in [0, ")
00627                        + to_str(this->GetDataSize()-1) + "], but is equal to "
00628                        + to_str(i) + ".");
00629 #endif
00630 
00631     return this->data_[i];
00632   }
00633 
00634 
00636 
00641   template <class T, class Prop, class Storage, class Allocator>
00642   inline Matrix_Hermitian<T, Prop, Storage, Allocator>&
00643   Matrix_Hermitian<T, Prop, Storage, Allocator>
00644   ::operator=(const Matrix_Hermitian<T, Prop, Storage, Allocator>& A)
00645   {
00646     this->Copy(A);
00647 
00648     return *this;
00649   }
00650 
00651 
00653 
00658   template <class T, class Prop, class Storage, class Allocator>
00659   inline void Matrix_Hermitian<T, Prop, Storage, Allocator>
00660   ::Copy(const Matrix_Hermitian<T, Prop, Storage, Allocator>& A)
00661   {
00662     this->Reallocate(A.GetM(), A.GetN());
00663 
00664     this->allocator_.memorycpy(this->data_, A.GetData(), this->GetDataSize());
00665   }
00666 
00667 
00668   /************************
00669    * CONVENIENT FUNCTIONS *
00670    ************************/
00671 
00672 
00674 
00678   template <class T, class Prop, class Storage, class Allocator>
00679   void Matrix_Hermitian<T, Prop, Storage, Allocator>::Zero()
00680   {
00681     this->allocator_.memoryset(this->data_, char(0),
00682                                this->GetDataSize() * sizeof(value_type));
00683   }
00684 
00685 
00687 
00691   template <class T, class Prop, class Storage, class Allocator>
00692   void Matrix_Hermitian<T, Prop, Storage, Allocator>::SetIdentity()
00693   {
00694     this->Fill(T(0));
00695 
00696     T one(1);
00697     for (int i = 0; i < min(this->m_, this->n_); i++)
00698       this->Val(i,i) = one;
00699   }
00700 
00701 
00703 
00707   template <class T, class Prop, class Storage, class Allocator>
00708   void Matrix_Hermitian<T, Prop, Storage, Allocator>::Fill()
00709   {
00710     for (int i = 0; i < this->GetDataSize(); i++)
00711       this->data_[i] = i;
00712   }
00713 
00714 
00716 
00719   template <class T, class Prop, class Storage, class Allocator>
00720   template <class T0>
00721   void Matrix_Hermitian<T, Prop, Storage, Allocator>::Fill(const T0& x)
00722   {
00723     for (int i = 0; i < this->GetDataSize(); i++)
00724       this->data_[i] = x;
00725   }
00726 
00727 
00729 
00732   template <class T, class Prop, class Storage, class Allocator>
00733   template <class T0>
00734   Matrix_Hermitian<T, Prop, Storage, Allocator>&
00735   Matrix_Hermitian<T, Prop, Storage, Allocator>::operator= (const T0& x)
00736   {
00737     this->Fill(x);
00738 
00739     return *this;
00740   }
00741 
00742 
00744 
00747   template <class T, class Prop, class Storage, class Allocator>
00748   void Matrix_Hermitian<T, Prop, Storage, Allocator>::FillRand()
00749   {
00750     srand(time(NULL));
00751     for (int i = 0; i < this->GetDataSize(); i++)
00752       this->data_[i] = rand();
00753   }
00754 
00755 
00757 
00762   template <class T, class Prop, class Storage, class Allocator>
00763   void Matrix_Hermitian<T, Prop, Storage, Allocator>::Print() const
00764   {
00765     for (int i = 0; i < this->m_; i++)
00766       {
00767         for (int j = 0; j < this->n_; j++)
00768           cout << (*this)(i, j) << "\t";
00769         cout << endl;
00770       }
00771   }
00772 
00773 
00775 
00786   template <class T, class Prop, class Storage, class Allocator>
00787   void Matrix_Hermitian<T, Prop, Storage, Allocator>
00788   ::Print(int a, int b, int m, int n) const
00789   {
00790     for (int i = a; i < min(this->m_, a+m); i++)
00791       {
00792         for (int j = b; j < min(this->n_, b+n); j++)
00793           cout << (*this)(i, j) << "\t";
00794         cout << endl;
00795       }
00796   }
00797 
00798 
00800 
00808   template <class T, class Prop, class Storage, class Allocator>
00809   void Matrix_Hermitian<T, Prop, Storage, Allocator>::Print(int l) const
00810   {
00811     Print(0, 0, l, l);
00812   }
00813 
00814 
00815   /**************************
00816    * INPUT/OUTPUT FUNCTIONS *
00817    **************************/
00818 
00819 
00821 
00828   template <class T, class Prop, class Storage, class Allocator>
00829   void Matrix_Hermitian<T, Prop, Storage, Allocator>
00830   ::Write(string FileName) const
00831   {
00832     ofstream FileStream;
00833     FileStream.open(FileName.c_str());
00834 
00835 #ifdef SELDON_CHECK_IO
00836     // Checks if the file was opened.
00837     if (!FileStream.is_open())
00838       throw IOError("Matrix_Hermitian::Write(string FileName)",
00839                     string("Unable to open file \"") + FileName + "\".");
00840 #endif
00841 
00842     this->Write(FileStream);
00843 
00844     FileStream.close();
00845   }
00846 
00847 
00849 
00856   template <class T, class Prop, class Storage, class Allocator>
00857   void Matrix_Hermitian<T, Prop, Storage, Allocator>
00858   ::Write(ostream& FileStream) const
00859   {
00860 
00861 #ifdef SELDON_CHECK_IO
00862     // Checks if the stream is ready.
00863     if (!FileStream.good())
00864       throw IOError("Matrix_Hermitian::Write(ofstream& FileStream)",
00865                     "Stream is not ready.");
00866 #endif
00867 
00868     FileStream.write(reinterpret_cast<char*>(const_cast<int*>(&this->m_)),
00869                      sizeof(int));
00870     FileStream.write(reinterpret_cast<char*>(const_cast<int*>(&this->n_)),
00871                      sizeof(int));
00872 
00873     FileStream.write(reinterpret_cast<char*>(this->data_),
00874                      this->m_ * this->n_ * sizeof(value_type));
00875 
00876 #ifdef SELDON_CHECK_IO
00877     // Checks if data was written.
00878     if (!FileStream.good())
00879       throw IOError("Matrix_Hermitian::Write(ofstream& FileStream)",
00880                     string("Output operation failed.")
00881                     + string(" The output file may have been removed")
00882                     + " or there is no space left on device.");
00883 #endif
00884 
00885   }
00886 
00887 
00889 
00896   template <class T, class Prop, class Storage, class Allocator>
00897   void Matrix_Hermitian<T, Prop, Storage, Allocator>
00898   ::WriteText(string FileName) const
00899   {
00900     ofstream FileStream;
00901     FileStream.precision(cout.precision());
00902     FileStream.flags(cout.flags());
00903     FileStream.open(FileName.c_str());
00904 
00905 #ifdef SELDON_CHECK_IO
00906     // Checks if the file was opened.
00907     if (!FileStream.is_open())
00908       throw IOError("Matrix_Hermitian::WriteText(string FileName)",
00909                     string("Unable to open file \"") + FileName + "\".");
00910 #endif
00911 
00912     this->WriteText(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   ::WriteText(ostream& FileStream) const
00929   {
00930 
00931 #ifdef SELDON_CHECK_IO
00932     // Checks if the file is ready.
00933     if (!FileStream.good())
00934       throw IOError("Matrix_Hermitian::WriteText(ofstream& FileStream)",
00935                     "Stream is not ready.");
00936 #endif
00937 
00938     int i, j;
00939     for (i = 0; i < this->GetM(); i++)
00940       {
00941         for (j = 0; j < this->GetN(); j++)
00942           FileStream << (*this)(i, j) << '\t';
00943         FileStream << endl;
00944       }
00945 
00946 #ifdef SELDON_CHECK_IO
00947     // Checks if data was written.
00948     if (!FileStream.good())
00949       throw IOError("Matrix_Hermitian::WriteText(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>::Read(string FileName)
00968   {
00969     ifstream FileStream;
00970     FileStream.open(FileName.c_str());
00971 
00972 #ifdef SELDON_CHECK_IO
00973     // Checks if the file was opened.
00974     if (!FileStream.is_open())
00975       throw IOError("Matrix_Hermitian::Read(string FileName)",
00976                     string("Unable to open file \"") + FileName + "\".");
00977 #endif
00978 
00979     this->Read(FileStream);
00980 
00981     FileStream.close();
00982   }
00983 
00984 
00986 
00993   template <class T, class Prop, class Storage, class Allocator>
00994   void Matrix_Hermitian<T, Prop, Storage, Allocator>
00995   ::Read(istream& FileStream)
00996   {
00997 
00998 #ifdef SELDON_CHECK_IO
00999     // Checks if the stream is ready.
01000     if (!FileStream.good())
01001       throw IOError("Matrix_Hermitian::Read(ifstream& FileStream)",
01002                     "Stream is not ready.");
01003 #endif
01004 
01005     int new_m, new_n;
01006     FileStream.read(reinterpret_cast<char*>(&new_m), sizeof(int));
01007     FileStream.read(reinterpret_cast<char*>(&new_n), sizeof(int));
01008     this->Reallocate(new_m, new_n);
01009 
01010     FileStream.read(reinterpret_cast<char*>(this->data_),
01011                     new_m * new_n * sizeof(value_type));
01012 
01013 #ifdef SELDON_CHECK_IO
01014     // Checks if data was read.
01015     if (!FileStream.good())
01016       throw IOError("Matrix_Hermitian::Read(ifstream& FileStream)",
01017                     string("Output operation failed.")
01018                     + string(" The intput file may have been removed")
01019                     + " or may not contain enough data.");
01020 #endif
01021 
01022   }
01023 
01024 
01026 
01030   template <class T, class Prop, class Storage, class Allocator>
01031   void Matrix_Hermitian<T, Prop, Storage, Allocator>::ReadText(string FileName)
01032   {
01033     ifstream FileStream;
01034     FileStream.open(FileName.c_str());
01035 
01036 #ifdef SELDON_CHECK_IO
01037     // Checks if the file was opened.
01038     if (!FileStream.is_open())
01039       throw IOError("Matrix_Pointers::ReadText(string FileName)",
01040                     string("Unable to open file \"") + FileName + "\".");
01041 #endif
01042 
01043     this->ReadText(FileStream);
01044 
01045     FileStream.close();
01046   }
01047 
01048 
01050 
01054   template <class T, class Prop, class Storage, class Allocator>
01055   void Matrix_Hermitian<T, Prop, Storage, Allocator>
01056   ::ReadText(istream& FileStream)
01057   {
01058     // clears previous matrix
01059     Clear();
01060 
01061 #ifdef SELDON_CHECK_IO
01062     // Checks if the stream is ready.
01063     if (!FileStream.good())
01064       throw IOError("Matrix_Pointers::ReadText(ifstream& FileStream)",
01065                     "Stream is not ready.");
01066 #endif
01067 
01068     // we read first line
01069     string line;
01070     getline(FileStream, line);
01071 
01072     if (FileStream.fail())
01073       {
01074         // empty file ?
01075         return;
01076       }
01077 
01078     // converting first line into a vector
01079     istringstream line_stream(line);
01080     Vector<T> first_row;
01081     first_row.ReadText(line_stream);
01082 
01083     // and now the other rows
01084     Vector<T> other_rows;
01085     other_rows.ReadText(FileStream);
01086 
01087     // number of rows and columns
01088     int n = first_row.GetM();
01089     int m = 1 + other_rows.GetM()/n;
01090 
01091 #ifdef SELDON_CHECK_IO
01092     // Checking number of elements
01093     if (other_rows.GetM() != (m-1)*n)
01094       throw IOError("Matrix_Pointers::ReadText(ifstream& FileStream)",
01095                     "The file should contain same number of columns.");
01096 #endif
01097 
01098     this->Reallocate(m,n);
01099     // filling matrix
01100     for (int j = 0; j < n; j++)
01101       this->Val(0, j) = first_row(j);
01102 
01103     int nb = 0;
01104     for (int i = 1; i < m; i++)
01105       {
01106         for (int j = 0; j < i; j++)
01107           nb++;
01108 
01109         for (int j = i; j < n; j++)
01110           this->Val(i, j) = other_rows(nb++);
01111       }
01112   }
01113 
01114 
01115 
01117   // MATRIX<COLHERM> //
01119 
01120 
01121   /****************
01122    * CONSTRUCTORS *
01123    ****************/
01124 
01125 
01127 
01130   template <class T, class Prop, class Allocator>
01131   Matrix<T, Prop, ColHerm, Allocator>::Matrix()  throw():
01132     Matrix_Hermitian<T, Prop, ColHerm, Allocator>()
01133   {
01134   }
01135 
01136 
01138 
01142   template <class T, class Prop, class Allocator>
01143   Matrix<T, Prop, ColHerm, Allocator>::Matrix(int i, int j):
01144     Matrix_Hermitian<T, Prop, ColHerm, Allocator>(i, j)
01145   {
01146   }
01147 
01148 
01149   /*****************
01150    * OTHER METHODS *
01151    *****************/
01152 
01153 
01155 
01158   template <class T, class Prop, class Allocator>
01159   template <class T0>
01160   Matrix<T, Prop, ColHerm, Allocator>&
01161   Matrix<T, Prop, ColHerm, Allocator>::operator= (const T0& x)
01162   {
01163     this->Fill(x);
01164 
01165     return *this;
01166   }
01167 
01168 
01170 
01173   template <class T, class Prop, class Allocator>
01174   template <class T0>
01175   Matrix<T, Prop, ColHerm, Allocator>&
01176   Matrix<T, Prop, ColHerm, Allocator>::operator*= (const T0& x)
01177   {
01178     for (int i = 0; i < this->GetDataSize();i++)
01179       this->data_[i] *= x;
01180 
01181     return *this;
01182   }
01183 
01184 
01185 
01187   // MATRIX<ROWHERM> //
01189 
01190 
01191   /****************
01192    * CONSTRUCTORS *
01193    ****************/
01194 
01195 
01197 
01200   template <class T, class Prop, class Allocator>
01201   Matrix<T, Prop, RowHerm, Allocator>::Matrix()  throw():
01202     Matrix_Hermitian<T, Prop, RowHerm, Allocator>()
01203   {
01204   }
01205 
01206 
01208 
01212   template <class T, class Prop, class Allocator>
01213   Matrix<T, Prop, RowHerm, Allocator>::Matrix(int i, int j):
01214     Matrix_Hermitian<T, Prop, RowHerm, 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, RowHerm, Allocator>&
01231   Matrix<T, Prop, RowHerm, Allocator>::operator= (const T0& x)
01232   {
01233     this->Fill(x);
01234 
01235     return *this;
01236   }
01237 
01238 
01240 
01243   template <class T, class Prop, class Allocator>
01244   template <class T0>
01245   Matrix<T, Prop, RowHerm, Allocator>&
01246   Matrix<T, Prop, RowHerm, Allocator>::operator*= (const T0& x)
01247   {
01248     for (int i = 0; i < this->GetDataSize();i++)
01249       this->data_[i] *= x;
01250 
01251     return *this;
01252   }
01253 
01254 } // namespace Seldon.
01255 
01256 #define SELDON_FILE_MATRIX_HERMITIAN_CXX
01257 #endif