matrix/Matrix_SymPacked.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_SYMPACKED_CXX
00022 
00023 #include "Matrix_SymPacked.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_SymPacked<T, Prop, Storage, Allocator>::Matrix_SymPacked():
00040     Matrix_Base<T, Allocator>()
00041   {
00042   }
00043 
00044 
00046 
00051   template <class T, class Prop, class Storage, class Allocator>
00052   inline Matrix_SymPacked<T, Prop, Storage, Allocator>
00053   ::Matrix_SymPacked(int i, int j): Matrix_Base<T, Allocator>(i, i)
00054   {
00055 
00056 #ifdef SELDON_CHECK_MEMORY
00057     try
00058       {
00059 #endif
00060 
00061         this->data_ = this->allocator_.allocate((i * (i + 1)) / 2, this);
00062 
00063 #ifdef SELDON_CHECK_MEMORY
00064       }
00065     catch (...)
00066       {
00067         this->m_ = 0;
00068         this->n_ = 0;
00069         this->data_ = NULL;
00070         return;
00071       }
00072     if (this->data_ == NULL)
00073       {
00074         this->m_ = 0;
00075         this->n_ = 0;
00076         return;
00077       }
00078 #endif
00079 
00080   }
00081 
00082 
00084   template <class T, class Prop, class Storage, class Allocator>
00085   inline Matrix_SymPacked<T, Prop, Storage, Allocator>
00086   ::Matrix_SymPacked(const Matrix_SymPacked<T, Prop, Storage, Allocator>& A)
00087     : Matrix_Base<T, Allocator>()
00088   {
00089     this->m_ = 0;
00090     this->n_ = 0;
00091     this->data_ = NULL;
00092 
00093     this->Copy(A);
00094   }
00095 
00096 
00097   /**************
00098    * DESTRUCTOR *
00099    **************/
00100 
00101 
00103   template <class T, class Prop, class Storage, class Allocator>
00104   inline Matrix_SymPacked<T, Prop, Storage, Allocator>::~Matrix_SymPacked()
00105   {
00106 
00107 #ifdef SELDON_CHECK_MEMORY
00108     try
00109       {
00110 #endif
00111 
00112         if (this->data_ != NULL)
00113           {
00114             this->allocator_.deallocate(this->data_,
00115                                         (this->m_ * (this->m_ + 1)) / 2);
00116             this->data_ = NULL;
00117           }
00118 
00119 #ifdef SELDON_CHECK_MEMORY
00120       }
00121     catch (...)
00122       {
00123         this->m_ = 0;
00124         this->n_ = 0;
00125         this->data_ = NULL;
00126       }
00127 #endif
00128 
00129   }
00130 
00131 
00133 
00137   template <class T, class Prop, class Storage, class Allocator>
00138   inline void Matrix_SymPacked<T, Prop, Storage, Allocator>::Clear()
00139   {
00140     this->~Matrix_SymPacked();
00141     this->m_ = 0;
00142     this->n_ = 0;
00143   }
00144 
00145 
00146   /*******************
00147    * BASIC FUNCTIONS *
00148    *******************/
00149 
00150 
00152 
00155   template <class T, class Prop, class Storage, class Allocator>
00156   int Matrix_SymPacked<T, Prop, Storage, Allocator>::GetDataSize() const
00157   {
00158     return (this->m_ * (this->m_ + 1)) / 2;
00159   }
00160 
00161 
00162   /*********************
00163    * MEMORY MANAGEMENT *
00164    *********************/
00165 
00166 
00168 
00174   template <class T, class Prop, class Storage, class Allocator>
00175   inline void Matrix_SymPacked<T, Prop, Storage, Allocator>::Reallocate(int i,
00176                                                                         int j)
00177   {
00178 
00179     if (i != this->m_)
00180       {
00181         this->m_ = i;
00182         this->n_ = i;
00183 
00184 #ifdef SELDON_CHECK_MEMORY
00185         try
00186           {
00187 #endif
00188 
00189             this->data_ =
00190               reinterpret_cast<pointer>(this->allocator_
00191                                         .reallocate(this->data_,
00192                                                     (i * (i + 1)) / 2,
00193                                                     this));
00194 
00195 #ifdef SELDON_CHECK_MEMORY
00196           }
00197         catch (...)
00198           {
00199             this->m_ = 0;
00200             this->n_ = 0;
00201             this->data_ = NULL;
00202             throw NoMemory("Matrix_SymPacked::Reallocate(int, int)",
00203                            "Unable to reallocate memory for data_.");
00204           }
00205         if (this->data_ == NULL)
00206           {
00207             this->m_ = 0;
00208             this->n_ = 0;
00209             throw NoMemory("Matrix_SymPacked::Reallocate(int, int)",
00210                            "Unable to reallocate memory for data_.");
00211           }
00212 #endif
00213 
00214       }
00215   }
00216 
00217 
00220 
00234   template <class T, class Prop, class Storage, class Allocator>
00235   inline void Matrix_SymPacked<T, Prop, Storage, Allocator>
00236   ::SetData(int i, int j,
00237             typename Matrix_SymPacked<T, Prop, Storage, Allocator>
00238             ::pointer data)
00239   {
00240     this->Clear();
00241 
00242     this->m_ = i;
00243     this->n_ = i;
00244 
00245     this->data_ = data;
00246   }
00247 
00248 
00250 
00254   template <class T, class Prop, class Storage, class Allocator>
00255   inline void Matrix_SymPacked<T, Prop, Storage, Allocator>::Nullify()
00256   {
00257     this->data_ = NULL;
00258     this->m_ = 0;
00259     this->n_ = 0;
00260   }
00261 
00262 
00263   /**********************************
00264    * ELEMENT ACCESS AND AFFECTATION *
00265    **********************************/
00266 
00267 
00269 
00275   template <class T, class Prop, class Storage, class Allocator>
00276   inline typename Matrix_SymPacked<T, Prop, Storage, Allocator>::reference
00277   Matrix_SymPacked<T, Prop, Storage, Allocator>::operator() (int i, int j)
00278   {
00279 
00280 #ifdef SELDON_CHECK_BOUNDS
00281     if (i < 0 || i >= this->m_)
00282       throw WrongRow("Matrix_SymPacked::operator()",
00283                      string("Index should be in [0, ") + to_str(this->m_-1)
00284                      + "], but is equal to " + to_str(i) + ".");
00285     if (j < 0 || j >= this->n_)
00286       throw WrongCol("Matrix_SymPacked::operator()",
00287                      string("Index should be in [0, ") + to_str(this->n_-1)
00288                      + "], but is equal to " + to_str(j) + ".");
00289 #endif
00290 
00291     return this->data_[j > i
00292                        ? Storage::GetFirst(i * this->n_
00293                                            - (i * (i + 1)) / 2 + j,
00294                                            (j*(j+1)) / 2 + i)
00295                        : Storage::GetFirst(j * this->m_
00296                                            - (j * (j + 1)) / 2 + i,
00297                                            (i * (i + 1)) / 2 + j)];
00298   }
00299 
00300 
00302 
00308   template <class T, class Prop, class Storage, class Allocator>
00309   inline typename Matrix_SymPacked<T, Prop, Storage, Allocator>
00310   ::const_reference
00311   Matrix_SymPacked<T, Prop, Storage, Allocator>::operator() (int i,
00312                                                              int j) const
00313   {
00314 
00315 #ifdef SELDON_CHECK_BOUNDS
00316     if (i < 0 || i >= this->m_)
00317       throw WrongRow("Matrix_SymPacked::operator()",
00318                      string("Index should be in [0, ") + to_str(this->m_-1)
00319                      + "], but is equal to " + to_str(i) + ".");
00320     if (j < 0 || j >= this->n_)
00321       throw WrongCol("Matrix_SymPacked::operator()",
00322                      string("Index should be in [0, ") + to_str(this->n_-1)
00323                      + "], but is equal to " + to_str(j) + ".");
00324 #endif
00325 
00326     return this->data_[j > i
00327                        ? Storage::GetFirst(i * this->n_
00328                                            - (i * (i + 1)) / 2 + j,
00329                                            (j * (j + 1)) / 2 + i)
00330                        : Storage::GetFirst(j * this->m_
00331                                            - (j * (j + 1)) / 2 + i,
00332                                            (i * (i + 1)) / 2 + j)];
00333   }
00334 
00335 
00337 
00344   template <class T, class Prop, class Storage, class Allocator>
00345   inline typename Matrix_SymPacked<T, Prop, Storage, Allocator>::reference
00346   Matrix_SymPacked<T, Prop, Storage, Allocator>::Val(int i, int j)
00347   {
00348 
00349 #ifdef SELDON_CHECK_BOUNDS
00350     if (i < 0 || i >= this->m_)
00351       throw WrongRow("Matrix_SymPacked::Val(int, int)",
00352                      string("Index should be in [0, ") + to_str(this->m_-1)
00353                      + "], but is equal to " + to_str(i) + ".");
00354     if (j < 0 || j >= this->n_)
00355       throw WrongCol("Matrix_SymPacked::Val(int, int)",
00356                      string("Index should be in [0, ") + to_str(this->n_-1)
00357                      + "], but is equal to " + to_str(j) + ".");
00358 #endif
00359 
00360     return this->data_[j > i
00361                        ? Storage::GetFirst(i * this->n_
00362                                            - (i * (i + 1)) / 2 + j,
00363                                            (j * (j + 1)) / 2 + i)
00364                        : Storage::GetFirst(j * this->m_
00365                                            - (j * (j + 1)) / 2 + i,
00366                                            (i * (i + 1)) / 2 + j)];
00367   }
00368 
00369 
00371 
00378   template <class T, class Prop, class Storage, class Allocator>
00379   inline typename Matrix_SymPacked<T, Prop, Storage, Allocator>
00380   ::const_reference
00381   Matrix_SymPacked<T, Prop, Storage, Allocator>::Val(int i, int j) const
00382   {
00383 
00384 #ifdef SELDON_CHECK_BOUNDS
00385     if (i < 0 || i >= this->m_)
00386       throw WrongRow("Matrix_SymPacked::Val(int, int) const",
00387                      string("Index should be in [0, ") + to_str(this->m_-1)
00388                      + "], but is equal to " + to_str(i) + ".");
00389     if (j < 0 || j >= this->n_)
00390       throw WrongCol("Matrix_SymPacked::Val(int, int) const",
00391                      string("Index should be in [0, ") + to_str(this->n_-1)
00392                      + "], but is equal to " + to_str(j) + ".");
00393 #endif
00394 
00395     return this->data_[j > i
00396                        ? Storage::GetFirst(i * this->n_
00397                                            - (i * (i + 1)) / 2 + j,
00398                                            (j * (j + 1)) / 2 + i)
00399                        : Storage::GetFirst(j * this->m_
00400                                            - (j * (j + 1)) / 2 + i,
00401                                            (i * (i + 1)) / 2 + j)];
00402   }
00403 
00404 
00406 
00412   template <class T, class Prop, class Storage, class Allocator>
00413   inline typename Matrix_SymPacked<T, Prop, Storage, Allocator>
00414   ::const_reference
00415   Matrix_SymPacked<T, Prop, Storage, Allocator>::Get(int i, int j) const
00416   {
00417     return this->Val(i, j);
00418   }
00419 
00420 
00422 
00428   template <class T, class Prop, class Storage, class Allocator>
00429   inline typename Matrix_SymPacked<T, Prop, Storage, Allocator>
00430   ::reference Matrix_SymPacked<T, Prop, Storage, Allocator>::Get(int i, int j)
00431   {
00432     return this->Val(i, j);
00433   }
00434 
00435 
00437 
00442   template <class T, class Prop, class Storage, class Allocator>
00443   inline typename Matrix_SymPacked<T, Prop, Storage, Allocator>::reference
00444   Matrix_SymPacked<T, Prop, Storage, Allocator>::operator[] (int i)
00445   {
00446 
00447 #ifdef SELDON_CHECK_BOUNDS
00448     if (i < 0 || i >= this->GetDataSize())
00449       throw WrongIndex("Matrix_SymPacked::operator[] (int)",
00450                        string("Index should be in [0, ")
00451                        + to_str(this->GetDataSize()-1) + "], but is equal to "
00452                        + to_str(i) + ".");
00453 #endif
00454 
00455     return this->data_[i];
00456   }
00457 
00458 
00460 
00465   template <class T, class Prop, class Storage, class Allocator>
00466   inline typename Matrix_SymPacked<T, Prop, Storage, Allocator>
00467   ::const_reference
00468   Matrix_SymPacked<T, Prop, Storage, Allocator>::operator[] (int i) const
00469   {
00470 
00471 #ifdef SELDON_CHECK_BOUNDS
00472     if (i < 0 || i >= this->GetDataSize())
00473       throw WrongIndex("Matrix_SymPacked::operator[] (int) const",
00474                        string("Index should be in [0, ")
00475                        + to_str(this->GetDataSize()-1) + "], but is equal to "
00476                        + to_str(i) + ".");
00477 #endif
00478 
00479     return this->data_[i];
00480   }
00481 
00482 
00484 
00489   template <class T, class Prop, class Storage, class Allocator>
00490   inline Matrix_SymPacked<T, Prop, Storage, Allocator>&
00491   Matrix_SymPacked<T, Prop, Storage, Allocator>
00492   ::operator= (const Matrix_SymPacked<T, Prop, Storage, Allocator>& A)
00493   {
00494     this->Copy(A);
00495 
00496     return *this;
00497   }
00498 
00499 
00501 
00506   template <class T, class Prop, class Storage, class Allocator>
00507   inline void Matrix_SymPacked<T, Prop, Storage, Allocator>
00508   ::Set(int i, int j, const T& x)
00509   {
00510     this->Val(i, j) = x;
00511   }
00512 
00513 
00515 
00520   template <class T, class Prop, class Storage, class Allocator>
00521   inline void Matrix_SymPacked<T, Prop, Storage, Allocator>
00522   ::Copy(const Matrix_SymPacked<T, Prop, Storage, Allocator>& A)
00523   {
00524     this->Reallocate(A.GetM(), A.GetN());
00525 
00526     this->allocator_.memorycpy(this->data_, A.GetData(), this->GetDataSize());
00527   }
00528 
00529 
00530   /************************
00531    * CONVENIENT FUNCTIONS *
00532    ************************/
00533 
00534 
00536 
00540   template <class T, class Prop, class Storage, class Allocator>
00541   void Matrix_SymPacked<T, Prop, Storage, Allocator>::Zero()
00542   {
00543     this->allocator_.memoryset(this->data_, char(0),
00544                                this->GetDataSize() * sizeof(value_type));
00545   }
00546 
00547 
00549   template <class T, class Prop, class Storage, class Allocator>
00550   void Matrix_SymPacked<T, Prop, Storage, Allocator>::SetIdentity()
00551   {
00552     this->Fill(T(0));
00553 
00554     T one(1);
00555     for (int i = 0; i < min(this->m_, this->n_); i++)
00556       (*this)(i, i) = one;
00557   }
00558 
00559 
00561 
00565   template <class T, class Prop, class Storage, class Allocator>
00566   void Matrix_SymPacked<T, Prop, Storage, Allocator>::Fill()
00567   {
00568     for (int i = 0; i < this->GetDataSize(); i++)
00569       this->data_[i] = i;
00570   }
00571 
00572 
00574 
00577   template <class T, class Prop, class Storage, class Allocator>
00578   template <class T0>
00579   void Matrix_SymPacked<T, Prop, Storage, Allocator>::Fill(const T0& x)
00580   {
00581     for (int i = 0; i < this->GetDataSize(); i++)
00582       this->data_[i] = x;
00583   }
00584 
00585 
00587 
00590   template <class T, class Prop, class Storage, class Allocator>
00591   template <class T0>
00592   Matrix_SymPacked<T, Prop, Storage, Allocator>&
00593   Matrix_SymPacked<T, Prop, Storage, Allocator>::operator= (const T0& x)
00594   {
00595     this->Fill(x);
00596 
00597     return *this;
00598   }
00599 
00600 
00602 
00605   template <class T, class Prop, class Storage, class Allocator>
00606   void Matrix_SymPacked<T, Prop, Storage, Allocator>::FillRand()
00607   {
00608     srand(time(NULL));
00609     for (int i = 0; i < this->GetDataSize(); i++)
00610       this->data_[i] = rand();
00611   }
00612 
00613 
00615 
00620   template <class T, class Prop, class Storage, class Allocator>
00621   void Matrix_SymPacked<T, Prop, Storage, Allocator>::Print() const
00622   {
00623     for (int i = 0; i < this->m_; i++)
00624       {
00625         for (int j = 0; j < this->n_; j++)
00626           cout << (*this)(i, j) << "\t";
00627         cout << endl;
00628       }
00629   }
00630 
00631 
00633 
00644   template <class T, class Prop, class Storage, class Allocator>
00645   void Matrix_SymPacked<T, Prop, Storage, Allocator>
00646   ::Print(int a, int b, int m, int n) const
00647   {
00648     for (int i = a; i < min(this->m_, a + m); i++)
00649       {
00650         for (int j = b; j < min(this->n_, b + n); j++)
00651           cout << (*this)(i, j) << "\t";
00652         cout << endl;
00653       }
00654   }
00655 
00656 
00658 
00666   template <class T, class Prop, class Storage, class Allocator>
00667   void Matrix_SymPacked<T, Prop, Storage, Allocator>::Print(int l) const
00668   {
00669     Print(0, 0, l, l);
00670   }
00671 
00672 
00673   /**************************
00674    * INPUT/OUTPUT FUNCTIONS *
00675    **************************/
00676 
00677 
00679 
00686   template <class T, class Prop, class Storage, class Allocator>
00687   void Matrix_SymPacked<T, Prop, Storage, Allocator>
00688   ::Write(string FileName) const
00689   {
00690     ofstream FileStream;
00691     FileStream.open(FileName.c_str(), ofstream::binary);
00692 
00693 #ifdef SELDON_CHECK_IO
00694     // Checks if the file was opened.
00695     if (!FileStream.is_open())
00696       throw IOError("Matrix_SymPacked::Write(string FileName)",
00697                     string("Unable to open file \"") + FileName + "\".");
00698 #endif
00699 
00700     this->Write(FileStream);
00701 
00702     FileStream.close();
00703   }
00704 
00705 
00707 
00714   template <class T, class Prop, class Storage, class Allocator>
00715   void Matrix_SymPacked<T, Prop, Storage, Allocator>
00716   ::Write(ostream& FileStream) const
00717   {
00718 
00719 #ifdef SELDON_CHECK_IO
00720     // Checks if the file is ready.
00721     if (!FileStream.good())
00722       throw IOError("Matrix_SymPacked::Write(ostream& FileStream)",
00723                     "The stream is not ready.");
00724 #endif
00725 
00726     FileStream.write(reinterpret_cast<char*>(const_cast<int*>(&this->m_)),
00727                      sizeof(int));
00728     FileStream.write(reinterpret_cast<char*>(const_cast<int*>(&this->n_)),
00729                      sizeof(int));
00730 
00731     FileStream.write(reinterpret_cast<char*>(this->data_),
00732                      this->GetDataSize() * sizeof(value_type));
00733 
00734 #ifdef SELDON_CHECK_IO
00735     // Checks if data was written.
00736     if (!FileStream.good())
00737       throw IOError("Matrix_SymPacked::Write(ostream& FileStream)",
00738                     "Output operation failed.");
00739 #endif
00740 
00741   }
00742 
00743 
00745 
00752   template <class T, class Prop, class Storage, class Allocator>
00753   void Matrix_SymPacked<T, Prop, Storage, Allocator>
00754   ::WriteText(string FileName) const
00755   {
00756     ofstream FileStream;
00757     FileStream.precision(cout.precision());
00758     FileStream.flags(cout.flags());
00759     FileStream.open(FileName.c_str());
00760 
00761 #ifdef SELDON_CHECK_IO
00762     // Checks if the file was opened.
00763     if (!FileStream.is_open())
00764       throw IOError("Matrix_SymPacked::WriteText(string FileName)",
00765                     string("Unable to open file \"") + FileName + "\".");
00766 #endif
00767 
00768     this->WriteText(FileStream);
00769 
00770     FileStream.close();
00771   }
00772 
00773 
00775 
00782   template <class T, class Prop, class Storage, class Allocator>
00783   void Matrix_SymPacked<T, Prop, Storage, Allocator>
00784   ::WriteText(ostream& FileStream) const
00785   {
00786 
00787 #ifdef SELDON_CHECK_IO
00788     // Checks if the stream is ready.
00789     if (!FileStream.good())
00790       throw IOError("Matrix_SymPacked::WriteText(ostream& FileStream)",
00791                     "The stream is not ready.");
00792 #endif
00793 
00794     int i, j;
00795     for (i = 0; i < this->GetM(); i++)
00796       {
00797         for (j = 0; j < this->GetN(); j++)
00798           FileStream << (*this)(i, j) << '\t';
00799         FileStream << endl;
00800       }
00801 
00802 #ifdef SELDON_CHECK_IO
00803     // Checks if data was written.
00804     if (!FileStream.good())
00805       throw IOError("Matrix_SymPacked::WriteText(ostream& FileStream)",
00806                     "Output operation failed.");
00807 #endif
00808 
00809   }
00810 
00811 
00813 
00820   template <class T, class Prop, class Storage, class Allocator>
00821   void Matrix_SymPacked<T, Prop, Storage, Allocator>::Read(string FileName)
00822   {
00823     ifstream FileStream;
00824     FileStream.open(FileName.c_str(), ifstream::binary);
00825 
00826 #ifdef SELDON_CHECK_IO
00827     // Checks if the file was opened.
00828     if (!FileStream.good())
00829       throw IOError("Matrix_SymPacked::Read(string FileName)",
00830                     string("Unable to open file \"") + FileName + "\".");
00831 #endif
00832 
00833     this->Read(FileStream);
00834 
00835     FileStream.close();
00836   }
00837 
00838 
00840 
00847   template <class T, class Prop, class Storage, class Allocator>
00848   void Matrix_SymPacked<T, Prop, Storage, Allocator>
00849   ::Read(istream& FileStream)
00850   {
00851 
00852 #ifdef SELDON_CHECK_IO
00853     // Checks if the stream is ready.
00854     if (!FileStream.good())
00855       throw IOError("Matrix_SymPacked::Read(istream& FileStream)",
00856                     "The stream is not ready.");
00857 #endif
00858 
00859     int new_m, new_n;
00860     FileStream.read(reinterpret_cast<char*>(&new_m), sizeof(int));
00861     FileStream.read(reinterpret_cast<char*>(&new_n), sizeof(int));
00862     this->Reallocate(new_m, new_n);
00863 
00864     FileStream.read(reinterpret_cast<char*>(this->data_),
00865                     this->GetDataSize() * sizeof(value_type));
00866 
00867 #ifdef SELDON_CHECK_IO
00868     // Checks if data was read.
00869     if (!FileStream.good())
00870       throw IOError("Matrix_SymPacked::Read(istream& FileStream)",
00871                     "Input operation failed.");
00872 #endif
00873 
00874   }
00875 
00876 
00878 
00882   template <class T, class Prop, class Storage, class Allocator>
00883   void Matrix_SymPacked<T, Prop, Storage, Allocator>
00884   ::ReadText(string FileName)
00885   {
00886     ifstream FileStream;
00887     FileStream.open(FileName.c_str());
00888 
00889 #ifdef SELDON_CHECK_IO
00890     // Checks if the file was opened.
00891     if (!FileStream.is_open())
00892       throw IOError("Matrix_Pointers::ReadText(string FileName)",
00893                     string("Unable to open file \"") + FileName + "\".");
00894 #endif
00895 
00896     this->ReadText(FileStream);
00897 
00898     FileStream.close();
00899   }
00900 
00901 
00903 
00907   template <class T, class Prop, class Storage, class Allocator>
00908   void Matrix_SymPacked<T, Prop, Storage, Allocator>
00909   ::ReadText(istream& FileStream)
00910   {
00911     // Clears the matrix.
00912     Clear();
00913 
00914 #ifdef SELDON_CHECK_IO
00915     // Checks if the stream is ready.
00916     if (!FileStream.good())
00917       throw IOError("Matrix_SymPacked::ReadText(istream& FileStream)",
00918                     "The stream is not ready.");
00919 #endif
00920 
00921     // Reads the first line.
00922     string line;
00923     getline(FileStream, line);
00924     if (FileStream.fail())
00925       // Is the file empty?
00926       return;
00927 
00928     // Converts the first line into a vector.
00929     istringstream line_stream(line);
00930     Vector<T> first_row;
00931     first_row.ReadText(line_stream);
00932 
00933     // Now reads all other rows, and puts them in a single vector.
00934     Vector<T> other_row;
00935     other_row.ReadText(FileStream);
00936 
00937     // Number of rows and columns.
00938     int n = first_row.GetM();
00939     int m = 1 + other_row.GetM() / n;
00940 
00941 #ifdef SELDON_CHECK_IO
00942     // Checks that enough elements were read.
00943     if (other_row.GetM() != (m - 1) * n)
00944       throw IOError("Matrix_SymPacked::ReadText(istream& FileStream)",
00945                     "Not all rows have the same number of columns.");
00946 #endif
00947 
00948     this->Reallocate(m,n);
00949 
00950     // Fills the matrix.
00951     for (int j = 0; j < n; j++)
00952       this->Val(0, j) = first_row(j);
00953     int k = 0;
00954     for (int i = 1; i < m; i++)
00955       {
00956         k += i;
00957         for (int j = i; j < n; j++)
00958           this->Val(i, j) = other_row(k++);
00959       }
00960   }
00961 
00962 
00964   // MATRIX<COLSYMPACKED> //
00966 
00967 
00968   /****************
00969    * CONSTRUCTORS *
00970    ****************/
00971 
00972 
00974 
00977   template <class T, class Prop, class Allocator>
00978   Matrix<T, Prop, ColSymPacked, Allocator>::Matrix():
00979     Matrix_SymPacked<T, Prop, ColSymPacked, Allocator>()
00980   {
00981   }
00982 
00983 
00985 
00990   template <class T, class Prop, class Allocator>
00991   Matrix<T, Prop, ColSymPacked, Allocator>::Matrix(int i, int j):
00992     Matrix_SymPacked<T, Prop, ColSymPacked, Allocator>(i, i)
00993   {
00994   }
00995 
00996 
00997   /*****************
00998    * OTHER METHODS *
00999    *****************/
01000 
01001 
01003 
01006   template <class T, class Prop, class Allocator>
01007   template <class T0>
01008   Matrix<T, Prop, ColSymPacked, Allocator>&
01009   Matrix<T, Prop, ColSymPacked, Allocator>::operator= (const T0& x)
01010   {
01011     this->Fill(x);
01012 
01013     return *this;
01014   }
01015 
01017 
01022   template <class T, class Prop, class Allocator>
01023   inline Matrix<T, Prop, ColSymPacked, Allocator>&
01024   Matrix<T, Prop, ColSymPacked, Allocator>::operator= (const Matrix<T, Prop,
01025                                                        ColSymPacked,
01026                                                        Allocator>& A)
01027   {
01028     this->Copy(A);
01029     return *this;
01030   }
01031 
01032 
01034 
01037   template <class T, class Prop, class Allocator>
01038   template <class T0>
01039   Matrix<T, Prop, ColSymPacked, Allocator>&
01040   Matrix<T, Prop, ColSymPacked, Allocator>::operator*= (const T0& x)
01041   {
01042     for (int i = 0; i < this->GetDataSize();i++)
01043       this->data_[i] *= x;
01044 
01045     return *this;
01046   }
01047 
01048 
01050 
01057   template <class T, class Prop, class Allocator>
01058   inline void Matrix<T, Prop, ColSymPacked, Allocator>::Resize(int i, int j)
01059   {
01060 
01061     // Storing the old values of the matrix.
01062     int nold = this->GetDataSize();
01063     Vector<T, VectFull, Allocator> xold(nold);
01064     for (int k = 0; k < nold; k++)
01065       xold(k) = this->data_[k];
01066 
01067     // Reallocation.
01068     this->Reallocate(i,j);
01069 
01070     // Filling the matrix with its old values.
01071     int nmin = min(nold, this->GetDataSize());
01072     for (int k = 0; k < nmin; k++)
01073       this->data_[k] = xold(k);
01074   }
01075 
01076 
01078   // MATRIX<ROWSYMPACKED> //
01080 
01081 
01082   /****************
01083    * CONSTRUCTORS *
01084    ****************/
01085 
01086 
01088 
01091   template <class T, class Prop, class Allocator>
01092   Matrix<T, Prop, RowSymPacked, Allocator>::Matrix():
01093     Matrix_SymPacked<T, Prop, RowSymPacked, Allocator>()
01094   {
01095   }
01096 
01097 
01099 
01104   template <class T, class Prop, class Allocator>
01105   Matrix<T, Prop, RowSymPacked, Allocator>::Matrix(int i, int j):
01106     Matrix_SymPacked<T, Prop, RowSymPacked, Allocator>(i, i)
01107   {
01108   }
01109 
01110 
01111   /*****************
01112    * OTHER METHODS *
01113    *****************/
01114 
01115 
01117 
01120   template <class T, class Prop, class Allocator>
01121   template <class T0>
01122   Matrix<T, Prop, RowSymPacked, Allocator>&
01123   Matrix<T, Prop, RowSymPacked, Allocator>::operator= (const T0& x)
01124   {
01125     this->Fill(x);
01126     return *this;
01127   }
01128 
01129 
01131 
01136   template <class T, class Prop, class Allocator>
01137   inline Matrix<T, Prop, RowSymPacked, Allocator>&
01138   Matrix<T, Prop, RowSymPacked, Allocator>::operator= (const Matrix<T, Prop,
01139                                                        RowSymPacked,
01140                                                        Allocator>& A)
01141   {
01142     this->Copy(A);
01143     return *this;
01144   }
01145 
01146 
01148 
01151   template <class T, class Prop, class Allocator>
01152   template <class T0>
01153   Matrix<T, Prop, RowSymPacked, Allocator>&
01154   Matrix<T, Prop, RowSymPacked, Allocator>::operator*= (const T0& x)
01155   {
01156     for (int i = 0; i < this->GetDataSize();i++)
01157       this->data_[i] *= x;
01158 
01159     return *this;
01160   }
01161 
01162 
01164 
01171   template <class T, class Prop, class Allocator>
01172   inline void Matrix<T, Prop, RowSymPacked, Allocator>::Resize(int i, int j)
01173   {
01174 
01175     // Storing the old values of the matrix.
01176     int nold = this->GetDataSize(), iold = this->m_;
01177     Vector<T, VectFull, Allocator> xold(nold);
01178     for (int k = 0; k < nold; k++)
01179       xold(k) = this->data_[k];
01180 
01181     // Reallocation.
01182     this->Reallocate(i,j);
01183 
01184     // Filling the matrix with its old values.
01185     int imin = min(iold, i);
01186     nold = 0;
01187     int n = 0;
01188     for (int k = 0; k < imin; k++)
01189       {
01190         for (int l = k; l < imin; l++)
01191           this->data_[n+l-k] = xold(nold+l-k);
01192 
01193         n += i - k;
01194         nold += iold - k;
01195       }
01196   }
01197 
01198 
01199 } // namespace Seldon.
01200 
01201 #define SELDON_FILE_MATRIX_SYMPACKED_CXX
01202 #endif