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>::reference
00278   Matrix_TriangPacked<T, Prop, Storage, Allocator>::operator() (int i, int j)
00279   {
00280 
00281 #ifdef SELDON_CHECK_BOUNDS
00282     if (i < 0 || i >= this->m_)
00283       throw WrongRow("Matrix_TriangPacked::operator()(int, int)",
00284                      string("Index should be in [0, ") + to_str(this->m_-1)
00285                      + "], but is equal to " + to_str(i) + ".");
00286     if (j < 0 || j >= this->n_)
00287       throw WrongCol("Matrix_TriangPacked::operator()(int, int)",
00288                      string("Index should be in [0, ") + to_str(this->n_-1)
00289                      + "], but is equal to " + to_str(j) + ".");
00290 
00291     if (Storage::UpLo())
00292       {
00293         if (i > j)
00294           throw WrongRow("Matrix_TriangPacked::operator()(int, int)",
00295                          string("Attempted to access to element (")
00296                          + to_str(i) + ", " + to_str(j) + string(") but row")
00297                          + string(" index should not be strictly more")
00298                          + " than column index (upper triangular matrix).");
00299         return this->data_[Storage::GetFirst(i * this->n_
00300                                              - (i * (i + 1)) / 2 + j,
00301                                              (j * (j + 1)) / 2 + i)];
00302       }
00303     else
00304       {
00305         if (j > i)
00306           throw WrongCol("Matrix_TriangPacked::operator()(int, int)",
00307                          string("Attempted to access to element (")
00308                          + to_str(i) + ", " + to_str(j) + string(") but")
00309                          + string(" column index should not be strictly more")
00310                          + " than row index (lower triangular matrix).");
00311         return this->data_[Storage::GetFirst((i * (i + 1)) / 2 + j,
00312                                              j * this->m_
00313                                              - (j * (j + 1)) / 2 + i)];
00314       }
00315 
00316 #endif
00317 
00318     if (Storage::UpLo())
00319       return this->data_[Storage::GetFirst(i * this->n_
00320                                            - (i * (i + 1)) / 2 + j,
00321                                            (j * (j + 1)) / 2 + i)];
00322     else
00323       return this->data_[Storage::GetFirst((i * (i + 1)) / 2 + j,
00324                                            j * this->m_
00325                                            - (j * (j + 1)) / 2 + i)];
00326 
00327   }
00328 
00329 
00331 
00337   template <class T, class Prop, class Storage, class Allocator>
00338   inline typename Matrix_TriangPacked<T, Prop, Storage, Allocator>::value_type
00339   Matrix_TriangPacked<T, Prop, Storage, Allocator>
00340   ::operator() (int i, int j) const
00341   {
00342 
00343 #ifdef SELDON_CHECK_BOUNDS
00344     if (i < 0 || i >= this->m_)
00345       throw WrongRow("Matrix_TriangPacked::operator()",
00346                      string("Index should be in [0, ") + to_str(this->m_-1)
00347                      + "], but is equal to " + to_str(i) + ".");
00348     if (j < 0 || j >= this->n_)
00349       throw WrongCol("Matrix_TriangPacked::operator()",
00350                      string("Index should be in [0, ") + to_str(this->n_-1)
00351                      + "], but is equal to " + to_str(j) + ".");
00352 #endif
00353 
00354     if (Storage::UpLo())
00355       if (i > j)
00356         return 0;
00357       else
00358         return this->data_[Storage::GetFirst(i * this->n_
00359                                              - (i * (i + 1)) / 2 + j,
00360                                              (j * (j + 1)) / 2 + i)];
00361     else
00362       if (i < j)
00363         return 0;
00364       else
00365         return this->data_[Storage::GetFirst((i * (i + 1)) / 2 + j,
00366                                              j * this->m_
00367                                              - (j * (j + 1)) / 2 + i)];
00368   }
00369 
00370 
00372 
00379   template <class T, class Prop, class Storage, class Allocator>
00380   inline typename Matrix_TriangPacked<T, Prop, Storage, Allocator>::reference
00381   Matrix_TriangPacked<T, Prop, Storage, Allocator>::Val(int i, int j)
00382   {
00383 
00384 #ifdef SELDON_CHECK_BOUNDS
00385     if (i < 0 || i >= this->m_)
00386       throw WrongRow("Matrix_TriangPacked::Val(int, int)",
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_TriangPacked::Val(int, int)",
00391                      string("Index should be in [0, ") + to_str(this->n_-1)
00392                      + "], but is equal to " + to_str(j) + ".");
00393     if (Storage::UpLo())
00394       {
00395         if (i > j)
00396           throw WrongRow("Matrix_TriangPacked::Val(int, int)",
00397                          string("Attempted to access to element (")
00398                          + to_str(i) + ", " + to_str(j) + string(") but row")
00399                          + string(" index should not be strictly more")
00400                          + " than column index (upper triangular matrix).");
00401         return this->data_[Storage::GetFirst(i * this->n_
00402                                              - (i * (i + 1)) / 2 + j,
00403                                              (j * (j + 1)) / 2 + i)];
00404       }
00405     else
00406       {
00407         if (j > i)
00408           throw WrongCol("Matrix_TriangPacked::Val(int, int)",
00409                          string("Attempted to access to element (")
00410                          + to_str(i) + ", " + to_str(j) + string(") but")
00411                          + string(" column index should not be strictly more")
00412                          + " than row index (lower triangular matrix).");
00413         return this->data_[Storage::GetFirst((i * (i + 1)) / 2 + j,
00414                                              j * this->m_
00415                                              - (j * (j + 1)) / 2 + i)];
00416       }
00417 #endif
00418 
00419     if (Storage::UpLo())
00420       return this->data_[Storage::GetFirst(i * this->n_
00421                                            - (i * (i + 1)) / 2 + j,
00422                                            (j * (j + 1)) / 2 + i)];
00423     else
00424       return this->data_[Storage::GetFirst((i * (i + 1)) / 2 + j,
00425                                            j * this->m_
00426                                            - (j * (j + 1)) / 2 + i)];
00427   }
00428 
00429 
00431 
00438   template <class T, class Prop, class Storage, class Allocator>
00439   inline typename Matrix_TriangPacked<T, Prop, Storage, Allocator>
00440   ::const_reference
00441   Matrix_TriangPacked<T, Prop, Storage, Allocator>::Val(int i, int j) const
00442   {
00443 
00444 #ifdef SELDON_CHECK_BOUNDS
00445     if (i < 0 || i >= this->m_)
00446       throw WrongRow("Matrix_TriangPacked::Val(int, int) const",
00447                      string("Index should be in [0, ") + to_str(this->m_-1)
00448                      + "], but is equal to " + to_str(i) + ".");
00449     if (j < 0 || j >= this->n_)
00450       throw WrongCol("Matrix_TriangPacked::Val(int, int)",
00451                      string("Index should be in [0, ") + to_str(this->n_-1)
00452                      + "], but is equal to " + to_str(j) + ".");
00453     if (Storage::UpLo())
00454       {
00455         if (i > j)
00456           throw WrongRow("Matrix_TriangPacked::Val(int, int) const",
00457                          string("Attempted to access to element (")
00458                          + to_str(i) + ", " + to_str(j) + string(") but row")
00459                          + string(" index should not be strictly more")
00460                          + " than column index (upper triangular matrix).");
00461         return this->data_[Storage::GetFirst(i * this->n_
00462                                              - (i * (i + 1)) / 2 + j,
00463                                              (j * (j + 1)) / 2 + i)];
00464       }
00465     else
00466       {
00467         if (j > i)
00468           throw WrongCol("Matrix_TriangPacked::Val(int, int) const",
00469                          string("Attempted to access to element (")
00470                          + to_str(i) + ", " + to_str(j) + string(") but")
00471                          + string(" column index should not be strictly more")
00472                          + " than row index (lower triangular matrix).");
00473         return this->data_[Storage::GetFirst((i * (i + 1)) / 2 + j,
00474                                              j * this->m_
00475                                              - (j * (j + 1)) / 2 + i)];
00476       }
00477 #endif
00478 
00479     if (Storage::UpLo())
00480       return this->data_[Storage::GetFirst(i * this->n_
00481                                            - (i * (i + 1)) / 2 + j,
00482                                            (j * (j + 1)) / 2 + i)];
00483     else
00484       return this->data_[Storage::GetFirst((i * (i + 1)) / 2 + j,
00485                                            j * this->m_
00486                                            - (j * (j + 1)) / 2 + i)];
00487   }
00488 
00489 
00491 
00496   template <class T, class Prop, class Storage, class Allocator>
00497   inline typename Matrix_TriangPacked<T, Prop, Storage, Allocator>::reference
00498   Matrix_TriangPacked<T, Prop, Storage, Allocator>::operator[] (int i)
00499   {
00500 
00501 #ifdef SELDON_CHECK_BOUNDS
00502     if (i < 0 || i >= this->GetDataSize())
00503       throw WrongIndex("Matrix_TriangPacked::operator[] (int)",
00504                        string("Index should be in [0, ")
00505                        + to_str(this->GetDataSize()-1) + "], but is equal to "
00506                        + to_str(i) + ".");
00507 #endif
00508 
00509     return this->data_[i];
00510   }
00511 
00512 
00514 
00519   template <class T, class Prop, class Storage, class Allocator>
00520   inline typename Matrix_TriangPacked<T, Prop, Storage, Allocator>
00521   ::const_reference
00522   Matrix_TriangPacked<T, Prop, Storage, Allocator>::operator[] (int i) const
00523   {
00524 
00525 #ifdef SELDON_CHECK_BOUNDS
00526     if (i < 0 || i >= this->GetDataSize())
00527       throw WrongIndex("Matrix_TriangPacked::operator[] (int) const",
00528                        string("Index should be in [0, ")
00529                        + to_str(this->GetDataSize()-1) + "], but is equal to "
00530                        + to_str(i) + ".");
00531 #endif
00532 
00533     return this->data_[i];
00534   }
00535 
00536 
00538 
00543   template <class T, class Prop, class Storage, class Allocator>
00544   inline Matrix_TriangPacked<T, Prop, Storage, Allocator>&
00545   Matrix_TriangPacked<T, Prop, Storage, Allocator>::
00546   operator= (const Matrix_TriangPacked<T, Prop, Storage, Allocator>& A)
00547   {
00548     this->Copy(A);
00549 
00550     return *this;
00551   }
00552 
00553 
00555 
00560   template <class T, class Prop, class Storage, class Allocator>
00561   inline void Matrix_TriangPacked<T, Prop, Storage, Allocator>::
00562   Copy(const Matrix_TriangPacked<T, Prop, Storage, Allocator>& A)
00563   {
00564     this->Reallocate(A.GetM(), A.GetN());
00565 
00566     this->allocator_.memorycpy(this->data_, A.GetData(), this->GetDataSize());
00567   }
00568 
00569 
00570   /************************
00571    * CONVENIENT FUNCTIONS *
00572    ************************/
00573 
00574 
00576 
00580   template <class T, class Prop, class Storage, class Allocator>
00581   void Matrix_TriangPacked<T, Prop, Storage, Allocator>::Zero()
00582   {
00583     this->allocator_.memoryset(this->data_, char(0),
00584                                this->GetDataSize() * sizeof(value_type));
00585   }
00586 
00587 
00589   template <class T, class Prop, class Storage, class Allocator>
00590   void Matrix_TriangPacked<T, Prop, Storage, Allocator>::SetIdentity()
00591   {
00592     this->Fill(T(0));
00593 
00594     T one(1);
00595     bool storage_col = (Storage::GetFirst(1,0) == 0);
00596     if ((Storage::UpLo() && storage_col)||(!Storage::UpLo() && !storage_col))
00597       {
00598         int index(-1);
00599         for (int i = 0; i < min(this->m_, this->n_); i++)
00600           {
00601             index += i+1;
00602             this->data_[index] = one;
00603           }
00604       }
00605     else if (Storage::UpLo() && !storage_col)
00606       {
00607         int index(0);
00608         for (int i = 0; i < min(this->m_, this->n_); i++)
00609           {
00610             this->data_[index] = one;
00611             index += this->m_-i;
00612           }
00613       }
00614     else if (!Storage::UpLo() && storage_col)
00615       {
00616         int index(0);
00617         for (int i = 0; i < min(this->m_, this->n_); i++)
00618           {
00619             this->data_[index] = one;
00620             index += this->n_-i;
00621           }
00622       }
00623   }
00624 
00625 
00627 
00631   template <class T, class Prop, class Storage, class Allocator>
00632   void Matrix_TriangPacked<T, Prop, Storage, Allocator>::Fill()
00633   {
00634     for (int i = 0; i < this->GetDataSize(); i++)
00635       this->data_[i] = i;
00636   }
00637 
00638 
00640 
00643   template <class T, class Prop, class Storage, class Allocator>
00644   template <class T0>
00645   void Matrix_TriangPacked<T, Prop, Storage, Allocator>::Fill(const T0& x)
00646   {
00647     for (int i = 0; i < this->GetDataSize(); i++)
00648       this->data_[i] = x;
00649   }
00650 
00651 
00653 
00656   template <class T, class Prop, class Storage, class Allocator>
00657   template <class T0>
00658   Matrix_TriangPacked<T, Prop, Storage, Allocator>&
00659   Matrix_TriangPacked<T, Prop, Storage, Allocator>::operator= (const T0& x)
00660   {
00661     this->Fill(x);
00662 
00663     return *this;
00664   }
00665 
00666 
00668 
00671   template <class T, class Prop, class Storage, class Allocator>
00672   void Matrix_TriangPacked<T, Prop, Storage, Allocator>::FillRand()
00673   {
00674     srand(time(NULL));
00675     for (int i = 0; i < this->GetDataSize(); i++)
00676       this->data_[i] = rand();
00677   }
00678 
00679 
00681 
00686   template <class T, class Prop, class Storage, class Allocator>
00687   void Matrix_TriangPacked<T, Prop, Storage, Allocator>::Print() const
00688   {
00689     for (int i = 0; i < this->m_; i++)
00690       {
00691         for (int j = 0; j < this->n_; j++)
00692           cout << (*this)(i, j) << "\t";
00693         cout << endl;
00694       }
00695   }
00696 
00697 
00699 
00710   template <class T, class Prop, class Storage, class Allocator>
00711   void Matrix_TriangPacked<T, Prop, Storage, Allocator>
00712   ::Print(int a, int b, int m, int n) const
00713   {
00714     for (int i = a; i < min(this->m_, a + m); i++)
00715       {
00716         for (int j = b; j < min(this->n_, b + n); j++)
00717           cout << (*this)(i, j) << "\t";
00718         cout << endl;
00719       }
00720   }
00721 
00722 
00724 
00732   template <class T, class Prop, class Storage, class Allocator>
00733   void Matrix_TriangPacked<T, Prop, Storage, Allocator>::Print(int l) const
00734   {
00735     Print(0, 0, l, l);
00736   }
00737 
00738 
00739   /**************************
00740    * INPUT/OUTPUT FUNCTIONS *
00741    **************************/
00742 
00743 
00745 
00752   template <class T, class Prop, class Storage, class Allocator>
00753   void Matrix_TriangPacked<T, Prop, Storage, Allocator>
00754   ::Write(string FileName) const
00755   {
00756     ofstream FileStream;
00757     FileStream.open(FileName.c_str());
00758 
00759 #ifdef SELDON_CHECK_IO
00760     // Checks if the file was opened.
00761     if (!FileStream.is_open())
00762       throw IOError("Matrix_TriangPacked::Write(string FileName)",
00763                     string("Unable to open file \"") + FileName + "\".");
00764 #endif
00765 
00766     this->Write(FileStream);
00767 
00768     FileStream.close();
00769   }
00770 
00771 
00773 
00780   template <class T, class Prop, class Storage, class Allocator>
00781   void Matrix_TriangPacked<T, Prop, Storage, Allocator>
00782   ::Write(ostream& FileStream) const
00783   {
00784 
00785 #ifdef SELDON_CHECK_IO
00786     // Checks if the file is ready.
00787     if (!FileStream.good())
00788       throw IOError("Matrix_TriangPacked::Write(ofstream& FileStream)",
00789                     "Stream is not ready.");
00790 #endif
00791 
00792     FileStream.write(reinterpret_cast<char*>(const_cast<int*>(&this->m_)),
00793                      sizeof(int));
00794     FileStream.write(reinterpret_cast<char*>(const_cast<int*>(&this->n_)),
00795                      sizeof(int));
00796 
00797     FileStream.write(reinterpret_cast<char*>(this->data_),
00798                      this->GetDataSize() * sizeof(value_type));
00799 
00800 #ifdef SELDON_CHECK_IO
00801     // Checks if data was written.
00802     if (!FileStream.good())
00803       throw IOError("Matrix_TriangPacked::Write(ofstream& FileStream)",
00804                     string("Output operation failed.")
00805                     + string(" The output file may have been removed")
00806                     + " or there is no space left on device.");
00807 #endif
00808 
00809   }
00810 
00811 
00813 
00820   template <class T, class Prop, class Storage, class Allocator>
00821   void Matrix_TriangPacked<T, Prop, Storage, Allocator>
00822   ::WriteText(string FileName) const
00823   {
00824     ofstream FileStream;
00825     FileStream.precision(cout.precision());
00826     FileStream.flags(cout.flags());
00827     FileStream.open(FileName.c_str());
00828 
00829 #ifdef SELDON_CHECK_IO
00830     // Checks if the file was opened.
00831     if (!FileStream.is_open())
00832       throw IOError("Matrix_TriangPacked::WriteText(string FileName)",
00833                     string("Unable to open file \"") + FileName + "\".");
00834 #endif
00835 
00836     this->WriteText(FileStream);
00837 
00838     FileStream.close();
00839   }
00840 
00841 
00843 
00850   template <class T, class Prop, class Storage, class Allocator>
00851   void Matrix_TriangPacked<T, Prop, Storage, Allocator>
00852   ::WriteText(ostream& FileStream) const
00853   {
00854 
00855 #ifdef SELDON_CHECK_IO
00856     // Checks if the stream is ready.
00857     if (!FileStream.good())
00858       throw IOError("Matrix_TriangPacked::WriteText(ofstream& FileStream)",
00859                     "Stream is not ready.");
00860 #endif
00861 
00862     int i, j;
00863     for (i = 0; i < this->GetM(); i++)
00864       {
00865         for (j = 0; j < this->GetN(); j++)
00866           FileStream << (*this)(i, j) << '\t';
00867         FileStream << endl;
00868       }
00869 
00870 #ifdef SELDON_CHECK_IO
00871     // Checks if data was written.
00872     if (!FileStream.good())
00873       throw IOError("Matrix_TriangPacked::WriteText(ofstream& FileStream)",
00874                     string("Output operation failed.")
00875                     + string(" The output file may have been removed")
00876                     + " or there is no space left on device.");
00877 #endif
00878 
00879   }
00880 
00881 
00883 
00890   template <class T, class Prop, class Storage, class Allocator>
00891   void Matrix_TriangPacked<T, Prop, Storage, Allocator>::Read(string FileName)
00892   {
00893     ifstream FileStream;
00894     FileStream.open(FileName.c_str());
00895 
00896 #ifdef SELDON_CHECK_IO
00897     // Checks if the file was opened.
00898     if (!FileStream.good())
00899       throw IOError("Matrix_TriangPacked::Read(string FileName)",
00900                     string("Unable to open file \"") + FileName + "\".");
00901 #endif
00902 
00903     this->Read(FileStream);
00904 
00905     FileStream.close();
00906   }
00907 
00908 
00910 
00917   template <class T, class Prop, class Storage, class Allocator>
00918   void Matrix_TriangPacked<T, Prop, Storage, Allocator>
00919   ::Read(istream& FileStream)
00920   {
00921 
00922 #ifdef SELDON_CHECK_IO
00923     // Checks if the stream is ready.
00924     if (!FileStream.good())
00925       throw IOError("Matrix_TriangPacked::Read(ifstream& FileStream)",
00926                     "Stream is not ready.");
00927 #endif
00928 
00929     int new_m, new_n;
00930     FileStream.read(reinterpret_cast<char*>(&new_m), sizeof(int));
00931     FileStream.read(reinterpret_cast<char*>(&new_n), sizeof(int));
00932     this->Reallocate(new_m, new_n);
00933 
00934     FileStream.read(reinterpret_cast<char*>(this->data_),
00935                     this->GetDataSize() * sizeof(value_type));
00936 
00937 #ifdef SELDON_CHECK_IO
00938     // Checks if data was read.
00939     if (!FileStream.good())
00940       throw IOError("Matrix_TriangPacked::Read(ifstream& FileStream)",
00941                     string("Output operation failed.")
00942                     + string(" The intput file may have been removed")
00943                     + " or may not contain enough data.");
00944 #endif
00945 
00946   }
00947 
00948 
00950 
00954   template <class T, class Prop, class Storage, class Allocator>
00955   void Matrix_TriangPacked<T, Prop, Storage, Allocator>::ReadText(string FileName)
00956   {
00957     ifstream FileStream;
00958     FileStream.open(FileName.c_str());
00959 
00960 #ifdef SELDON_CHECK_IO
00961     // Checks if the file was opened.
00962     if (!FileStream.is_open())
00963       throw IOError("Matrix_Pointers::ReadText(string FileName)",
00964                     string("Unable to open file \"") + FileName + "\".");
00965 #endif
00966 
00967     this->ReadText(FileStream);
00968 
00969     FileStream.close();
00970   }
00971 
00972 
00974 
00978   template <class T, class Prop, class Storage, class Allocator>
00979   void Matrix_TriangPacked<T, Prop, Storage, Allocator>
00980   ::ReadText(istream& FileStream)
00981   {
00982     // clears previous matrix
00983     Clear();
00984 
00985 #ifdef SELDON_CHECK_IO
00986     // Checks if the stream is ready.
00987     if (!FileStream.good())
00988       throw IOError("Matrix_Pointers::ReadText(ifstream& FileStream)",
00989                     "Stream is not ready.");
00990 #endif
00991 
00992     // we read first line
00993     string line;
00994     getline(FileStream, line);
00995 
00996     if (FileStream.fail())
00997       {
00998         // empty file ?
00999         return;
01000       }
01001 
01002     // converting first line into a vector
01003     istringstream line_stream(line);
01004     Vector<T> first_row;
01005     first_row.ReadText(line_stream);
01006 
01007     // and now the other rows
01008     Vector<T> other_rows;
01009     other_rows.ReadText(FileStream);
01010 
01011     // number of rows and columns
01012     int n = first_row.GetM();
01013     int m = 1 + other_rows.GetM()/n;
01014 
01015 #ifdef SELDON_CHECK_IO
01016     // Checking number of elements
01017     if (other_rows.GetM() != (m-1)*n)
01018       throw IOError("Matrix_Pointers::ReadText(ifstream& FileStream)",
01019                     "The file should contain same number of columns.");
01020 #endif
01021 
01022     this->Reallocate(m,n);
01023     // filling matrix
01024     if (Storage::UpLo())
01025       for (int j = 0; j < n; j++)
01026         this->Val(0, j) = first_row(j);
01027     else
01028       this->Val(0, 0) = first_row(0);
01029 
01030     int nb = 0;
01031     if (Storage::UpLo())
01032       for (int i = 1; i < m; i++)
01033         {
01034           for (int j = 0; j < i; j++)
01035             nb++;
01036 
01037           for (int j = i; j < n; j++)
01038             this->Val(i, j) = other_rows(nb++);
01039         }
01040     else
01041       for (int i = 1; i < m; i++)
01042         {
01043           for (int j = 0; j <= i; j++)
01044             this->Val(i, j) = other_rows(nb++);
01045 
01046           for (int j = i+1; j < n; j++)
01047             nb++;
01048         }
01049   }
01050 
01051 
01052 
01054   // MATRIX<COLUPTRIANGPACKED> //
01056 
01057 
01058   /****************
01059    * CONSTRUCTORS *
01060    ****************/
01061 
01062 
01064 
01067   template <class T, class Prop, class Allocator>
01068   inline Matrix<T, Prop, ColUpTriangPacked, Allocator>::Matrix():
01069     Matrix_TriangPacked<T, Prop, ColUpTriangPacked, Allocator>()
01070   {
01071   }
01072 
01073 
01075 
01080   template <class T, class Prop, class Allocator>
01081   inline Matrix<T, Prop, ColUpTriangPacked, Allocator>::Matrix(int i, int j):
01082     Matrix_TriangPacked<T, Prop, ColUpTriangPacked, Allocator>(i, i)
01083   {
01084   }
01085 
01086 
01087   /*****************
01088    * OTHER METHODS *
01089    *****************/
01090 
01091 
01093 
01100   template <class T, class Prop, class Allocator>
01101   inline void Matrix<T, Prop, ColUpTriangPacked, Allocator>
01102   ::Resize(int i, int j)
01103   {
01104 
01105     // Storing the old values of the matrix.
01106     int nold = this->GetDataSize();
01107     Vector<T, VectFull, Allocator> xold(nold);
01108     for (int k = 0; k < nold; k++)
01109       xold(k) = this->data_[k];
01110 
01111     // Reallocation.
01112     this->Reallocate(i, j);
01113 
01114     // Filling the matrix with its old values.
01115     int nmin = min(nold, this->GetDataSize());
01116     for (int k = 0; k < nmin; k++)
01117       this->data_[k] = xold(k);
01118   }
01119 
01120 
01122 
01125   template <class T, class Prop, class Allocator>
01126   template <class T0>
01127   Matrix<T, Prop, ColUpTriangPacked, Allocator>&
01128   Matrix<T, Prop, ColUpTriangPacked, Allocator>::operator= (const T0& x)
01129   {
01130     this->Fill(x);
01131 
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 
01248   template <class T, class Prop, class Allocator>
01249   template <class T0>
01250   Matrix<T, Prop, ColLoTriangPacked, Allocator>&
01251   Matrix<T, Prop, ColLoTriangPacked, Allocator>::operator*= (const T0& x)
01252   {
01253     for (int i = 0; i < this->GetDataSize();i++)
01254       this->data_[i] *= x;
01255 
01256     return *this;
01257   }
01258 
01259 
01260 
01262   // MATRIX<ROWUPTRIANGPACKED> //
01264 
01265 
01266   /****************
01267    * CONSTRUCTORS *
01268    ****************/
01269 
01270 
01272 
01275   template <class T, class Prop, class Allocator>
01276   inline Matrix<T, Prop, RowUpTriangPacked, Allocator>::Matrix():
01277     Matrix_TriangPacked<T, Prop, RowUpTriangPacked, Allocator>()
01278   {
01279   }
01280 
01281 
01283 
01288   template <class T, class Prop, class Allocator>
01289   inline Matrix<T, Prop, RowUpTriangPacked, Allocator>::Matrix(int i, int j):
01290     Matrix_TriangPacked<T, Prop, RowUpTriangPacked, Allocator>(i, i)
01291   {
01292   }
01293 
01294 
01295   /*****************
01296    * OTHER METHODS *
01297    *****************/
01298 
01299 
01301 
01308   template <class T, class Prop, class Allocator>
01309   inline void Matrix<T, Prop, RowUpTriangPacked, Allocator>
01310   ::Resize(int i, int j)
01311   {
01312 
01313     // Storing the old values of the matrix.
01314     int nold = this->GetDataSize(), iold = this->m_;
01315     Vector<T, VectFull, Allocator> xold(nold);
01316     for (int k = 0; k < nold; k++)
01317       xold(k) = this->data_[k];
01318 
01319     // Reallocation.
01320     this->Reallocate(i, j);
01321 
01322     // Filling the matrix with its old values.
01323     int imin = min(iold, i);
01324     nold = 0;
01325     int n = 0;
01326     for (int k = 0; k < imin; k++)
01327       {
01328         for (int l = k; l < imin; l++)
01329           this->data_[n+l-k] = xold(nold+l-k);
01330 
01331         n += i - k;
01332         nold += iold - k;
01333       }
01334   }
01335 
01336 
01338 
01341   template <class T, class Prop, class Allocator>
01342   template <class T0>
01343   Matrix<T, Prop, RowUpTriangPacked, Allocator>&
01344   Matrix<T, Prop, RowUpTriangPacked, Allocator>::operator= (const T0& x)
01345   {
01346     this->Fill(x);
01347 
01348     return *this;
01349   }
01350 
01351 
01353 
01356   template <class T, class Prop, class Allocator>
01357   template <class T0>
01358   Matrix<T, Prop, RowUpTriangPacked, Allocator>&
01359   Matrix<T, Prop, RowUpTriangPacked, Allocator>::operator*= (const T0& x)
01360   {
01361     for (int i = 0; i < this->GetDataSize();i++)
01362       this->data_[i] *= x;
01363 
01364     return *this;
01365   }
01366 
01367 
01368 
01370   // MATRIX<ROWLOTRIANGPACKED> //
01372 
01373 
01374   /****************
01375    * CONSTRUCTORS *
01376    ****************/
01377 
01378 
01380 
01383   template <class T, class Prop, class Allocator>
01384   inline Matrix<T, Prop, RowLoTriangPacked, Allocator>::Matrix():
01385     Matrix_TriangPacked<T, Prop, RowLoTriangPacked, Allocator>()
01386   {
01387   }
01388 
01389 
01391 
01396   template <class T, class Prop, class Allocator>
01397   inline Matrix<T, Prop, RowLoTriangPacked, Allocator>::Matrix(int i, int j):
01398     Matrix_TriangPacked<T, Prop, RowLoTriangPacked, Allocator>(i, i)
01399   {
01400   }
01401 
01402 
01403   /*****************
01404    * OTHER METHODS *
01405    *****************/
01406 
01407 
01409 
01416   template <class T, class Prop, class Allocator>
01417   inline void Matrix<T, Prop, RowLoTriangPacked, Allocator>
01418   ::Resize(int i, int j)
01419   {
01420 
01421     // Storing the old values of the matrix.
01422     int nold = this->GetDataSize();
01423     Vector<T, VectFull, Allocator> xold(nold);
01424     for (int k = 0; k < nold; k++)
01425       xold(k) = this->data_[k];
01426 
01427     // Reallocation.
01428     this->Reallocate(i, j);
01429 
01430     // Filling the matrix with its old values.
01431     int nmin = min(nold, this->GetDataSize());
01432     for (int k = 0; k < nmin; k++)
01433       this->data_[k] = xold(k);
01434   }
01435 
01436 
01438 
01441   template <class T, class Prop, class Allocator>
01442   template <class T0>
01443   Matrix<T, Prop, RowLoTriangPacked, Allocator>&
01444   Matrix<T, Prop, RowLoTriangPacked, Allocator>::operator= (const T0& x)
01445   {
01446     this->Fill(x);
01447 
01448     return *this;
01449   }
01450 
01451 
01453 
01456   template <class T, class Prop, class Allocator>
01457   template <class T0>
01458   Matrix<T, Prop, RowLoTriangPacked, Allocator>&
01459   Matrix<T, Prop, RowLoTriangPacked, Allocator>::operator*= (const T0& x)
01460   {
01461     for (int i = 0; i < this->GetDataSize();i++)
01462       this->data_[i] *= x;
01463 
01464     return *this;
01465   }
01466 
01467 } // namespace Seldon.
01468 
01469 #define SELDON_FILE_MATRIX_TRIANGPACKED_CXX
01470 #endif