matrix/Matrix_TriangPacked.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_TRIANGPACKED_CXX
00022 
00023 #include "Matrix_TriangPacked.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_TriangPacked<T, Prop, Storage, Allocator>
00040   ::Matrix_TriangPacked(): Matrix_Base<T, Allocator>()
00041   {
00042   }
00043 
00044 
00046 
00051   template <class T, class Prop, class Storage, class Allocator>
00052   inline Matrix_TriangPacked<T, Prop, Storage, Allocator>
00053   ::Matrix_TriangPacked(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_TriangPacked<T, Prop, Storage, Allocator>
00086   ::Matrix_TriangPacked(const Matrix_TriangPacked<T, Prop,
00087                         Storage, Allocator>& A)
00088     : Matrix_Base<T, Allocator>()
00089   {
00090     this->m_ = 0;
00091     this->n_ = 0;
00092     this->data_ = NULL;
00093 
00094     this->Copy(A);
00095   }
00096 
00097 
00098   /**************
00099    * DESTRUCTOR *
00100    **************/
00101 
00102 
00104   template <class T, class Prop, class Storage, class Allocator>
00105   inline Matrix_TriangPacked<T, Prop, Storage, Allocator>
00106   ::~Matrix_TriangPacked()
00107   {
00108 
00109 #ifdef SELDON_CHECK_MEMORY
00110     try
00111       {
00112 #endif
00113 
00114         if (this->data_ != NULL)
00115           {
00116             this->allocator_.deallocate(this->data_,
00117                                         (this->m_ * (this->m_ + 1)) / 2);
00118             this->data_ = NULL;
00119           }
00120 
00121 #ifdef SELDON_CHECK_MEMORY
00122       }
00123     catch (...)
00124       {
00125         this->m_ = 0;
00126         this->n_ = 0;
00127         this->data_ = NULL;
00128       }
00129 #endif
00130 
00131   }
00132 
00133 
00135 
00139   template <class T, class Prop, class Storage, class Allocator>
00140   inline void Matrix_TriangPacked<T, Prop, Storage, Allocator>::Clear()
00141   {
00142     this->~Matrix_TriangPacked();
00143     this->m_ = 0;
00144     this->n_ = 0;
00145   }
00146 
00147 
00148   /*******************
00149    * BASIC FUNCTIONS *
00150    *******************/
00151 
00152 
00154 
00157   template <class T, class Prop, class Storage, class Allocator>
00158   int Matrix_TriangPacked<T, Prop, Storage, Allocator>::GetDataSize() const
00159   {
00160     return (this->m_ * (this->m_ + 1)) / 2;
00161   }
00162 
00163 
00164   /*********************
00165    * MEMORY MANAGEMENT *
00166    *********************/
00167 
00168 
00170 
00176   template <class T, class Prop, class Storage, class Allocator>
00177   inline void Matrix_TriangPacked<T, Prop, Storage, Allocator>
00178   ::Reallocate(int i, int j)
00179   {
00180 
00181     if (i != this->m_)
00182       {
00183         this->m_ = i;
00184         this->n_ = i;
00185 
00186 #ifdef SELDON_CHECK_MEMORY
00187         try
00188           {
00189 #endif
00190 
00191             this->data_ =
00192               reinterpret_cast<pointer>(this->allocator_.reallocate(this->data_,
00193                                                                     (i*(i+1))/2,
00194                                                                     this) );
00195 
00196 #ifdef SELDON_CHECK_MEMORY
00197           }
00198         catch (...)
00199           {
00200             this->m_ = 0;
00201             this->n_ = 0;
00202             this->data_ = NULL;
00203             throw NoMemory("Matrix_TriangPacked::Reallocate(int, int)",
00204                            "Unable to reallocate memory for data_.");
00205           }
00206         if (this->data_ == NULL)
00207           {
00208             this->m_ = 0;
00209             this->n_ = 0;
00210             throw NoMemory("Matrix_TriangPacked::Reallocate(int, int)",
00211                            "Unable to reallocate memory for data_.");
00212           }
00213 #endif
00214 
00215       }
00216   }
00217 
00218 
00221 
00235   template <class T, class Prop, class Storage, class Allocator>
00236   inline void Matrix_TriangPacked<T, Prop, Storage, Allocator>::
00237   SetData(int i, int j,
00238           typename Matrix_TriangPacked<T, Prop, Storage, Allocator>
00239           ::pointer data)
00240   {
00241     this->Clear();
00242 
00243     this->m_ = i;
00244     this->n_ = i;
00245 
00246     this->data_ = data;
00247   }
00248 
00249 
00251 
00255   template <class T, class Prop, class Storage, class Allocator>
00256   inline void Matrix_TriangPacked<T, Prop, Storage, Allocator>::Nullify()
00257   {
00258     this->data_ = NULL;
00259     this->m_ = 0;
00260     this->n_ = 0;
00261   }
00262 
00263 
00264   /**********************************
00265    * ELEMENT ACCESS AND AFFECTATION *
00266    **********************************/
00267 
00268 
00270 
00276   template <class T, class Prop, class Storage, class Allocator>
00277   inline typename Matrix_TriangPacked<T, Prop, Storage, Allocator>::value_type
00278   Matrix_TriangPacked<T, Prop, Storage, Allocator>
00279   ::operator() (int i, int j) const
00280   {
00281 
00282 #ifdef SELDON_CHECK_BOUNDS
00283     if (i < 0 || i >= this->m_)
00284       throw WrongRow("Matrix_TriangPacked::operator()",
00285                      string("Index should be in [0, ") + to_str(this->m_-1)
00286                      + "], but is equal to " + to_str(i) + ".");
00287     if (j < 0 || j >= this->n_)
00288       throw WrongCol("Matrix_TriangPacked::operator()",
00289                      string("Index should be in [0, ") + to_str(this->n_-1)
00290                      + "], but is equal to " + to_str(j) + ".");
00291 #endif
00292 
00293     if (Storage::UpLo())
00294       if (i > j)
00295         return 0;
00296       else
00297         return this->data_[Storage::GetFirst(i * this->n_
00298                                              - (i * (i + 1)) / 2 + j,
00299                                              (j * (j + 1)) / 2 + i)];
00300     else
00301       if (i < j)
00302         return 0;
00303       else
00304         return this->data_[Storage::GetFirst((i * (i + 1)) / 2 + j,
00305                                              j * this->m_
00306                                              - (j * (j + 1)) / 2 + i)];
00307   }
00308 
00309 
00311 
00318   template <class T, class Prop, class Storage, class Allocator>
00319   inline typename Matrix_TriangPacked<T, Prop, Storage, Allocator>::reference
00320   Matrix_TriangPacked<T, Prop, Storage, Allocator>::Val(int i, int j)
00321   {
00322 
00323 #ifdef SELDON_CHECK_BOUNDS
00324     if (i < 0 || i >= this->m_)
00325       throw WrongRow("Matrix_TriangPacked::Val(int, int)",
00326                      string("Index should be in [0, ") + to_str(this->m_-1)
00327                      + "], but is equal to " + to_str(i) + ".");
00328     if (j < 0 || j >= this->n_)
00329       throw WrongCol("Matrix_TriangPacked::Val(int, int)",
00330                      string("Index should be in [0, ") + to_str(this->n_-1)
00331                      + "], but is equal to " + to_str(j) + ".");
00332     if (Storage::UpLo())
00333       {
00334         if (i > j)
00335           throw WrongRow("Matrix_TriangPacked::Val(int, int)",
00336                          string("Attempted to access to element (")
00337                          + to_str(i) + ", " + to_str(j) + string(") but row")
00338                          + string(" index should not be strictly more")
00339                          + " than column index (upper triangular matrix).");
00340         return this->data_[Storage::GetFirst(i * this->n_
00341                                              - (i * (i + 1)) / 2 + j,
00342                                              (j * (j + 1)) / 2 + i)];
00343       }
00344     else
00345       {
00346         if (j > i)
00347           throw WrongCol("Matrix_TriangPacked::Val(int, int)",
00348                          string("Attempted to access to element (")
00349                          + to_str(i) + ", " + to_str(j) + string(") but")
00350                          + string(" column index should not be strictly more")
00351                          + " than row index (lower triangular matrix).");
00352         return this->data_[Storage::GetFirst((i * (i + 1)) / 2 + j,
00353                                              j * this->m_
00354                                              - (j * (j + 1)) / 2 + i)];
00355       }
00356 #endif
00357 
00358     if (Storage::UpLo())
00359       return this->data_[Storage::GetFirst(i * this->n_
00360                                            - (i * (i + 1)) / 2 + j,
00361                                            (j * (j + 1)) / 2 + i)];
00362     else
00363       return this->data_[Storage::GetFirst((i * (i + 1)) / 2 + j,
00364                                            j * this->m_
00365                                            - (j * (j + 1)) / 2 + i)];
00366   }
00367 
00368 
00370 
00377   template <class T, class Prop, class Storage, class Allocator>
00378   inline typename Matrix_TriangPacked<T, Prop, Storage, Allocator>
00379   ::const_reference
00380   Matrix_TriangPacked<T, Prop, Storage, Allocator>::Val(int i, int j) const
00381   {
00382 
00383 #ifdef SELDON_CHECK_BOUNDS
00384     if (i < 0 || i >= this->m_)
00385       throw WrongRow("Matrix_TriangPacked::Val(int, int) const",
00386                      string("Index should be in [0, ") + to_str(this->m_-1)
00387                      + "], but is equal to " + to_str(i) + ".");
00388     if (j < 0 || j >= this->n_)
00389       throw WrongCol("Matrix_TriangPacked::Val(int, int)",
00390                      string("Index should be in [0, ") + to_str(this->n_-1)
00391                      + "], but is equal to " + to_str(j) + ".");
00392     if (Storage::UpLo())
00393       {
00394         if (i > j)
00395           throw WrongRow("Matrix_TriangPacked::Val(int, int) const",
00396                          string("Attempted to access to element (")
00397                          + to_str(i) + ", " + to_str(j) + string(") but row")
00398                          + string(" index should not be strictly more")
00399                          + " than column index (upper triangular matrix).");
00400         return this->data_[Storage::GetFirst(i * this->n_
00401                                              - (i * (i + 1)) / 2 + j,
00402                                              (j * (j + 1)) / 2 + i)];
00403       }
00404     else
00405       {
00406         if (j > i)
00407           throw WrongCol("Matrix_TriangPacked::Val(int, int) const",
00408                          string("Attempted to access to element (")
00409                          + to_str(i) + ", " + to_str(j) + string(") but")
00410                          + string(" column index should not be strictly more")
00411                          + " than row index (lower triangular matrix).");
00412         return this->data_[Storage::GetFirst((i * (i + 1)) / 2 + j,
00413                                              j * this->m_
00414                                              - (j * (j + 1)) / 2 + i)];
00415       }
00416 #endif
00417 
00418     if (Storage::UpLo())
00419       return this->data_[Storage::GetFirst(i * this->n_
00420                                            - (i * (i + 1)) / 2 + j,
00421                                            (j * (j + 1)) / 2 + i)];
00422     else
00423       return this->data_[Storage::GetFirst((i * (i + 1)) / 2 + j,
00424                                            j * this->m_
00425                                            - (j * (j + 1)) / 2 + i)];
00426   }
00427 
00428 
00430 
00436   template <class T, class Prop, class Storage, class Allocator>
00437   inline typename Matrix_TriangPacked<T, Prop, Storage, Allocator>::reference
00438   Matrix_TriangPacked<T, Prop, Storage, Allocator>::Get(int i, int j)
00439   {
00440     return this->Val(i, j);
00441   }
00442 
00443 
00445 
00451   template <class T, class Prop, class Storage, class Allocator>
00452   inline typename Matrix_TriangPacked<T, Prop, Storage, Allocator>
00453   ::const_reference
00454   Matrix_TriangPacked<T, Prop, Storage, Allocator>::Get(int i, int j) const
00455   {
00456     return this->Val(i, j);
00457   }
00458 
00459 
00461 
00466   template <class T, class Prop, class Storage, class Allocator>
00467   inline typename Matrix_TriangPacked<T, Prop, Storage, Allocator>::reference
00468   Matrix_TriangPacked<T, Prop, Storage, Allocator>::operator[] (int i)
00469   {
00470 
00471 #ifdef SELDON_CHECK_BOUNDS
00472     if (i < 0 || i >= this->GetDataSize())
00473       throw WrongIndex("Matrix_TriangPacked::operator[] (int)",
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 typename Matrix_TriangPacked<T, Prop, Storage, Allocator>
00491   ::const_reference
00492   Matrix_TriangPacked<T, Prop, Storage, Allocator>::operator[] (int i) const
00493   {
00494 
00495 #ifdef SELDON_CHECK_BOUNDS
00496     if (i < 0 || i >= this->GetDataSize())
00497       throw WrongIndex("Matrix_TriangPacked::operator[] (int) const",
00498                        string("Index should be in [0, ")
00499                        + to_str(this->GetDataSize()-1) + "], but is equal to "
00500                        + to_str(i) + ".");
00501 #endif
00502 
00503     return this->data_[i];
00504   }
00505 
00506 
00508 
00513   template <class T, class Prop, class Storage, class Allocator>
00514   inline Matrix_TriangPacked<T, Prop, Storage, Allocator>&
00515   Matrix_TriangPacked<T, Prop, Storage, Allocator>::
00516   operator= (const Matrix_TriangPacked<T, Prop, Storage, Allocator>& A)
00517   {
00518     this->Copy(A);
00519 
00520     return *this;
00521   }
00522 
00523 
00525 
00530   template <class T, class Prop, class Storage, class Allocator>
00531   inline void Matrix_TriangPacked<T, Prop, Storage, Allocator>
00532   ::Set(int i, int j, const T& x)
00533   {
00534     this->Val(i, j) = x;
00535   }
00536 
00537 
00539 
00544   template <class T, class Prop, class Storage, class Allocator>
00545   inline void Matrix_TriangPacked<T, Prop, Storage, Allocator>::
00546   Copy(const Matrix_TriangPacked<T, Prop, Storage, Allocator>& A)
00547   {
00548     this->Reallocate(A.GetM(), A.GetN());
00549 
00550     this->allocator_.memorycpy(this->data_, A.GetData(), this->GetDataSize());
00551   }
00552 
00553 
00554   /************************
00555    * CONVENIENT FUNCTIONS *
00556    ************************/
00557 
00558 
00560 
00564   template <class T, class Prop, class Storage, class Allocator>
00565   void Matrix_TriangPacked<T, Prop, Storage, Allocator>::Zero()
00566   {
00567     this->allocator_.memoryset(this->data_, char(0),
00568                                this->GetDataSize() * sizeof(value_type));
00569   }
00570 
00571 
00573   template <class T, class Prop, class Storage, class Allocator>
00574   void Matrix_TriangPacked<T, Prop, Storage, Allocator>::SetIdentity()
00575   {
00576     this->Fill(T(0));
00577 
00578     T one(1);
00579     bool storage_col = (Storage::GetFirst(1,0) == 0);
00580     if ((Storage::UpLo() && storage_col)||(!Storage::UpLo() && !storage_col))
00581       {
00582         int index(-1);
00583         for (int i = 0; i < min(this->m_, this->n_); i++)
00584           {
00585             index += i+1;
00586             this->data_[index] = one;
00587           }
00588       }
00589     else if (Storage::UpLo() && !storage_col)
00590       {
00591         int index(0);
00592         for (int i = 0; i < min(this->m_, this->n_); i++)
00593           {
00594             this->data_[index] = one;
00595             index += this->m_-i;
00596           }
00597       }
00598     else if (!Storage::UpLo() && storage_col)
00599       {
00600         int index(0);
00601         for (int i = 0; i < min(this->m_, this->n_); i++)
00602           {
00603             this->data_[index] = one;
00604             index += this->n_-i;
00605           }
00606       }
00607   }
00608 
00609 
00611 
00615   template <class T, class Prop, class Storage, class Allocator>
00616   void Matrix_TriangPacked<T, Prop, Storage, Allocator>::Fill()
00617   {
00618     for (int i = 0; i < this->GetDataSize(); i++)
00619       this->data_[i] = i;
00620   }
00621 
00622 
00624 
00627   template <class T, class Prop, class Storage, class Allocator>
00628   template <class T0>
00629   void Matrix_TriangPacked<T, Prop, Storage, Allocator>::Fill(const T0& x)
00630   {
00631     for (int i = 0; i < this->GetDataSize(); i++)
00632       this->data_[i] = x;
00633   }
00634 
00635 
00637 
00640   template <class T, class Prop, class Storage, class Allocator>
00641   template <class T0>
00642   Matrix_TriangPacked<T, Prop, Storage, Allocator>&
00643   Matrix_TriangPacked<T, Prop, Storage, Allocator>::operator= (const T0& x)
00644   {
00645     this->Fill(x);
00646 
00647     return *this;
00648   }
00649 
00650 
00652 
00655   template <class T, class Prop, class Storage, class Allocator>
00656   void Matrix_TriangPacked<T, Prop, Storage, Allocator>::FillRand()
00657   {
00658     srand(time(NULL));
00659     for (int i = 0; i < this->GetDataSize(); i++)
00660       this->data_[i] = rand();
00661   }
00662 
00663 
00665 
00670   template <class T, class Prop, class Storage, class Allocator>
00671   void Matrix_TriangPacked<T, Prop, Storage, Allocator>::Print() const
00672   {
00673     for (int i = 0; i < this->m_; i++)
00674       {
00675         for (int j = 0; j < this->n_; j++)
00676           cout << (*this)(i, j) << "\t";
00677         cout << endl;
00678       }
00679   }
00680 
00681 
00683 
00694   template <class T, class Prop, class Storage, class Allocator>
00695   void Matrix_TriangPacked<T, Prop, Storage, Allocator>
00696   ::Print(int a, int b, int m, int n) const
00697   {
00698     for (int i = a; i < min(this->m_, a + m); i++)
00699       {
00700         for (int j = b; j < min(this->n_, b + n); j++)
00701           cout << (*this)(i, j) << "\t";
00702         cout << endl;
00703       }
00704   }
00705 
00706 
00708 
00716   template <class T, class Prop, class Storage, class Allocator>
00717   void Matrix_TriangPacked<T, Prop, Storage, Allocator>::Print(int l) const
00718   {
00719     Print(0, 0, l, l);
00720   }
00721 
00722 
00723   /**************************
00724    * INPUT/OUTPUT FUNCTIONS *
00725    **************************/
00726 
00727 
00729 
00736   template <class T, class Prop, class Storage, class Allocator>
00737   void Matrix_TriangPacked<T, Prop, Storage, Allocator>
00738   ::Write(string FileName) const
00739   {
00740     ofstream FileStream;
00741     FileStream.open(FileName.c_str(), ofstream::binary);
00742 
00743 #ifdef SELDON_CHECK_IO
00744     // Checks if the file was opened.
00745     if (!FileStream.is_open())
00746       throw IOError("Matrix_TriangPacked::Write(string FileName)",
00747                     string("Unable to open file \"") + FileName + "\".");
00748 #endif
00749 
00750     this->Write(FileStream);
00751 
00752     FileStream.close();
00753   }
00754 
00755 
00757 
00764   template <class T, class Prop, class Storage, class Allocator>
00765   void Matrix_TriangPacked<T, Prop, Storage, Allocator>
00766   ::Write(ostream& FileStream) const
00767   {
00768 
00769 #ifdef SELDON_CHECK_IO
00770     // Checks if the file is ready.
00771     if (!FileStream.good())
00772       throw IOError("Matrix_TriangPacked::Write(ofstream& FileStream)",
00773                     "Stream is not ready.");
00774 #endif
00775 
00776     FileStream.write(reinterpret_cast<char*>(const_cast<int*>(&this->m_)),
00777                      sizeof(int));
00778     FileStream.write(reinterpret_cast<char*>(const_cast<int*>(&this->n_)),
00779                      sizeof(int));
00780 
00781     FileStream.write(reinterpret_cast<char*>(this->data_),
00782                      this->GetDataSize() * sizeof(value_type));
00783 
00784 #ifdef SELDON_CHECK_IO
00785     // Checks if data was written.
00786     if (!FileStream.good())
00787       throw IOError("Matrix_TriangPacked::Write(ofstream& FileStream)",
00788                     string("Output operation failed.")
00789                     + string(" The output file may have been removed")
00790                     + " or there is no space left on device.");
00791 #endif
00792 
00793   }
00794 
00795 
00797 
00804   template <class T, class Prop, class Storage, class Allocator>
00805   void Matrix_TriangPacked<T, Prop, Storage, Allocator>
00806   ::WriteText(string FileName) const
00807   {
00808     ofstream FileStream;
00809     FileStream.precision(cout.precision());
00810     FileStream.flags(cout.flags());
00811     FileStream.open(FileName.c_str());
00812 
00813 #ifdef SELDON_CHECK_IO
00814     // Checks if the file was opened.
00815     if (!FileStream.is_open())
00816       throw IOError("Matrix_TriangPacked::WriteText(string FileName)",
00817                     string("Unable to open file \"") + FileName + "\".");
00818 #endif
00819 
00820     this->WriteText(FileStream);
00821 
00822     FileStream.close();
00823   }
00824 
00825 
00827 
00834   template <class T, class Prop, class Storage, class Allocator>
00835   void Matrix_TriangPacked<T, Prop, Storage, Allocator>
00836   ::WriteText(ostream& FileStream) const
00837   {
00838 
00839 #ifdef SELDON_CHECK_IO
00840     // Checks if the stream is ready.
00841     if (!FileStream.good())
00842       throw IOError("Matrix_TriangPacked::WriteText(ofstream& FileStream)",
00843                     "Stream is not ready.");
00844 #endif
00845 
00846     int i, j;
00847     for (i = 0; i < this->GetM(); i++)
00848       {
00849         for (j = 0; j < this->GetN(); j++)
00850           FileStream << (*this)(i, j) << '\t';
00851         FileStream << endl;
00852       }
00853 
00854 #ifdef SELDON_CHECK_IO
00855     // Checks if data was written.
00856     if (!FileStream.good())
00857       throw IOError("Matrix_TriangPacked::WriteText(ofstream& FileStream)",
00858                     string("Output operation failed.")
00859                     + string(" The output file may have been removed")
00860                     + " or there is no space left on device.");
00861 #endif
00862 
00863   }
00864 
00865 
00867 
00874   template <class T, class Prop, class Storage, class Allocator>
00875   void Matrix_TriangPacked<T, Prop, Storage, Allocator>::Read(string FileName)
00876   {
00877     ifstream FileStream;
00878     FileStream.open(FileName.c_str(), ifstream::binary);
00879 
00880 #ifdef SELDON_CHECK_IO
00881     // Checks if the file was opened.
00882     if (!FileStream.good())
00883       throw IOError("Matrix_TriangPacked::Read(string FileName)",
00884                     string("Unable to open file \"") + FileName + "\".");
00885 #endif
00886 
00887     this->Read(FileStream);
00888 
00889     FileStream.close();
00890   }
00891 
00892 
00894 
00901   template <class T, class Prop, class Storage, class Allocator>
00902   void Matrix_TriangPacked<T, Prop, Storage, Allocator>
00903   ::Read(istream& FileStream)
00904   {
00905 
00906 #ifdef SELDON_CHECK_IO
00907     // Checks if the stream is ready.
00908     if (!FileStream.good())
00909       throw IOError("Matrix_TriangPacked::Read(ifstream& FileStream)",
00910                     "Stream is not ready.");
00911 #endif
00912 
00913     int new_m, new_n;
00914     FileStream.read(reinterpret_cast<char*>(&new_m), sizeof(int));
00915     FileStream.read(reinterpret_cast<char*>(&new_n), sizeof(int));
00916     this->Reallocate(new_m, new_n);
00917 
00918     FileStream.read(reinterpret_cast<char*>(this->data_),
00919                     this->GetDataSize() * sizeof(value_type));
00920 
00921 #ifdef SELDON_CHECK_IO
00922     // Checks if data was read.
00923     if (!FileStream.good())
00924       throw IOError("Matrix_TriangPacked::Read(ifstream& FileStream)",
00925                     string("Input operation failed.")
00926                     + string(" The input file may have been removed")
00927                     + " or may not contain enough data.");
00928 #endif
00929 
00930   }
00931 
00932 
00934 
00938   template <class T, class Prop, class Storage, class Allocator>
00939   void Matrix_TriangPacked<T, Prop, Storage, Allocator>::ReadText(string FileName)
00940   {
00941     ifstream FileStream;
00942     FileStream.open(FileName.c_str());
00943 
00944 #ifdef SELDON_CHECK_IO
00945     // Checks if the file was opened.
00946     if (!FileStream.is_open())
00947       throw IOError("Matrix_Pointers::ReadText(string FileName)",
00948                     string("Unable to open file \"") + FileName + "\".");
00949 #endif
00950 
00951     this->ReadText(FileStream);
00952 
00953     FileStream.close();
00954   }
00955 
00956 
00958 
00962   template <class T, class Prop, class Storage, class Allocator>
00963   void Matrix_TriangPacked<T, Prop, Storage, Allocator>
00964   ::ReadText(istream& FileStream)
00965   {
00966     // clears previous matrix
00967     Clear();
00968 
00969 #ifdef SELDON_CHECK_IO
00970     // Checks if the stream is ready.
00971     if (!FileStream.good())
00972       throw IOError("Matrix_Pointers::ReadText(ifstream& FileStream)",
00973                     "Stream is not ready.");
00974 #endif
00975 
00976     // we read first line
00977     string line;
00978     getline(FileStream, line);
00979 
00980     if (FileStream.fail())
00981       {
00982         // empty file ?
00983         return;
00984       }
00985 
00986     // converting first line into a vector
00987     istringstream line_stream(line);
00988     Vector<T> first_row;
00989     first_row.ReadText(line_stream);
00990 
00991     // and now the other rows
00992     Vector<T> other_rows;
00993     other_rows.ReadText(FileStream);
00994 
00995     // number of rows and columns
00996     int n = first_row.GetM();
00997     int m = 1 + other_rows.GetM()/n;
00998 
00999 #ifdef SELDON_CHECK_IO
01000     // Checking number of elements
01001     if (other_rows.GetM() != (m-1)*n)
01002       throw IOError("Matrix_Pointers::ReadText(ifstream& FileStream)",
01003                     "The file should contain same number of columns.");
01004 #endif
01005 
01006     this->Reallocate(m,n);
01007     // filling matrix
01008     if (Storage::UpLo())
01009       for (int j = 0; j < n; j++)
01010         this->Val(0, j) = first_row(j);
01011     else
01012       this->Val(0, 0) = first_row(0);
01013 
01014     int nb = 0;
01015     if (Storage::UpLo())
01016       for (int i = 1; i < m; i++)
01017         {
01018           for (int j = 0; j < i; j++)
01019             nb++;
01020 
01021           for (int j = i; j < n; j++)
01022             this->Val(i, j) = other_rows(nb++);
01023         }
01024     else
01025       for (int i = 1; i < m; i++)
01026         {
01027           for (int j = 0; j <= i; j++)
01028             this->Val(i, j) = other_rows(nb++);
01029 
01030           for (int j = i+1; j < n; j++)
01031             nb++;
01032         }
01033   }
01034 
01035 
01036 
01038   // MATRIX<COLUPTRIANGPACKED> //
01040 
01041 
01042   /****************
01043    * CONSTRUCTORS *
01044    ****************/
01045 
01046 
01048 
01051   template <class T, class Prop, class Allocator>
01052   inline Matrix<T, Prop, ColUpTriangPacked, Allocator>::Matrix():
01053     Matrix_TriangPacked<T, Prop, ColUpTriangPacked, Allocator>()
01054   {
01055   }
01056 
01057 
01059 
01064   template <class T, class Prop, class Allocator>
01065   inline Matrix<T, Prop, ColUpTriangPacked, Allocator>::Matrix(int i, int j):
01066     Matrix_TriangPacked<T, Prop, ColUpTriangPacked, Allocator>(i, i)
01067   {
01068   }
01069 
01070 
01071   /*****************
01072    * OTHER METHODS *
01073    *****************/
01074 
01075 
01077 
01084   template <class T, class Prop, class Allocator>
01085   inline void Matrix<T, Prop, ColUpTriangPacked, Allocator>
01086   ::Resize(int i, int j)
01087   {
01088 
01089     // Storing the old values of the matrix.
01090     int nold = this->GetDataSize();
01091     Vector<T, VectFull, Allocator> xold(nold);
01092     for (int k = 0; k < nold; k++)
01093       xold(k) = this->data_[k];
01094 
01095     // Reallocation.
01096     this->Reallocate(i, j);
01097 
01098     // Filling the matrix with its old values.
01099     int nmin = min(nold, this->GetDataSize());
01100     for (int k = 0; k < nmin; k++)
01101       this->data_[k] = xold(k);
01102   }
01103 
01104 
01106 
01109   template <class T, class Prop, class Allocator>
01110   template <class T0>
01111   Matrix<T, Prop, ColUpTriangPacked, Allocator>&
01112   Matrix<T, Prop, ColUpTriangPacked, Allocator>::operator= (const T0& x)
01113   {
01114     this->Fill(x);
01115 
01116     return *this;
01117   }
01118 
01119 
01121 
01126   template <class T, class Prop, class Allocator>
01127   inline Matrix<T, Prop, ColUpTriangPacked, Allocator>&
01128   Matrix<T, Prop, ColUpTriangPacked, Allocator>::operator=
01129   (const Matrix<T, Prop, ColUpTriangPacked, Allocator>& A)
01130   {
01131     this->Copy(A);
01132     return *this;
01133   }
01134 
01135 
01137 
01140   template <class T, class Prop, class Allocator>
01141   template <class T0>
01142   Matrix<T, Prop, ColUpTriangPacked, Allocator>&
01143   Matrix<T, Prop, ColUpTriangPacked, Allocator>::operator*= (const T0& x)
01144   {
01145     for (int i = 0; i < this->GetDataSize();i++)
01146       this->data_[i] *= x;
01147 
01148     return *this;
01149   }
01150 
01151 
01152 
01154   // MATRIX<COLLOTRIANGPACKED> //
01156 
01157 
01158   /****************
01159    * CONSTRUCTORS *
01160    ****************/
01161 
01162 
01164 
01167   template <class T, class Prop, class Allocator>
01168   inline Matrix<T, Prop, ColLoTriangPacked, Allocator>::Matrix():
01169     Matrix_TriangPacked<T, Prop, ColLoTriangPacked, Allocator>()
01170   {
01171   }
01172 
01173 
01175 
01180   template <class T, class Prop, class Allocator>
01181   inline Matrix<T, Prop, ColLoTriangPacked, Allocator>::Matrix(int i, int j):
01182     Matrix_TriangPacked<T, Prop, ColLoTriangPacked, Allocator>(i, i)
01183   {
01184   }
01185 
01186 
01187   /*****************
01188    * OTHER METHODS *
01189    *****************/
01190 
01191 
01193 
01200   template <class T, class Prop, class Allocator>
01201   inline void Matrix<T, Prop, ColLoTriangPacked, Allocator>
01202   ::Resize(int i, int j)
01203   {
01204 
01205     // Storing the old values of the matrix.
01206     int nold = this->GetDataSize(), iold = this->m_;
01207     Vector<T, VectFull, Allocator> xold(nold);
01208     for (int k = 0; k < nold; k++)
01209       xold(k) = this->data_[k];
01210 
01211     // Reallocation.
01212     this->Reallocate(i, j);
01213 
01214     // Filling the matrix with its old values.
01215     int imin = min(iold, i);
01216     nold = 0;
01217     int n = 0;
01218     for (int k = 0; k < imin; k++)
01219       {
01220         for (int l = k; l < imin; l++)
01221           this->data_[n+l-k] = xold(nold+l-k);
01222 
01223         n += i - k;
01224         nold += iold - k;
01225       }
01226   }
01227 
01228 
01230 
01233   template <class T, class Prop, class Allocator>
01234   template <class T0>
01235   Matrix<T, Prop, ColLoTriangPacked, Allocator>&
01236   Matrix<T, Prop, ColLoTriangPacked, Allocator>::operator= (const T0& x)
01237   {
01238     this->Fill(x);
01239 
01240     return *this;
01241   }
01242 
01243 
01245 
01250   template <class T, class Prop, class Allocator>
01251   inline Matrix<T, Prop, ColLoTriangPacked, Allocator>&
01252   Matrix<T, Prop, ColLoTriangPacked, Allocator>::operator=
01253   (const Matrix<T, Prop, ColLoTriangPacked, Allocator>& A)
01254   {
01255     this->Copy(A);
01256     return *this;
01257   }
01258 
01259 
01261 
01264   template <class T, class Prop, class Allocator>
01265   template <class T0>
01266   Matrix<T, Prop, ColLoTriangPacked, Allocator>&
01267   Matrix<T, Prop, ColLoTriangPacked, Allocator>::operator*= (const T0& x)
01268   {
01269     for (int i = 0; i < this->GetDataSize();i++)
01270       this->data_[i] *= x;
01271 
01272     return *this;
01273   }
01274 
01275 
01276 
01278   // MATRIX<ROWUPTRIANGPACKED> //
01280 
01281 
01282   /****************
01283    * CONSTRUCTORS *
01284    ****************/
01285 
01286 
01288 
01291   template <class T, class Prop, class Allocator>
01292   inline Matrix<T, Prop, RowUpTriangPacked, Allocator>::Matrix():
01293     Matrix_TriangPacked<T, Prop, RowUpTriangPacked, Allocator>()
01294   {
01295   }
01296 
01297 
01299 
01304   template <class T, class Prop, class Allocator>
01305   inline Matrix<T, Prop, RowUpTriangPacked, Allocator>::Matrix(int i, int j):
01306     Matrix_TriangPacked<T, Prop, RowUpTriangPacked, Allocator>(i, i)
01307   {
01308   }
01309 
01310 
01311   /*****************
01312    * OTHER METHODS *
01313    *****************/
01314 
01315 
01317 
01324   template <class T, class Prop, class Allocator>
01325   inline void Matrix<T, Prop, RowUpTriangPacked, Allocator>
01326   ::Resize(int i, int j)
01327   {
01328 
01329     // Storing the old values of the matrix.
01330     int nold = this->GetDataSize(), iold = this->m_;
01331     Vector<T, VectFull, Allocator> xold(nold);
01332     for (int k = 0; k < nold; k++)
01333       xold(k) = this->data_[k];
01334 
01335     // Reallocation.
01336     this->Reallocate(i, j);
01337 
01338     // Filling the matrix with its old values.
01339     int imin = min(iold, i);
01340     nold = 0;
01341     int n = 0;
01342     for (int k = 0; k < imin; k++)
01343       {
01344         for (int l = k; l < imin; l++)
01345           this->data_[n+l-k] = xold(nold+l-k);
01346 
01347         n += i - k;
01348         nold += iold - k;
01349       }
01350   }
01351 
01352 
01354 
01357   template <class T, class Prop, class Allocator>
01358   template <class T0>
01359   Matrix<T, Prop, RowUpTriangPacked, Allocator>&
01360   Matrix<T, Prop, RowUpTriangPacked, Allocator>::operator= (const T0& x)
01361   {
01362     this->Fill(x);
01363 
01364     return *this;
01365   }
01366 
01367 
01369 
01374   template <class T, class Prop, class Allocator>
01375   inline Matrix<T, Prop, RowUpTriangPacked, Allocator>&
01376   Matrix<T, Prop, RowUpTriangPacked, Allocator>::operator=
01377   (const Matrix<T, Prop, RowUpTriangPacked, Allocator>& A)
01378   {
01379     this->Copy(A);
01380     return *this;
01381   }
01382 
01383 
01385 
01388   template <class T, class Prop, class Allocator>
01389   template <class T0>
01390   Matrix<T, Prop, RowUpTriangPacked, Allocator>&
01391   Matrix<T, Prop, RowUpTriangPacked, Allocator>::operator*= (const T0& x)
01392   {
01393     for (int i = 0; i < this->GetDataSize();i++)
01394       this->data_[i] *= x;
01395 
01396     return *this;
01397   }
01398 
01399 
01400 
01402   // MATRIX<ROWLOTRIANGPACKED> //
01404 
01405 
01406   /****************
01407    * CONSTRUCTORS *
01408    ****************/
01409 
01410 
01412 
01415   template <class T, class Prop, class Allocator>
01416   inline Matrix<T, Prop, RowLoTriangPacked, Allocator>::Matrix():
01417     Matrix_TriangPacked<T, Prop, RowLoTriangPacked, Allocator>()
01418   {
01419   }
01420 
01421 
01423 
01428   template <class T, class Prop, class Allocator>
01429   inline Matrix<T, Prop, RowLoTriangPacked, Allocator>::Matrix(int i, int j):
01430     Matrix_TriangPacked<T, Prop, RowLoTriangPacked, Allocator>(i, i)
01431   {
01432   }
01433 
01434 
01435   /*****************
01436    * OTHER METHODS *
01437    *****************/
01438 
01439 
01441 
01448   template <class T, class Prop, class Allocator>
01449   inline void Matrix<T, Prop, RowLoTriangPacked, Allocator>
01450   ::Resize(int i, int j)
01451   {
01452 
01453     // Storing the old values of the matrix.
01454     int nold = this->GetDataSize();
01455     Vector<T, VectFull, Allocator> xold(nold);
01456     for (int k = 0; k < nold; k++)
01457       xold(k) = this->data_[k];
01458 
01459     // Reallocation.
01460     this->Reallocate(i, j);
01461 
01462     // Filling the matrix with its old values.
01463     int nmin = min(nold, this->GetDataSize());
01464     for (int k = 0; k < nmin; k++)
01465       this->data_[k] = xold(k);
01466   }
01467 
01468 
01470 
01473   template <class T, class Prop, class Allocator>
01474   template <class T0>
01475   Matrix<T, Prop, RowLoTriangPacked, Allocator>&
01476   Matrix<T, Prop, RowLoTriangPacked, Allocator>::operator= (const T0& x)
01477   {
01478     this->Fill(x);
01479 
01480     return *this;
01481   }
01482 
01483 
01485 
01490   template <class T, class Prop, class Allocator>
01491   inline Matrix<T, Prop, RowLoTriangPacked, Allocator>&
01492   Matrix<T, Prop, RowLoTriangPacked, Allocator>::operator=
01493   (const Matrix<T, Prop, RowLoTriangPacked, Allocator>& A)
01494   {
01495     this->Copy(A);
01496     return *this;
01497   }
01498 
01499 
01501 
01504   template <class T, class Prop, class Allocator>
01505   template <class T0>
01506   Matrix<T, Prop, RowLoTriangPacked, Allocator>&
01507   Matrix<T, Prop, RowLoTriangPacked, Allocator>::operator*= (const T0& x)
01508   {
01509     for (int i = 0; i < this->GetDataSize();i++)
01510       this->data_[i] *= x;
01511 
01512     return *this;
01513   }
01514 
01515 } // namespace Seldon.
01516 
01517 #define SELDON_FILE_MATRIX_TRIANGPACKED_CXX
01518 #endif