matrix/Matrix_Triangular.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_TRIANGULAR_CXX
00022 
00023 #include "Matrix_Triangular.hxx"
00024 
00025 namespace Seldon
00026 {
00027 
00028 
00029   /****************
00030    * CONSTRUCTORS *
00031    ****************/
00032 
00033 
00035 
00038   template <class T, class Prop, class Storage, class Allocator>
00039   inline Matrix_Triangular<T, Prop, Storage, Allocator>::Matrix_Triangular():
00040     Matrix_Base<T, Allocator>()
00041   {
00042     me_ = NULL;
00043   }
00044 
00045 
00047 
00052   template <class T, class Prop, class Storage, class Allocator>
00053   inline Matrix_Triangular<T, Prop, Storage, Allocator>
00054   ::Matrix_Triangular(int i, int j): Matrix_Base<T, Allocator>(i, i)
00055   {
00056 
00057 #ifdef SELDON_CHECK_MEMORY
00058     try
00059       {
00060 #endif
00061 
00062         me_ = reinterpret_cast<pointer*>( calloc(i, sizeof(pointer)) );
00063 
00064 #ifdef SELDON_CHECK_MEMORY
00065       }
00066     catch (...)
00067       {
00068         this->m_ = 0;
00069         this->n_ = 0;
00070         me_ = NULL;
00071         this->data_ = NULL;
00072       }
00073     if (me_ == NULL)
00074       {
00075         this->m_ = 0;
00076         this->n_ = 0;
00077         this->data_ = NULL;
00078       }
00079     if (me_ == NULL && i != 0)
00080       throw NoMemory("Matrix_Triangular::Matrix_Triangular(int, int)",
00081                      string("Unable to allocate memory for a matrix of size ")
00082                      + to_str(static_cast<long int>(i)
00083                               * static_cast<long int>(i)
00084                               * static_cast<long int>(sizeof(T)))
00085                      + " bytes (" + to_str(i) + " x " + to_str(i)
00086                      + " elements).");
00087 #endif
00088 
00089 #ifdef SELDON_CHECK_MEMORY
00090     try
00091       {
00092 #endif
00093 
00094         this->data_ = this->allocator_.allocate(i * i, this);
00095 
00096 #ifdef SELDON_CHECK_MEMORY
00097       }
00098     catch (...)
00099       {
00100         this->m_ = 0;
00101         this->n_ = 0;
00102         free(me_);
00103         me_ = NULL;
00104         this->data_ = NULL;
00105       }
00106     if (this->data_ == NULL)
00107       {
00108         this->m_ = 0;
00109         this->n_ = 0;
00110         free(me_);
00111         me_ = NULL;
00112       }
00113     if (this->data_ == NULL && i != 0)
00114       throw NoMemory("Matrix_Triangular::Matrix_Triangular(int, int)",
00115                      string("Unable to allocate memory for a matrix of size ")
00116                      + to_str(static_cast<long int>(i)
00117                               * static_cast<long int>(i)
00118                               * static_cast<long int>(sizeof(T)))
00119                      + " bytes (" + to_str(i) + " x " + to_str(i)
00120                      + " elements).");
00121 #endif
00122 
00123     pointer ptr = this->data_;
00124     int lgth = i;
00125     for (int k = 0; k < i; k++, ptr += lgth)
00126       me_[k] = ptr;
00127   }
00128 
00129 
00131   template <class T, class Prop, class Storage, class Allocator>
00132   inline Matrix_Triangular<T, Prop, Storage, Allocator>
00133   ::Matrix_Triangular(const Matrix_Triangular<T, Prop,
00134                       Storage, Allocator>& A)
00135     : Matrix_Base<T, Allocator>()
00136   {
00137     this->m_ = 0;
00138     this->n_ = 0;
00139     this->data_ = NULL;
00140     this->me_ = NULL;
00141 
00142     this->Copy(A);
00143   }
00144 
00145 
00146   /**************
00147    * DESTRUCTOR *
00148    **************/
00149 
00150 
00152   template <class T, class Prop, class Storage, class Allocator>
00153   inline Matrix_Triangular<T, Prop, Storage, Allocator>::~Matrix_Triangular()
00154   {
00155 
00156 #ifdef SELDON_CHECK_MEMORY
00157     try
00158       {
00159 #endif
00160 
00161         if (this->data_ != NULL)
00162           {
00163             this->allocator_.deallocate(this->data_, this->m_ * this->n_);
00164             this->data_ = NULL;
00165           }
00166 
00167 #ifdef SELDON_CHECK_MEMORY
00168       }
00169     catch (...)
00170       {
00171         this->data_ = NULL;
00172       }
00173 #endif
00174 
00175 #ifdef SELDON_CHECK_MEMORY
00176     try
00177       {
00178 #endif
00179 
00180         if (me_ != NULL)
00181           {
00182             free(me_);
00183             me_ = NULL;
00184           }
00185 
00186 #ifdef SELDON_CHECK_MEMORY
00187       }
00188     catch (...)
00189       {
00190         this->m_ = 0;
00191         this->n_ = 0;
00192         me_ = NULL;
00193       }
00194 #endif
00195 
00196   }
00197 
00198 
00200 
00204   template <class T, class Prop, class Storage, class Allocator>
00205   inline void Matrix_Triangular<T, Prop, Storage, Allocator>::Clear()
00206   {
00207     this->~Matrix_Triangular();
00208     this->m_ = 0;
00209     this->n_ = 0;
00210   }
00211 
00212 
00213   /*******************
00214    * BASIC FUNCTIONS *
00215    *******************/
00216 
00217 
00219 
00225   template <class T, class Prop, class Storage, class Allocator>
00226   int Matrix_Triangular<T, Prop, Storage, Allocator>::GetDataSize() const
00227   {
00228     return this->m_ * this->n_;
00229   }
00230 
00231 
00232   /*********************
00233    * MEMORY MANAGEMENT *
00234    *********************/
00235 
00236 
00238 
00244   template <class T, class Prop, class Storage, class Allocator>
00245   inline void Matrix_Triangular<T, Prop, Storage, Allocator>
00246   ::Reallocate(int i, int j)
00247   {
00248 
00249     if (i != this->m_)
00250       {
00251         this->m_ = i;
00252         this->n_ = i;
00253 
00254 #ifdef SELDON_CHECK_MEMORY
00255         try
00256           {
00257 #endif
00258 
00259             me_ = reinterpret_cast<pointer*>( realloc(me_,
00260                                                       i * sizeof(pointer)) );
00261 
00262 #ifdef SELDON_CHECK_MEMORY
00263           }
00264         catch (...)
00265           {
00266             this->m_ = 0;
00267             this->n_ = 0;
00268             me_ = NULL;
00269             this->data_ = NULL;
00270           }
00271         if (me_ == NULL)
00272           {
00273             this->m_ = 0;
00274             this->n_ = 0;
00275             this->data_ = NULL;
00276           }
00277         if (me_ == NULL && i != 0)
00278           throw NoMemory("Matrix_Triangular::Reallocate(int, int)",
00279                          string("Unable to reallocate memory")
00280                          + " for a matrix of size "
00281                          + to_str(static_cast<long int>(i)
00282                                   * static_cast<long int>(i)
00283                                   * static_cast<long int>(sizeof(T)))
00284                          + " bytes (" + to_str(i) + " x " + to_str(i)
00285                          + " elements).");
00286 #endif
00287 
00288 #ifdef SELDON_CHECK_MEMORY
00289         try
00290           {
00291 #endif
00292 
00293             this->data_ =
00294               reinterpret_cast<pointer>(this->allocator_.reallocate(this->data_,
00295                                                                     i * i,
00296                                                                     this) );
00297 
00298 #ifdef SELDON_CHECK_MEMORY
00299           }
00300         catch (...)
00301           {
00302             this->m_ = 0;
00303             this->n_ = 0;
00304             free(me_);
00305             me_ = NULL;
00306             this->data_ = NULL;
00307           }
00308         if (this->data_ == NULL)
00309           {
00310             this->m_ = 0;
00311             this->n_ = 0;
00312             free(me_);
00313             me_ = NULL;
00314           }
00315         if (this->data_ == NULL && i != 0)
00316           throw NoMemory("Matrix_Triangular::Reallocate(int, int)",
00317                          string("Unable to reallocate memory")
00318                          + " for a matrix of size "
00319                          + to_str(static_cast<long int>(i)
00320                                   * static_cast<long int>(i)
00321                                   * static_cast<long int>(sizeof(T)))
00322                          + " bytes (" + to_str(i) + " x " + to_str(i)
00323                          + " elements).");
00324 #endif
00325 
00326         pointer ptr = this->data_;
00327         int lgth = Storage::GetSecond(i, i);
00328         for (int k = 0; k < Storage::GetFirst(i, i); k++, ptr += lgth)
00329           me_[k] = ptr;
00330       }
00331   }
00332 
00333 
00335 
00342   template <class T, class Prop, class Storage, class Allocator>
00343   inline void Matrix_Triangular<T, Prop, Storage, Allocator>
00344   ::Resize(int i, int j)
00345   {
00346 
00347     if (i != this->m_)
00348       {
00349         // Storing the previous values of the matrix.
00350         int iold = this->m_;
00351         Vector<value_type, VectFull, Allocator> xold(this->GetDataSize());
00352         for (int k = 0; k < this->GetDataSize(); k++)
00353           xold(k) = this->data_[k];
00354 
00355         // Reallocation.
00356         this->Reallocate(i, i);
00357 
00358         // Filling the matrix with its previous values.
00359         int imin = min(iold, i);
00360         for (int k = 0; k < imin; k++)
00361           for (int l = 0; l < imin; l++)
00362             this->data_[k*i + l] = xold(k*iold + l);
00363       }
00364   }
00365 
00366 
00369 
00383   template <class T, class Prop, class Storage, class Allocator>
00384   inline void Matrix_Triangular<T, Prop, Storage, Allocator>
00385   ::SetData(int i, int j,
00386             typename Matrix_Triangular<T, Prop, Storage, Allocator>
00387             ::pointer data)
00388   {
00389 
00390     this->Clear();
00391 
00392     this->m_ = i;
00393     this->n_ = i;
00394 
00395 #ifdef SELDON_CHECK_MEMORY
00396     try
00397       {
00398 #endif
00399 
00400         me_ = reinterpret_cast<pointer*>( calloc(i, sizeof(pointer)) );
00401 
00402 #ifdef SELDON_CHECK_MEMORY
00403       }
00404     catch (...)
00405       {
00406         this->m_ = 0;
00407         this->n_ = 0;
00408         me_ = NULL;
00409         this->data_ = NULL;
00410         return;
00411       }
00412     if (me_ == NULL)
00413       {
00414         this->m_ = 0;
00415         this->n_ = 0;
00416         this->data_ = NULL;
00417         return;
00418       }
00419 #endif
00420 
00421     this->data_ = data;
00422 
00423     pointer ptr = this->data_;
00424     int lgth = i;
00425     for (int k = 0; k < i; k++, ptr += lgth)
00426       me_[k] = ptr;
00427   }
00428 
00429 
00431 
00436   template <class T, class Prop, class Storage, class Allocator>
00437   inline void Matrix_Triangular<T, Prop, Storage, Allocator>::Nullify()
00438   {
00439     this->m_ = 0;
00440     this->n_ = 0;
00441 
00442 #ifdef SELDON_CHECK_MEMORY
00443     try
00444       {
00445 #endif
00446 
00447         if (me_ != NULL)
00448           {
00449             free(me_);
00450             me_ = NULL;
00451           }
00452 
00453 #ifdef SELDON_CHECK_MEMORY
00454       }
00455     catch (...)
00456       {
00457         this->m_ = 0;
00458         this->n_ = 0;
00459         me_ = NULL;
00460       }
00461 #endif
00462 
00463     this->data_ = NULL;
00464   }
00465 
00466 
00467   /**********************************
00468    * ELEMENT ACCESS AND AFFECTATION *
00469    **********************************/
00470 
00471 
00473 
00479   template <class T, class Prop, class Storage, class Allocator>
00480   inline typename Matrix_Triangular<T, Prop, Storage, Allocator>::value_type
00481   Matrix_Triangular<T, Prop, Storage, Allocator>::operator() (int i, int j)
00482   {
00483 
00484 #ifdef SELDON_CHECK_BOUNDS
00485     if (i < 0 || i >= this->m_)
00486       throw WrongRow("Matrix_Triangular::operator()",
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_Triangular::operator()",
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 (Storage::UpLo())
00496       {
00497         if (i > j)
00498           return T(0);
00499         else
00500           return me_[Storage::GetFirst(i, j)][Storage::GetSecond(i, j)];
00501       }
00502     else
00503       {
00504         if (i < j)
00505           return T(0);
00506         else
00507           return me_[Storage::GetFirst(i, j)][Storage::GetSecond(i, j)];
00508       }
00509   }
00510 
00511 
00513 
00519   template <class T, class Prop, class Storage, class Allocator>
00520   inline typename Matrix_Triangular<T, Prop, Storage, Allocator>::value_type
00521   Matrix_Triangular<T, Prop, Storage, Allocator>
00522   ::operator() (int i, int j) const
00523   {
00524 
00525 #ifdef SELDON_CHECK_BOUNDS
00526     if (i < 0 || i >= this->m_)
00527       throw WrongRow("Matrix_Triangular::operator() const",
00528                      string("Index should be in [0, ") + to_str(this->m_-1)
00529                      + "], but is equal to " + to_str(i) + ".");
00530     if (j < 0 || j >= this->n_)
00531       throw WrongCol("Matrix_Triangular::operator() const",
00532                      string("Index should be in [0, ") + to_str(this->n_-1)
00533                      + "], but is equal to " + to_str(j) + ".");
00534 #endif
00535 
00536     if (Storage::UpLo())
00537       {
00538         if (i > j)
00539           return T(0);
00540         else
00541           return me_[Storage::GetFirst(i, j)][Storage::GetSecond(i, j)];
00542       }
00543     else
00544       {
00545         if (i < j)
00546           return T(0);
00547         else
00548           return me_[Storage::GetFirst(i, j)][Storage::GetSecond(i, j)];
00549       }
00550   }
00551 
00552 
00554 
00563   template <class T, class Prop, class Storage, class Allocator>
00564   inline typename Matrix_Triangular<T, Prop, Storage, Allocator>
00565   ::const_reference
00566   Matrix_Triangular<T, Prop, Storage, Allocator>::Val(int i, int j) const
00567   {
00568 
00569 #ifdef SELDON_CHECK_BOUNDS
00570     if (i < 0 || i >= this->m_)
00571       throw WrongRow("Matrix_Triangular::Val(int, int) const",
00572                      string("Index should be in [0, ") + to_str(this->m_-1)
00573                      + "], but is equal to " + to_str(i) + ".");
00574     if (j < 0 || j >= this->n_)
00575       throw WrongCol("Matrix_Triangular::Val(int, int) const",
00576                      string("Index should be in [0, ") + to_str(this->n_-1)
00577                      + "], but is equal to " + to_str(j) + ".");
00578 #endif
00579 
00580     return me_[Storage::GetFirst(i, j)][Storage::GetSecond(i, j)];
00581   }
00582 
00583 
00585 
00594   template <class T, class Prop, class Storage, class Allocator>
00595   inline typename Matrix_Triangular<T, Prop, Storage, Allocator>::reference
00596   Matrix_Triangular<T, Prop, Storage, Allocator>::Val(int i, int j)
00597   {
00598 
00599 #ifdef SELDON_CHECK_BOUNDS
00600     if (i < 0 || i >= this->m_)
00601       throw WrongRow("Matrix_Triangular::Val(int, int)",
00602                      string("Index should be in [0, ") + to_str(this->m_-1)
00603                      + "], but is equal to " + to_str(i) + ".");
00604     if (j < 0 || j >= this->n_)
00605       throw WrongCol("Matrix_Triangular::Val(int, int)",
00606                      string("Index should be in [0, ") + to_str(this->n_-1)
00607                      + "], but is equal to " + to_str(j) + ".");
00608 #endif
00609 
00610     return me_[Storage::GetFirst(i, j)][Storage::GetSecond(i, j)];
00611   }
00612 
00613 
00615 
00620   template <class T, class Prop, class Storage, class Allocator>
00621   inline typename Matrix_Triangular<T, Prop, Storage, Allocator>::reference
00622   Matrix_Triangular<T, Prop, Storage, Allocator>::operator[] (int i)
00623   {
00624 
00625 #ifdef SELDON_CHECK_BOUNDS
00626     if (i < 0 || i >= this->GetDataSize())
00627       throw WrongIndex("Matrix_Triangular::operator[] (int)",
00628                        string("Index should be in [0, ")
00629                        + to_str(this->GetDataSize()-1) + "], but is equal to "
00630                        + to_str(i) + ".");
00631 #endif
00632 
00633     return this->data_[i];
00634   }
00635 
00636 
00638 
00643   template <class T, class Prop, class Storage, class Allocator>
00644   inline typename Matrix_Triangular<T, Prop, Storage, Allocator>
00645   ::const_reference
00646   Matrix_Triangular<T, Prop, Storage, Allocator>::operator[] (int i) const
00647   {
00648 
00649 #ifdef SELDON_CHECK_BOUNDS
00650     if (i < 0 || i >= this->GetDataSize())
00651       throw WrongIndex("Matrix_Triangular::operator[] (int) const",
00652                        string("Index should be in [0, ")
00653                        + to_str(this->GetDataSize()-1) + "], but is equal to "
00654                        + to_str(i) + ".");
00655 #endif
00656 
00657     return this->data_[i];
00658   }
00659 
00660 
00662 
00667   template <class T, class Prop, class Storage, class Allocator>
00668   inline Matrix_Triangular<T, Prop, Storage, Allocator>&
00669   Matrix_Triangular<T, Prop, Storage, Allocator>
00670   ::operator= (const Matrix_Triangular<T, Prop, Storage, Allocator>& A)
00671   {
00672     this->Copy(A);
00673 
00674     return *this;
00675   }
00676 
00677 
00679 
00684   template <class T, class Prop, class Storage, class Allocator>
00685   inline void Matrix_Triangular<T, Prop, Storage, Allocator>
00686   ::Copy(const Matrix_Triangular<T, Prop, Storage, Allocator>& A)
00687   {
00688     this->Reallocate(A.GetM(), A.GetN());
00689 
00690     this->allocator_.memorycpy(this->data_, A.GetData(), this->GetDataSize());
00691   }
00692 
00693 
00694   /************************
00695    * CONVENIENT FUNCTIONS *
00696    ************************/
00697 
00698 
00700 
00704   template <class T, class Prop, class Storage, class Allocator>
00705   void Matrix_Triangular<T, Prop, Storage, Allocator>::Zero()
00706   {
00707     this->allocator_.memoryset(this->data_, char(0),
00708                                this->GetDataSize() * sizeof(value_type));
00709   }
00710 
00711 
00713   template <class T, class Prop, class Storage, class Allocator>
00714   void Matrix_Triangular<T, Prop, Storage, Allocator>::SetIdentity()
00715   {
00716     this->Fill(T(0));
00717 
00718     T one(1);
00719     for (int i = 0; i < min(this->m_, this->n_); i++)
00720       this->Val(i, i) = one;
00721   }
00722 
00723 
00725 
00729   template <class T, class Prop, class Storage, class Allocator>
00730   void Matrix_Triangular<T, Prop, Storage, Allocator>::Fill()
00731   {
00732     for (int i = 0; i < this->GetDataSize(); i++)
00733       this->data_[i] = i;
00734   }
00735 
00736 
00738 
00742   template <class T, class Prop, class Storage, class Allocator>
00743   template <class T0>
00744   void Matrix_Triangular<T, Prop, Storage, Allocator>::Fill(const T0& x)
00745   {
00746     for (int i = 0; i < this->GetDataSize(); i++)
00747       this->data_[i] = x;
00748   }
00749 
00750 
00752 
00756   template <class T, class Prop, class Storage, class Allocator>
00757   template <class T0>
00758   Matrix_Triangular<T, Prop, Storage, Allocator>&
00759   Matrix_Triangular<T, Prop, Storage, Allocator>::operator= (const T0& x)
00760   {
00761     this->Fill(x);
00762 
00763     return *this;
00764   }
00765 
00766 
00768 
00771   template <class T, class Prop, class Storage, class Allocator>
00772   void Matrix_Triangular<T, Prop, Storage, Allocator>::FillRand()
00773   {
00774     srand(time(NULL));
00775     for (int i = 0; i < this->GetDataSize(); i++)
00776       this->data_[i] = rand();
00777   }
00778 
00779 
00781 
00786   template <class T, class Prop, class Storage, class Allocator>
00787   void Matrix_Triangular<T, Prop, Storage, Allocator>::Print() const
00788   {
00789     for (int i = 0; i < this->m_; i++)
00790       {
00791         for (int j = 0; j < this->n_; j++)
00792           cout << (*this)(i, j) << "\t";
00793         cout << endl;
00794       }
00795   }
00796 
00797 
00799 
00810   template <class T, class Prop, class Storage, class Allocator>
00811   void Matrix_Triangular<T, Prop, Storage, Allocator>
00812   ::Print(int a, int b, int m, int n) const
00813   {
00814     for (int i = a; i < min(this->m_, a + m); i++)
00815       {
00816         for (int j = b; j < min(this->n_, b + n); j++)
00817           cout << (*this)(i, j) << "\t";
00818         cout << endl;
00819       }
00820   }
00821 
00822 
00824 
00832   template <class T, class Prop, class Storage, class Allocator>
00833   void Matrix_Triangular<T, Prop, Storage, Allocator>::Print(int l) const
00834   {
00835     Print(0, 0, l, l);
00836   }
00837 
00838 
00839   /**************************
00840    * INPUT/OUTPUT FUNCTIONS *
00841    **************************/
00842 
00843 
00845 
00852   template <class T, class Prop, class Storage, class Allocator>
00853   void Matrix_Triangular<T, Prop, Storage, Allocator>
00854   ::Write(string FileName) const
00855   {
00856     ofstream FileStream;
00857     FileStream.open(FileName.c_str());
00858 
00859 #ifdef SELDON_CHECK_IO
00860     // Checks if the file was opened.
00861     if (!FileStream.is_open())
00862       throw IOError("Matrix_Triangular::Write(string FileName)",
00863                     string("Unable to open file \"") + FileName + "\".");
00864 #endif
00865 
00866     this->Write(FileStream);
00867 
00868     FileStream.close();
00869   }
00870 
00871 
00873 
00880   template <class T, class Prop, class Storage, class Allocator>
00881   void Matrix_Triangular<T, Prop, Storage, Allocator>
00882   ::Write(ostream& FileStream) const
00883   {
00884 
00885 #ifdef SELDON_CHECK_IO
00886     // Checks if the stream is ready.
00887     if (!FileStream.good())
00888       throw IOError("Matrix_Triangular::Write(ofstream& FileStream)",
00889                     "Stream is not ready.");
00890 #endif
00891 
00892     FileStream.write(reinterpret_cast<char*>(const_cast<int*>(&this->m_)),
00893                      sizeof(int));
00894     FileStream.write(reinterpret_cast<char*>(const_cast<int*>(&this->n_)),
00895                      sizeof(int));
00896 
00897     FileStream.write(reinterpret_cast<char*>(this->data_),
00898                      this->m_ * this->n_ * sizeof(value_type));
00899 
00900 #ifdef SELDON_CHECK_IO
00901     // Checks if data was written.
00902     if (!FileStream.good())
00903       throw IOError("Matrix_Triangular::Write(ofstream& FileStream)",
00904                     string("Output operation failed.")
00905                     + string(" The output file may have been removed")
00906                     + " or there is no space left on device.");
00907 #endif
00908 
00909   }
00910 
00911 
00913 
00920   template <class T, class Prop, class Storage, class Allocator>
00921   void Matrix_Triangular<T, Prop, Storage, Allocator>
00922   ::WriteText(string FileName) const
00923   {
00924     ofstream FileStream;
00925     FileStream.precision(cout.precision());
00926     FileStream.flags(cout.flags());
00927     FileStream.open(FileName.c_str());
00928 
00929 #ifdef SELDON_CHECK_IO
00930     // Checks if the file was opened.
00931     if (!FileStream.is_open())
00932       throw IOError("Matrix_Triangular::WriteText(string FileName)",
00933                     string("Unable to open file \"") + FileName + "\".");
00934 #endif
00935 
00936     this->WriteText(FileStream);
00937 
00938     FileStream.close();
00939   }
00940 
00941 
00943 
00950   template <class T, class Prop, class Storage, class Allocator>
00951   void Matrix_Triangular<T, Prop, Storage, Allocator>
00952   ::WriteText(ostream& FileStream) const
00953   {
00954 
00955 #ifdef SELDON_CHECK_IO
00956     // Checks if the file is ready.
00957     if (!FileStream.good())
00958       throw IOError("Matrix_Triangular::WriteText(ofstream& FileStream)",
00959                     "Stream is not ready.");
00960 #endif
00961 
00962     int i, j;
00963     for (i = 0; i < this->GetM(); i++)
00964       {
00965         for (j = 0; j < this->GetN(); j++)
00966           FileStream << (*this)(i, j) << '\t';
00967         FileStream << endl;
00968       }
00969 
00970 #ifdef SELDON_CHECK_IO
00971     // Checks if data was written.
00972     if (!FileStream.good())
00973       throw IOError("Matrix_Triangular::WriteText(ofstream& FileStream)",
00974                     string("Output operation failed.")
00975                     + string(" The output file may have been removed")
00976                     + " or there is no space left on device.");
00977 #endif
00978 
00979   }
00980 
00981 
00983 
00990   template <class T, class Prop, class Storage, class Allocator>
00991   void Matrix_Triangular<T, Prop, Storage, Allocator>::Read(string FileName)
00992   {
00993     ifstream FileStream;
00994     FileStream.open(FileName.c_str());
00995 
00996 #ifdef SELDON_CHECK_IO
00997     // Checks if the file was opened.
00998     if (!FileStream.is_open())
00999       throw IOError("Matrix_Triangular::Read(string FileName)",
01000                     string("Unable to open file \"") + FileName + "\".");
01001 #endif
01002 
01003     this->Read(FileStream);
01004 
01005     FileStream.close();
01006   }
01007 
01008 
01010 
01017   template <class T, class Prop, class Storage, class Allocator>
01018   void Matrix_Triangular<T, Prop, Storage, Allocator>
01019   ::Read(istream& FileStream)
01020   {
01021 
01022 #ifdef SELDON_CHECK_IO
01023     // Checks if the stream is ready.
01024     if (!FileStream.good())
01025       throw IOError("Matrix_Triangular::Read(ifstream& FileStream)",
01026                     "Stream is not ready.");
01027 #endif
01028 
01029     int new_m, new_n;
01030     FileStream.read(reinterpret_cast<char*>(&new_m), sizeof(int));
01031     FileStream.read(reinterpret_cast<char*>(&new_n), sizeof(int));
01032     this->Reallocate(new_m, new_n);
01033 
01034     FileStream.read(reinterpret_cast<char*>(this->data_),
01035                     new_m * new_n * sizeof(value_type));
01036 
01037 #ifdef SELDON_CHECK_IO
01038     // Checks if data was read.
01039     if (!FileStream.good())
01040       throw IOError("Matrix_Triangular::Read(ifstream& FileStream)",
01041                     string("Output operation failed.")
01042                     + string(" The intput file may have been removed")
01043                     + " or may not contain enough data.");
01044 #endif
01045 
01046   }
01047 
01048 
01050 
01054   template <class T, class Prop, class Storage, class Allocator>
01055   void Matrix_Triangular<T, Prop, Storage, Allocator>::ReadText(string FileName)
01056   {
01057     ifstream FileStream;
01058     FileStream.open(FileName.c_str());
01059 
01060 #ifdef SELDON_CHECK_IO
01061     // Checks if the file was opened.
01062     if (!FileStream.is_open())
01063       throw IOError("Matrix_Pointers::ReadText(string FileName)",
01064                     string("Unable to open file \"") + FileName + "\".");
01065 #endif
01066 
01067     this->ReadText(FileStream);
01068 
01069     FileStream.close();
01070   }
01071 
01072 
01074 
01078   template <class T, class Prop, class Storage, class Allocator>
01079   void Matrix_Triangular<T, Prop, Storage, Allocator>
01080   ::ReadText(istream& FileStream)
01081   {
01082     // clears previous matrix
01083     Clear();
01084 
01085 #ifdef SELDON_CHECK_IO
01086     // Checks if the stream is ready.
01087     if (!FileStream.good())
01088       throw IOError("Matrix_Pointers::ReadText(ifstream& FileStream)",
01089                     "Stream is not ready.");
01090 #endif
01091 
01092     // we read first line
01093     string line;
01094     getline(FileStream, line);
01095 
01096     if (FileStream.fail())
01097       {
01098         // empty file ?
01099         return;
01100       }
01101 
01102     // converting first line into a vector
01103     istringstream line_stream(line);
01104     Vector<T> first_row;
01105     first_row.ReadText(line_stream);
01106 
01107     // and now the other rows
01108     Vector<T> other_rows;
01109     other_rows.ReadText(FileStream);
01110 
01111     // number of rows and columns
01112     int n = first_row.GetM();
01113     int m = 1 + other_rows.GetM()/n;
01114 
01115 #ifdef SELDON_CHECK_IO
01116     // Checking number of elements
01117     if (other_rows.GetM() != (m-1)*n)
01118       throw IOError("Matrix_Pointers::ReadText(ifstream& FileStream)",
01119                     "The file should contain same number of columns.");
01120 #endif
01121 
01122     this->Reallocate(m,n);
01123     // filling matrix
01124     for (int j = 0; j < n; j++)
01125       this->Val(0, j) = first_row(j);
01126 
01127     int nb = 0;
01128     if (Storage::UpLo())
01129       for (int i = 1; i < m; i++)
01130         {
01131           for (int j = 0; j < i; j++)
01132             nb++;
01133 
01134           for (int j = i; j < n; j++)
01135             this->Val(i, j) = other_rows(nb++);
01136         }
01137     else
01138       for (int i = 1; i < m; i++)
01139         {
01140           for (int j = 0; j <= i; j++)
01141             this->Val(i, j) = other_rows(nb++);
01142 
01143           for (int j = i+1; j < n; j++)
01144             nb++;
01145         }
01146   }
01147 
01148 
01149 
01151   // MATRIX<COLUPTRIANG> //
01153 
01154 
01155   /****************
01156    * CONSTRUCTORS *
01157    ****************/
01158 
01159 
01161 
01164   template <class T, class Prop, class Allocator>
01165   Matrix<T, Prop, ColUpTriang, Allocator>::Matrix()  throw():
01166     Matrix_Triangular<T, Prop, ColUpTriang, Allocator>()
01167   {
01168   }
01169 
01170 
01172 
01176   template <class T, class Prop, class Allocator>
01177   Matrix<T, Prop, ColUpTriang, Allocator>::Matrix(int i, int j):
01178     Matrix_Triangular<T, Prop, ColUpTriang, Allocator>(i, j)
01179   {
01180   }
01181 
01182 
01183   /*****************
01184    * OTHER METHODS *
01185    *****************/
01186 
01187 
01189 
01193   template <class T, class Prop, class Allocator>
01194   template <class T0>
01195   Matrix<T, Prop, ColUpTriang, Allocator>&
01196   Matrix<T, Prop, ColUpTriang, Allocator>::operator= (const T0& x)
01197   {
01198     this->Fill(x);
01199 
01200     return *this;
01201   }
01202 
01203 
01205 
01208   template <class T, class Prop, class Allocator>
01209   template <class T0>
01210   Matrix<T, Prop, ColUpTriang, Allocator>&
01211   Matrix<T, Prop, ColUpTriang, Allocator>::operator*= (const T0& x)
01212   {
01213     for (int i = 0; i < this->GetDataSize();i++)
01214       this->data_[i] *= x;
01215 
01216     return *this;
01217   }
01218 
01219 
01220 
01222   // MATRIX<COLLOTRIANG> //
01224 
01225 
01226   /****************
01227    * CONSTRUCTORS *
01228    ****************/
01229 
01230 
01232 
01235   template <class T, class Prop, class Allocator>
01236   Matrix<T, Prop, ColLoTriang, Allocator>::Matrix()  throw():
01237     Matrix_Triangular<T, Prop, ColLoTriang, Allocator>()
01238   {
01239   }
01240 
01241 
01243 
01247   template <class T, class Prop, class Allocator>
01248   Matrix<T, Prop, ColLoTriang, Allocator>::Matrix(int i, int j):
01249     Matrix_Triangular<T, Prop, ColLoTriang, Allocator>(i, j)
01250   {
01251   }
01252 
01253 
01254   /*****************
01255    * OTHER METHODS *
01256    *****************/
01257 
01258 
01260 
01264   template <class T, class Prop, class Allocator>
01265   template <class T0>
01266   Matrix<T, Prop, ColLoTriang, Allocator>&
01267   Matrix<T, Prop, ColLoTriang, Allocator>::operator= (const T0& x)
01268   {
01269     this->Fill(x);
01270 
01271     return *this;
01272   }
01273 
01274 
01276 
01279   template <class T, class Prop, class Allocator>
01280   template <class T0>
01281   Matrix<T, Prop, ColLoTriang, Allocator>&
01282   Matrix<T, Prop, ColLoTriang, Allocator>::operator*= (const T0& x)
01283   {
01284     for (int i = 0; i < this->GetDataSize();i++)
01285       this->data_[i] *= x;
01286 
01287     return *this;
01288   }
01289 
01290 
01291 
01293   // MATRIX<ROWUPTRIANG> //
01295 
01296 
01297   /****************
01298    * CONSTRUCTORS *
01299    ****************/
01300 
01301 
01303 
01306   template <class T, class Prop, class Allocator>
01307   Matrix<T, Prop, RowUpTriang, Allocator>::Matrix()  throw():
01308     Matrix_Triangular<T, Prop, RowUpTriang, Allocator>()
01309   {
01310   }
01311 
01312 
01314 
01318   template <class T, class Prop, class Allocator>
01319   Matrix<T, Prop, RowUpTriang, Allocator>::Matrix(int i, int j):
01320     Matrix_Triangular<T, Prop, RowUpTriang, Allocator>(i, j)
01321   {
01322   }
01323 
01324 
01325   /*****************
01326    * OTHER METHODS *
01327    *****************/
01328 
01329 
01331 
01335   template <class T, class Prop, class Allocator>
01336   template <class T0>
01337   Matrix<T, Prop, RowUpTriang, Allocator>&
01338   Matrix<T, Prop, RowUpTriang, Allocator>::operator= (const T0& x)
01339   {
01340     this->Fill(x);
01341 
01342     return *this;
01343   }
01344 
01345 
01347 
01350   template <class T, class Prop, class Allocator>
01351   template <class T0>
01352   Matrix<T, Prop, RowUpTriang, Allocator>&
01353   Matrix<T, Prop, RowUpTriang, Allocator>::operator*= (const T0& x)
01354   {
01355     for (int i = 0; i < this->GetDataSize();i++)
01356       this->data_[i] *= x;
01357 
01358     return *this;
01359   }
01360 
01361 
01362 
01364   // MATRIX<ROWLOTRIANG> //
01366 
01367 
01368   /****************
01369    * CONSTRUCTORS *
01370    ****************/
01371 
01372 
01374 
01377   template <class T, class Prop, class Allocator>
01378   Matrix<T, Prop, RowLoTriang, Allocator>::Matrix()  throw():
01379     Matrix_Triangular<T, Prop, RowLoTriang, Allocator>()
01380   {
01381   }
01382 
01383 
01385 
01389   template <class T, class Prop, class Allocator>
01390   Matrix<T, Prop, RowLoTriang, Allocator>::Matrix(int i, int j):
01391     Matrix_Triangular<T, Prop, RowLoTriang, Allocator>(i, j)
01392   {
01393   }
01394 
01395 
01396   /*****************
01397    * OTHER METHODS *
01398    *****************/
01399 
01400 
01402 
01406   template <class T, class Prop, class Allocator>
01407   template <class T0>
01408   Matrix<T, Prop, RowLoTriang, Allocator>&
01409   Matrix<T, Prop, RowLoTriang, Allocator>::operator= (const T0& x)
01410   {
01411     this->Fill(x);
01412 
01413     return *this;
01414   }
01415 
01416 
01418 
01421   template <class T, class Prop, class Allocator>
01422   template <class T0>
01423   Matrix<T, Prop, RowLoTriang, Allocator>&
01424   Matrix<T, Prop, RowLoTriang, Allocator>::operator*= (const T0& x)
01425   {
01426     for (int i = 0; i < this->GetDataSize();i++)
01427       this->data_[i] *= x;
01428 
01429     return *this;
01430   }
01431 
01432 } // namespace Seldon.
01433 
01434 #define SELDON_FILE_MATRIX_TRIANGULAR_CXX
01435 #endif