Warning: this documentation for the development version is under construction.

/home/vivien/public_html/.src_seldon/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>
00482   ::operator() (int i, int j) const
00483   {
00484 
00485 #ifdef SELDON_CHECK_BOUNDS
00486     if (i < 0 || i >= this->m_)
00487       throw WrongRow("Matrix_Triangular::operator() const",
00488                      string("Index should be in [0, ") + to_str(this->m_-1)
00489                      + "], but is equal to " + to_str(i) + ".");
00490     if (j < 0 || j >= this->n_)
00491       throw WrongCol("Matrix_Triangular::operator() const",
00492                      string("Index should be in [0, ") + to_str(this->n_-1)
00493                      + "], but is equal to " + to_str(j) + ".");
00494 #endif
00495 
00496     if (Storage::UpLo())
00497       {
00498         if (i > j)
00499           return T(0);
00500         else
00501           return me_[Storage::GetFirst(i, j)][Storage::GetSecond(i, j)];
00502       }
00503     else
00504       {
00505         if (i < j)
00506           return T(0);
00507         else
00508           return me_[Storage::GetFirst(i, j)][Storage::GetSecond(i, j)];
00509       }
00510   }
00511 
00512 
00514 
00523   template <class T, class Prop, class Storage, class Allocator>
00524   inline typename Matrix_Triangular<T, Prop, Storage, Allocator>
00525   ::const_reference
00526   Matrix_Triangular<T, Prop, Storage, Allocator>::Val(int i, int j) const
00527   {
00528 
00529 #ifdef SELDON_CHECK_BOUNDS
00530     if (i < 0 || i >= this->m_)
00531       throw WrongRow("Matrix_Triangular::Val(int, int) const",
00532                      string("Index should be in [0, ") + to_str(this->m_-1)
00533                      + "], but is equal to " + to_str(i) + ".");
00534     if (j < 0 || j >= this->n_)
00535       throw WrongCol("Matrix_Triangular::Val(int, int) const",
00536                      string("Index should be in [0, ") + to_str(this->n_-1)
00537                      + "], but is equal to " + to_str(j) + ".");
00538     if ( (Storage::UpLo() && (i > j)) || (!Storage::UpLo() && (i < j)) )
00539       throw WrongRow("Matrix_Triangular::Val(int, int)",
00540                      string("Attempted to access to element (")
00541                      + to_str(i) + ", " + to_str(j)
00542                      + ") but this element is null.");
00543 #endif
00544 
00545     return me_[Storage::GetFirst(i, j)][Storage::GetSecond(i, j)];
00546   }
00547 
00548 
00550 
00559   template <class T, class Prop, class Storage, class Allocator>
00560   inline typename Matrix_Triangular<T, Prop, Storage, Allocator>::reference
00561   Matrix_Triangular<T, Prop, Storage, Allocator>::Val(int i, int j)
00562   {
00563 
00564 #ifdef SELDON_CHECK_BOUNDS
00565     if (i < 0 || i >= this->m_)
00566       throw WrongRow("Matrix_Triangular::Val(int, int)",
00567                      string("Index should be in [0, ") + to_str(this->m_-1)
00568                      + "], but is equal to " + to_str(i) + ".");
00569     if (j < 0 || j >= this->n_)
00570       throw WrongCol("Matrix_Triangular::Val(int, int)",
00571                      string("Index should be in [0, ") + to_str(this->n_-1)
00572                      + "], but is equal to " + to_str(j) + ".");
00573     if ( (Storage::UpLo() && (i > j)) || (!Storage::UpLo() && (i < j)) )
00574       throw WrongRow("Matrix_Triangular::Val(int, int)",
00575                      string("Attempted to access to element (")
00576                      + to_str(i) + ", " + to_str(j)
00577                      + ") but this element is null.");
00578 #endif
00579 
00580     return me_[Storage::GetFirst(i, j)][Storage::GetSecond(i, j)];
00581   }
00582 
00583 
00585 
00591   template <class T, class Prop, class Storage, class Allocator>
00592   inline typename Matrix_Triangular<T, Prop, Storage, Allocator>
00593   ::const_reference
00594   Matrix_Triangular<T, Prop, Storage, Allocator>::Get(int i, int j) const
00595   {
00596     return this->Val(i, j);
00597   }
00598 
00599 
00601 
00607   template <class T, class Prop, class Storage, class Allocator>
00608   inline typename Matrix_Triangular<T, Prop, Storage, Allocator>::reference
00609   Matrix_Triangular<T, Prop, Storage, Allocator>::Get(int i, int j)
00610   {
00611     return this->Val(i, j);
00612   }
00613 
00614 
00616 
00621   template <class T, class Prop, class Storage, class Allocator>
00622   inline typename Matrix_Triangular<T, Prop, Storage, Allocator>::reference
00623   Matrix_Triangular<T, Prop, Storage, Allocator>::operator[] (int i)
00624   {
00625 
00626 #ifdef SELDON_CHECK_BOUNDS
00627     if (i < 0 || i >= this->GetDataSize())
00628       throw WrongIndex("Matrix_Triangular::operator[] (int)",
00629                        string("Index should be in [0, ")
00630                        + to_str(this->GetDataSize()-1) + "], but is equal to "
00631                        + to_str(i) + ".");
00632 #endif
00633 
00634     return this->data_[i];
00635   }
00636 
00637 
00639 
00644   template <class T, class Prop, class Storage, class Allocator>
00645   inline typename Matrix_Triangular<T, Prop, Storage, Allocator>
00646   ::const_reference
00647   Matrix_Triangular<T, Prop, Storage, Allocator>::operator[] (int i) const
00648   {
00649 
00650 #ifdef SELDON_CHECK_BOUNDS
00651     if (i < 0 || i >= this->GetDataSize())
00652       throw WrongIndex("Matrix_Triangular::operator[] (int) const",
00653                        string("Index should be in [0, ")
00654                        + to_str(this->GetDataSize()-1) + "], but is equal to "
00655                        + to_str(i) + ".");
00656 #endif
00657 
00658     return this->data_[i];
00659   }
00660 
00661 
00663 
00668   template <class T, class Prop, class Storage, class Allocator>
00669   inline Matrix_Triangular<T, Prop, Storage, Allocator>&
00670   Matrix_Triangular<T, Prop, Storage, Allocator>
00671   ::operator= (const Matrix_Triangular<T, Prop, Storage, Allocator>& A)
00672   {
00673     this->Copy(A);
00674 
00675     return *this;
00676   }
00677 
00678 
00680 
00685   template <class T, class Prop, class Storage, class Allocator>
00686   inline void Matrix_Triangular<T, Prop, Storage, Allocator>
00687   ::Set(int i, int j, const T& x)
00688   {
00689     this->Val(i, j) = x;
00690   }
00691 
00692 
00694 
00699   template <class T, class Prop, class Storage, class Allocator>
00700   inline void Matrix_Triangular<T, Prop, Storage, Allocator>
00701   ::Copy(const Matrix_Triangular<T, Prop, Storage, Allocator>& A)
00702   {
00703     this->Reallocate(A.GetM(), A.GetN());
00704 
00705     this->allocator_.memorycpy(this->data_, A.GetData(), this->GetDataSize());
00706   }
00707 
00708 
00709   /************************
00710    * CONVENIENT FUNCTIONS *
00711    ************************/
00712 
00713 
00715 
00719   template <class T, class Prop, class Storage, class Allocator>
00720   void Matrix_Triangular<T, Prop, Storage, Allocator>::Zero()
00721   {
00722     this->allocator_.memoryset(this->data_, char(0),
00723                                this->GetDataSize() * sizeof(value_type));
00724   }
00725 
00726 
00728   template <class T, class Prop, class Storage, class Allocator>
00729   void Matrix_Triangular<T, Prop, Storage, Allocator>::SetIdentity()
00730   {
00731     this->Fill(T(0));
00732 
00733     T one(1);
00734     for (int i = 0; i < min(this->m_, this->n_); i++)
00735       this->Val(i, i) = one;
00736   }
00737 
00738 
00740 
00744   template <class T, class Prop, class Storage, class Allocator>
00745   void Matrix_Triangular<T, Prop, Storage, Allocator>::Fill()
00746   {
00747     for (int i = 0; i < this->GetDataSize(); i++)
00748       this->data_[i] = i;
00749   }
00750 
00751 
00753 
00757   template <class T, class Prop, class Storage, class Allocator>
00758   template <class T0>
00759   void Matrix_Triangular<T, Prop, Storage, Allocator>::Fill(const T0& x)
00760   {
00761     for (int i = 0; i < this->GetDataSize(); i++)
00762       this->data_[i] = x;
00763   }
00764 
00765 
00767 
00771   template <class T, class Prop, class Storage, class Allocator>
00772   template <class T0>
00773   Matrix_Triangular<T, Prop, Storage, Allocator>&
00774   Matrix_Triangular<T, Prop, Storage, Allocator>::operator= (const T0& x)
00775   {
00776     this->Fill(x);
00777 
00778     return *this;
00779   }
00780 
00781 
00783 
00786   template <class T, class Prop, class Storage, class Allocator>
00787   void Matrix_Triangular<T, Prop, Storage, Allocator>::FillRand()
00788   {
00789     srand(time(NULL));
00790     for (int i = 0; i < this->GetDataSize(); i++)
00791       this->data_[i] = rand();
00792   }
00793 
00794 
00796 
00801   template <class T, class Prop, class Storage, class Allocator>
00802   void Matrix_Triangular<T, Prop, Storage, Allocator>::Print() const
00803   {
00804     for (int i = 0; i < this->m_; i++)
00805       {
00806         for (int j = 0; j < this->n_; j++)
00807           cout << (*this)(i, j) << "\t";
00808         cout << endl;
00809       }
00810   }
00811 
00812 
00814 
00825   template <class T, class Prop, class Storage, class Allocator>
00826   void Matrix_Triangular<T, Prop, Storage, Allocator>
00827   ::Print(int a, int b, int m, int n) const
00828   {
00829     for (int i = a; i < min(this->m_, a + m); i++)
00830       {
00831         for (int j = b; j < min(this->n_, b + n); j++)
00832           cout << (*this)(i, j) << "\t";
00833         cout << endl;
00834       }
00835   }
00836 
00837 
00839 
00847   template <class T, class Prop, class Storage, class Allocator>
00848   void Matrix_Triangular<T, Prop, Storage, Allocator>::Print(int l) const
00849   {
00850     Print(0, 0, l, l);
00851   }
00852 
00853 
00854   /**************************
00855    * INPUT/OUTPUT FUNCTIONS *
00856    **************************/
00857 
00858 
00860 
00867   template <class T, class Prop, class Storage, class Allocator>
00868   void Matrix_Triangular<T, Prop, Storage, Allocator>
00869   ::Write(string FileName) const
00870   {
00871     ofstream FileStream;
00872     FileStream.open(FileName.c_str(), ofstream::binary);
00873 
00874 #ifdef SELDON_CHECK_IO
00875     // Checks if the file was opened.
00876     if (!FileStream.is_open())
00877       throw IOError("Matrix_Triangular::Write(string FileName)",
00878                     string("Unable to open file \"") + FileName + "\".");
00879 #endif
00880 
00881     this->Write(FileStream);
00882 
00883     FileStream.close();
00884   }
00885 
00886 
00888 
00895   template <class T, class Prop, class Storage, class Allocator>
00896   void Matrix_Triangular<T, Prop, Storage, Allocator>
00897   ::Write(ostream& FileStream) const
00898   {
00899 
00900 #ifdef SELDON_CHECK_IO
00901     // Checks if the stream is ready.
00902     if (!FileStream.good())
00903       throw IOError("Matrix_Triangular::Write(ofstream& FileStream)",
00904                     "Stream is not ready.");
00905 #endif
00906 
00907     FileStream.write(reinterpret_cast<char*>(const_cast<int*>(&this->m_)),
00908                      sizeof(int));
00909     FileStream.write(reinterpret_cast<char*>(const_cast<int*>(&this->n_)),
00910                      sizeof(int));
00911 
00912     FileStream.write(reinterpret_cast<char*>(this->data_),
00913                      this->m_ * this->n_ * sizeof(value_type));
00914 
00915 #ifdef SELDON_CHECK_IO
00916     // Checks if data was written.
00917     if (!FileStream.good())
00918       throw IOError("Matrix_Triangular::Write(ofstream& FileStream)",
00919                     string("Output operation failed.")
00920                     + string(" The output file may have been removed")
00921                     + " or there is no space left on device.");
00922 #endif
00923 
00924   }
00925 
00926 
00928 
00935   template <class T, class Prop, class Storage, class Allocator>
00936   void Matrix_Triangular<T, Prop, Storage, Allocator>
00937   ::WriteText(string FileName) const
00938   {
00939     ofstream FileStream;
00940     FileStream.precision(cout.precision());
00941     FileStream.flags(cout.flags());
00942     FileStream.open(FileName.c_str());
00943 
00944 #ifdef SELDON_CHECK_IO
00945     // Checks if the file was opened.
00946     if (!FileStream.is_open())
00947       throw IOError("Matrix_Triangular::WriteText(string FileName)",
00948                     string("Unable to open file \"") + FileName + "\".");
00949 #endif
00950 
00951     this->WriteText(FileStream);
00952 
00953     FileStream.close();
00954   }
00955 
00956 
00958 
00965   template <class T, class Prop, class Storage, class Allocator>
00966   void Matrix_Triangular<T, Prop, Storage, Allocator>
00967   ::WriteText(ostream& FileStream) const
00968   {
00969 
00970 #ifdef SELDON_CHECK_IO
00971     // Checks if the file is ready.
00972     if (!FileStream.good())
00973       throw IOError("Matrix_Triangular::WriteText(ofstream& FileStream)",
00974                     "Stream is not ready.");
00975 #endif
00976 
00977     int i, j;
00978     for (i = 0; i < this->GetM(); i++)
00979       {
00980         for (j = 0; j < this->GetN(); j++)
00981           FileStream << (*this)(i, j) << '\t';
00982         FileStream << endl;
00983       }
00984 
00985 #ifdef SELDON_CHECK_IO
00986     // Checks if data was written.
00987     if (!FileStream.good())
00988       throw IOError("Matrix_Triangular::WriteText(ofstream& FileStream)",
00989                     string("Output operation failed.")
00990                     + string(" The output file may have been removed")
00991                     + " or there is no space left on device.");
00992 #endif
00993 
00994   }
00995 
00996 
00998 
01005   template <class T, class Prop, class Storage, class Allocator>
01006   void Matrix_Triangular<T, Prop, Storage, Allocator>::Read(string FileName)
01007   {
01008     ifstream FileStream;
01009     FileStream.open(FileName.c_str(), ifstream::binary);
01010 
01011 #ifdef SELDON_CHECK_IO
01012     // Checks if the file was opened.
01013     if (!FileStream.is_open())
01014       throw IOError("Matrix_Triangular::Read(string FileName)",
01015                     string("Unable to open file \"") + FileName + "\".");
01016 #endif
01017 
01018     this->Read(FileStream);
01019 
01020     FileStream.close();
01021   }
01022 
01023 
01025 
01032   template <class T, class Prop, class Storage, class Allocator>
01033   void Matrix_Triangular<T, Prop, Storage, Allocator>
01034   ::Read(istream& FileStream)
01035   {
01036 
01037 #ifdef SELDON_CHECK_IO
01038     // Checks if the stream is ready.
01039     if (!FileStream.good())
01040       throw IOError("Matrix_Triangular::Read(ifstream& FileStream)",
01041                     "Stream is not ready.");
01042 #endif
01043 
01044     int new_m, new_n;
01045     FileStream.read(reinterpret_cast<char*>(&new_m), sizeof(int));
01046     FileStream.read(reinterpret_cast<char*>(&new_n), sizeof(int));
01047     this->Reallocate(new_m, new_n);
01048 
01049     FileStream.read(reinterpret_cast<char*>(this->data_),
01050                     new_m * new_n * sizeof(value_type));
01051 
01052 #ifdef SELDON_CHECK_IO
01053     // Checks if data was read.
01054     if (!FileStream.good())
01055       throw IOError("Matrix_Triangular::Read(ifstream& FileStream)",
01056                     string("Input operation failed.")
01057                     + string(" The input file may have been removed")
01058                     + " or may not contain enough data.");
01059 #endif
01060 
01061   }
01062 
01063 
01065 
01069   template <class T, class Prop, class Storage, class Allocator>
01070   void Matrix_Triangular<T, Prop, Storage, Allocator>::ReadText(string FileName)
01071   {
01072     ifstream FileStream;
01073     FileStream.open(FileName.c_str());
01074 
01075 #ifdef SELDON_CHECK_IO
01076     // Checks if the file was opened.
01077     if (!FileStream.is_open())
01078       throw IOError("Matrix_Pointers::ReadText(string FileName)",
01079                     string("Unable to open file \"") + FileName + "\".");
01080 #endif
01081 
01082     this->ReadText(FileStream);
01083 
01084     FileStream.close();
01085   }
01086 
01087 
01089 
01093   template <class T, class Prop, class Storage, class Allocator>
01094   void Matrix_Triangular<T, Prop, Storage, Allocator>
01095   ::ReadText(istream& FileStream)
01096   {
01097     // clears previous matrix
01098     Clear();
01099 
01100 #ifdef SELDON_CHECK_IO
01101     // Checks if the stream is ready.
01102     if (!FileStream.good())
01103       throw IOError("Matrix_Pointers::ReadText(ifstream& FileStream)",
01104                     "Stream is not ready.");
01105 #endif
01106 
01107     // we read first line
01108     string line;
01109     getline(FileStream, line);
01110 
01111     if (FileStream.fail())
01112       {
01113         // empty file ?
01114         return;
01115       }
01116 
01117     // converting first line into a vector
01118     istringstream line_stream(line);
01119     Vector<T> first_row;
01120     first_row.ReadText(line_stream);
01121 
01122     // and now the other rows
01123     Vector<T> other_rows;
01124     other_rows.ReadText(FileStream);
01125 
01126     // number of rows and columns
01127     int n = first_row.GetM();
01128     int m = 1 + other_rows.GetM()/n;
01129 
01130 #ifdef SELDON_CHECK_IO
01131     // Checking number of elements
01132     if (other_rows.GetM() != (m-1)*n)
01133       throw IOError("Matrix_Pointers::ReadText(ifstream& FileStream)",
01134                     "The file should contain same number of columns.");
01135 #endif
01136 
01137     this->Reallocate(m,n);
01138     // filling matrix
01139     if (Storage::UpLo())
01140       for (int j = 0; j < n; j++)
01141         this->Val(0, j) = first_row(j);
01142     else
01143       this->Val(0, 0) = first_row(0);
01144 
01145     int nb = 0;
01146     if (Storage::UpLo())
01147       for (int i = 1; i < m; i++)
01148         {
01149           for (int j = 0; j < i; j++)
01150             nb++;
01151 
01152           for (int j = i; j < n; j++)
01153             this->Val(i, j) = other_rows(nb++);
01154         }
01155     else
01156       for (int i = 1; i < m; i++)
01157         {
01158           for (int j = 0; j <= i; j++)
01159             this->Val(i, j) = other_rows(nb++);
01160 
01161           for (int j = i+1; j < n; j++)
01162             nb++;
01163         }
01164   }
01165 
01166 
01167 
01169   // MATRIX<COLUPTRIANG> //
01171 
01172 
01173   /****************
01174    * CONSTRUCTORS *
01175    ****************/
01176 
01177 
01179 
01182   template <class T, class Prop, class Allocator>
01183   Matrix<T, Prop, ColUpTriang, Allocator>::Matrix():
01184     Matrix_Triangular<T, Prop, ColUpTriang, Allocator>()
01185   {
01186   }
01187 
01188 
01190 
01194   template <class T, class Prop, class Allocator>
01195   Matrix<T, Prop, ColUpTriang, Allocator>::Matrix(int i, int j):
01196     Matrix_Triangular<T, Prop, ColUpTriang, Allocator>(i, j)
01197   {
01198   }
01199 
01200 
01201   /*****************
01202    * OTHER METHODS *
01203    *****************/
01204 
01205 
01207 
01211   template <class T, class Prop, class Allocator>
01212   template <class T0>
01213   Matrix<T, Prop, ColUpTriang, Allocator>&
01214   Matrix<T, Prop, ColUpTriang, Allocator>::operator= (const T0& x)
01215   {
01216     this->Fill(x);
01217 
01218     return *this;
01219   }
01220 
01221 
01223 
01228   template <class T, class Prop, class Allocator>
01229   inline Matrix<T, Prop, ColUpTriang, Allocator>&
01230   Matrix<T, Prop, ColUpTriang, Allocator>::operator=
01231   (const Matrix<T, Prop, ColUpTriang, Allocator>& A)
01232   {
01233     this->Copy(A);
01234     return *this;
01235   }
01236 
01237 
01239 
01242   template <class T, class Prop, class Allocator>
01243   template <class T0>
01244   Matrix<T, Prop, ColUpTriang, Allocator>&
01245   Matrix<T, Prop, ColUpTriang, Allocator>::operator*= (const T0& x)
01246   {
01247     for (int i = 0; i < this->GetDataSize();i++)
01248       this->data_[i] *= x;
01249 
01250     return *this;
01251   }
01252 
01253 
01254 
01256   // MATRIX<COLLOTRIANG> //
01258 
01259 
01260   /****************
01261    * CONSTRUCTORS *
01262    ****************/
01263 
01264 
01266 
01269   template <class T, class Prop, class Allocator>
01270   Matrix<T, Prop, ColLoTriang, Allocator>::Matrix():
01271     Matrix_Triangular<T, Prop, ColLoTriang, Allocator>()
01272   {
01273   }
01274 
01275 
01277 
01281   template <class T, class Prop, class Allocator>
01282   Matrix<T, Prop, ColLoTriang, Allocator>::Matrix(int i, int j):
01283     Matrix_Triangular<T, Prop, ColLoTriang, Allocator>(i, j)
01284   {
01285   }
01286 
01287 
01288   /*****************
01289    * OTHER METHODS *
01290    *****************/
01291 
01292 
01294 
01298   template <class T, class Prop, class Allocator>
01299   template <class T0>
01300   Matrix<T, Prop, ColLoTriang, Allocator>&
01301   Matrix<T, Prop, ColLoTriang, Allocator>::operator= (const T0& x)
01302   {
01303     this->Fill(x);
01304 
01305     return *this;
01306   }
01307 
01308 
01310 
01315   template <class T, class Prop, class Allocator>
01316   inline Matrix<T, Prop, ColLoTriang, Allocator>&
01317   Matrix<T, Prop, ColLoTriang, Allocator>::operator=
01318   (const Matrix<T, Prop, ColLoTriang, Allocator>& A)
01319   {
01320     this->Copy(A);
01321     return *this;
01322   }
01323 
01324 
01326 
01329   template <class T, class Prop, class Allocator>
01330   template <class T0>
01331   Matrix<T, Prop, ColLoTriang, Allocator>&
01332   Matrix<T, Prop, ColLoTriang, Allocator>::operator*= (const T0& x)
01333   {
01334     for (int i = 0; i < this->GetDataSize();i++)
01335       this->data_[i] *= x;
01336 
01337     return *this;
01338   }
01339 
01340 
01341 
01343   // MATRIX<ROWUPTRIANG> //
01345 
01346 
01347   /****************
01348    * CONSTRUCTORS *
01349    ****************/
01350 
01351 
01353 
01356   template <class T, class Prop, class Allocator>
01357   Matrix<T, Prop, RowUpTriang, Allocator>::Matrix():
01358     Matrix_Triangular<T, Prop, RowUpTriang, Allocator>()
01359   {
01360   }
01361 
01362 
01364 
01368   template <class T, class Prop, class Allocator>
01369   Matrix<T, Prop, RowUpTriang, Allocator>::Matrix(int i, int j):
01370     Matrix_Triangular<T, Prop, RowUpTriang, Allocator>(i, j)
01371   {
01372   }
01373 
01374 
01375   /*****************
01376    * OTHER METHODS *
01377    *****************/
01378 
01379 
01381 
01385   template <class T, class Prop, class Allocator>
01386   template <class T0>
01387   Matrix<T, Prop, RowUpTriang, Allocator>&
01388   Matrix<T, Prop, RowUpTriang, Allocator>::operator= (const T0& x)
01389   {
01390     this->Fill(x);
01391 
01392     return *this;
01393   }
01394 
01395 
01397 
01402   template <class T, class Prop, class Allocator>
01403   inline Matrix<T, Prop, RowUpTriang, Allocator>&
01404   Matrix<T, Prop, RowUpTriang, Allocator>::operator=
01405   (const Matrix<T, Prop, RowUpTriang, Allocator>& A)
01406   {
01407     this->Copy(A);
01408     return *this;
01409   }
01410 
01411 
01413 
01416   template <class T, class Prop, class Allocator>
01417   template <class T0>
01418   Matrix<T, Prop, RowUpTriang, Allocator>&
01419   Matrix<T, Prop, RowUpTriang, Allocator>::operator*= (const T0& x)
01420   {
01421     for (int i = 0; i < this->GetDataSize();i++)
01422       this->data_[i] *= x;
01423 
01424     return *this;
01425   }
01426 
01427 
01428 
01430   // MATRIX<ROWLOTRIANG> //
01432 
01433 
01434   /****************
01435    * CONSTRUCTORS *
01436    ****************/
01437 
01438 
01440 
01443   template <class T, class Prop, class Allocator>
01444   Matrix<T, Prop, RowLoTriang, Allocator>::Matrix():
01445     Matrix_Triangular<T, Prop, RowLoTriang, Allocator>()
01446   {
01447   }
01448 
01449 
01451 
01455   template <class T, class Prop, class Allocator>
01456   Matrix<T, Prop, RowLoTriang, Allocator>::Matrix(int i, int j):
01457     Matrix_Triangular<T, Prop, RowLoTriang, Allocator>(i, j)
01458   {
01459   }
01460 
01461 
01462   /*****************
01463    * OTHER METHODS *
01464    *****************/
01465 
01466 
01468 
01472   template <class T, class Prop, class Allocator>
01473   template <class T0>
01474   Matrix<T, Prop, RowLoTriang, Allocator>&
01475   Matrix<T, Prop, RowLoTriang, Allocator>::operator= (const T0& x)
01476   {
01477     this->Fill(x);
01478 
01479     return *this;
01480   }
01481 
01482 
01484 
01489   template <class T, class Prop, class Allocator>
01490   inline Matrix<T, Prop, RowLoTriang, Allocator>&
01491   Matrix<T, Prop, RowLoTriang, Allocator>::operator=
01492   (const Matrix<T, Prop, RowLoTriang, Allocator>& A)
01493   {
01494     this->Copy(A);
01495     return *this;
01496   }
01497 
01498 
01500 
01503   template <class T, class Prop, class Allocator>
01504   template <class T0>
01505   Matrix<T, Prop, RowLoTriang, Allocator>&
01506   Matrix<T, Prop, RowLoTriang, Allocator>::operator*= (const T0& x)
01507   {
01508     for (int i = 0; i < this->GetDataSize();i++)
01509       this->data_[i] *= x;
01510 
01511     return *this;
01512   }
01513 
01514 } // namespace Seldon.
01515 
01516 #define SELDON_FILE_MATRIX_TRIANGULAR_CXX
01517 #endif