matrix_sparse/Matrix_ArraySparse.cxx

00001 // Copyright (C) 2003-2011 Marc Duruflé
00002 //
00003 // This file is part of the linear-algebra library Seldon,
00004 // http://seldon.sourceforge.net/.
00005 //
00006 // Seldon is free software; you can redistribute it and/or modify it under the
00007 // terms of the GNU Lesser General Public License as published by the Free
00008 // Software Foundation; either version 2.1 of the License, or (at your option)
00009 // any later version.
00010 //
00011 // Seldon is distributed in the hope that it will be useful, but WITHOUT ANY
00012 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00013 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
00014 // more details.
00015 //
00016 // You should have received a copy of the GNU Lesser General Public License
00017 // along with Seldon. If not, see http://www.gnu.org/licenses/.
00018 
00019 
00020 #ifndef SELDON_FILE_MATRIX_ARRAY_SPARSE_CXX
00021 
00022 #include "Matrix_ArraySparse.hxx"
00023 
00024 namespace Seldon
00025 {
00026 
00028 
00031   template <class T, class Prop, class Storage, class Allocator>
00032   inline Matrix_ArraySparse<T, Prop, Storage, Allocator>::Matrix_ArraySparse()
00033     : val_()
00034   {
00035     this->m_ = 0;
00036     this->n_ = 0;
00037   }
00038 
00039 
00041 
00046   template <class T, class Prop, class Storage, class Allocator>
00047   inline Matrix_ArraySparse<T, Prop, Storage, Allocator>::
00048   Matrix_ArraySparse(int i, int j) :
00049     val_(Storage::GetFirst(i, j))
00050   {
00051     this->m_ = i;
00052     this->n_ = j;
00053   }
00054 
00055 
00057   template <class T, class Prop, class Storage, class Allocat>
00058   inline Matrix_ArraySparse<T, Prop, Storage, Allocat>::~Matrix_ArraySparse()
00059   {
00060     this->m_ = 0;
00061     this->n_ = 0;
00062   }
00063 
00064 
00066 
00069   template <class T, class Prop, class Storage, class Allocator>
00070   inline void Matrix_ArraySparse<T, Prop, Storage, Allocator>::Clear()
00071   {
00072     this->~Matrix_ArraySparse();
00073   }
00074 
00075 
00076   /*********************
00077    * MEMORY MANAGEMENT *
00078    *********************/
00079 
00080 
00082 
00088   template <class T, class Prop, class Storage, class Allocator>
00089   inline void Matrix_ArraySparse<T, Prop, Storage, Allocator>::
00090   Reallocate(int i, int j)
00091   {
00092     // Clears previous entries.
00093     Clear();
00094 
00095     this->m_ = i;
00096     this->n_ = j;
00097 
00098     int n = Storage::GetFirst(i, j);
00099     val_.Reallocate(n);
00100   }
00101 
00102 
00104 
00110   template <class T, class Prop, class Storage, class Allocator>
00111   void Matrix_ArraySparse<T, Prop, Storage, Allocator>::Resize(int i, int j)
00112   {
00113     int n = Storage::GetFirst(this->m_, n_);
00114     int new_n = Storage::GetFirst(i, j);
00115     if (n != new_n)
00116       {
00117         Vector<Vector<T, VectSparse, Allocator>, VectFull,
00118           NewAlloc<Vector<T, VectSparse, Allocator> > > new_val;
00119 
00120         new_val.Reallocate(new_n);
00121 
00122         for (int k = 0 ; k < min(n, new_n) ; k++)
00123           Swap(new_val(k), this->val_(k));
00124 
00125         val_.SetData(new_n, new_val.GetData());
00126         new_val.Nullify();
00127 
00128       }
00129 
00130     this->m_ = i;
00131     this->n_ = j;
00132   }
00133 
00134 
00135   /*******************
00136    * BASIC FUNCTIONS *
00137    *******************/
00138 
00139 
00141 
00144   template <class T, class Prop, class Storage, class Allocator>
00145   inline int Matrix_ArraySparse<T, Prop, Storage, Allocator>::GetM() const
00146   {
00147     return m_;
00148   }
00149 
00150 
00152 
00155   template <class T, class Prop, class Storage, class Allocator>
00156   inline int Matrix_ArraySparse<T, Prop, Storage, Allocator>::GetN() const
00157   {
00158     return n_;
00159   }
00160 
00161 
00163 
00167   template <class T, class Prop, class Storage, class Allocator>
00168   inline int Matrix_ArraySparse<T, Prop, Storage, Allocator>
00169   ::GetM(const SeldonTranspose& status) const
00170   {
00171     if (status.NoTrans())
00172       return m_;
00173     else
00174       return n_;
00175   }
00176 
00177 
00179 
00183   template <class T, class Prop, class Storage, class Allocator>
00184   inline int Matrix_ArraySparse<T, Prop, Storage, Allocator>
00185   ::GetN(const SeldonTranspose& status) const
00186   {
00187     if (status.NoTrans())
00188       return n_;
00189     else
00190       return m_;
00191   }
00192 
00193 
00195 
00198   template <class T, class Prop, class Storage, class Allocator>
00199   inline int Matrix_ArraySparse<T, Prop, Storage, Allocator>::GetNonZeros()
00200     const
00201   {
00202     int nnz = 0;
00203     for (int i = 0; i < this->val_.GetM(); i++)
00204       nnz += this->val_(i).GetM();
00205 
00206     return nnz;
00207   }
00208 
00209 
00211 
00216   template <class T, class Prop, class Storage, class Allocator>
00217   inline int Matrix_ArraySparse<T, Prop, Storage, Allocator>::GetDataSize()
00218     const
00219   {
00220     return GetNonZeros();
00221   }
00222 
00223 
00225 
00230   template <class T, class Prop, class Storage, class Allocator>
00231   inline int* Matrix_ArraySparse<T, Prop, Storage, Allocator>::GetIndex(int i)
00232     const
00233   {
00234     return val_(i).GetIndex();
00235   }
00236 
00237 
00239 
00243   template <class T, class Prop, class Storage, class Allocator>
00244   inline T*
00245   Matrix_ArraySparse<T, Prop, Storage, Allocator>::GetData(int i) const
00246   {
00247     return val_(i).GetData();
00248   }
00249 
00250 
00252 
00256   template <class T, class Prop, class Storage, class Allocat>
00257   inline Vector<T, VectSparse, Allocat>*
00258   Matrix_ArraySparse<T, Prop, Storage, Allocat>::GetData() const
00259   {
00260     return val_.GetData();
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 T
00278   Matrix_ArraySparse<T, Prop, Storage, Allocator>::operator() (int i, int j)
00279     const
00280   {
00281 
00282 #ifdef SELDON_CHECK_BOUNDS
00283     if (i < 0 || i >= this->m_)
00284       throw WrongRow("Matrix_ArraySparse::operator()",
00285                      "Index should be in [0, " + to_str(this->m_-1) +
00286                      "],but is equal to " + to_str(i) + ".");
00287 
00288     if (j < 0 || j >= this->n_)
00289       throw WrongCol("Matrix_ArraySparse::operator()",
00290                      "Index should be in [0, " + to_str(this->n_-1) +
00291                      "], but is equal to " + to_str(j) + ".");
00292 #endif
00293 
00294     return this->val_(Storage::GetFirst(i, j))(Storage::GetSecond(i, j));
00295   }
00296 
00297 
00299 
00305   template <class T, class Prop, class Storage, class Allocator>
00306   inline T&
00307   Matrix_ArraySparse<T, Prop, Storage, Allocator>::Get(int i, int j)
00308   {
00309 
00310 #ifdef SELDON_CHECK_BOUNDS
00311     if (i < 0 || i >= this->m_)
00312       throw WrongRow("Matrix_ArraySparse::operator()",
00313                      "Index should be in [0, " + to_str(this->m_-1) +
00314                      "],but is equal to " + to_str(i) + ".");
00315 
00316     if (j < 0 || j >= this->n_)
00317       throw WrongCol("Matrix_ArraySparse::operator()",
00318                      "Index should be in [0, " + to_str(this->n_-1) +
00319                      "], but is equal to " + to_str(j) + ".");
00320 #endif
00321 
00322     return this->val_(Storage::GetFirst(i, j)).Get(Storage::GetSecond(i, j));
00323   }
00324 
00325 
00327 
00333   template <class T, class Prop, class Storage, class Allocator>
00334   inline const T&
00335   Matrix_ArraySparse<T, Prop, Storage, Allocator>::Get(int i, int j) const
00336   {
00337 
00338 #ifdef SELDON_CHECK_BOUNDS
00339     if (i < 0 || i >= this->m_)
00340       throw WrongRow("Matrix_ArraySparse::operator()",
00341                      "Index should be in [0, " + to_str(this->m_-1) +
00342                      "],but is equal to " + to_str(i) + ".");
00343 
00344     if (j < 0 || j >= this->n_)
00345       throw WrongCol("Matrix_ArraySparse::operator()",
00346                      "Index should be in [0, " + to_str(this->n_-1) +
00347                      "], but is equal to " + to_str(j) + ".");
00348 #endif
00349 
00350     return this->val_(Storage::GetFirst(i, j)).Get(Storage::GetSecond(i, j));
00351   }
00352 
00353 
00355 
00361   template <class T, class Prop, class Storage, class Allocator>
00362   inline T&
00363   Matrix_ArraySparse<T, Prop, Storage, Allocator>::Val(int i, int j)
00364   {
00365 
00366 #ifdef SELDON_CHECK_BOUNDS
00367     if (i < 0 || i >= this->m_)
00368       throw WrongRow("Matrix_ArraySparse::operator()",
00369                      "Index should be in [0, " + to_str(this->m_-1) +
00370                      "], but is equal to " + to_str(i) + ".");
00371 
00372     if (j < 0 || j >= this->n_)
00373       throw WrongCol("Matrix_ArraySparse::operator()",
00374                      "Index should be in [0, " + to_str(this->n_-1) +
00375                      "], but is equal to " + to_str(j) + ".");
00376 #endif
00377 
00378     return
00379       this->val_(Storage::GetFirst(i, j)).Val(Storage::GetSecond(i, j));
00380   }
00381 
00382 
00384 
00390   template <class T, class Prop, class Storage, class Allocator>
00391   inline const T&
00392   Matrix_ArraySparse<T, Prop, Storage, Allocator>::Val(int i, int j) const
00393   {
00394 
00395 #ifdef SELDON_CHECK_BOUNDS
00396     if (i < 0 || i >= this->m_)
00397       throw WrongRow("Matrix_ArraySparse::operator()",
00398                      "Index should be in [0, " + to_str(this->m_-1) +
00399                      "], but is equal to " + to_str(i) + ".");
00400 
00401     if (j < 0 || j >= this->n_)
00402       throw WrongCol("Matrix_ArraySparse::operator()",
00403                      "Index should be in [0, " + to_str(this->n_-1) +
00404                      "], but is equal to " + to_str(j) + ".");
00405 #endif
00406 
00407     return
00408       this->val_(Storage::GetFirst(i, j)).Val(Storage::GetSecond(i, j));
00409   }
00410 
00411 
00413 
00418   template <class T, class Prop, class Storage, class Allocator>
00419   inline void Matrix_ArraySparse<T, Prop, Storage, Allocator>
00420   ::Set(int i, int j, const T& x)
00421   {
00422     this->Get(i, j) = x;
00423   }
00424 
00425 
00427 
00432   template <class T, class Prop, class Storage, class Allocator>
00433   inline const T& Matrix_ArraySparse<T, Prop, Storage, Allocator>::
00434   Value (int i, int j) const
00435   {
00436 
00437 #ifdef SELDON_CHECK_BOUNDS
00438     if (i < 0 || i >= Storage::GetFirst(this->m_, this->n_))
00439       throw WrongRow("Matrix_ArraySparse::value", "Index should be in [0, "
00440                      + to_str(Storage::GetFirst(this->m_, this->n_)-1)
00441                      + "], but is equal to " + to_str(i) + ".");
00442 
00443     if ((j < 0)||(j >= this->val_(i).GetM()))
00444       throw WrongCol("Matrix_ArraySparse::value", "Index should be in [0, " +
00445                      to_str(this->val_(i).GetM()-1) + "], but is equal to "
00446                      + to_str(j) + ".");
00447 #endif
00448 
00449     return val_(i).Value(j);
00450   }
00451 
00452 
00454 
00459   template <class T, class Prop, class Storage, class Allocator>
00460   inline T&
00461   Matrix_ArraySparse<T, Prop, Storage, Allocator>::Value (int i, int j)
00462   {
00463 
00464 #ifdef SELDON_CHECK_BOUNDS
00465     if (i < 0 || i >= Storage::GetFirst(this->m_, this->n_))
00466       throw WrongRow("Matrix_ArraySparse::value", "Index should be in [0, "
00467                      + to_str(Storage::GetFirst(this->m_, this->n_)-1)
00468                      + "], but is equal to " + to_str(i) + ".");
00469 
00470     if ((j < 0)||(j >= this->val_(i).GetM()))
00471       throw WrongCol("Matrix_ArraySparse::value", "Index should be in [0, " +
00472                      to_str(this->val_(i).GetM()-1) + "], but is equal to "
00473                      + to_str(j) + ".");
00474 #endif
00475 
00476     return val_(i).Value(j);
00477   }
00478 
00479 
00481 
00486   template <class T, class Prop, class Storage, class Allocator> inline
00487   int Matrix_ArraySparse<T, Prop, Storage, Allocator>::Index(int i, int j)
00488     const
00489   {
00490 
00491 #ifdef SELDON_CHECK_BOUNDS
00492     if (i < 0 || i >= Storage::GetFirst(this->m_, this->n_))
00493       throw WrongRow("Matrix_ArraySparse::index", "Index should be in [0, "
00494                      + to_str(Storage::GetFirst(this->m_, this->n_)-1)
00495                      + "], but is equal to " + to_str(i) + ".");
00496 
00497     if ((j < 0)||(j >= this->val_(i).GetM()))
00498       throw WrongCol("Matrix_ArraySparse::index", "Index should be in [0, " +
00499                      to_str(this->val_(i).GetM()-1) + "], but is equal to "
00500                      + to_str(j) + ".");
00501 #endif
00502 
00503     return val_(i).Index(j);
00504   }
00505 
00506 
00508 
00513   template <class T, class Prop, class Storage, class Allocator> inline
00514   int& Matrix_ArraySparse<T, Prop, Storage, Allocator>::Index(int i, int j)
00515   {
00516 
00517 #ifdef SELDON_CHECK_BOUNDS
00518     if (i < 0 || i >= Storage::GetFirst(this->m_, this->n_))
00519       throw WrongRow("Matrix_ArraySparse::index", "Index should be in [0, "
00520                      + to_str(Storage::GetFirst(this->m_, this->n_)-1)
00521                      + "], but is equal to " + to_str(i) + ".");
00522 
00523     if (j < 0 || j >= this->val_(i).GetM())
00524       throw WrongCol("Matrix_ArraySparse::index", "Index should be in [0, " +
00525                      to_str(this->val_(i).GetM()-1) + "], but is equal to "
00526                      + to_str(j) + ".");
00527 #endif
00528 
00529     return val_(i).Index(j);
00530   }
00531 
00532 
00534 
00540   template <class T, class Prop, class Storage, class Allocator>
00541   inline void Matrix_ArraySparse<T, Prop, Storage, Allocator>::
00542   SetData(int i, int n, T* val, int* ind)
00543   {
00544     val_(i).SetData(n, val, ind);
00545   }
00546 
00547 
00549 
00553   template <class T, class Prop, class Storage, class Allocator>
00554   inline void Matrix_ArraySparse<T, Prop, Storage, Allocator>::Nullify(int i)
00555   {
00556     val_(i).Nullify();
00557   }
00558 
00559 
00561 
00566   template <class T, class Prop, class Storage, class Allocator>
00567   inline void Matrix_ArraySparse<T, Prop, Storage, Allocator>::
00568   SetData(int m, int n, Vector<T, VectSparse, Allocator>* val)
00569   {
00570     m_ = m;
00571     n_ = n;
00572     val_.SetData(Storage::GetFirst(m, n), val);
00573   }
00574 
00575 
00577 
00581   template <class T, class Prop, class Storage, class Allocator>
00582   inline void Matrix_ArraySparse<T, Prop, Storage, Allocator>::Nullify()
00583   {
00584     m_ = 0;
00585     n_ = 0;
00586     val_.Nullify();
00587   }
00588 
00589 
00590   /************************
00591    * CONVENIENT FUNCTIONS *
00592    ************************/
00593 
00594 
00596 
00601   template <class T, class Prop, class Storage, class Allocator>
00602   void Matrix_ArraySparse<T, Prop, Storage, Allocator>::Print() const
00603   {
00604     if (Storage::GetFirst(1, 0) == 1)
00605       for (int i = 0; i < this->m_; i++)
00606         {
00607           for (int j = 0; j < this->val_(i).GetM(); j++)
00608             cout << (i+1) << " " << this->val_(i).Index(j)+1
00609                  << " " << this->val_(i).Value(j) << endl;
00610         }
00611     else
00612       for (int i = 0; i < this->n_; i++)
00613         {
00614           for (int j = 0; j < this->val_(i).GetM(); j++)
00615             cout << this->val_(i).Index(j)+1 << " " << i+1
00616                  << " " << this->val_(i).Value(j) << endl;
00617         }
00618   }
00619 
00620 
00622 
00628   template <class T, class Prop, class Storage, class Allocator>
00629   void Matrix_ArraySparse<T, Prop, Storage, Allocator>::Assemble()
00630   {
00631     for (int i = 0; i < val_.GetM(); i++)
00632       val_(i).Assemble();
00633   }
00634 
00635 
00637 
00640   template <class T, class Prop, class Storage, class Allocator>
00641   template<class T0>
00642   void Matrix_ArraySparse<T, Prop, Storage, Allocator>::
00643   RemoveSmallEntry(const T0& epsilon)
00644   {
00645     for (int i = 0; i < val_.GetM(); i++)
00646       val_(i).RemoveSmallEntry(epsilon);
00647   }
00648 
00649 
00651   template <class T, class Prop, class Storage, class Allocator>
00652   inline void Matrix_ArraySparse<T, Prop, Storage, Allocator>::SetIdentity()
00653   {
00654     this->n_ = this->m_;
00655     for (int i = 0; i < this->m_; i++)
00656       {
00657         val_(i).Reallocate(1);
00658         val_(i).Index(0) = i;
00659         val_(i).Value(0) = T(1);
00660       }
00661   }
00662 
00663 
00665   template <class T, class Prop, class Storage, class Allocator>
00666   inline void Matrix_ArraySparse<T, Prop, Storage, Allocator>::Zero()
00667   {
00668     for (int i = 0; i < val_.GetM(); i++)
00669       val_(i).Zero();
00670   }
00671 
00672 
00674   template <class T, class Prop, class Storage, class Allocator>
00675   inline void Matrix_ArraySparse<T, Prop, Storage, Allocator>::Fill()
00676   {
00677     int value = 0;
00678     for (int i = 0; i < val_.GetM(); i++)
00679       for (int j = 0; j < val_(i).GetM(); j++)
00680         val_(i).Value(j) = value++;
00681   }
00682 
00683 
00685   template <class T, class Prop, class Storage, class Allo> template<class T0>
00686   inline void Matrix_ArraySparse<T, Prop, Storage, Allo>::Fill(const T0& x)
00687   {
00688     for (int i = 0; i < val_.GetM(); i++)
00689       val_(i).Fill(x);
00690   }
00691 
00692 
00694   template <class T, class Prop, class Storage, class Allocator>
00695   template <class T0>
00696   inline Matrix_ArraySparse<T, Prop, Storage, Allocator>&
00697   Matrix_ArraySparse<T, Prop, Storage, Allocator>::operator= (const T0& x)
00698   {
00699     this->Fill(x);
00700   }
00701 
00702 
00704   template <class T, class Prop, class Storage, class Allocator>
00705   inline void Matrix_ArraySparse<T, Prop, Storage, Allocator>::FillRand()
00706   {
00707     for (int i = 0; i < val_.GetM(); i++)
00708       val_(i).FillRand();
00709   }
00710 
00711 
00713 
00720   template <class T, class Prop, class Storage, class Allocator>
00721   void Matrix_ArraySparse<T, Prop, Storage, Allocator>::
00722   Write(string FileName) const
00723   {
00724     ofstream FileStream;
00725     FileStream.open(FileName.c_str(), ofstream::binary);
00726 
00727 #ifdef SELDON_CHECK_IO
00728     // Checks if the file was opened.
00729     if (!FileStream.is_open())
00730       throw IOError("Matrix_ArraySparse::Write(string FileName)",
00731                     string("Unable to open file \"") + FileName + "\".");
00732 #endif
00733 
00734     this->Write(FileStream);
00735 
00736     FileStream.close();
00737   }
00738 
00739 
00741 
00748   template <class T, class Prop, class Storage, class Allocator>
00749   void Matrix_ArraySparse<T, Prop, Storage, Allocator>::
00750   Write(ostream& FileStream) const
00751   {
00752 
00753 #ifdef SELDON_CHECK_IO
00754     // Checks if the stream is ready.
00755     if (!FileStream.good())
00756       throw IOError("Matrix_ArraySparse::Write(ofstream& FileStream)",
00757                     "Stream is not ready.");
00758 #endif
00759 
00760     FileStream.write(reinterpret_cast<char*>(const_cast<int*>(&this->m_)),
00761                      sizeof(int));
00762     FileStream.write(reinterpret_cast<char*>(const_cast<int*>(&this->n_)),
00763                      sizeof(int));
00764 
00765     for (int i = 0; i < val_.GetM(); i++)
00766       val_(i).Write(FileStream);
00767   }
00768 
00769 
00771 
00775   template <class T, class Prop, class Storage, class Allocator>
00776   void Matrix_ArraySparse<T, Prop, Storage, Allocator>::
00777   WriteText(string FileName) const
00778   {
00779     ofstream FileStream; FileStream.precision(14);
00780     FileStream.open(FileName.c_str());
00781 
00782 #ifdef SELDON_CHECK_IO
00783     // Checks if the file was opened.
00784     if (!FileStream.is_open())
00785       throw IOError("Matrix_ArraySparse::Write(string FileName)",
00786                     string("Unable to open file \"") + FileName + "\".");
00787 #endif
00788 
00789     this->WriteText(FileStream);
00790 
00791     FileStream.close();
00792   }
00793 
00794 
00796 
00800   template <class T, class Prop, class Storage, class Allocator>
00801   void Matrix_ArraySparse<T, Prop, Storage, Allocator>::
00802   WriteText(ostream& FileStream) const
00803   {
00804 
00805 #ifdef SELDON_CHECK_IO
00806     // Checks if the stream is ready.
00807     if (!FileStream.good())
00808       throw IOError("Matrix_ArraySparse::Write(ofstream& FileStream)",
00809                     "Stream is not ready.");
00810 #endif
00811 
00812     // conversion in coordinate format (1-index convention)
00813     IVect IndRow, IndCol; Vector<T> Value;
00814     const Matrix<T, Prop, Storage, Allocator>& leaf_class =
00815       static_cast<const Matrix<T, Prop, Storage, Allocator>& >(*this);
00816 
00817     ConvertMatrix_to_Coordinates(leaf_class, IndRow, IndCol,
00818                                  Value, 1, true);
00819 
00820     for (int i = 0; i < IndRow.GetM(); i++)
00821       FileStream << IndRow(i) << " " << IndCol(i) << " " << Value(i) << '\n';
00822 
00823     // If the last element a_{m,n} does not exist, we add a zero.
00824     int m = Storage::GetFirst(this->m_, this->n_);
00825     int n = Storage::GetSecond(this->m_, this->n_);
00826     if (m > 0 && n > 0)
00827       {
00828         bool presence_last_elt = false;
00829         if (this->val_(m-1).GetM() > 0)
00830           {
00831             int p = this->val_(m-1).GetM();
00832             if (this->val_(m-1).Index(p-1) == n-1)
00833               presence_last_elt = true;
00834           }
00835 
00836         if (!presence_last_elt)
00837           {
00838             T zero;
00839             SetComplexZero(zero);
00840             FileStream << this->m_ << " " << this->n_ << " " << zero << '\n';
00841           }
00842       }
00843   }
00844 
00845 
00847 
00854   template <class T, class Prop, class Storage, class Allocator>
00855   void Matrix_ArraySparse<T, Prop, Storage, Allocator>::
00856   Read(string FileName)
00857   {
00858     ifstream FileStream;
00859     FileStream.open(FileName.c_str(), ifstream::binary);
00860 
00861 #ifdef SELDON_CHECK_IO
00862     // Checks if the file was opened.
00863     if (!FileStream.is_open())
00864       throw IOError("Matrix_ArraySparse::Read(string FileName)",
00865                     string("Unable to open file \"") + FileName + "\".");
00866 #endif
00867 
00868     this->Read(FileStream);
00869 
00870     FileStream.close();
00871   }
00872 
00873 
00875 
00882   template <class T, class Prop, class Storage, class Allocator>
00883   void Matrix_ArraySparse<T, Prop, Storage, Allocator>::
00884   Read(istream& FileStream)
00885   {
00886 
00887 #ifdef SELDON_CHECK_IO
00888     // Checks if the stream is ready.
00889     if (!FileStream.good())
00890       throw IOError("Matrix_ArraySparse::Read(ofstream& FileStream)",
00891                     "Stream is not ready.");
00892 #endif
00893 
00894     FileStream.read(reinterpret_cast<char*>(const_cast<int*>(&this->m_)),
00895                     sizeof(int));
00896     FileStream.read(reinterpret_cast<char*>(const_cast<int*>(&this->n_)),
00897                     sizeof(int));
00898 
00899     val_.Reallocate(Storage::GetFirst(this->m_, this->n_));
00900     for (int i = 0; i < val_.GetM(); i++)
00901       val_(i).Read(FileStream);
00902 
00903 #ifdef SELDON_CHECK_IO
00904     // Checks if data was read.
00905     if (!FileStream.good())
00906       throw IOError("Matrix_ArraySparse::Read(istream& FileStream)",
00907                     string("Input operation failed.")
00908                     + string(" The input file may have been removed")
00909                     + " or may not contain enough data.");
00910 #endif
00911 
00912   }
00913 
00914 
00916 
00920   template <class T, class Prop, class Storage, class Allocator>
00921   void Matrix_ArraySparse<T, Prop, Storage, Allocator>::
00922   ReadText(string FileName)
00923   {
00924     ifstream FileStream;
00925     FileStream.open(FileName.c_str());
00926 
00927 #ifdef SELDON_CHECK_IO
00928     // Checks if the file was opened.
00929     if (!FileStream.is_open())
00930       throw IOError("Matrix_ArraySparse::ReadText(string FileName)",
00931                     string("Unable to open file \"") + FileName + "\".");
00932 #endif
00933 
00934     this->ReadText(FileStream);
00935 
00936     FileStream.close();
00937   }
00938 
00939 
00941 
00945   template <class T, class Prop, class Storage, class Allocator>
00946   void Matrix_ArraySparse<T, Prop, Storage, Allocator>::
00947   ReadText(istream& FileStream)
00948   {
00949     Matrix<T, Prop, Storage, Allocator>& leaf_class =
00950       static_cast<Matrix<T, Prop, Storage, Allocator>& >(*this);
00951 
00952     T zero; int index = 1;
00953     ReadCoordinateMatrix(leaf_class, FileStream, zero, index);
00954   }
00955 
00956 
00958   // MATRIX<ARRAY_COLSPARSE> //
00960 
00961 
00963 
00966   template <class T, class Prop, class Allocator>
00967   inline Matrix<T, Prop, ArrayColSparse, Allocator>::Matrix():
00968     Matrix_ArraySparse<T, Prop, ArrayColSparse, Allocator>()
00969   {
00970   }
00971 
00972 
00974 
00979   template <class T, class Prop, class Allocator>
00980   inline Matrix<T, Prop, ArrayColSparse, Allocator>::Matrix(int i, int j):
00981     Matrix_ArraySparse<T, Prop, ArrayColSparse, Allocator>(i, j)
00982   {
00983   }
00984 
00985 
00987   template <class T, class Prop, class Allocator>
00988   inline void Matrix<T, Prop, ArrayColSparse, Allocator>::ClearColumn(int i)
00989   {
00990     this->val_(i).Clear();
00991   }
00992 
00993 
00995 
00999   template <class T, class Prop, class Alloc> inline
01000   void Matrix<T, Prop, ArrayColSparse, Alloc>::ReallocateColumn(int i,int j)
01001   {
01002     this->val_(i).Reallocate(j);
01003   }
01004 
01005 
01007 
01011   template <class T, class Prop, class Allocator> inline
01012   void Matrix<T, Prop, ArrayColSparse, Allocator>::ResizeColumn(int i,int j)
01013   {
01014     this->val_(i).Resize(j);
01015   }
01016 
01017 
01019 
01023   template <class T, class Prop, class Allocator> inline
01024   void Matrix<T, Prop, ArrayColSparse, Allocator>::SwapColumn(int i,int j)
01025   {
01026     Swap(this->val_(i), this->val_(j));
01027   }
01028 
01029 
01031 
01035   template <class T, class Prop, class Allocator>
01036   inline void Matrix<T, Prop, ArrayColSparse, Allocator>::
01037   ReplaceIndexColumn(int i, IVect& new_index)
01038   {
01039     for (int j = 0; j < this->val_(i).GetM(); j++)
01040       this->val_(i).Index(j) = new_index(j);
01041   }
01042 
01043 
01045 
01049   template <class T, class Prop, class Allocator>
01050   inline int Matrix<T, Prop, ArrayColSparse, Allocator>::
01051   GetColumnSize(int i) const
01052   {
01053     return this->val_(i).GetSize();
01054   }
01055 
01056 
01058   template <class T, class Prop, class Allocator> inline
01059   void Matrix<T, Prop, ArrayColSparse, Allocator>::PrintColumn(int i) const
01060   {
01061     this->val_(i).Print();
01062   }
01063 
01064 
01066 
01071   template <class T, class Prop, class Allocator> inline
01072   void Matrix<T, Prop, ArrayColSparse, Allocator>::AssembleColumn(int i)
01073   {
01074     this->val_(i).Assemble();
01075   }
01076 
01077 
01079 
01084   template <class T, class Prop, class Allocator>
01085   inline void Matrix<T, Prop, ArrayColSparse, Allocator>::
01086   AddInteraction(int i, int j, const T& val)
01087   {
01088     this->val_(j).AddInteraction(i, val);
01089   }
01090 
01091 
01093 
01099   template <class T, class Prop, class Allocator>
01100   inline void Matrix<T, Prop, ArrayColSparse, Allocator>::
01101   AddInteractionRow(int i, int nb, int* col_, T* value_)
01102   {
01103     IVect col;
01104     col.SetData(nb, col_);
01105     Vector<T> val;
01106     val.SetData(nb, value_);
01107     AddInteractionRow(i, nb, col, val);
01108     col.Nullify();
01109     val.Nullify();
01110   }
01111 
01112 
01114 
01120   template <class T, class Prop, class Allocator>
01121   inline void Matrix<T, Prop, ArrayColSparse, Allocator>::
01122   AddInteractionColumn(int i, int nb, int* row_, T* value_)
01123   {
01124     IVect row;
01125     row.SetData(nb, row_);
01126     Vector<T> val;
01127     val.SetData(nb, value_);
01128     AddInteractionColumn(i, nb, row, val);
01129     row.Nullify();
01130     val.Nullify();
01131   }
01132 
01133 
01135 
01141   template <class T, class Prop, class Allocator> template <class Alloc1>
01142   inline void Matrix<T, Prop, ArrayColSparse, Allocator>::
01143   AddInteractionRow(int i, int nb, const IVect& col,
01144                     const Vector<T, VectFull, Alloc1>& val)
01145   {
01146     for (int j = 0; j < nb; j++)
01147       this->val_(col(j)).AddInteraction(i, val(j));
01148   }
01149 
01150 
01152 
01158   template <class T, class Prop, class Allocator> template <class Alloc1>
01159   inline void Matrix<T, Prop, ArrayColSparse, Allocator>::
01160   AddInteractionColumn(int i, int nb, const IVect& row,
01161                        const Vector<T, VectFull, Alloc1>& val)
01162   {
01163     this->val_(i).AddInteractionRow(nb, row, val);
01164   }
01165 
01166 
01168   // MATRIX<ARRAY_ROWSPARSE> //
01170 
01171 
01173 
01176   template <class T, class Prop, class Allocator>
01177   inline Matrix<T, Prop, ArrayRowSparse, Allocator>::Matrix():
01178     Matrix_ArraySparse<T, Prop, ArrayRowSparse, Allocator>()
01179   {
01180   }
01181 
01182 
01184 
01189   template <class T, class Prop, class Allocator>
01190   inline Matrix<T, Prop, ArrayRowSparse, Allocator>::Matrix(int i, int j):
01191     Matrix_ArraySparse<T, Prop, ArrayRowSparse, Allocator>(i, j)
01192   {
01193   }
01194 
01195 
01197   template <class T, class Prop, class Allocator>
01198   inline void Matrix<T, Prop, ArrayRowSparse, Allocator>::ClearRow(int i)
01199   {
01200     this->val_(i).Clear();
01201   }
01202 
01203 
01205 
01210   template <class T, class Prop, class Allocator>
01211   inline void Matrix<T, Prop, ArrayRowSparse, Allocator>::
01212   ReallocateRow(int i, int j)
01213   {
01214     this->val_(i).Reallocate(j);
01215   }
01216 
01217 
01219 
01224   template <class T, class Prop, class Allocator> inline
01225   void Matrix<T, Prop, ArrayRowSparse, Allocator>::ResizeRow(int i, int j)
01226   {
01227     this->val_(i).Resize(j);
01228   }
01229 
01230 
01232 
01236   template <class T, class Prop, class Allocator>
01237   inline void Matrix<T, Prop, ArrayRowSparse, Allocator>::SwapRow(int i,int j)
01238   {
01239     Swap(this->val_(i), this->val_(j));
01240   }
01241 
01242 
01244 
01248   template <class T, class Prop, class Allocator>
01249   inline void Matrix<T, Prop, ArrayRowSparse, Allocator>::
01250   ReplaceIndexRow(int i, IVect& new_index)
01251   {
01252     for (int j = 0; j < this->val_(i).GetM(); j++)
01253       this->val_(i).Index(j) = new_index(j);
01254   }
01255 
01256 
01258 
01262   template <class T, class Prop, class Allocator> inline
01263   int Matrix<T, Prop, ArrayRowSparse, Allocator>::GetRowSize(int i) const
01264   {
01265     return this->val_(i).GetSize();
01266   }
01267 
01268 
01270   template <class T, class Prop, class Allocator> inline
01271   void Matrix<T, Prop, ArrayRowSparse, Allocator>::PrintRow(int i) const
01272   {
01273     this->val_(i).Print();
01274   }
01275 
01276 
01278 
01283   template <class T, class Prop, class Allocator>
01284   inline void Matrix<T, Prop, ArrayRowSparse, Allocator>::AssembleRow(int i)
01285   {
01286     this->val_(i).Assemble();
01287   }
01288 
01290 
01295   template <class T, class Prop, class Allocator>
01296   inline void Matrix<T, Prop, ArrayRowSparse, Allocator>::
01297   AddInteraction(int i, int j, const T& val)
01298   {
01299     this->val_(i).AddInteraction(j, val);
01300   }
01301 
01302 
01304 
01310   template <class T, class Prop, class Allocator>
01311   inline void Matrix<T, Prop, ArrayRowSparse, Allocator>::
01312   AddInteractionRow(int i, int nb, int* col_, T* value_)
01313   {
01314     IVect col;
01315     col.SetData(nb, col_);
01316     Vector<T> val;
01317     val.SetData(nb, value_);
01318     AddInteractionRow(i, nb, col, val);
01319     col.Nullify();
01320     val.Nullify();
01321   }
01322 
01323 
01325 
01331   template <class T, class Prop, class Allocator>
01332   inline void Matrix<T, Prop, ArrayRowSparse, Allocator>::
01333   AddInteractionColumn(int i, int nb, int* row_, T* value_)
01334   {
01335     IVect row;
01336     row.SetData(nb, row_);
01337     Vector<T> val;
01338     val.SetData(nb, value_);
01339     AddInteractionColumn(i, nb, row, val);
01340     row.Nullify();
01341     val.Nullify();
01342   }
01343 
01344 
01346 
01352   template <class T, class Prop, class Allocator> template <class Alloc1>
01353   inline void Matrix<T, Prop, ArrayRowSparse, Allocator>::
01354   AddInteractionRow(int i, int nb, const IVect& col,
01355                     const Vector<T, VectFull, Alloc1>& val)
01356   {
01357     this->val_(i).AddInteractionRow(nb, col, val);
01358   }
01359 
01360 
01362 
01368   template <class T, class Prop, class Allocator> template <class Alloc1>
01369   inline void Matrix<T, Prop, ArrayRowSparse, Allocator>::
01370   AddInteractionColumn(int i, int nb, const IVect& row,
01371                        const Vector<T, VectFull, Alloc1>& val)
01372   {
01373     for (int j = 0; j < nb; j++)
01374       this->val_(row(j)).AddInteraction(i, val(j));
01375   }
01376 
01377 
01379   // MATRIX<ARRAY_COLSYMSPARSE> //
01381 
01382 
01384 
01387   template <class T, class Prop, class Allocator>
01388   inline Matrix<T, Prop, ArrayColSymSparse, Allocator>::Matrix():
01389     Matrix_ArraySparse<T, Prop, ArrayColSymSparse, Allocator>()
01390   {
01391   }
01392 
01393 
01395 
01400   template <class T, class Prop, class Allocator>
01401   inline Matrix<T, Prop, ArrayColSymSparse, Allocator>::Matrix(int i, int j):
01402     Matrix_ArraySparse<T, Prop, ArrayColSymSparse, Allocator>(i, j)
01403   {
01404   }
01405 
01406 
01407   /**********************************
01408    * ELEMENT ACCESS AND AFFECTATION *
01409    **********************************/
01410 
01411 
01413 
01419   template <class T, class Prop, class Allocator>
01420   inline T
01421   Matrix<T, Prop, ArrayColSymSparse, Allocator>::operator() (int i, int j)
01422     const
01423   {
01424 
01425 #ifdef SELDON_CHECK_BOUNDS
01426     if (i < 0 || i >= this->m_)
01427       throw WrongRow("Matrix::operator()", "Index should be in [0, "
01428                      + to_str(this->m_-1) + "], but is equal to "
01429                      + to_str(i) + ".");
01430     if (j < 0 || j >= this->n_)
01431       throw WrongCol("Matrix::operator()", "Index should be in [0, "
01432                      + to_str(this->n_-1) + "], but is equal to "
01433                      + to_str(j) + ".");
01434 #endif
01435 
01436     if (i < j)
01437       return this->val_(j)(i);
01438 
01439     return this->val_(i)(j);
01440   }
01441 
01442 
01444 
01450   template <class T, class Prop, class Allocator>
01451   inline T&
01452   Matrix<T, Prop, ArrayColSymSparse, Allocator>::Get(int i, int j)
01453   {
01454 
01455 #ifdef SELDON_CHECK_BOUNDS
01456     if (i < 0 || i >= this->m_)
01457       throw WrongRow("Matrix::operator()", "Index should be in [0, "
01458                      + to_str(this->m_-1) + "], but is equal to "
01459                      + to_str(i) + ".");
01460     if (j < 0 || j >= this->n_)
01461       throw WrongCol("Matrix::operator()", "Index should be in [0, "
01462                      + to_str(this->n_-1) + "], but is equal to "
01463                      + to_str(j) + ".");
01464 #endif
01465 
01466     if (i < j)
01467       return this->val_(j).Get(i);
01468 
01469     return this->val_(i).Get(j);
01470   }
01471 
01472 
01474 
01480   template <class T, class Prop, class Allocator>
01481   inline const T&
01482   Matrix<T, Prop, ArrayColSymSparse, Allocator>::Get(int i, int j) const
01483   {
01484 
01485 #ifdef SELDON_CHECK_BOUNDS
01486     if (i < 0 || i >= this->m_)
01487       throw WrongRow("Matrix::operator()", "Index should be in [0, "
01488                      + to_str(this->m_-1) + "], but is equal to "
01489                      + to_str(i) + ".");
01490     if (j < 0 || j >= this->n_)
01491       throw WrongCol("Matrix::operator()", "Index should be in [0, "
01492                      + to_str(this->n_-1) + "], but is equal to "
01493                      + to_str(j) + ".");
01494 #endif
01495 
01496     if (i < j)
01497       return this->val_(j).Get(i);
01498 
01499     return this->val_(i).Get(j);
01500   }
01501 
01502 
01504 
01510   template <class T, class Prop, class Allocator>
01511   inline T&
01512   Matrix<T, Prop, ArrayColSymSparse, Allocator>::Val(int i, int j)
01513   {
01514 
01515 #ifdef SELDON_CHECK_BOUNDS
01516     if (i < 0 || i >= this->m_)
01517       throw WrongRow("Matrix::operator()", "Index should be in [0, "
01518                      + to_str(this->m_-1) + "], but is equal to "
01519                      + to_str(i) + ".");
01520     if (j < 0 || j >= this->n_)
01521       throw WrongCol("Matrix::operator()", "Index should be in [0, "
01522                      + to_str(this->n_-1) + "], but is equal to "
01523                      + to_str(j) + ".");
01524     if (i > j)
01525       throw WrongArgument("Matrix::Val()", string("With this function, you ")
01526                           + "can only access upper part of matrix.");
01527 #endif
01528 
01529     return this->val_(j).Val(i);
01530   }
01531 
01532 
01534 
01540   template <class T, class Prop, class Allocator>
01541   inline const T&
01542   Matrix<T, Prop, ArrayColSymSparse, Allocator>::Val(int i, int j) const
01543   {
01544 
01545 #ifdef SELDON_CHECK_BOUNDS
01546     if (i < 0 || i >= this->m_)
01547       throw WrongRow("Matrix::operator()", "Index should be in [0, "
01548                      + to_str(this->m_-1) + "], but is equal to "
01549                      + to_str(i) + ".");
01550     if (j < 0 || j >= this->n_)
01551       throw WrongCol("Matrix::operator()", "Index should be in [0, "
01552                      + to_str(this->n_-1) + "], but is equal to "
01553                      + to_str(j) + ".");
01554 #endif
01555 
01556     return this->val_(j).Val(i);
01557   }
01558 
01559 
01561 
01566   template <class T, class Prop, class Allocator>
01567   inline void
01568   Matrix<T, Prop, ArrayColSymSparse, Allocator>::Set(int i, int j, const T& x)
01569   {
01570     if (i < j)
01571       this->val_(j).Get(i) = x;
01572     else
01573       this->val_(i).Get(j) = x;
01574   }
01575 
01576 
01578   template <class T, class Prop, class Allocator> inline
01579   void Matrix<T, Prop, ArrayColSymSparse, Allocator>::ClearColumn(int i)
01580   {
01581     this->val_(i).Clear();
01582   }
01583 
01584 
01586 
01591   template <class T, class Prop, class Allocator>
01592   inline void Matrix<T, Prop, ArrayColSymSparse, Allocator>::
01593   ReallocateColumn(int i, int j)
01594   {
01595     this->val_(i).Reallocate(j);
01596   }
01597 
01598 
01600 
01604   template <class T, class Prop, class Allocator>
01605   inline void Matrix<T, Prop, ArrayColSymSparse, Allocator>::
01606   ResizeColumn(int i, int j)
01607   {
01608     this->val_(i).Resize(j);
01609   }
01610 
01611 
01613 
01617   template <class T, class Prop, class Allocator>
01618   inline void Matrix<T, Prop, ArrayColSymSparse, Allocator>::
01619   SwapColumn(int i, int j)
01620   {
01621     Swap(this->val_(i), this->val_(j));
01622   }
01623 
01624 
01626 
01630   template <class T, class Prop, class Allocator>
01631   inline void Matrix<T, Prop, ArrayColSymSparse, Allocator>::
01632   ReplaceIndexColumn(int i, IVect& new_index)
01633   {
01634     for (int j = 0; j < this->val_(i).GetM(); j++)
01635       this->val_(i).Index(j) = new_index(j);
01636   }
01637 
01638 
01640 
01644   template <class T, class Prop, class Allocator>
01645   inline int Matrix<T, Prop, ArrayColSymSparse, Allocator>::
01646   GetColumnSize(int i) const
01647   {
01648     return this->val_(i).GetSize();
01649   }
01650 
01651 
01653   template <class T, class Prop, class Allocator>
01654   inline void Matrix<T, Prop, ArrayColSymSparse, Allocator>::
01655   PrintColumn(int i) const
01656   {
01657     this->val_(i).Print();
01658   }
01659 
01660 
01662 
01667   template <class T, class Prop, class Allocator>
01668   inline void Matrix<T, Prop, ArrayColSymSparse, Allocator>::
01669   AssembleColumn(int i)
01670   {
01671     this->val_(i).Assemble();
01672   }
01673 
01674 
01676 
01682   template <class T, class Prop, class Allocator>
01683   inline void Matrix<T, Prop, ArrayColSymSparse, Allocator>::
01684   AddInteractionRow(int i, int nb, int* col_, T* value_)
01685   {
01686     IVect col;
01687     col.SetData(nb, col_);
01688     Vector<T> val;
01689     val.SetData(nb, value_);
01690     AddInteractionRow(i, nb, col, val);
01691     col.Nullify();
01692     val.Nullify();
01693   }
01694 
01695 
01697 
01703   template <class T, class Prop, class Allocator>
01704   inline void Matrix<T, Prop, ArrayColSymSparse, Allocator>::
01705   AddInteractionColumn(int i, int nb, int* row_, T* value_)
01706   {
01707     IVect row;
01708     row.SetData(nb, row_);
01709     Vector<T> val;
01710     val.SetData(nb, value_);
01711     AddInteractionColumn(i, nb, row, val);
01712     row.Nullify();
01713     val.Nullify();
01714   }
01715 
01716 
01718 
01723   template <class T, class Prop, class Allocator>
01724   inline void Matrix<T, Prop, ArrayColSymSparse, Allocator>::
01725   AddInteraction(int i, int j, const T& val)
01726   {
01727     if (i <= j)
01728       this->val_(j).AddInteraction(i, val);
01729   }
01730 
01731 
01733 
01739   template <class T, class Prop, class Allocator> template <class Alloc1>
01740   inline void Matrix<T, Prop, ArrayColSymSparse, Allocator>::
01741   AddInteractionRow(int i, int nb, const IVect& col,
01742                     const Vector<T, VectFull, Alloc1>& val)
01743   {
01744     for (int j = 0; j < nb; j++)
01745       if (i <= col(j))
01746         this->val_(col(j)).AddInteraction(i, val(j));
01747   }
01748 
01749 
01751 
01757   template <class T, class Prop, class Allocator> template <class Alloc1>
01758   inline void Matrix<T, Prop, ArrayColSymSparse, Allocator>::
01759   AddInteractionColumn(int i, int nb, const IVect& row,
01760                        const Vector<T, VectFull, Alloc1>& val)
01761   {
01762     IVect new_row(nb);
01763     Vector<T, VectFull, Alloc1> new_val(nb);
01764     nb = 0;
01765     for (int j = 0; j < new_row.GetM(); j++)
01766       if (row(j) <= i)
01767         {
01768           new_row(nb) = row(j);
01769           new_val(nb) = val(j); nb++;
01770         }
01771 
01772     this->val_(i).AddInteractionRow(nb, new_row, new_val);
01773   }
01774 
01775 
01777   // MATRIX<ARRAY_ROWSYMSPARSE> //
01779 
01780 
01782 
01785   template <class T, class Prop, class Allocator>
01786   inline Matrix<T, Prop, ArrayRowSymSparse, Allocator>::Matrix():
01787     Matrix_ArraySparse<T, Prop, ArrayRowSymSparse, Allocator>()
01788   {
01789   }
01790 
01791 
01793 
01798   template <class T, class Prop, class Allocator>
01799   inline Matrix<T, Prop, ArrayRowSymSparse, Allocator>::Matrix(int i, int j):
01800     Matrix_ArraySparse<T, Prop, ArrayRowSymSparse, Allocator>(i, j)
01801   {
01802   }
01803 
01804 
01805   /**********************************
01806    * ELEMENT ACCESS AND AFFECTATION *
01807    **********************************/
01808 
01809 
01811 
01817   template <class T, class Prop, class Allocator>
01818   inline T
01819   Matrix<T, Prop, ArrayRowSymSparse, Allocator>::operator() (int i, int j)
01820     const
01821   {
01822 
01823 #ifdef SELDON_CHECK_BOUNDS
01824     if (i < 0 || i >= this->m_)
01825       throw WrongRow("Matrix_ArraySparse::operator()",
01826                      "Index should be in [0, "
01827                      + to_str(this->m_-1) + "], but is equal to "
01828                      + to_str(i) + ".");
01829     if (j < 0 || j >= this->n_)
01830       throw WrongCol("Matrix_ArraySparse::operator()",
01831                      "Index should be in [0, "
01832                      + to_str(this->n_-1) + "], but is equal to "
01833                      + to_str(j) + ".");
01834 #endif
01835 
01836     if (i < j)
01837       return this->val_(i)(j);
01838 
01839     return this->val_(j)(i);
01840   }
01841 
01842 
01844 
01850   template <class T, class Prop, class Allocator>
01851   inline T&
01852   Matrix<T, Prop, ArrayRowSymSparse, Allocator>::Get(int i, int j)
01853   {
01854 
01855 #ifdef SELDON_CHECK_BOUNDS
01856     if (i < 0 || i >= this->m_)
01857       throw WrongRow("Matrix::operator()", "Index should be in [0, "
01858                      + to_str(this->m_-1) + "], but is equal to "
01859                      + to_str(i) + ".");
01860     if (j < 0 || j >= this->n_)
01861       throw WrongCol("Matrix::operator()", "Index should be in [0, "
01862                      + to_str(this->n_-1) + "], but is equal to "
01863                      + to_str(j) + ".");
01864 #endif
01865 
01866     if (i < j)
01867       return this->val_(i).Get(j);
01868 
01869     return this->val_(j).Get(i);
01870   }
01871 
01872 
01874 
01880   template <class T, class Prop, class Allocator>
01881   inline const T&
01882   Matrix<T, Prop, ArrayRowSymSparse, Allocator>::Get(int i, int j) const
01883   {
01884 
01885 #ifdef SELDON_CHECK_BOUNDS
01886     if (i < 0 || i >= this->m_)
01887       throw WrongRow("Matrix::operator()", "Index should be in [0, "
01888                      + to_str(this->m_-1) + "], but is equal to "
01889                      + to_str(i) + ".");
01890     if (j < 0 || j >= this->n_)
01891       throw WrongCol("Matrix::operator()", "Index should be in [0, "
01892                      + to_str(this->n_-1) + "], but is equal to "
01893                      + to_str(j) + ".");
01894 #endif
01895 
01896     if (i < j)
01897       return this->val_(i).Get(j);
01898 
01899     return this->val_(j).Get(i);
01900   }
01901 
01902 
01904 
01910   template <class T, class Prop, class Allocator>
01911   inline T&
01912   Matrix<T, Prop, ArrayRowSymSparse, Allocator>::Val(int i, int j)
01913   {
01914 
01915 #ifdef SELDON_CHECK_BOUNDS
01916     if (i < 0 || i >= this->m_)
01917       throw WrongRow("Matrix::operator()", "Index should be in [0, "
01918                      + to_str(this->m_-1) + "], but is equal to "
01919                      + to_str(i) + ".");
01920     if (j < 0 || j >= this->n_)
01921       throw WrongCol("Matrix::operator()", "Index should be in [0, "
01922                      + to_str(this->n_-1) + "], but is equal to "
01923                      + to_str(j) + ".");
01924     if (i > j)
01925       throw WrongArgument("Matrix::Val()", string("With this function, you ")
01926                           + "can only access upper part of matrix.");
01927 #endif
01928 
01929     return this->val_(i).Val(j);
01930   }
01931 
01932 
01934 
01940   template <class T, class Prop, class Allocator>
01941   inline const T&
01942   Matrix<T, Prop, ArrayRowSymSparse, Allocator>::Val(int i, int j) const
01943   {
01944 
01945 #ifdef SELDON_CHECK_BOUNDS
01946     if (i < 0 || i >= this->m_)
01947       throw WrongRow("Matrix::operator()", "Index should be in [0, "
01948                      + to_str(this->m_-1) + "], but is equal to "
01949                      + to_str(i) + ".");
01950     if (j < 0 || j >= this->n_)
01951       throw WrongCol("Matrix::operator()", "Index should be in [0, "
01952                      + to_str(this->n_-1) + "], but is equal to "
01953                      + to_str(j) + ".");
01954     if (i > j)
01955       throw WrongArgument("Matrix::Val()", string("With this function, you ")
01956                           + "can only access upper part of matrix.");
01957 #endif
01958 
01959     return this->val_(i).Val(j);
01960   }
01961 
01962 
01964 
01969   template <class T, class Prop, class Allocator>
01970   inline void
01971   Matrix<T, Prop, ArrayRowSymSparse, Allocator>::Set(int i, int j, const T& x)
01972   {
01973     if (i < j)
01974       this->val_(i).Get(j) = x;
01975     else
01976       this->val_(j).Get(i) = x;
01977   }
01978 
01979 
01981   template <class T, class Prop, class Allocator>
01982   inline void Matrix<T, Prop, ArrayRowSymSparse, Allocator>::ClearRow(int i)
01983   {
01984     this->val_(i).Clear();
01985   }
01986 
01987 
01989 
01994   template <class T, class Prop, class Allocator>
01995   inline void Matrix<T, Prop, ArrayRowSymSparse, Allocator>::
01996   ReallocateRow(int i,int j)
01997   {
01998     this->val_(i).Reallocate(j);
01999   }
02000 
02001 
02003 
02007   template <class T, class Prop, class Allocator>
02008   inline void Matrix<T, Prop, ArrayRowSymSparse, Allocator>::
02009   ResizeRow(int i,int j)
02010   {
02011     this->val_(i).Resize(j);
02012   }
02013 
02014 
02016 
02020   template <class T, class Prop, class Allocator>
02021   inline void Matrix<T, Prop, ArrayRowSymSparse, Allocator>::
02022   SwapRow(int i,int j)
02023   {
02024     Swap(this->val_(i), this->val_(j));
02025   }
02026 
02027 
02029 
02033   template <class T, class Prop, class Allocator>
02034   inline void Matrix<T, Prop, ArrayRowSymSparse, Allocator>::
02035   ReplaceIndexRow(int i,IVect& new_index)
02036   {
02037     for (int j = 0; j < this->val_(i).GetM(); j++)
02038       this->val_(i).Index(j) = new_index(j);
02039   }
02040 
02041 
02043 
02047   template <class T, class Prop, class Allocator>
02048   inline int Matrix<T, Prop, ArrayRowSymSparse, Allocator>::GetRowSize(int i)
02049     const
02050   {
02051     return this->val_(i).GetSize();
02052   }
02053 
02054 
02056   template <class T, class Prop, class Allocator>
02057   inline void Matrix<T, Prop, ArrayRowSymSparse, Allocator>::PrintRow(int i)
02058     const
02059   {
02060     this->val_(i).Print();
02061   }
02062 
02063 
02065 
02070   template <class T, class Prop, class Allocator>
02071   inline void Matrix<T, Prop, ArrayRowSymSparse, Allocator>
02072   ::AssembleRow(int i)
02073   {
02074     this->val_(i).Assemble();
02075   }
02076 
02077 
02079 
02084   template <class T, class Prop, class Allocator>
02085   inline void Matrix<T, Prop, ArrayRowSymSparse, Allocator>::
02086   AddInteraction(int i, int j, const T& val)
02087   {
02088     if (i <= j)
02089       this->val_(i).AddInteraction(j, val);
02090   }
02091 
02092 
02094 
02100   template <class T, class Prop, class Allocator>
02101   inline void Matrix<T, Prop, ArrayRowSymSparse, Allocator>::
02102   AddInteractionRow(int i, int nb, int* col_, T* value_)
02103   {
02104     IVect col;
02105     col.SetData(nb, col_);
02106     Vector<T> val;
02107     val.SetData(nb, value_);
02108     AddInteractionRow(i, nb, col, val);
02109     col.Nullify();
02110     val.Nullify();
02111   }
02112 
02113 
02115 
02121   template <class T, class Prop, class Allocator>
02122   inline void Matrix<T, Prop, ArrayRowSymSparse, Allocator>::
02123   AddInteractionColumn(int i, int nb, int* row_, T* value_)
02124   {
02125     IVect row;
02126     row.SetData(nb, row_);
02127     Vector<T> val;
02128     val.SetData(nb, value_);
02129     AddInteractionColumn(i, nb, row, val);
02130     row.Nullify();
02131     val.Nullify();
02132   }
02133 
02134 
02136 
02142   template <class T, class Prop, class Allocator> template <class Alloc1>
02143   inline void Matrix<T, Prop, ArrayRowSymSparse, Allocator>::
02144   AddInteractionRow(int i, int nb, const IVect& col,
02145                     const Vector<T, VectFull, Alloc1>& val)
02146   {
02147     IVect new_col(nb);
02148     Vector<T, VectFull, Alloc1> new_val(nb);
02149     nb = 0;
02150     for (int j = 0; j < new_col.GetM(); j++)
02151       if (i <= col(j))
02152         {
02153           new_col(nb) = col(j);
02154           new_val(nb) = val(j); nb++;
02155         }
02156 
02157     this->val_(i).AddInteractionRow(nb, new_col, new_val);
02158   }
02159 
02160 
02162 
02168   template <class T, class Prop, class Allocator> template <class Alloc1>
02169   inline void Matrix<T, Prop, ArrayRowSymSparse, Allocator>::
02170   AddInteractionColumn(int i, int nb, const IVect& row,
02171                        const Vector<T,VectFull,Alloc1>& val)
02172   {
02173     for (int j = 0; j < nb; j++)
02174       if (row(j) <= i)
02175         this->val_(row(j)).AddInteraction(i, val(j));
02176   }
02177 
02178 
02179   template <class T, class Prop, class Allocator>
02180   ostream& operator <<(ostream& out,
02181                        const Matrix<T, Prop, ArrayRowSparse, Allocator>& A)
02182   {
02183     A.WriteText(out);
02184 
02185     return out;
02186   }
02187 
02188 
02189   template <class T, class Prop, class Allocator>
02190   ostream& operator <<(ostream& out,
02191                        const Matrix<T, Prop, ArrayColSparse, Allocator>& A)
02192   {
02193     A.WriteText(out);
02194 
02195     return out;
02196   }
02197 
02198 
02199   template <class T, class Prop, class Allocator>
02200   ostream& operator <<(ostream& out,
02201                        const Matrix<T, Prop, ArrayRowSymSparse, Allocator>& A)
02202   {
02203     A.WriteText(out);
02204 
02205     return out;
02206   }
02207 
02208 
02209   template <class T, class Prop, class Allocator>
02210   ostream& operator <<(ostream& out,
02211                        const Matrix<T, Prop, ArrayColSymSparse, Allocator>& A)
02212   {
02213     A.WriteText(out);
02214 
02215     return out;
02216   }
02217 
02218 
02219 } // namespace Seldon
02220 
02221 #define SELDON_FILE_MATRIX_ARRAY_SPARSE_CXX
02222 #endif