matrix/HeterogeneousMatrixCollection.cxx

00001 // Copyright (C) 2010 INRIA
00002 // Author(s): Marc Fragu
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_HETEROGENEOUS_MATRIX_COLLECTION_CXX
00022 
00023 #include "HeterogeneousMatrixCollection.hxx"
00024 
00025 namespace Seldon
00026 {
00027 
00028 
00030   // HETEROGENEOUSMATRIXCOLLECTION //
00032 
00033 
00034   /****************
00035    * CONSTRUCTORS *
00036    ****************/
00037 
00038 
00040 
00043   template <class Prop0, class Storage0,
00044             class Prop1, class Storage1,
00045             template <class U> class Allocator> inline
00046   HeterogeneousMatrixCollection<Prop0, Storage0, Prop1, Storage1, Allocator>
00047   ::HeterogeneousMatrixCollection():
00048     Matrix_Base<double, Allocator<double> >(), Mlocal_(), Mlocal_sum_(1),
00049     Nlocal_(), Nlocal_sum_(1), collection_(), float_dense_c_(),
00050     float_sparse_c_(), double_dense_c_(), double_sparse_c_()
00051   {
00052     nz_ = 0;
00053     Mmatrix_ = 0;
00054     Nmatrix_ = 0;
00055     Mlocal_sum_.Fill(0);
00056     Nlocal_sum_.Fill(0);
00057     collection_.Fill(-1);
00058   }
00059 
00060 
00062 
00066   template <class Prop0, class Storage0,
00067             class Prop1, class Storage1,
00068             template <class U> class Allocator> inline
00069   HeterogeneousMatrixCollection<Prop0, Storage0, Prop1, Storage1, Allocator>
00070   ::HeterogeneousMatrixCollection(int i, int j):
00071     Matrix_Base<double, Allocator<double> >(i, j),
00072     Mlocal_(i), Mlocal_sum_(i + 1),
00073     Nlocal_(j), Nlocal_sum_(j + 1), collection_(i, j), float_dense_c_(i, j),
00074     float_sparse_c_(i, j), double_dense_c_(i, j), double_sparse_c_(i, j)
00075   {
00076     nz_ = 0;
00077     Mmatrix_ = i;
00078     Nmatrix_ = j;
00079     Mlocal_.Fill(0);
00080     Nlocal_.Fill(0);
00081     Mlocal_sum_.Fill(0);
00082     Nlocal_sum_.Fill(0);
00083     collection_.Fill(-1);
00084   }
00085 
00086 
00088 
00093   template <class Prop0, class Storage0,
00094             class Prop1, class Storage1,
00095             template <class U> class Allocator> inline
00096   HeterogeneousMatrixCollection<Prop0, Storage0, Prop1, Storage1, Allocator>
00097   ::HeterogeneousMatrixCollection(const HeterogeneousMatrixCollection<Prop0,
00098                                   Storage0, Prop1, Storage1, Allocator>& A):
00099     Matrix_Base<double, Allocator<double> >()
00100   {
00101     this->Copy(A);
00102   }
00103 
00104 
00105   /**************
00106    * DESTRUCTOR *
00107    **************/
00108 
00109 
00111   template <class Prop0, class Storage0,
00112             class Prop1, class Storage1,
00113             template <class U> class Allocator> inline
00114   HeterogeneousMatrixCollection<Prop0, Storage0, Prop1, Storage1, Allocator>
00115   ::~HeterogeneousMatrixCollection()
00116   {
00117     this->Clear();
00118   }
00119 
00120 
00122   template <class Prop0, class Storage0,
00123             class Prop1, class Storage1,
00124             template <class U> class Allocator> inline void
00125   HeterogeneousMatrixCollection<Prop0, Storage0, Prop1, Storage1, Allocator>
00126   ::Clear()
00127   {
00128     float_dense_c_.Nullify();
00129     float_sparse_c_.Nullify();
00130     double_dense_c_.Nullify();
00131     double_sparse_c_.Nullify();
00132 
00133     nz_ = 0;
00134     Mmatrix_ = 0;
00135     Nmatrix_ = 0;
00136     Mlocal_.Clear();
00137     Nlocal_.Clear();
00138     Mlocal_sum_.Clear();
00139     Nlocal_sum_.Clear();
00140     collection_.Clear();
00141   }
00142 
00143 
00145   template <class Prop0, class Storage0,
00146             class Prop1, class Storage1,
00147             template <class U> class Allocator> inline void
00148   HeterogeneousMatrixCollection<Prop0, Storage0, Prop1, Storage1, Allocator>
00149   ::Nullify()
00150   {
00151     float_dense_c_.Nullify();
00152     float_sparse_c_.Nullify();
00153     double_dense_c_.Nullify();
00154     double_sparse_c_.Nullify();
00155 
00156     nz_ = 0;
00157     Mmatrix_ = 0;
00158     Nmatrix_ = 0;
00159     Mlocal_.Clear();
00160     Nlocal_.Clear();
00161     Mlocal_sum_.Clear();
00162     Nlocal_sum_.Clear();
00163     collection_.Clear();
00164   }
00165 
00166 
00168 
00172   template <class Prop0, class Storage0,
00173             class Prop1, class Storage1,
00174             template <class U> class Allocator> inline void
00175   HeterogeneousMatrixCollection<Prop0, Storage0, Prop1, Storage1, Allocator>
00176   ::Nullify(int i, int j)
00177   {
00178 #ifdef SELDON_CHECK_BOUNDS
00179     if (i < 0 || i >= Mmatrix_)
00180       throw WrongRow("HeterogeneousMatrixCollection::Nullify()",
00181                      string("Index should be in [0, ")
00182                      + to_str(Mmatrix_ - 1) + "], but is equal to "
00183                      + to_str(i) + ".");
00184     if (j < 0 || j >= Nmatrix_)
00185       throw WrongCol("HeterogeneousMatrixCollection::Nullify()",
00186                      string("Index should be in [0, ")
00187                      + to_str(Nmatrix_ - 1) + "], but is equal to "
00188                      + to_str(j) + ".");
00189 #endif
00190 
00191     switch (collection_(i, j))
00192       {
00193       case 0:
00194         nz_ -= float_dense_c_.GetMatrix(i, j).GetDataSize();
00195         float_dense_c_.Nullify(i, j);
00196       case 1:
00197         nz_ -= float_sparse_c_.GetMatrix(i, j).GetDataSize();
00198         float_sparse_c_.Nullify(i, j);
00199         break;
00200       case 2:
00201         nz_ -= double_dense_c_.GetMatrix(i, j).GetDataSize();
00202         double_dense_c_.Nullify(i, j);
00203         break;
00204       case 3:
00205         nz_ -= double_sparse_c_.GetMatrix(i, j).GetDataSize();
00206         double_sparse_c_.Nullify(i, j);
00207         break;
00208       }
00209 
00210     collection_(i, j) = -1;
00211   }
00212 
00213 
00215   template <class Prop0, class Storage0,
00216             class Prop1, class Storage1,
00217             template <class U> class Allocator> inline void
00218   HeterogeneousMatrixCollection<Prop0, Storage0, Prop1, Storage1, Allocator>
00219   ::Deallocate()
00220   {
00221     float_dense_c_.Deallocate();
00222     float_sparse_c_.Deallocate();
00223     double_dense_c_.Deallocate();
00224     double_sparse_c_.Deallocate();
00225     this->~HeterogeneousMatrixCollection();
00226   }
00227 
00228 
00229   /*******************
00230    * BASIC FUNCTIONS *
00231    *******************/
00232 
00233 
00235 
00239   template <class Prop0, class Storage0,
00240             class Prop1, class Storage1,
00241             template <class U> class Allocator> inline int
00242   HeterogeneousMatrixCollection<Prop0, Storage0, Prop1, Storage1, Allocator>
00243   ::GetM() const
00244   {
00245     return this->m_;
00246   }
00247 
00248 
00250 
00254   template <class Prop0, class Storage0,
00255             class Prop1, class Storage1,
00256             template <class U> class Allocator> inline int
00257   HeterogeneousMatrixCollection<Prop0, Storage0, Prop1, Storage1, Allocator>
00258   ::GetMmatrix() const
00259   {
00260     return Mmatrix_;
00261   }
00262 
00263 
00265 
00269   template <class Prop0, class Storage0,
00270             class Prop1, class Storage1,
00271             template <class U> class Allocator> inline int
00272   HeterogeneousMatrixCollection<Prop0, Storage0, Prop1, Storage1, Allocator>
00273   ::GetM(int i) const
00274   {
00275 #ifdef SELDON_CHECK_BOUNDS
00276     if (i < 0 || i >= Mmatrix_)
00277       throw WrongRow("HeterogeneousMatrixCollection::GetM()",
00278                      string("Index should be in [0, ")
00279                      + to_str(Mmatrix_ - 1) + "], but is equal to "
00280                      + to_str(i) + ".");
00281 #endif
00282 
00283     return Mlocal_(i);
00284   }
00285 
00286 
00288 
00292   template <class Prop0, class Storage0,
00293             class Prop1, class Storage1,
00294             template <class U> class Allocator> inline int
00295   HeterogeneousMatrixCollection<Prop0, Storage0, Prop1, Storage1, Allocator>
00296   ::GetN() const
00297   {
00298     return this->n_;
00299   }
00300 
00301 
00303 
00307   template <class Prop0, class Storage0,
00308             class Prop1, class Storage1,
00309             template <class U> class Allocator> inline int
00310   HeterogeneousMatrixCollection<Prop0, Storage0, Prop1, Storage1, Allocator>
00311   ::GetNmatrix() const
00312   {
00313     return Nmatrix_;
00314   }
00315 
00316 
00318 
00323   template <class Prop0, class Storage0,
00324             class Prop1, class Storage1,
00325             template <class U> class Allocator> inline int
00326   HeterogeneousMatrixCollection<Prop0, Storage0, Prop1, Storage1, Allocator>
00327   ::GetN(int j) const
00328   {
00329 #ifdef SELDON_CHECK_BOUNDS
00330     if (j < 0 || j >= Nmatrix_)
00331       throw WrongCol("HeterogeneousMatrixCollection::GetN()",
00332                      string("Index should be in [0, ")
00333                      + to_str(Nmatrix_ - 1) + "], but is equal to "
00334                      + to_str(j) + ".");
00335 #endif
00336 
00337     return Nlocal_(j);
00338   }
00339 
00340 
00342 
00345   template <class Prop0, class Storage0,
00346             class Prop1, class Storage1,
00347             template <class U> class Allocator> inline int
00348   HeterogeneousMatrixCollection<Prop0, Storage0, Prop1, Storage1, Allocator>
00349   ::GetSize() const
00350   {
00351     return this->m_ * this->n_;
00352   }
00353 
00354 
00356 
00359   template <class Prop0, class Storage0,
00360             class Prop1, class Storage1,
00361             template <class U> class Allocator>
00362   inline int
00363   HeterogeneousMatrixCollection<Prop0, Storage0, Prop1, Storage1, Allocator>
00364   ::GetDataSize() const
00365   {
00366     return nz_;
00367   }
00368 
00369 
00371 
00380   template <class Prop0, class Storage0,
00381             class Prop1, class Storage1,
00382             template <class U> class Allocator>
00383   inline int
00384   HeterogeneousMatrixCollection<Prop0, Storage0, Prop1, Storage1, Allocator>
00385   ::GetType(int i, int j) const
00386   {
00387 #ifdef SELDON_CHECK_BOUNDS
00388     if (i < 0 || i >= Mmatrix_)
00389       throw WrongRow("HeterogeneousMatrixCollection::GetType()",
00390                      string("Index should be in [0, ")
00391                      + to_str(Mmatrix_ - 1) + "], but is equal to "
00392                      + to_str(i) + ".");
00393     if (j < 0 || j >= Nmatrix_)
00394       throw WrongCol("HeterogeneousMatrixCollection::GetType()",
00395                      string("Index should be in [0, ")
00396                      + to_str(Nmatrix_ - 1) + "], but is equal to "
00397                      + to_str(j) + ".");
00398 #endif
00399     return collection_(i, j);
00400   }
00401 
00402 
00403 
00405 
00408   template <class Prop0, class Storage0,
00409             class Prop1, class Storage1,
00410             template <class U> class Allocator> inline typename
00411   HeterogeneousMatrixCollection<Prop0, Storage0, Prop1, Storage1, Allocator>
00412   ::float_dense_c&
00413   HeterogeneousMatrixCollection<Prop0, Storage0, Prop1, Storage1, Allocator>
00414   ::GetFloatDense()
00415   {
00416     return float_dense_c_;
00417   }
00418 
00419 
00421 
00424   template <class Prop0, class Storage0,
00425             class Prop1, class Storage1,
00426             template <class U> class Allocator> inline const typename
00427   HeterogeneousMatrixCollection<Prop0, Storage0, Prop1, Storage1, Allocator>
00428   ::float_dense_c&
00429   HeterogeneousMatrixCollection<Prop0, Storage0, Prop1, Storage1, Allocator>
00430   ::GetFloatDense() const
00431   {
00432     return float_dense_c_;
00433   }
00434 
00435 
00437 
00440   template <class Prop0, class Storage0,
00441             class Prop1, class Storage1,
00442             template <class U> class Allocator> inline typename
00443   HeterogeneousMatrixCollection<Prop0, Storage0, Prop1, Storage1, Allocator>
00444   ::float_sparse_c&
00445   HeterogeneousMatrixCollection<Prop0, Storage0, Prop1, Storage1, Allocator>
00446   ::GetFloatSparse()
00447   {
00448     return float_sparse_c_;
00449   }
00450 
00451 
00453 
00456   template <class Prop0, class Storage0,
00457             class Prop1, class Storage1,
00458             template <class U> class Allocator> inline const typename
00459   HeterogeneousMatrixCollection<Prop0, Storage0, Prop1, Storage1, Allocator>
00460   ::float_sparse_c&
00461   HeterogeneousMatrixCollection<Prop0, Storage0, Prop1, Storage1, Allocator>
00462   ::GetFloatSparse() const
00463   {
00464     return float_sparse_c_;
00465   }
00466 
00467 
00469 
00472   template <class Prop0, class Storage0,
00473             class Prop1, class Storage1,
00474             template <class U> class Allocator> inline typename
00475   HeterogeneousMatrixCollection<Prop0, Storage0, Prop1, Storage1, Allocator>
00476   ::double_dense_c&
00477   HeterogeneousMatrixCollection<Prop0, Storage0, Prop1, Storage1, Allocator>
00478   ::GetDoubleDense()
00479   {
00480     return double_dense_c_;
00481   }
00482 
00483 
00485 
00488   template <class Prop0, class Storage0,
00489             class Prop1, class Storage1,
00490             template <class U> class Allocator> inline const typename
00491   HeterogeneousMatrixCollection<Prop0, Storage0, Prop1, Storage1, Allocator>
00492   ::double_dense_c&
00493   HeterogeneousMatrixCollection<Prop0, Storage0, Prop1, Storage1, Allocator>
00494   ::GetDoubleDense() const
00495   {
00496     return double_dense_c_;
00497   }
00498 
00499 
00501 
00504   template <class Prop0, class Storage0,
00505             class Prop1, class Storage1,
00506             template <class U> class Allocator> inline typename
00507   HeterogeneousMatrixCollection<Prop0, Storage0, Prop1, Storage1, Allocator>
00508   ::double_sparse_c&
00509   HeterogeneousMatrixCollection<Prop0, Storage0, Prop1, Storage1, Allocator>
00510   ::GetDoubleSparse()
00511   {
00512     return double_sparse_c_;
00513   }
00514 
00515 
00517 
00520   template <class Prop0, class Storage0,
00521             class Prop1, class Storage1,
00522             template <class U> class Allocator> inline const typename
00523   HeterogeneousMatrixCollection<Prop0, Storage0, Prop1, Storage1, Allocator>
00524   ::double_sparse_c&
00525   HeterogeneousMatrixCollection<Prop0, Storage0, Prop1, Storage1, Allocator>
00526   ::GetDoubleSparse() const
00527   {
00528     return double_sparse_c_;
00529   }
00530 
00531 
00532   /*********************
00533    * MEMORY MANAGEMENT *
00534    *********************/
00535 
00536 
00538 
00544   template <class Prop0, class Storage0,
00545             class Prop1, class Storage1,
00546             template <class U> class Allocator> inline void
00547   HeterogeneousMatrixCollection<Prop0, Storage0, Prop1, Storage1, Allocator>
00548   ::Reallocate(int i, int j)
00549   {
00550     nz_ = 0;
00551     Mmatrix_ = i;
00552     Nmatrix_ = j;
00553     Mlocal_.Reallocate(i);
00554     Nlocal_.Reallocate(j);
00555     Mlocal_sum_.Reallocate(i + 1);
00556     Nlocal_sum_.Reallocate(j + 1);
00557     Mlocal_.Fill(0);
00558     Nlocal_.Fill(0);
00559     Mlocal_sum_.Fill(0);
00560     Nlocal_sum_.Fill(0);
00561 
00562     collection_.Reallocate(i, j);
00563     float_dense_c_.Reallocate(i, j);
00564     float_sparse_c_.Reallocate(i, j);
00565     double_dense_c_.Reallocate(i, j);
00566     double_sparse_c_.Reallocate(i, j);
00567   }
00568 
00569 
00571 
00576   template <class Prop0, class Storage0,
00577             class Prop1, class Storage1,
00578             template <class U> class Allocator> inline void
00579   HeterogeneousMatrixCollection<Prop0, Storage0, Prop1, Storage1, Allocator>
00580   ::SetMatrix(int i, int j, const typename HeterogeneousMatrixCollection<
00581               Prop0, Storage0, Prop1, Storage1, Allocator>::float_dense_m& A)
00582   {
00583 #ifdef SELDON_CHECK_BOUNDS
00584     if (i < 0 || i >= Mmatrix_)
00585       throw WrongRow("HeterogeneousMatrixCollection::"
00586                      "SetMatrix(float_dense_m)",
00587                      string("Index should be in [0, ")
00588                      + to_str(Mmatrix_ - 1) + "], but is equal to "
00589                      + to_str(i) + ".");
00590     if (j < 0 || j >= Nmatrix_)
00591       throw WrongCol("HeterogeneousMatrixCollection::"
00592                      "SetMatrix(float_dense_m)",
00593                      string("Index should be in [0, ")
00594                      + to_str(Nmatrix_ - 1) + "], but is equal to "
00595                      + to_str(j) + ".");
00596     if ((Mlocal_(i) != 0) && (Mlocal_(i) != A.GetM()))
00597       throw WrongDim("HeterogeneousMatrixCollection::"
00598                      "SetMatrix(float_dense_m)",
00599                      string("The matrix expected should have ")
00600                      + to_str(this->Mlocal_(i)) + " lines, but has "
00601                      + to_str(A.GetM()) + " lines.");
00602     if ((Nlocal_(j) != 0) && (Nlocal_(j) != A.GetN()))
00603       throw WrongDim("HeterogeneousMatrixCollection::"
00604                      "SetMatrix(float_dense_m)",
00605                      string("The matrix expected should have ")
00606                      + to_str(this->Nlocal_(j)) + " columns, but has "
00607                      + to_str(A.GetN()) + " columns.");
00608 #endif
00609 
00610     Nullify(i, j);
00611 
00612     collection_(i, j) = 0;
00613 
00614     int Mdiff = A.GetM() - Mlocal_(i);
00615     int Ndiff = A.GetN() - Nlocal_(j);
00616 
00617     Mlocal_(i) = A.GetM();
00618     Nlocal_(j) = A.GetN();
00619 
00620     for (int k = i + 1; k < Mmatrix_ + 1; k++)
00621       Mlocal_sum_(k) += Mdiff;
00622 
00623     for (int k = j + 1; k < Nmatrix_ + 1; k++)
00624       Nlocal_sum_(k) += Ndiff;
00625 
00626     this->m_ = Mlocal_sum_(Mmatrix_);
00627     this->n_ = Nlocal_sum_(Nmatrix_);
00628 
00629     float_dense_c_.SetMatrix(i, j, A);
00630   }
00631 
00632 
00634 
00639   template <class Prop0, class Storage0,
00640             class Prop1, class Storage1,
00641             template <class U> class Allocator> inline void
00642   HeterogeneousMatrixCollection<Prop0, Storage0, Prop1, Storage1, Allocator>
00643   ::SetMatrix(int i, int j, const typename HeterogeneousMatrixCollection<
00644               Prop0, Storage0, Prop1, Storage1, Allocator>::float_sparse_m& A)
00645   {
00646 #ifdef SELDON_CHECK_BOUNDS
00647     if (i < 0 || i >= Mmatrix_)
00648       throw WrongRow("HeterogeneousMatrixCollection::"
00649                      "SetMatrix(float_sparse_m)",
00650                      string("Index should be in [0, ")
00651                      + to_str(Mmatrix_ - 1) + "], but is equal to "
00652                      + to_str(i) + ".");
00653     if (j < 0 || j >= Nmatrix_)
00654       throw WrongCol("HeterogeneousMatrixCollection::"
00655                      "SetMatrix(float_sparse_m)",
00656                      string("Index should be in [0, ")
00657                      + to_str(Nmatrix_ - 1) + "], but is equal to "
00658                      + to_str(j) + ".");
00659     if ((Mlocal_(i) != 0) && (Mlocal_(i) != A.GetM()))
00660       throw WrongDim("HeterogeneousMatrixCollection::"
00661                      "SetMatrix(float_sparse_m)",
00662                      string("The matrix expected should have ")
00663                      + to_str(this->Mlocal_(i)) + " lines, but has "
00664                      + to_str(A.GetM()) + " lines.");
00665     if ((Nlocal_(j) != 0) && (Nlocal_(j) != A.GetN()))
00666       throw WrongDim("HeterogeneousMatrixCollection::"
00667                      "SetMatrix(float_sparse_m)",
00668                      string("The matrix expected should have ")
00669                      + to_str(this->Nlocal_(j)) + " columns, but has "
00670                      + to_str(A.GetN()) + " columns.");
00671 #endif
00672 
00673     Nullify(i, j);
00674 
00675     collection_(i, j) = 1;
00676 
00677     int Mdiff = A.GetM() - Mlocal_(i);
00678     int Ndiff = A.GetN() - Nlocal_(j);
00679 
00680     Mlocal_(i) = A.GetM();
00681     Nlocal_(j) = A.GetN();
00682 
00683     for (int k = i + 1; k < Mmatrix_ + 1; k++)
00684       Mlocal_sum_(k) += Mdiff;
00685 
00686     for (int k = j + 1; k < Nmatrix_ + 1; k++)
00687       Nlocal_sum_(k) += Ndiff;
00688 
00689     this->m_ = Mlocal_sum_(Mmatrix_);
00690     this->n_ = Nlocal_sum_(Nmatrix_);
00691 
00692     float_sparse_c_.SetMatrix(i, j, A);
00693   }
00694 
00695 
00697 
00702   template <class Prop0, class Storage0,
00703             class Prop1, class Storage1,
00704             template <class U> class Allocator> inline void
00705   HeterogeneousMatrixCollection<Prop0, Storage0, Prop1, Storage1, Allocator>
00706   ::SetMatrix(int i, int j, const typename HeterogeneousMatrixCollection<
00707               Prop0, Storage0, Prop1, Storage1, Allocator>::double_dense_m& A)
00708   {
00709 #ifdef SELDON_CHECK_BOUNDS
00710     if (i < 0 || i >= Mmatrix_)
00711       throw WrongRow("HeterogeneousMatrixCollection::"
00712                      "SetMatrix(double_dense_m)",
00713                      string("Index should be in [0, ")
00714                      + to_str(Mmatrix_ - 1) + "], but is equal to "
00715                      + to_str(i) + ".");
00716     if (j < 0 || j >= Nmatrix_)
00717       throw WrongCol("HeterogeneousMatrixCollection::"
00718                      "SetMatrix(double_dense_m)",
00719                      string("Index should be in [0, ")
00720                      + to_str(Nmatrix_ - 1) + "], but is equal to "
00721                      + to_str(j) + ".");
00722     if ((Mlocal_(i) != 0) && (Mlocal_(i) != A.GetM()))
00723       throw WrongDim("HeterogeneousMatrixCollection::"
00724                      "SetMatrix(double_dense_m)",
00725                      string("The matrix expected should have ")
00726                      + to_str(this->Mlocal_(i)) + " lines, but has "
00727                      + to_str(A.GetM()) + " lines.");
00728     if ((Nlocal_(j) != 0) && (Nlocal_(j) != A.GetN()))
00729       throw WrongDim("HeterogeneousMatrixCollection::"
00730                      "SetMatrix(double_dense_m)",
00731                      string("The matrix expected should have ")
00732                      + to_str(this->Nlocal_(j)) + " columns, but has "
00733                      + to_str(A.GetN()) + " columns.");
00734 #endif
00735 
00736     Nullify(i, j);
00737 
00738     collection_(i, j) = 2;
00739 
00740     int Mdiff = A.GetM() - Mlocal_(i);
00741     int Ndiff = A.GetN() - Nlocal_(j);
00742 
00743     Mlocal_(i) = A.GetM();
00744     Nlocal_(j) = A.GetN();
00745 
00746     for (int k = i + 1; k < Mmatrix_ + 1; k++)
00747       Mlocal_sum_(k) += Mdiff;
00748 
00749     for (int k = j + 1; k < Nmatrix_ + 1; k++)
00750       Nlocal_sum_(k) += Ndiff;
00751 
00752     this->m_ = Mlocal_sum_(Mmatrix_);
00753     this->n_ = Nlocal_sum_(Nmatrix_);
00754 
00755     double_dense_c_.SetMatrix(i, j, A);
00756   }
00757 
00758 
00760 
00765   template <class Prop0, class Storage0,
00766             class Prop1, class Storage1,
00767             template <class U> class Allocator> inline void
00768   HeterogeneousMatrixCollection<Prop0, Storage0, Prop1, Storage1, Allocator>
00769   ::SetMatrix(int i, int j,
00770               const typename HeterogeneousMatrixCollection< Prop0, Storage0,
00771               Prop1, Storage1, Allocator>::double_sparse_m& A)
00772   {
00773 #ifdef SELDON_CHECK_BOUNDS
00774     if (i < 0 || i >= Mmatrix_)
00775       throw WrongRow("HeterogeneousMatrixCollection::"
00776                      "SetMatrix(double_sparse_m)",
00777                      string("Index should be in [0, ")
00778                      + to_str(Mmatrix_ - 1) + "], but is equal to "
00779                      + to_str(i) + ".");
00780     if (j < 0 || j >= Nmatrix_)
00781       throw WrongCol("HeterogeneousMatrixCollection::"
00782                      "SetMatrix(double_sparse_m)",
00783                      string("Index should be in [0, ")
00784                      + to_str(Nmatrix_ - 1) + "], but is equal to "
00785                      + to_str(j) + ".");
00786     if ((Mlocal_(i) != 0) && (Mlocal_(i) != A.GetM()))
00787       throw WrongDim("HeterogeneousMatrixCollection::"
00788                      "SetMatrix(double_sparse_m)",
00789                      string("The matrix expected should have ")
00790                      + to_str(this->Mlocal_(i)) + " lines, but has "
00791                      + to_str(A.GetM()) + " lines.");
00792     if ((Nlocal_(j) != 0) && (Nlocal_(j) != A.GetN()))
00793       throw WrongDim("HeterogeneousMatrixCollection::"
00794                      "SetMatrix(double_sparse_m)",
00795                      string("The matrix expected should have ")
00796                      + to_str(this->Nlocal_(j)) + " columns, but has "
00797                      + to_str(A.GetN()) + " columns.");
00798 #endif
00799 
00800     Nullify(i, j);
00801 
00802     collection_(i, j) = 3;
00803 
00804     int Mdiff = A.GetM() - Mlocal_(i);
00805     int Ndiff = A.GetN() - Nlocal_(j);
00806 
00807     Mlocal_(i) = A.GetM();
00808     Nlocal_(j) = A.GetN();
00809 
00810     for (int k = i + 1; k < Mmatrix_ + 1; k++)
00811       Mlocal_sum_(k) += Mdiff;
00812 
00813     for (int k = j + 1; k < Nmatrix_ + 1; k++)
00814       Nlocal_sum_(k) += Ndiff;
00815 
00816     this->m_ = Mlocal_sum_(Mmatrix_);
00817     this->n_ = Nlocal_sum_(Nmatrix_);
00818 
00819     double_sparse_c_.SetMatrix(i, j, A);
00820   }
00821 
00822 
00823   /**********************************
00824    * ELEMENT ACCESS AND AFFECTATION *
00825    **********************************/
00826 
00827 
00829 
00835   template <class Prop0, class Storage0,
00836             class Prop1, class Storage1,
00837             template <class U> class Allocator> inline void
00838   HeterogeneousMatrixCollection<Prop0, Storage0, Prop1, Storage1, Allocator>
00839   ::GetMatrix(int i, int j, typename HeterogeneousMatrixCollection<
00840               Prop0, Storage0, Prop1, Storage1, Allocator>::float_dense_m& M)
00841     const
00842   {
00843 #ifdef SELDON_CHECK_BOUNDS
00844     if (i < 0 || i >= Mmatrix_)
00845       throw WrongRow("HeterogeneousMatrixCollection::"
00846                      "GetMatrix(float_dense_m)",
00847                      string("Row index should be in [0, ")
00848                      + to_str(Mmatrix_ - 1) + "], but is equal to "
00849                      + to_str(i) + ".");
00850     if (j < 0 || j >= Nmatrix_)
00851       throw WrongCol("HeterogeneousMatrixCollection::"
00852                      "GetMatrix(float_dense_m)",
00853                      string("Column index should be in [0, ")
00854                      + to_str(Nmatrix_ - 1) + "], but is equal to "
00855                      + to_str(j) + ".");
00856 #endif
00857 
00858     if (collection_(i, j) != 0)
00859       {
00860         string matrix_type;
00861         switch(collection_(i, j))
00862           {
00863           case 1:
00864             matrix_type = "float_sparse";
00865             break;
00866           case 2:
00867             matrix_type = "double_dense";
00868             break;
00869           case 3:
00870             matrix_type = "double_sparse";
00871             break;
00872           default:
00873             throw
00874               WrongArgument("HeterogeneousMatrixCollection::GetMatrix(i, j,"
00875                             "Matrix<Float, Dense> M)",
00876                             "Underlying matrix (" + to_str(i) + " ,"
00877                             + to_str(j) + " ) not defined.");
00878           }
00879 
00880         throw WrongArgument("HeterogeneousMatrixCollection::GetMatrix(i, j, "
00881                             "Matrix<Float, Dense> M)",
00882                             string("Wrong type for matrix ")
00883                             + matrix_type + " M.");
00884       }
00885 
00886     M.SetData(Mlocal_(i), Nlocal_(j),
00887               float_dense_c_.GetMatrix(i, j).GetData());
00888   }
00889 
00890 
00892 
00898   template <class Prop0, class Storage0,
00899             class Prop1, class Storage1,
00900             template <class U> class Allocator> inline void
00901   HeterogeneousMatrixCollection<Prop0, Storage0, Prop1, Storage1, Allocator>
00902   ::GetMatrix(int i, int j, typename HeterogeneousMatrixCollection<
00903               Prop0, Storage0, Prop1, Storage1, Allocator>::float_sparse_m& M)
00904     const
00905   {
00906 #ifdef SELDON_CHECK_BOUNDS
00907     if (i < 0 || i >= Mmatrix_)
00908       throw WrongRow("HeterogeneousMatrixCollection::"
00909                      "GetMatrix(float_sparse_m)",
00910                      string("Row index should be in [0, ")
00911                      + to_str(Mmatrix_ - 1) + "], but is equal to "
00912                      + to_str(i) + ".");
00913     if (j < 0 || j >= Nmatrix_)
00914       throw WrongCol("HeterogeneousMatrixCollection::"
00915                      "GetMatrix(float_sparse_m)",
00916                      string("Column index should be in [0, ")
00917                      + to_str(Nmatrix_ - 1) + "], but is equal to "
00918                      + to_str(j) + ".");
00919 #endif
00920 
00921     if (collection_(i, j) != 1)
00922       {
00923         string matrix_type;
00924         switch(collection_(i, j))
00925           {
00926           case 0:
00927             matrix_type = "float_dense";
00928             break;
00929           case 2:
00930             matrix_type = "double_dense";
00931             break;
00932           case 3:
00933             matrix_type = "double_sparse";
00934             break;
00935           default:
00936             throw
00937               WrongArgument("HeterogeneousMatrixCollection::GetMatrix(i, j, "
00938                             "Matrix<Float, Sparse> M)",
00939                             "Underlying matrix (" + to_str(i) + " ,"
00940                             + to_str(j) + " ) not defined.");
00941           }
00942 
00943         throw WrongArgument("HeterogeneousMatrixCollection::GetMatrix(i, j, "
00944                             "Matrix<Float, Sparse> M)",
00945                             string("Wrong type for matrix ")
00946                             + matrix_type + " M.");
00947       }
00948 
00949     M.SetData(float_sparse_c_.GetMatrix(i, j).GetM(),
00950               float_sparse_c_.GetMatrix(i, j).GetN(),
00951               float_sparse_c_.GetMatrix(i, j).GetNonZeros(),
00952               float_sparse_c_.GetMatrix(i, j).GetData(),
00953               float_sparse_c_.GetMatrix(i, j).GetPtr(),
00954               float_sparse_c_.GetMatrix(i, j).GetInd());
00955   }
00956 
00957 
00959 
00965   template <class Prop0, class Storage0,
00966             class Prop1, class Storage1,
00967             template <class U> class Allocator> inline void
00968   HeterogeneousMatrixCollection<Prop0, Storage0, Prop1, Storage1, Allocator>
00969   ::GetMatrix(int i, int j, typename HeterogeneousMatrixCollection<
00970               Prop0, Storage0, Prop1, Storage1, Allocator>::double_dense_m& M)
00971     const
00972   {
00973 #ifdef SELDON_CHECK_BOUNDS
00974     if (i < 0 || i >= Mmatrix_)
00975       throw WrongRow("HeterogeneousMatrixCollection::"
00976                      "GetMatrix(double_dense_m)",
00977                      string("Row index should be in [0, ")
00978                      + to_str(Mmatrix_ - 1) + "], but is equal to "
00979                      + to_str(i) + ".");
00980     if (j < 0 || j >= Nmatrix_)
00981       throw WrongCol("HeterogeneousMatrixCollection::"
00982                      "GetMatrix(double_dense_m)",
00983                      string("Column index should be in [0, ")
00984                      + to_str(Nmatrix_ - 1) + "], but is equal to "
00985                      + to_str(j) + ".");
00986 #endif
00987 
00988     if (collection_(i, j) != 2)
00989       {
00990         string matrix_type;
00991         switch(collection_(i, j))
00992           {
00993           case 0:
00994             matrix_type = "float_dense";
00995             break;
00996           case 1:
00997             matrix_type = "float_sparse";
00998             break;
00999           case 3:
01000             matrix_type = "double_sparse";
01001             break;
01002           default:
01003             throw
01004               WrongArgument("HeterogeneousMatrixCollection::GetMatrix(i, j, "
01005                             "Matrix<Double, Dense> M)",
01006                             "Underlying matrix (" + to_str(i) + " ,"
01007                             + to_str(j) + " ) not defined.");
01008           }
01009 
01010         throw WrongArgument("HeterogeneousMatrixCollection::GetMatrix(i, j, "
01011                             "Matrix<Double, Dense> M)",
01012                             string("Wrong type for matrix ")
01013                             + matrix_type + " M.");
01014       }
01015 
01016     M.SetData(Mlocal_(i), Nlocal_(j),
01017               double_dense_c_.GetMatrix(i, j).GetData());
01018   }
01019 
01020 
01022 
01028   template <class Prop0, class Storage0,
01029             class Prop1, class Storage1,
01030             template <class U> class Allocator> inline void
01031   HeterogeneousMatrixCollection<Prop0, Storage0, Prop1, Storage1, Allocator>
01032   ::GetMatrix(int i, int j, typename HeterogeneousMatrixCollection<Prop0,
01033               Storage0, Prop1, Storage1, Allocator>::double_sparse_m& M)
01034     const
01035   {
01036 #ifdef SELDON_CHECK_BOUNDS
01037     if (i < 0 || i >= Mmatrix_)
01038       throw WrongRow("HeterogeneousMatrixCollection::"
01039                      "GetMatrix(double_sparse_m)",
01040                      string("Row index should be in [0, ")
01041                      + to_str(Mmatrix_ - 1) + "], but is equal to "
01042                      + to_str(i) + ".");
01043     if (j < 0 || j >= Nmatrix_)
01044       throw WrongCol("HeterogeneousMatrixCollection::"
01045                      "GetMatrix(double_sparse_m)",
01046                      string("Column index should be in [0, ")
01047                      + to_str(Nmatrix_ - 1) + "], but is equal to "
01048                      + to_str(j) + ".");
01049 #endif
01050 
01051     if (collection_(i, j) != 3)
01052       {
01053         string matrix_type;
01054         switch(collection_(i, j))
01055           {
01056           case 0:
01057             matrix_type = "float_dense";
01058             break;
01059           case 1:
01060             matrix_type = "float_sparse";
01061             break;
01062           case 2:
01063             matrix_type = "double_dense";
01064             break;
01065           default:
01066             throw
01067               WrongArgument("HeterogeneousMatrixCollection::GetMatrix(i, j,"
01068                             "Matrix<Double, Sparse> M)",
01069                             "Underlying matrix (" + to_str(i) + " ,"
01070                             + to_str(j) + " ) not defined.");
01071           }
01072 
01073         throw WrongArgument("HeterogeneousMatrixCollection::GetMatrix(i, j,"
01074                             "Matrix<Double, Sparse> M)",
01075                             string("Wrong type for matrix ")
01076                             + matrix_type + " M.");
01077       }
01078 
01079     M.Nullify();
01080     M.SetData(double_sparse_c_.GetMatrix(i, j).GetM(),
01081               double_sparse_c_.GetMatrix(i, j).GetN(),
01082               double_sparse_c_.GetMatrix(i, j).GetNonZeros(),
01083               double_sparse_c_.GetMatrix(i, j).GetData(),
01084               double_sparse_c_.GetMatrix(i, j).GetPtr(),
01085               double_sparse_c_.GetMatrix(i, j).GetInd());
01086   }
01087 
01088 
01090 
01096   template <class Prop0, class Storage0,
01097             class Prop1, class Storage1,
01098             template <class U> class Allocator>
01099   inline
01100   double HeterogeneousMatrixCollection<Prop0, Storage0,
01101                                        Prop1, Storage1, Allocator>
01102   ::operator() (int i, int j) const
01103   {
01104 
01105 #ifdef SELDON_CHECK_BOUNDS
01106     if (i < 0 || i >= this->Mlocal_sum_(Mmatrix_))
01107       throw WrongRow("HeterogeneousMatrixCollection::operator()",
01108                      string("Index should be in [0, ")
01109                      + to_str(this->Mlocal_sum_(Mmatrix_) - 1)
01110                      + "], but is equal to "
01111                      + to_str(i) + ".");
01112     if (j < 0 || j >= this->Nlocal_sum_(Nmatrix_))
01113       throw WrongCol("HeterogeneousMatrixCollection::operator()",
01114                      string("Index should be in [0, ")
01115                      + to_str(this->Nlocal_sum_(Nmatrix_) - 1)
01116                      + "], but is equal to "
01117                      + to_str(j) + ".");
01118 #endif
01119 
01120     int i_global = 0;
01121     while (i >= Mlocal_sum_(i_global))
01122       i_global++;
01123     i_global--;
01124 
01125     int j_global = 0;
01126     while (j >= Nlocal_sum_(j_global))
01127       j_global++;
01128     j_global--;
01129 
01130     double res = 0.;
01131     switch(collection_(i_global, j_global))
01132       {
01133       case 0:
01134         res = double(float_dense_c_.GetMatrix(i_global, j_global)
01135                      (i - Mlocal_sum_(i_global), j - Nlocal_sum_(j_global)));
01136         break;
01137       case 1:
01138         res = double(float_sparse_c_.GetMatrix(i_global, j_global)
01139                      (i - Mlocal_sum_(i_global), j - Nlocal_sum_(j_global)));
01140         break;
01141       case 2:
01142         res = double_dense_c_.GetMatrix(i_global, j_global)
01143           (i - Mlocal_sum_(i_global), j - Nlocal_sum_(j_global));
01144         break;
01145       case 3:
01146         res = double_sparse_c_.GetMatrix(i_global, j_global)
01147           (i - Mlocal_sum_(i_global), j - Nlocal_sum_(j_global));
01148         break;
01149       default:
01150         throw
01151           WrongArgument("HeterogeneousMatrixCollection::operator(int, int)",
01152                         "Underlying matrix (" + to_str(i) + " ,"
01153                         + to_str(j) + " ) not defined.");
01154       }
01155     return res;
01156   }
01157 
01158 
01160 
01165   template <class Prop0, class Storage0,
01166             class Prop1, class Storage1,
01167             template <class U> class Allocator>
01168   inline
01169   HeterogeneousMatrixCollection<Prop0, Storage0, Prop1, Storage1, Allocator>&
01170   HeterogeneousMatrixCollection<Prop0, Storage0, Prop1, Storage1, Allocator>
01171   ::operator= (const HeterogeneousMatrixCollection<Prop0, Storage0,
01172                Prop1, Storage1, Allocator>& A)
01173   {
01174     this->Copy(A);
01175     return *this;
01176   }
01177 
01178 
01180 
01185   template <class Prop0, class Storage0,
01186             class Prop1, class Storage1,
01187             template <class U> class Allocator>
01188   inline void
01189   HeterogeneousMatrixCollection<Prop0, Storage0, Prop1, Storage1, Allocator>
01190   ::Copy(const HeterogeneousMatrixCollection<Prop0, Storage0, Prop1,
01191          Storage1, Allocator>& A)
01192   {
01193     Clear();
01194     this->nz_ = A.nz_;
01195     Mmatrix_ = A.Mmatrix_;
01196     Nmatrix_ = A.Nmatrix_;
01197     this->m_ = A.GetM();
01198     this->n_ = A.GetN();
01199 
01200     this->Mlocal_ = A.Mlocal_;
01201     this->Mlocal_sum_ = A.Mlocal_sum_;
01202     this->Nlocal_ = A.Nlocal_;
01203     this->Nlocal_sum_ = A.Nlocal_sum_;
01204 
01205     collection_.Copy(A.collection_);
01206 
01207     float_dense_c_.Reallocate(Mmatrix_, Nmatrix_);
01208     float_sparse_c_.Reallocate(Mmatrix_, Nmatrix_);
01209     double_dense_c_.Reallocate(Mmatrix_, Nmatrix_);
01210     double_sparse_c_.Reallocate(Mmatrix_, Nmatrix_);
01211 
01212     float_dense_m m0a;
01213     float_sparse_m m1a;
01214     double_dense_m m2a;
01215     double_sparse_m m3a;
01216 
01217     for (int i = 0; i < Mmatrix_; i++ )
01218       for (int j = 0; j < Nmatrix_; j++)
01219         {
01220           switch (A.GetType(i, j))
01221             {
01222             case 0:
01223               A.GetMatrix(i, j, m0a);
01224               SetMatrix(i, j, m0a);
01225               m0a.Nullify();
01226               break;
01227             case 1:
01228               A.GetMatrix(i, j, m1a);
01229               SetMatrix(i, j, m1a);
01230               m1a.Nullify();
01231               break;
01232             case 2:
01233               A.GetMatrix(i, j, m2a);
01234               SetMatrix(i, j, m2a);
01235               m2a.Nullify();
01236               break;
01237             case 3:
01238               A.GetMatrix(i, j, m3a);
01239               SetMatrix(i, j, m3a);
01240               m3a.Nullify();
01241               break;
01242             default:
01243               throw WrongArgument("Matrix<FloatDouble, DenseSparseCollection>"
01244                                   "::MltAdd(alpha, A, B, beta, C) ",
01245                                   "Underlying matrix  C (" + to_str(i) + " ,"
01246                                   + to_str(j) + " ) not defined.");
01247             }
01248         }
01249   }
01250 
01251 
01252   /************************
01253    * CONVENIENT FUNCTIONS *
01254    ************************/
01255 
01256 
01258 
01261   template <class Prop0, class Storage0,
01262             class Prop1, class Storage1,
01263             template <class U> class Allocator> void
01264   HeterogeneousMatrixCollection<Prop0, Storage0, Prop1, Storage1, Allocator>
01265   ::Print() const
01266   {
01267     for (int i = 0; i < Mlocal_sum_(Mmatrix_); i++)
01268       {
01269         for (int j = 0; j < Nlocal_sum_(Nmatrix_); j++)
01270           cout << (*this)(i, j) << endl;
01271         cout << endl;
01272       }
01273   }
01274 
01275 
01277 
01285   template <class Prop0, class Storage0,
01286             class Prop1, class Storage1,
01287             template <class U> class Allocator> void
01288   HeterogeneousMatrixCollection<Prop0, Storage0, Prop1, Storage1, Allocator>
01289   ::Write(string FileName, bool with_size) const
01290   {
01291     ofstream FileStream;
01292     FileStream.open(FileName.c_str());
01293 
01294 #ifdef SELDON_CHECK_IO
01295     // Checks if the file was opened.
01296     if (!FileStream.is_open())
01297       throw IOError("Matrix_Pointers::Write(string FileName)",
01298                     string("Unable to open file \"") + FileName + "\".");
01299 #endif
01300 
01301     this->Write(FileStream, with_size);
01302 
01303     FileStream.close();
01304   }
01305 
01306 
01308 
01316   template <class Prop0, class Storage0,
01317             class Prop1, class Storage1,
01318             template <class U> class Allocator> void
01319   HeterogeneousMatrixCollection<Prop0, Storage0, Prop1, Storage1, Allocator>
01320   ::Write(ostream& FileStream, bool with_size = true) const
01321   {
01322 
01323 #ifdef SELDON_CHECK_IO
01324     // Checks if the stream is ready.
01325     if (!FileStream.good())
01326       throw IOError("HeterogeneousMatrixCollection"
01327                     "::Write(ostream& FileStream)",
01328                     "The stream is not ready.");
01329 #endif
01330 
01331     if (with_size)
01332       {
01333         FileStream.write(reinterpret_cast<char*>(const_cast<int*>(&Mmatrix_)),
01334                          sizeof(int));
01335         FileStream.write(reinterpret_cast<char*>(const_cast<int*>(&Nmatrix_)),
01336                          sizeof(int));
01337       }
01338 
01339     collection_.Write(FileStream, with_size);
01340 
01341     float_dense_m m0a;
01342     float_sparse_m m1a;
01343     double_dense_m m2a;
01344     double_sparse_m m3a;
01345 
01346     int i, j;
01347     for (i = 0; i < Mmatrix_; i++)
01348       for (j = 0; j < Nmatrix_; j++)
01349         {
01350           switch (GetType(i, j))
01351             {
01352             case 0:
01353               GetMatrix(i, j, m0a);
01354               m0a.Write(FileStream, with_size);
01355               m0a.Nullify();
01356               break;
01357             case 1:
01358               throw Undefined("Matrix<FloatDouble, DenseSparseCollection>"
01359                               "Storage0, Prop1, Storage1, Allocator>"
01360                               "::Write(ostream& FileStream, bool "
01361                               "with_size = true) ");
01362             case 2:
01363               GetMatrix(i, j, m2a);
01364               m2a.Write(FileStream, with_size);
01365               m2a.Nullify();
01366               break;
01367             case 3:
01368               throw Undefined("Matrix<FloatDouble, DenseSparseCollection>"
01369                               "Storage0, Prop1, Storage1, Allocator>"
01370                               "::Write(ostream& FileStream, bool "
01371                               "with_size = true) ");
01372             default:
01373               throw WrongArgument("Matrix<FloatDouble, DenseSparseCollection>"
01374                                   "::Write(ostream& FileStream, "
01375                                   "bool with_size = true) ",
01376                                   "Underlying matrix  A (" + to_str(i) + " ,"
01377                                   + to_str(j) + " ) not defined.");
01378             }
01379         }
01380 
01381 
01382 #ifdef SELDON_CHECK_IO
01383     // Checks if data was written.
01384     if (!FileStream.good())
01385       throw IOError("HeterogeneousMatrixCollection"
01386                     "::Write(ostream& FileStream)",
01387                     "Output operation failed.");
01388 #endif
01389 
01390   }
01391 
01392 
01394 
01399   template <class Prop0, class Storage0,
01400             class Prop1, class Storage1,
01401             template <class U> class Allocator> void
01402   HeterogeneousMatrixCollection<Prop0, Storage0, Prop1, Storage1, Allocator>
01403   ::WriteText(string FileName) const
01404   {
01405     ofstream FileStream;
01406     FileStream.precision(cout.precision());
01407     FileStream.flags(cout.flags());
01408     FileStream.open(FileName.c_str());
01409 
01410 #ifdef SELDON_CHECK_IO
01411     // Checks if the file was opened.
01412     if (!FileStream.is_open())
01413       throw IOError("HeterogeneousMatrixCollection"
01414                     "::WriteText(string FileName)",
01415                     string("Unable to open file \"") + FileName + "\".");
01416 #endif
01417 
01418     this->WriteText(FileStream);
01419 
01420     FileStream.close();
01421   }
01422 
01423 
01425 
01431   template <class Prop0, class Storage0,
01432             class Prop1, class Storage1,
01433             template <class U> class Allocator> void
01434   HeterogeneousMatrixCollection<Prop0, Storage0, Prop1, Storage1, Allocator>
01435   ::WriteText(ostream& FileStream) const
01436   {
01437 
01438 #ifdef SELDON_CHECK_IO
01439     // Checks if the file is ready.
01440     if (!FileStream.good())
01441       throw IOError("HeterogeneousMatrixCollection"
01442                     "::WriteText(ostream& FileStream)",
01443                     "The stream is not ready.");
01444 #endif
01445 
01446     float_dense_m m0a;
01447     float_sparse_m m1a;
01448     double_dense_m m2a;
01449     double_sparse_m m3a;
01450 
01451     int i, j;
01452     for (i = 0; i < Mmatrix_; i++)
01453       for (j = 0; j < Nmatrix_; j++)
01454         {
01455           switch (GetType(i, j))
01456             {
01457             case 0:
01458               GetMatrix(i, j, m0a);
01459               m0a.WriteText(FileStream);
01460               m0a.Nullify();
01461               break;
01462             case 1:
01463               GetMatrix(i, j, m1a);
01464               m1a.WriteText(FileStream);
01465               m1a.Nullify();
01466               break;
01467             case 2:
01468               GetMatrix(i, j, m2a);
01469               m2a.WriteText(FileStream);
01470               m2a.Nullify();
01471               break;
01472             case 3:
01473               GetMatrix(i, j, m3a);
01474               m3a.WriteText(FileStream);
01475               m3a.Nullify();
01476               break;
01477             default:
01478               throw WrongArgument("Matrix<FloatDouble, DenseSparseCollection>"
01479                                   "::Write(ostream& FileStream, "
01480                                   "bool with_size = true) ",
01481                                   "Underlying matrix  A (" + to_str(i) + " ,"
01482                                   + to_str(j) + " ) not defined.");
01483             }
01484           FileStream << endl;
01485         }
01486 
01487 #ifdef SELDON_CHECK_IO
01488     // Checks if data was written.
01489     if (!FileStream.good())
01490       throw IOError("HeterogeneousMatrixCollection"
01491                     "::WriteText(ostream& FileStream)",
01492                     "Output operation failed.");
01493 #endif
01494 
01495   }
01496 
01497 
01499 
01505   template <class Prop0, class Storage0,
01506             class Prop1, class Storage1,
01507             template <class U> class Allocator> void
01508   HeterogeneousMatrixCollection<Prop0, Storage0, Prop1, Storage1, Allocator>
01509   ::Read(string FileName)
01510   {
01511     ifstream FileStream;
01512     FileStream.open(FileName.c_str());
01513 
01514 #ifdef SELDON_CHECK_IO
01515     // Checks if the file was opened.
01516     if (!FileStream.is_open())
01517       throw IOError("HeterogeneousMatrixCollection<Prop0, Storage0, Prop1,"
01518                     " Storage1, Allocator>::Read(string FileName)",
01519                     string("Unable to open file \"") + FileName + "\".");
01520 #endif
01521 
01522     this->Read(FileStream);
01523 
01524     FileStream.close();
01525   }
01526 
01527 
01529 
01535   template <class Prop0, class Storage0,
01536             class Prop1, class Storage1,
01537             template <class U> class Allocator> void
01538   HeterogeneousMatrixCollection<Prop0, Storage0, Prop1, Storage1, Allocator>
01539   ::Read(istream& FileStream)
01540   {
01541 
01542 #ifdef SELDON_CHECK_IO
01543     // Checks if the stream is ready.
01544     if (!FileStream.good())
01545       throw IOError("HeterogeneousMatrixCollection<Prop0, Storage0, Prop1,"
01546                     " Storage1, Allocator>::Read(istream& FileStream)",
01547                     "The stream is not ready.");
01548 #endif
01549 
01550     int *new_m, *new_n;
01551     new_m = new int;
01552     new_n = new int;
01553 
01554     FileStream.read(reinterpret_cast<char*>(new_m), sizeof(int));
01555     FileStream.read(reinterpret_cast<char*>(new_n), sizeof(int));
01556 
01557     this->Reallocate(*new_m, *new_n);
01558 
01559     collection_.Read(FileStream);
01560 
01561     float_dense_m m0a;
01562     float_sparse_m m1a;
01563     double_dense_m m2a;
01564     double_sparse_m m3a;
01565     int i, j;
01566     for (i = 0; i < Mmatrix_; i++)
01567       for (j = 0; j < Nmatrix_; j++)
01568         {
01569           switch (GetType(i, j))
01570             {
01571             case 0:
01572               m0a.Read(FileStream);
01573               SetMatrix(i, j, m0a);
01574               m0a.Nullify();
01575               break;
01576             case 1:
01577               throw Undefined("Matrix<FloatDouble, DenseSparseCollection>"
01578                               "Storage0, Prop1, Storage1, Allocator>"
01579                               "::Read(istream& FileStream)");
01580             case 2:
01581               m2a.Read(FileStream);
01582               SetMatrix(i, j, m2a);
01583               m2a.Nullify();
01584               break;
01585             case 3:
01586               throw Undefined("Matrix<FloatDouble, DenseSparseCollection>"
01587                               "Storage0, Prop1, Storage1, Allocator>"
01588                               "::Read(istream& FileStream)");
01589               break;
01590             default:
01591               throw WrongArgument("HeterogeneousMatrixCollection<Prop0, "
01592                                   "Storage0, Prop1, Storage1, Allocator>"
01593                                   "::Read(istream& FileStream) ",
01594                                   "Underlying matrix  A (" + to_str(i) + " ,"
01595                                   + to_str(j) + " ) not defined.");
01596             }
01597         }
01598 
01599 
01600     delete new_n;
01601     delete new_m;
01602 
01603 #ifdef SELDON_CHECK_IO
01604     // Checks if data was read.
01605     if (!FileStream.good())
01606       throw IOError("HeterogeneousMatrixCollection"
01607                     "::Read(istream& FileStream)",
01608                     "Output operation failed.");
01609 #endif
01610 
01611   }
01612 
01613 
01614   /****************
01615    * CONSTRUCTORS *
01616    ****************/
01617 
01618 
01620 
01623   template <template <class U> class Allocator>
01624   inline
01625   Matrix<FloatDouble, General, DenseSparseCollection, Allocator<double> >
01626   ::Matrix():
01627     HeterogeneousMatrixCollection<General, RowMajor, General,
01628                                   RowSparse, Allocator>()
01629   {
01630   }
01631 
01632 
01634 
01638   template <template <class U> class Allocator>
01639   inline
01640   Matrix<FloatDouble, General, DenseSparseCollection, Allocator<double> >
01641   ::Matrix(int i, int j):
01642     HeterogeneousMatrixCollection<General, RowMajor, General,
01643                                   RowSparse, Allocator>(i, j)
01644   {
01645   }
01646 
01647 
01648 } // namespace Seldon.
01649 
01650 #define SELDON_FILE_MATRIX_HETEROGENEOUS_COLLECTION_CXX
01651 #endif