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

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