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 
00411   template <class T, class Prop, class Storage, class Allocator>
00412   inline typename Matrix_SymPacked<T, Prop, Storage, Allocator>::reference
00413   Matrix_SymPacked<T, Prop, Storage, Allocator>::operator[] (int i)
00414   {
00415 
00416 #ifdef SELDON_CHECK_BOUNDS
00417     if (i < 0 || i >= this->GetDataSize())
00418       throw WrongIndex("Matrix_SymPacked::operator[] (int)",
00419                        string("Index should be in [0, ")
00420                        + to_str(this->GetDataSize()-1) + "], but is equal to "
00421                        + to_str(i) + ".");
00422 #endif
00423 
00424     return this->data_[i];
00425   }
00426 
00427 
00429 
00434   template <class T, class Prop, class Storage, class Allocator>
00435   inline typename Matrix_SymPacked<T, Prop, Storage, Allocator>
00436   ::const_reference
00437   Matrix_SymPacked<T, Prop, Storage, Allocator>::operator[] (int i) const
00438   {
00439 
00440 #ifdef SELDON_CHECK_BOUNDS
00441     if (i < 0 || i >= this->GetDataSize())
00442       throw WrongIndex("Matrix_SymPacked::operator[] (int) const",
00443                        string("Index should be in [0, ")
00444                        + to_str(this->GetDataSize()-1) + "], but is equal to "
00445                        + to_str(i) + ".");
00446 #endif
00447 
00448     return this->data_[i];
00449   }
00450 
00451 
00453 
00458   template <class T, class Prop, class Storage, class Allocator>
00459   inline Matrix_SymPacked<T, Prop, Storage, Allocator>&
00460   Matrix_SymPacked<T, Prop, Storage, Allocator>
00461   ::operator= (const Matrix_SymPacked<T, Prop, Storage, Allocator>& A)
00462   {
00463     this->Copy(A);
00464 
00465     return *this;
00466   }
00467 
00468 
00470 
00475   template <class T, class Prop, class Storage, class Allocator>
00476   inline void Matrix_SymPacked<T, Prop, Storage, Allocator>
00477   ::Copy(const Matrix_SymPacked<T, Prop, Storage, Allocator>& A)
00478   {
00479     this->Reallocate(A.GetM(), A.GetN());
00480 
00481     this->allocator_.memorycpy(this->data_, A.GetData(), this->GetDataSize());
00482   }
00483 
00484 
00485   /************************
00486    * CONVENIENT FUNCTIONS *
00487    ************************/
00488 
00489 
00491 
00495   template <class T, class Prop, class Storage, class Allocator>
00496   void Matrix_SymPacked<T, Prop, Storage, Allocator>::Zero()
00497   {
00498     this->allocator_.memoryset(this->data_, char(0),
00499                                this->GetDataSize() * sizeof(value_type));
00500   }
00501 
00502 
00504   template <class T, class Prop, class Storage, class Allocator>
00505   void Matrix_SymPacked<T, Prop, Storage, Allocator>::SetIdentity()
00506   {
00507     this->Fill(T(0));
00508 
00509     T one(1);
00510     for (int i = 0; i < min(this->m_, this->n_); i++)
00511       (*this)(i, i) = one;
00512   }
00513 
00514 
00516 
00520   template <class T, class Prop, class Storage, class Allocator>
00521   void Matrix_SymPacked<T, Prop, Storage, Allocator>::Fill()
00522   {
00523     for (int i = 0; i < this->GetDataSize(); i++)
00524       this->data_[i] = i;
00525   }
00526 
00527 
00529 
00532   template <class T, class Prop, class Storage, class Allocator>
00533   template <class T0>
00534   void Matrix_SymPacked<T, Prop, Storage, Allocator>::Fill(const T0& x)
00535   {
00536     for (int i = 0; i < this->GetDataSize(); i++)
00537       this->data_[i] = x;
00538   }
00539 
00540 
00542 
00545   template <class T, class Prop, class Storage, class Allocator>
00546   template <class T0>
00547   Matrix_SymPacked<T, Prop, Storage, Allocator>&
00548   Matrix_SymPacked<T, Prop, Storage, Allocator>::operator= (const T0& x)
00549   {
00550     this->Fill(x);
00551 
00552     return *this;
00553   }
00554 
00555 
00557 
00560   template <class T, class Prop, class Storage, class Allocator>
00561   void Matrix_SymPacked<T, Prop, Storage, Allocator>::FillRand()
00562   {
00563     srand(time(NULL));
00564     for (int i = 0; i < this->GetDataSize(); i++)
00565       this->data_[i] = rand();
00566   }
00567 
00568 
00570 
00575   template <class T, class Prop, class Storage, class Allocator>
00576   void Matrix_SymPacked<T, Prop, Storage, Allocator>::Print() const
00577   {
00578     for (int i = 0; i < this->m_; i++)
00579       {
00580         for (int j = 0; j < this->n_; j++)
00581           cout << (*this)(i, j) << "\t";
00582         cout << endl;
00583       }
00584   }
00585 
00586 
00588 
00599   template <class T, class Prop, class Storage, class Allocator>
00600   void Matrix_SymPacked<T, Prop, Storage, Allocator>
00601   ::Print(int a, int b, int m, int n) const
00602   {
00603     for (int i = a; i < min(this->m_, a + m); i++)
00604       {
00605         for (int j = b; j < min(this->n_, b + n); j++)
00606           cout << (*this)(i, j) << "\t";
00607         cout << endl;
00608       }
00609   }
00610 
00611 
00613 
00621   template <class T, class Prop, class Storage, class Allocator>
00622   void Matrix_SymPacked<T, Prop, Storage, Allocator>::Print(int l) const
00623   {
00624     Print(0, 0, l, l);
00625   }
00626 
00627 
00628   /**************************
00629    * INPUT/OUTPUT FUNCTIONS *
00630    **************************/
00631 
00632 
00634 
00641   template <class T, class Prop, class Storage, class Allocator>
00642   void Matrix_SymPacked<T, Prop, Storage, Allocator>
00643   ::Write(string FileName) const
00644   {
00645     ofstream FileStream;
00646     FileStream.open(FileName.c_str());
00647 
00648 #ifdef SELDON_CHECK_IO
00649     // Checks if the file was opened.
00650     if (!FileStream.is_open())
00651       throw IOError("Matrix_SymPacked::Write(string FileName)",
00652                     string("Unable to open file \"") + FileName + "\".");
00653 #endif
00654 
00655     this->Write(FileStream);
00656 
00657     FileStream.close();
00658   }
00659 
00660 
00662 
00669   template <class T, class Prop, class Storage, class Allocator>
00670   void Matrix_SymPacked<T, Prop, Storage, Allocator>
00671   ::Write(ostream& FileStream) const
00672   {
00673 
00674 #ifdef SELDON_CHECK_IO
00675     // Checks if the file is ready.
00676     if (!FileStream.good())
00677       throw IOError("Matrix_SymPacked::Write(ostream& FileStream)",
00678                     "The stream is not ready.");
00679 #endif
00680 
00681     FileStream.write(reinterpret_cast<char*>(const_cast<int*>(&this->m_)),
00682                      sizeof(int));
00683     FileStream.write(reinterpret_cast<char*>(const_cast<int*>(&this->n_)),
00684                      sizeof(int));
00685 
00686     FileStream.write(reinterpret_cast<char*>(this->data_),
00687                      this->GetDataSize() * sizeof(value_type));
00688 
00689 #ifdef SELDON_CHECK_IO
00690     // Checks if data was written.
00691     if (!FileStream.good())
00692       throw IOError("Matrix_SymPacked::Write(ostream& FileStream)",
00693                     "Output operation failed.");
00694 #endif
00695 
00696   }
00697 
00698 
00700 
00707   template <class T, class Prop, class Storage, class Allocator>
00708   void Matrix_SymPacked<T, Prop, Storage, Allocator>
00709   ::WriteText(string FileName) const
00710   {
00711     ofstream FileStream;
00712     FileStream.precision(cout.precision());
00713     FileStream.flags(cout.flags());
00714     FileStream.open(FileName.c_str());
00715 
00716 #ifdef SELDON_CHECK_IO
00717     // Checks if the file was opened.
00718     if (!FileStream.is_open())
00719       throw IOError("Matrix_SymPacked::WriteText(string FileName)",
00720                     string("Unable to open file \"") + FileName + "\".");
00721 #endif
00722 
00723     this->WriteText(FileStream);
00724 
00725     FileStream.close();
00726   }
00727 
00728 
00730 
00737   template <class T, class Prop, class Storage, class Allocator>
00738   void Matrix_SymPacked<T, Prop, Storage, Allocator>
00739   ::WriteText(ostream& FileStream) const
00740   {
00741 
00742 #ifdef SELDON_CHECK_IO
00743     // Checks if the stream is ready.
00744     if (!FileStream.good())
00745       throw IOError("Matrix_SymPacked::WriteText(ostream& FileStream)",
00746                     "The stream is not ready.");
00747 #endif
00748 
00749     int i, j;
00750     for (i = 0; i < this->GetM(); i++)
00751       {
00752         for (j = 0; j < this->GetN(); j++)
00753           FileStream << (*this)(i, j) << '\t';
00754         FileStream << endl;
00755       }
00756 
00757 #ifdef SELDON_CHECK_IO
00758     // Checks if data was written.
00759     if (!FileStream.good())
00760       throw IOError("Matrix_SymPacked::WriteText(ostream& FileStream)",
00761                     "Output operation failed.");
00762 #endif
00763 
00764   }
00765 
00766 
00768 
00775   template <class T, class Prop, class Storage, class Allocator>
00776   void Matrix_SymPacked<T, Prop, Storage, Allocator>::Read(string FileName)
00777   {
00778     ifstream FileStream;
00779     FileStream.open(FileName.c_str());
00780 
00781 #ifdef SELDON_CHECK_IO
00782     // Checks if the file was opened.
00783     if (!FileStream.good())
00784       throw IOError("Matrix_SymPacked::Read(string FileName)",
00785                     string("Unable to open file \"") + FileName + "\".");
00786 #endif
00787 
00788     this->Read(FileStream);
00789 
00790     FileStream.close();
00791   }
00792 
00793 
00795 
00802   template <class T, class Prop, class Storage, class Allocator>
00803   void Matrix_SymPacked<T, Prop, Storage, Allocator>
00804   ::Read(istream& FileStream)
00805   {
00806 
00807 #ifdef SELDON_CHECK_IO
00808     // Checks if the stream is ready.
00809     if (!FileStream.good())
00810       throw IOError("Matrix_SymPacked::Read(istream& FileStream)",
00811                     "The stream is not ready.");
00812 #endif
00813 
00814     int new_m, new_n;
00815     FileStream.read(reinterpret_cast<char*>(&new_m), sizeof(int));
00816     FileStream.read(reinterpret_cast<char*>(&new_n), sizeof(int));
00817     this->Reallocate(new_m, new_n);
00818 
00819     FileStream.read(reinterpret_cast<char*>(this->data_),
00820                     this->GetDataSize() * sizeof(value_type));
00821 
00822 #ifdef SELDON_CHECK_IO
00823     // Checks if data was read.
00824     if (!FileStream.good())
00825       throw IOError("Matrix_SymPacked::Read(istream& FileStream)",
00826                     "Output operation failed.");
00827 #endif
00828 
00829   }
00830 
00831 
00833 
00837   template <class T, class Prop, class Storage, class Allocator>
00838   void Matrix_SymPacked<T, Prop, Storage, Allocator>
00839   ::ReadText(string FileName)
00840   {
00841     ifstream FileStream;
00842     FileStream.open(FileName.c_str());
00843 
00844 #ifdef SELDON_CHECK_IO
00845     // Checks if the file was opened.
00846     if (!FileStream.is_open())
00847       throw IOError("Matrix_Pointers::ReadText(string FileName)",
00848                     string("Unable to open file \"") + FileName + "\".");
00849 #endif
00850 
00851     this->ReadText(FileStream);
00852 
00853     FileStream.close();
00854   }
00855 
00856 
00858 
00862   template <class T, class Prop, class Storage, class Allocator>
00863   void Matrix_SymPacked<T, Prop, Storage, Allocator>
00864   ::ReadText(istream& FileStream)
00865   {
00866     // Clears the matrix.
00867     Clear();
00868 
00869 #ifdef SELDON_CHECK_IO
00870     // Checks if the stream is ready.
00871     if (!FileStream.good())
00872       throw IOError("Matrix_SymPacked::ReadText(istream& FileStream)",
00873                     "The stream is not ready.");
00874 #endif
00875 
00876     // Reads the first line.
00877     string line;
00878     getline(FileStream, line);
00879     if (FileStream.fail())
00880       // Is the file empty?
00881       return;
00882 
00883     // Converts the first line into a vector.
00884     istringstream line_stream(line);
00885     Vector<T> first_row;
00886     first_row.ReadText(line_stream);
00887 
00888     // Now reads all other rows, and puts them in a single vector.
00889     Vector<T> other_row;
00890     other_row.ReadText(FileStream);
00891 
00892     // Number of rows and columns.
00893     int n = first_row.GetM();
00894     int m = 1 + other_row.GetM() / n;
00895 
00896 #ifdef SELDON_CHECK_IO
00897     // Checks that enough elements were read.
00898     if (other_row.GetM() != (m - 1) * n)
00899       throw IOError("Matrix_SymPacked::ReadText(istream& FileStream)",
00900                     "Not all rows have the same number of columns.");
00901 #endif
00902 
00903     this->Reallocate(m,n);
00904 
00905     // Fills the matrix.
00906     for (int j = 0; j < n; j++)
00907       this->Val(0, j) = first_row(j);
00908     int k = 0;
00909     for (int i = 1; i < m; i++)
00910       {
00911         k += i;
00912         for (int j = i; j < n; j++)
00913           this->Val(i, j) = other_row(k++);
00914       }
00915   }
00916 
00917 
00919   // MATRIX<COLSYMPACKED> //
00921 
00922 
00923   /****************
00924    * CONSTRUCTORS *
00925    ****************/
00926 
00927 
00929 
00932   template <class T, class Prop, class Allocator>
00933   Matrix<T, Prop, ColSymPacked, Allocator>::Matrix():
00934     Matrix_SymPacked<T, Prop, ColSymPacked, Allocator>()
00935   {
00936   }
00937 
00938 
00940 
00945   template <class T, class Prop, class Allocator>
00946   Matrix<T, Prop, ColSymPacked, Allocator>::Matrix(int i, int j):
00947     Matrix_SymPacked<T, Prop, ColSymPacked, Allocator>(i, i)
00948   {
00949   }
00950 
00951 
00952   /*****************
00953    * OTHER METHODS *
00954    *****************/
00955 
00956 
00958 
00961   template <class T, class Prop, class Allocator>
00962   template <class T0>
00963   Matrix<T, Prop, ColSymPacked, Allocator>&
00964   Matrix<T, Prop, ColSymPacked, Allocator>::operator= (const T0& x)
00965   {
00966     this->Fill(x);
00967 
00968     return *this;
00969   }
00970 
00971 
00973 
00976   template <class T, class Prop, class Allocator>
00977   template <class T0>
00978   Matrix<T, Prop, ColSymPacked, Allocator>&
00979   Matrix<T, Prop, ColSymPacked, Allocator>::operator*= (const T0& x)
00980   {
00981     for (int i = 0; i < this->GetDataSize();i++)
00982       this->data_[i] *= x;
00983 
00984     return *this;
00985   }
00986 
00987 
00989 
00996   template <class T, class Prop, class Allocator>
00997   inline void Matrix<T, Prop, ColSymPacked, Allocator>::Resize(int i, int j)
00998   {
00999 
01000     // Storing the old values of the matrix.
01001     int nold = this->GetDataSize();
01002     Vector<T, VectFull, Allocator> xold(nold);
01003     for (int k = 0; k < nold; k++)
01004       xold(k) = this->data_[k];
01005 
01006     // Reallocation.
01007     this->Reallocate(i,j);
01008 
01009     // Filling the matrix with its old values.
01010     int nmin = min(nold, this->GetDataSize());
01011     for (int k = 0; k < nmin; k++)
01012       this->data_[k] = xold(k);
01013   }
01014 
01015 
01017   // MATRIX<ROWSYMPACKED> //
01019 
01020 
01021   /****************
01022    * CONSTRUCTORS *
01023    ****************/
01024 
01025 
01027 
01030   template <class T, class Prop, class Allocator>
01031   Matrix<T, Prop, RowSymPacked, Allocator>::Matrix():
01032     Matrix_SymPacked<T, Prop, RowSymPacked, Allocator>()
01033   {
01034   }
01035 
01036 
01038 
01043   template <class T, class Prop, class Allocator>
01044   Matrix<T, Prop, RowSymPacked, Allocator>::Matrix(int i, int j):
01045     Matrix_SymPacked<T, Prop, RowSymPacked, Allocator>(i, i)
01046   {
01047   }
01048 
01049 
01050   /*****************
01051    * OTHER METHODS *
01052    *****************/
01053 
01054 
01056 
01059   template <class T, class Prop, class Allocator>
01060   template <class T0>
01061   Matrix<T, Prop, RowSymPacked, Allocator>&
01062   Matrix<T, Prop, RowSymPacked, Allocator>::operator= (const T0& x)
01063   {
01064     this->Fill(x);
01065 
01066     return *this;
01067   }
01068 
01069 
01071 
01074   template <class T, class Prop, class Allocator>
01075   template <class T0>
01076   Matrix<T, Prop, RowSymPacked, Allocator>&
01077   Matrix<T, Prop, RowSymPacked, Allocator>::operator*= (const T0& x)
01078   {
01079     for (int i = 0; i < this->GetDataSize();i++)
01080       this->data_[i] *= x;
01081 
01082     return *this;
01083   }
01084 
01085 
01087 
01094   template <class T, class Prop, class Allocator>
01095   inline void Matrix<T, Prop, RowSymPacked, Allocator>::Resize(int i, int j)
01096   {
01097 
01098     // Storing the old values of the matrix.
01099     int nold = this->GetDataSize(), iold = this->m_;
01100     Vector<T, VectFull, Allocator> xold(nold);
01101     for (int k = 0; k < nold; k++)
01102       xold(k) = this->data_[k];
01103 
01104     // Reallocation.
01105     this->Reallocate(i,j);
01106 
01107     // Filling the matrix with its old values.
01108     int imin = min(iold, i);
01109     nold = 0;
01110     int n = 0;
01111     for (int k = 0; k < imin; k++)
01112       {
01113         for (int l = k; l < imin; l++)
01114           this->data_[n+l-k] = xold(nold+l-k);
01115 
01116         n += i - k;
01117         nold += iold - k;
01118       }
01119   }
01120 
01121 
01122 } // namespace Seldon.
01123 
01124 #define SELDON_FILE_MATRIX_SYMPACKED_CXX
01125 #endif