matrix_sparse/Matrix_ArraySparse.cxx

00001 // Copyright (C) 2003-2009 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>::operator() (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))(Storage::GetSecond(i, j));
00323   }
00324 
00325 
00327 
00332   template <class T, class Prop, class Storage, class Allocator>
00333   inline T&
00334   Matrix_ArraySparse<T, Prop, Storage, Allocator>::Val(int i, int j)
00335   {
00336 
00337 #ifdef SELDON_CHECK_BOUNDS
00338     if (i < 0 || i >= this->m_)
00339       throw WrongRow("Matrix_ArraySparse::operator()",
00340                      "Index should be in [0, " + to_str(this->m_-1) +
00341                      "], but is equal to " + to_str(i) + ".");
00342 
00343     if (j < 0 || j >= this->n_)
00344       throw WrongCol("Matrix_ArraySparse::operator()",
00345                      "Index should be in [0, " + to_str(this->n_-1) +
00346                      "], but is equal to " + to_str(j) + ".");
00347 #endif
00348 
00349     return
00350       this->val_(Storage::GetFirst(i, j)).Val(Storage::GetSecond(i, j));
00351   }
00352 
00353 
00355 
00360   template <class T, class Prop, class Storage, class Allocator>
00361   inline const T&
00362   Matrix_ArraySparse<T, Prop, Storage, Allocator>::Val(int i, int j) const
00363   {
00364 
00365 #ifdef SELDON_CHECK_BOUNDS
00366     if (i < 0 || i >= this->m_)
00367       throw WrongRow("Matrix_ArraySparse::operator()",
00368                      "Index should be in [0, " + to_str(this->m_-1) +
00369                      "], but is equal to " + to_str(i) + ".");
00370 
00371     if (j < 0 || j >= this->n_)
00372       throw WrongCol("Matrix_ArraySparse::operator()",
00373                      "Index should be in [0, " + to_str(this->n_-1) +
00374                      "], but is equal to " + to_str(j) + ".");
00375 #endif
00376 
00377     return
00378       this->val_(Storage::GetFirst(i, j)).Val(Storage::GetSecond(i, j));
00379   }
00380 
00381 
00383 
00388   template <class T, class Prop, class Storage, class Allocator>
00389   inline const T& Matrix_ArraySparse<T, Prop, Storage, Allocator>::
00390   Value (int i, int j) const
00391   {
00392 
00393 #ifdef SELDON_CHECK_BOUNDS
00394     if (i < 0 || i >= this->m_)
00395       throw WrongRow("Matrix_ArraySparse::value", "Index should be in [0, "
00396                      + to_str(this->m_-1) + "], but is equal to "
00397                      + to_str(i) + ".");
00398 
00399     if ((j < 0)||(j >= this->val_(i).GetM()))
00400       throw WrongCol("Matrix_ArraySparse::value", "Index should be in [0, " +
00401                      to_str(this->val_(i).GetM()-1) + "], but is equal to "
00402                      + to_str(j) + ".");
00403 #endif
00404 
00405     return val_(i).Value(j);
00406   }
00407 
00408 
00410 
00415   template <class T, class Prop, class Storage, class Allocator>
00416   inline T&
00417   Matrix_ArraySparse<T, Prop, Storage, Allocator>::Value (int i, int j)
00418   {
00419 
00420 #ifdef SELDON_CHECK_BOUNDS
00421     if (i < 0 || i >= this->m_)
00422       throw WrongRow("Matrix_ArraySparse::value", "Index should be in [0, "
00423                      + to_str(this->m_-1) + "], but is equal to "
00424                      + to_str(i) + ".");
00425 
00426     if ((j < 0)||(j >= this->val_(i).GetM()))
00427       throw WrongCol("Matrix_ArraySparse::value", "Index should be in [0, " +
00428                      to_str(this->val_(i).GetM()-1) + "], but is equal to "
00429                      + to_str(j) + ".");
00430 #endif
00431 
00432     return val_(i).Value(j);
00433   }
00434 
00435 
00437 
00442   template <class T, class Prop, class Storage, class Allocator> inline
00443   int Matrix_ArraySparse<T, Prop, Storage, Allocator>::Index(int i, int j)
00444     const
00445   {
00446 
00447 #ifdef SELDON_CHECK_BOUNDS
00448     if (i < 0 || i >= this->m_)
00449       throw WrongRow("Matrix_ArraySparse::index", "Index should be in [0, "
00450                      + to_str(this->m_-1) + "], but is equal to "
00451                      + to_str(i) + ".");
00452 
00453     if ((j < 0)||(j >= this->val_(i).GetM()))
00454       throw WrongCol("Matrix_ArraySparse::index", "Index should be in [0, " +
00455                      to_str(this->val_(i).GetM()-1) + "], but is equal to "
00456                      + to_str(j) + ".");
00457 #endif
00458 
00459     return val_(i).Index(j);
00460   }
00461 
00462 
00464 
00469   template <class T, class Prop, class Storage, class Allocator> inline
00470   int& Matrix_ArraySparse<T, Prop, Storage, Allocator>::Index(int i, int j)
00471   {
00472 
00473 #ifdef SELDON_CHECK_BOUNDS
00474     if (i < 0 || i >= this->m_)
00475       throw WrongRow("Matrix_ArraySparse::index", "Index should be in [0, "
00476                      + to_str(this->m_-1) + "], but is equal to "
00477                      + to_str(i) + ".");
00478 
00479     if (j < 0 || j >= this->val_(i).GetM())
00480       throw WrongCol("Matrix_ArraySparse::index", "Index should be in [0, " +
00481                      to_str(this->val_(i).GetM()-1) + "], but is equal to "
00482                      + to_str(j) + ".");
00483 #endif
00484 
00485     return val_(i).Index(j);
00486   }
00487 
00488 
00490 
00496   template <class T, class Prop, class Storage, class Allocator>
00497   inline void Matrix_ArraySparse<T, Prop, Storage, Allocator>::
00498   SetData(int i, int n, T* val, int* ind)
00499   {
00500     val_(i).SetData(n, val, ind);
00501   }
00502 
00503 
00505 
00509   template <class T, class Prop, class Storage, class Allocator>
00510   inline void Matrix_ArraySparse<T, Prop, Storage, Allocator>::Nullify(int i)
00511   {
00512     val_(i).Nullify();
00513   }
00514 
00515 
00517 
00522   template <class T, class Prop, class Storage, class Allocator>
00523   inline void Matrix_ArraySparse<T, Prop, Storage, Allocator>::
00524   SetData(int m, int n, Vector<T, VectSparse, Allocator>* val)
00525   {
00526     m_ = m;
00527     n_ = n;
00528     val_.SetData(Storage::GetFirst(m, n), val);
00529   }
00530 
00531 
00533 
00537   template <class T, class Prop, class Storage, class Allocator>
00538   inline void Matrix_ArraySparse<T, Prop, Storage, Allocator>::Nullify()
00539   {
00540     m_ = 0;
00541     n_ = 0;
00542     val_.Nullify();
00543   }
00544 
00545 
00546   /************************
00547    * CONVENIENT FUNCTIONS *
00548    ************************/
00549 
00550 
00552 
00557   template <class T, class Prop, class Storage, class Allocator>
00558   void Matrix_ArraySparse<T, Prop, Storage, Allocator>::Print() const
00559   {
00560     if (Storage::GetFirst(1, 0) == 1)
00561       for (int i = 0; i < this->m_; i++)
00562         {
00563           for (int j = 0; j < this->val_(i).GetM(); j++)
00564             cout << (i+1) << " " << this->val_(i).Index(j)+1
00565                  << " " << this->val_(i).Value(j) << endl;
00566         }
00567     else
00568       for (int i = 0; i < this->n_; i++)
00569         {
00570           for (int j = 0; j < this->val_(i).GetM(); j++)
00571             cout << this->val_(i).Index(j)+1 << " " << i+1
00572                  << " " << this->val_(i).Value(j) << endl;
00573         }
00574   }
00575 
00576 
00578 
00584   template <class T, class Prop, class Storage, class Allocator>
00585   void Matrix_ArraySparse<T, Prop, Storage, Allocator>::Assemble()
00586   {
00587     for (int i = 0; i < val_.GetM(); i++)
00588       val_(i).Assemble();
00589   }
00590 
00591 
00593 
00596   template <class T, class Prop, class Storage, class Allocator>
00597   template<class T0>
00598   void Matrix_ArraySparse<T, Prop, Storage, Allocator>::
00599   RemoveSmallEntry(const T0& epsilon)
00600   {
00601     for (int i = 0; i < val_.GetM(); i++)
00602       val_(i).RemoveSmallEntry(epsilon);
00603   }
00604 
00605 
00607   template <class T, class Prop, class Storage, class Allocator>
00608   inline void Matrix_ArraySparse<T, Prop, Storage, Allocator>::SetIdentity()
00609   {
00610     this->n_ = this->m_;
00611     for (int i = 0; i < this->m_; i++)
00612       {
00613         val_(i).Reallocate(1);
00614         val_(i).Index(0) = i;
00615         val_(i).Value(0) = T(1);
00616       }
00617   }
00618 
00619 
00621   template <class T, class Prop, class Storage, class Allocator>
00622   inline void Matrix_ArraySparse<T, Prop, Storage, Allocator>::Zero()
00623   {
00624     for (int i = 0; i < val_.GetM(); i++)
00625       val_(i).Zero();
00626   }
00627 
00628 
00630   template <class T, class Prop, class Storage, class Allocator>
00631   inline void Matrix_ArraySparse<T, Prop, Storage, Allocator>::Fill()
00632   {
00633     int value = 0;
00634     for (int i = 0; i < val_.GetM(); i++)
00635       for (int j = 0; j < val_(i).GetM(); j++)
00636         val_(i).Value(j) = value++;
00637   }
00638 
00639 
00641   template <class T, class Prop, class Storage, class Allo> template<class T0>
00642   inline void Matrix_ArraySparse<T, Prop, Storage, Allo>::Fill(const T0& x)
00643   {
00644     for (int i = 0; i < val_.GetM(); i++)
00645       val_(i).Fill(x);
00646   }
00647 
00648 
00650   template <class T, class Prop, class Storage, class Allocator>
00651   template <class T0>
00652   inline Matrix_ArraySparse<T, Prop, Storage, Allocator>&
00653   Matrix_ArraySparse<T, Prop, Storage, Allocator>::operator= (const T0& x)
00654   {
00655     this->Fill(x);
00656   }
00657 
00658 
00660   template <class T, class Prop, class Storage, class Allocator>
00661   inline void Matrix_ArraySparse<T, Prop, Storage, Allocator>::FillRand()
00662   {
00663     for (int i = 0; i < val_.GetM(); i++)
00664       val_(i).FillRand();
00665   }
00666 
00667 
00669 
00676   template <class T, class Prop, class Storage, class Allocator>
00677   void Matrix_ArraySparse<T, Prop, Storage, Allocator>::
00678   Write(string FileName) const
00679   {
00680     ofstream FileStream;
00681     FileStream.open(FileName.c_str());
00682 
00683 #ifdef SELDON_CHECK_IO
00684     // Checks if the file was opened.
00685     if (!FileStream.is_open())
00686       throw IOError("Matrix_ArraySparse::Write(string FileName)",
00687                     string("Unable to open file \"") + FileName + "\".");
00688 #endif
00689 
00690     this->Write(FileStream);
00691 
00692     FileStream.close();
00693   }
00694 
00695 
00697 
00704   template <class T, class Prop, class Storage, class Allocator>
00705   void Matrix_ArraySparse<T, Prop, Storage, Allocator>::
00706   Write(ostream& FileStream) const
00707   {
00708 
00709 #ifdef SELDON_CHECK_IO
00710     // Checks if the stream is ready.
00711     if (!FileStream.good())
00712       throw IOError("Matrix_ArraySparse::Write(ofstream& FileStream)",
00713                     "Stream is not ready.");
00714 #endif
00715 
00716     FileStream.write(reinterpret_cast<char*>(const_cast<int*>(&this->m_)),
00717                      sizeof(int));
00718     FileStream.write(reinterpret_cast<char*>(const_cast<int*>(&this->n_)),
00719                      sizeof(int));
00720 
00721     for (int i = 0; i < this->m_; i++)
00722       val_(i).Write(FileStream);
00723   }
00724 
00725 
00727 
00731   template <class T, class Prop, class Storage, class Allocator>
00732   void Matrix_ArraySparse<T, Prop, Storage, Allocator>::
00733   WriteText(string FileName) const
00734   {
00735     ofstream FileStream; FileStream.precision(14);
00736     FileStream.open(FileName.c_str());
00737 
00738 #ifdef SELDON_CHECK_IO
00739     // Checks if the file was opened.
00740     if (!FileStream.is_open())
00741       throw IOError("Matrix_ArraySparse::Write(string FileName)",
00742                     string("Unable to open file \"") + FileName + "\".");
00743 #endif
00744 
00745     this->WriteText(FileStream);
00746 
00747     FileStream.close();
00748   }
00749 
00750 
00752 
00756   template <class T, class Prop, class Storage, class Allocator>
00757   void Matrix_ArraySparse<T, Prop, Storage, Allocator>::
00758   WriteText(ostream& FileStream) const
00759   {
00760 
00761 #ifdef SELDON_CHECK_IO
00762     // Checks if the stream is ready.
00763     if (!FileStream.good())
00764       throw IOError("Matrix_ArraySparse::Write(ofstream& FileStream)",
00765                     "Stream is not ready.");
00766 #endif
00767 
00768     // conversion in coordinate format (1-index convention)
00769     IVect IndRow, IndCol; Vector<T> Value;
00770     const Matrix<T, Prop, Storage, Allocator>& leaf_class =
00771       static_cast<const Matrix<T, Prop, Storage, Allocator>& >(*this);
00772 
00773     ConvertMatrix_to_Coordinates(leaf_class, IndRow, IndCol,
00774                                  Value, 1, true);
00775 
00776     for (int i = 0; i < IndRow.GetM(); i++)
00777       FileStream << IndRow(i) << " " << IndCol(i) << " " << Value(i) << '\n';
00778 
00779   }
00780 
00781 
00783 
00790   template <class T, class Prop, class Storage, class Allocator>
00791   void Matrix_ArraySparse<T, Prop, Storage, Allocator>::
00792   Read(string FileName)
00793   {
00794     ifstream FileStream;
00795     FileStream.open(FileName.c_str());
00796 
00797 #ifdef SELDON_CHECK_IO
00798     // Checks if the file was opened.
00799     if (!FileStream.is_open())
00800       throw IOError("Matrix_ArraySparse::Read(string FileName)",
00801                     string("Unable to open file \"") + FileName + "\".");
00802 #endif
00803 
00804     this->Read(FileStream);
00805 
00806     FileStream.close();
00807   }
00808 
00809 
00811 
00818   template <class T, class Prop, class Storage, class Allocator>
00819   void Matrix_ArraySparse<T, Prop, Storage, Allocator>::
00820   Read(istream& FileStream)
00821   {
00822 
00823 #ifdef SELDON_CHECK_IO
00824     // Checks if the stream is ready.
00825     if (!FileStream.good())
00826       throw IOError("Matrix_ArraySparse::Read(ofstream& FileStream)",
00827                     "Stream is not ready.");
00828 #endif
00829 
00830     FileStream.read(reinterpret_cast<char*>(const_cast<int*>(&this->m_)),
00831                     sizeof(int));
00832     FileStream.read(reinterpret_cast<char*>(const_cast<int*>(&this->n_)),
00833                     sizeof(int));
00834 
00835     val_.Reallocate(this->m_);
00836     for (int i = 0; i < this->m_; i++)
00837       val_(i).Read(FileStream);
00838 
00839 #ifdef SELDON_CHECK_IO
00840     // Checks if data was read.
00841     if (!FileStream.good())
00842       throw IOError("Matrix_ArraySparse::Read(istream& FileStream)",
00843                     string("Input operation failed.")
00844                     + string(" The input file may have been removed")
00845                     + " or may not contain enough data.");
00846 #endif
00847 
00848   }
00849 
00850 
00852 
00856   template <class T, class Prop, class Storage, class Allocator>
00857   void Matrix_ArraySparse<T, Prop, Storage, Allocator>::
00858   ReadText(string FileName)
00859   {
00860     ifstream FileStream;
00861     FileStream.open(FileName.c_str());
00862 
00863 #ifdef SELDON_CHECK_IO
00864     // Checks if the file was opened.
00865     if (!FileStream.is_open())
00866       throw IOError("Matrix_ArraySparse::ReadText(string FileName)",
00867                     string("Unable to open file \"") + FileName + "\".");
00868 #endif
00869 
00870     this->ReadText(FileStream);
00871 
00872     FileStream.close();
00873   }
00874 
00875 
00877 
00881   template <class T, class Prop, class Storage, class Allocator>
00882   void Matrix_ArraySparse<T, Prop, Storage, Allocator>::
00883   ReadText(istream& FileStream)
00884   {
00885     // previous elements are removed
00886     Clear();
00887 
00888 #ifdef SELDON_CHECK_IO
00889     // Checks if the stream is ready.
00890     if (!FileStream.good())
00891       throw IOError("Matrix_ArraySparse::ReadText(ofstream& FileStream)",
00892                     "Stream is not ready.");
00893 #endif
00894 
00895     Vector<T, VectFull, Allocator> values;
00896     Vector<int> row_numbers, col_numbers;
00897     T entry; int row = 0, col;
00898     int nb_elt = 0;
00899     while (!FileStream.eof())
00900       {
00901         // new entry is read (1-index)
00902         FileStream >> row >> col >> entry;
00903 
00904         if (FileStream.fail())
00905           break;
00906         else
00907           {
00908 #ifdef SELDON_CHECK_IO
00909             if (row < 1)
00910               throw IOError(string("Matrix_ArraySparse::ReadText")+
00911                             "(istream& FileStream)",
00912                             string("Error : Row number should be greater ")
00913                             + "than 0 but is equal to " + to_str(row));
00914 
00915             if (col < 1)
00916               throw IOError(string("Matrix_ArraySparse::ReadText")+
00917                             "(istream& FileStream)",
00918                             string("Error : Column number should be greater")
00919                             + " than 0 but is equal to " + to_str(col));
00920 #endif
00921 
00922             nb_elt++;
00923 
00924             // inserting new element
00925             if (nb_elt > values.GetM())
00926               {
00927                 values.Resize(2*nb_elt);
00928                 row_numbers.Resize(2*nb_elt);
00929                 col_numbers.Resize(2*nb_elt);
00930               }
00931 
00932             values(nb_elt-1) = entry;
00933             row_numbers(nb_elt-1) = row;
00934             col_numbers(nb_elt-1) = col;
00935           }
00936       }
00937 
00938     if (nb_elt > 0)
00939       {
00940         Matrix<T, Prop, Storage, Allocator>& leaf_class =
00941           static_cast<Matrix<T, Prop, Storage, Allocator>& >(*this);
00942         row_numbers.Resize(nb_elt);
00943         col_numbers.Resize(nb_elt);
00944         values.Resize(nb_elt);
00945         ConvertMatrix_from_Coordinates(row_numbers, col_numbers, values,
00946                                        leaf_class, 1);
00947       }
00948   }
00949 
00950 
00952   // MATRIX<ARRAY_COLSPARSE> //
00954 
00955 
00957 
00960   template <class T, class Prop, class Allocator>
00961   inline Matrix<T, Prop, ArrayColSparse, Allocator>::Matrix()  throw():
00962     Matrix_ArraySparse<T, Prop, ArrayColSparse, Allocator>()
00963   {
00964   }
00965 
00966 
00968 
00973   template <class T, class Prop, class Allocator>
00974   inline Matrix<T, Prop, ArrayColSparse, Allocator>::Matrix(int i, int j):
00975     Matrix_ArraySparse<T, Prop, ArrayColSparse, Allocator>(i, j)
00976   {
00977   }
00978 
00979 
00981   template <class T, class Prop, class Allocator>
00982   inline void Matrix<T, Prop, ArrayColSparse, Allocator>::ClearColumn(int i)
00983   {
00984     this->val_(i).Clear();
00985   }
00986 
00987 
00989 
00993   template <class T, class Prop, class Alloc> inline
00994   void Matrix<T, Prop, ArrayColSparse, Alloc>::ReallocateColumn(int i,int j)
00995   {
00996     this->val_(i).Reallocate(j);
00997   }
00998 
00999 
01001 
01005   template <class T, class Prop, class Allocator> inline
01006   void Matrix<T, Prop, ArrayColSparse, Allocator>::ResizeColumn(int i,int j)
01007   {
01008     this->val_(i).Resize(j);
01009   }
01010 
01011 
01013 
01017   template <class T, class Prop, class Allocator> inline
01018   void Matrix<T, Prop, ArrayColSparse, Allocator>::SwapColumn(int i,int j)
01019   {
01020     Swap(this->val_(i), this->val_(j));
01021   }
01022 
01023 
01025 
01029   template <class T, class Prop, class Allocator>
01030   inline void Matrix<T, Prop, ArrayColSparse, Allocator>::
01031   ReplaceIndexColumn(int i, IVect& new_index)
01032   {
01033     for (int j = 0; j < this->val_(i).GetM(); j++)
01034       this->val_(i).Index(j) = new_index(j);
01035   }
01036 
01037 
01039 
01043   template <class T, class Prop, class Allocator>
01044   inline int Matrix<T, Prop, ArrayColSparse, Allocator>::
01045   GetColumnSize(int i) const
01046   {
01047     return this->val_(i).GetSize();
01048   }
01049 
01050 
01052   template <class T, class Prop, class Allocator> inline
01053   void Matrix<T, Prop, ArrayColSparse, Allocator>::PrintColumn(int i) const
01054   {
01055     this->val_(i).Print();
01056   }
01057 
01058 
01060 
01065   template <class T, class Prop, class Allocator> inline
01066   void Matrix<T, Prop, ArrayColSparse, Allocator>::AssembleColumn(int i)
01067   {
01068     this->val_(i).Assemble();
01069   }
01070 
01071 
01073 
01078   template <class T, class Prop, class Allocator>
01079   inline void Matrix<T, Prop, ArrayColSparse, Allocator>::
01080   AddInteraction(int i, int j, const T& val)
01081   {
01082     this->val_(j).AddInteraction(i, val);
01083   }
01084 
01085 
01087 
01093   template <class T, class Prop, class Allocator>
01094   inline void Matrix<T, Prop, ArrayColSparse, Allocator>::
01095   AddInteractionRow(int i, int nb, int* col_, T* value_)
01096   {
01097     IVect col;
01098     col.SetData(nb, col_);
01099     Vector<T> val;
01100     val.SetData(nb, value_);
01101     AddInteractionRow(i, nb, col, val);
01102     col.Nullify();
01103     val.Nullify();
01104   }
01105 
01106 
01108 
01114   template <class T, class Prop, class Allocator>
01115   inline void Matrix<T, Prop, ArrayColSparse, Allocator>::
01116   AddInteractionColumn(int i, int nb, int* row_, T* value_)
01117   {
01118     IVect row;
01119     row.SetData(nb, row_);
01120     Vector<T> val;
01121     val.SetData(nb, value_);
01122     AddInteractionColumn(i, nb, row, val);
01123     row.Nullify();
01124     val.Nullify();
01125   }
01126 
01127 
01129 
01135   template <class T, class Prop, class Allocator> template <class Alloc1>
01136   inline void Matrix<T, Prop, ArrayColSparse, Allocator>::
01137   AddInteractionRow(int i, int nb, const IVect& col,
01138                     const Vector<T, VectFull, Alloc1>& val)
01139   {
01140     for (int j = 0; j < nb; j++)
01141       this->val_(col(j)).AddInteraction(i, val(j));
01142   }
01143 
01144 
01146 
01152   template <class T, class Prop, class Allocator> template <class Alloc1>
01153   inline void Matrix<T, Prop, ArrayColSparse, Allocator>::
01154   AddInteractionColumn(int i, int nb, const IVect& row,
01155                        const Vector<T, VectFull, Alloc1>& val)
01156   {
01157     this->val_(i).AddInteractionRow(nb, row, val);
01158   }
01159 
01160 
01162   // MATRIX<ARRAY_ROWSPARSE> //
01164 
01165 
01167 
01170   template <class T, class Prop, class Allocator>
01171   inline Matrix<T, Prop, ArrayRowSparse, Allocator>::Matrix()  throw():
01172     Matrix_ArraySparse<T, Prop, ArrayRowSparse, Allocator>()
01173   {
01174   }
01175 
01176 
01178 
01183   template <class T, class Prop, class Allocator>
01184   inline Matrix<T, Prop, ArrayRowSparse, Allocator>::Matrix(int i, int j):
01185     Matrix_ArraySparse<T, Prop, ArrayRowSparse, Allocator>(i, j)
01186   {
01187   }
01188 
01189 
01191   template <class T, class Prop, class Allocator>
01192   inline void Matrix<T, Prop, ArrayRowSparse, Allocator>::ClearRow(int i)
01193   {
01194     this->val_(i).Clear();
01195   }
01196 
01197 
01199 
01204   template <class T, class Prop, class Allocator>
01205   inline void Matrix<T, Prop, ArrayRowSparse, Allocator>::
01206   ReallocateRow(int i, int j)
01207   {
01208     this->val_(i).Reallocate(j);
01209   }
01210 
01211 
01213 
01218   template <class T, class Prop, class Allocator> inline
01219   void Matrix<T, Prop, ArrayRowSparse, Allocator>::ResizeRow(int i, int j)
01220   {
01221     this->val_(i).Resize(j);
01222   }
01223 
01224 
01226 
01230   template <class T, class Prop, class Allocator>
01231   inline void Matrix<T, Prop, ArrayRowSparse, Allocator>::SwapRow(int i,int j)
01232   {
01233     Swap(this->val_(i), this->val_(j));
01234   }
01235 
01236 
01238 
01242   template <class T, class Prop, class Allocator>
01243   inline void Matrix<T, Prop, ArrayRowSparse, Allocator>::
01244   ReplaceIndexRow(int i, IVect& new_index)
01245   {
01246     for (int j = 0; j < this->val_(i).GetM(); j++)
01247       this->val_(i).Index(j) = new_index(j);
01248   }
01249 
01250 
01252 
01256   template <class T, class Prop, class Allocator> inline
01257   int Matrix<T, Prop, ArrayRowSparse, Allocator>::GetRowSize(int i) const
01258   {
01259     return this->val_(i).GetSize();
01260   }
01261 
01262 
01264   template <class T, class Prop, class Allocator> inline
01265   void Matrix<T, Prop, ArrayRowSparse, Allocator>::PrintRow(int i) const
01266   {
01267     this->val_(i).Print();
01268   }
01269 
01270 
01272 
01277   template <class T, class Prop, class Allocator>
01278   inline void Matrix<T, Prop, ArrayRowSparse, Allocator>::AssembleRow(int i)
01279   {
01280     this->val_(i).Assemble();
01281   }
01282 
01284 
01289   template <class T, class Prop, class Allocator>
01290   inline void Matrix<T, Prop, ArrayRowSparse, Allocator>::
01291   AddInteraction(int i, int j, const T& val)
01292   {
01293     this->val_(i).AddInteraction(j, val);
01294   }
01295 
01296 
01298 
01304   template <class T, class Prop, class Allocator>
01305   inline void Matrix<T, Prop, ArrayRowSparse, Allocator>::
01306   AddInteractionRow(int i, int nb, int* col_, T* value_)
01307   {
01308     IVect col;
01309     col.SetData(nb, col_);
01310     Vector<T> val;
01311     val.SetData(nb, value_);
01312     AddInteractionRow(i, nb, col, val);
01313     col.Nullify();
01314     val.Nullify();
01315   }
01316 
01317 
01319 
01325   template <class T, class Prop, class Allocator>
01326   inline void Matrix<T, Prop, ArrayRowSparse, Allocator>::
01327   AddInteractionColumn(int i, int nb, int* row_, T* value_)
01328   {
01329     IVect row;
01330     row.SetData(nb, row_);
01331     Vector<T> val;
01332     val.SetData(nb, value_);
01333     AddInteractionColumn(i, nb, row, val);
01334     row.Nullify();
01335     val.Nullify();
01336   }
01337 
01338 
01340 
01346   template <class T, class Prop, class Allocator> template <class Alloc1>
01347   inline void Matrix<T, Prop, ArrayRowSparse, Allocator>::
01348   AddInteractionRow(int i, int nb, const IVect& col,
01349                     const Vector<T, VectFull, Alloc1>& val)
01350   {
01351     this->val_(i).AddInteractionRow(nb, col, val);
01352   }
01353 
01354 
01356 
01362   template <class T, class Prop, class Allocator> template <class Alloc1>
01363   inline void Matrix<T, Prop, ArrayRowSparse, Allocator>::
01364   AddInteractionColumn(int i, int nb, const IVect& row,
01365                        const Vector<T, VectFull, Alloc1>& val)
01366   {
01367     for (int j = 0; j < nb; j++)
01368       this->val_(row(j)).AddInteraction(i, val(j));
01369   }
01370 
01371 
01373   // MATRIX<ARRAY_COLSYMSPARSE> //
01375 
01376 
01378 
01381   template <class T, class Prop, class Allocator>
01382   inline Matrix<T, Prop, ArrayColSymSparse, Allocator>::Matrix()  throw():
01383     Matrix_ArraySparse<T, Prop, ArrayColSymSparse, Allocator>()
01384   {
01385   }
01386 
01387 
01389 
01394   template <class T, class Prop, class Allocator>
01395   inline Matrix<T, Prop, ArrayColSymSparse, Allocator>::Matrix(int i, int j):
01396     Matrix_ArraySparse<T, Prop, ArrayColSymSparse, Allocator>(i, j)
01397   {
01398   }
01399 
01400 
01401   /**********************************
01402    * ELEMENT ACCESS AND AFFECTATION *
01403    **********************************/
01404 
01405 
01407 
01413   template <class T, class Prop, class Allocator>
01414   inline T
01415   Matrix<T, Prop, ArrayColSymSparse, Allocator>::operator() (int i, int j)
01416     const
01417   {
01418 
01419 #ifdef SELDON_CHECK_BOUNDS
01420     if (i < 0 || i >= this->m_)
01421       throw WrongRow("Matrix::operator()", "Index should be in [0, "
01422                      + to_str(this->m_-1) + "], but is equal to "
01423                      + to_str(i) + ".");
01424     if (j < 0 || j >= this->n_)
01425       throw WrongCol("Matrix::operator()", "Index should be in [0, "
01426                      + to_str(this->n_-1) + "], but is equal to "
01427                      + to_str(j) + ".");
01428 #endif
01429 
01430     if (i <= j)
01431       return this->val_(j)(i);
01432 
01433     return this->val_(i)(j);
01434   }
01435 
01436 
01438 
01444   template <class T, class Prop, class Allocator>
01445   inline T&
01446   Matrix<T, Prop, ArrayColSymSparse, Allocator>::operator() (int i, int j)
01447   {
01448 
01449 #ifdef SELDON_CHECK_BOUNDS
01450     if (i < 0 || i >= this->m_)
01451       throw WrongRow("Matrix::operator()", "Index should be in [0, "
01452                      + to_str(this->m_-1) + "], but is equal to "
01453                      + to_str(i) + ".");
01454     if (j < 0 || j >= this->n_)
01455       throw WrongCol("Matrix::operator()", "Index should be in [0, "
01456                      + to_str(this->n_-1) + "], but is equal to "
01457                      + to_str(j) + ".");
01458 #endif
01459 
01460     if (i < j)
01461       return this->val_(j)(i);
01462 
01463     return this->val_(i)(j);
01464   }
01465 
01466 
01468   template <class T, class Prop, class Allocator> inline
01469   void Matrix<T, Prop, ArrayColSymSparse, Allocator>::ClearColumn(int i)
01470   {
01471     this->val_(i).Clear();
01472   }
01473 
01474 
01476 
01481   template <class T, class Prop, class Allocator>
01482   inline void Matrix<T, Prop, ArrayColSymSparse, Allocator>::
01483   ReallocateColumn(int i, int j)
01484   {
01485     this->val_(i).Reallocate(j);
01486   }
01487 
01488 
01490 
01494   template <class T, class Prop, class Allocator>
01495   inline void Matrix<T, Prop, ArrayColSymSparse, Allocator>::
01496   ResizeColumn(int i, int j)
01497   {
01498     this->val_(i).Resize(j);
01499   }
01500 
01501 
01503 
01507   template <class T, class Prop, class Allocator>
01508   inline void Matrix<T, Prop, ArrayColSymSparse, Allocator>::
01509   SwapColumn(int i, int j)
01510   {
01511     Swap(this->val_(i), this->val_(j));
01512   }
01513 
01514 
01516 
01520   template <class T, class Prop, class Allocator>
01521   inline void Matrix<T, Prop, ArrayColSymSparse, Allocator>::
01522   ReplaceIndexColumn(int i, IVect& new_index)
01523   {
01524     for (int j = 0; j < this->val_(i).GetM(); j++)
01525       this->val_(i).Index(j) = new_index(j);
01526   }
01527 
01528 
01530 
01534   template <class T, class Prop, class Allocator>
01535   inline int Matrix<T, Prop, ArrayColSymSparse, Allocator>::
01536   GetColumnSize(int i) const
01537   {
01538     return this->val_(i).GetSize();
01539   }
01540 
01541 
01543   template <class T, class Prop, class Allocator>
01544   inline void Matrix<T, Prop, ArrayColSymSparse, Allocator>::
01545   PrintColumn(int i) const
01546   {
01547     this->val_(i).Print();
01548   }
01549 
01550 
01552 
01557   template <class T, class Prop, class Allocator>
01558   inline void Matrix<T, Prop, ArrayColSymSparse, Allocator>::
01559   AssembleColumn(int i)
01560   {
01561     this->val_(i).Assemble();
01562   }
01563 
01564 
01566 
01572   template <class T, class Prop, class Allocator>
01573   inline void Matrix<T, Prop, ArrayColSymSparse, Allocator>::
01574   AddInteractionRow(int i, int nb, int* col_, T* value_)
01575   {
01576     IVect col;
01577     col.SetData(nb, col_);
01578     Vector<T> val;
01579     val.SetData(nb, value_);
01580     AddInteractionRow(i, nb, col, val);
01581     col.Nullify();
01582     val.Nullify();
01583   }
01584 
01585 
01587 
01593   template <class T, class Prop, class Allocator>
01594   inline void Matrix<T, Prop, ArrayColSymSparse, Allocator>::
01595   AddInteractionColumn(int i, int nb, int* row_, T* value_)
01596   {
01597     IVect row;
01598     row.SetData(nb, row_);
01599     Vector<T> val;
01600     val.SetData(nb, value_);
01601     AddInteractionColumn(i, nb, row, val);
01602     row.Nullify();
01603     val.Nullify();
01604   }
01605 
01606 
01608 
01613   template <class T, class Prop, class Allocator>
01614   inline void Matrix<T, Prop, ArrayColSymSparse, Allocator>::
01615   AddInteraction(int i, int j, const T& val)
01616   {
01617     if (i <= j)
01618       this->val_(j).AddInteraction(i, val);
01619   }
01620 
01621 
01623 
01629   template <class T, class Prop, class Allocator> template <class Alloc1>
01630   inline void Matrix<T, Prop, ArrayColSymSparse, Allocator>::
01631   AddInteractionRow(int i, int nb, const IVect& col,
01632                     const Vector<T, VectFull, Alloc1>& val)
01633   {
01634     AddInteractionColumn(i, nb, col, val);
01635   }
01636 
01637 
01639 
01645   template <class T, class Prop, class Allocator> template <class Alloc1>
01646   inline void Matrix<T, Prop, ArrayColSymSparse, Allocator>::
01647   AddInteractionColumn(int i, int nb, const IVect& row,
01648                        const Vector<T, VectFull, Alloc1>& val)
01649   {
01650     IVect new_row(nb);
01651     Vector<T, VectFull, Alloc1> new_val(nb);
01652     nb = 0;
01653     for (int j = 0; j < new_row.GetM(); j++)
01654       if (row(j) <= i)
01655         {
01656           new_row(nb) = row(j);
01657           new_val(nb) = val(j); nb++;
01658         }
01659 
01660     this->val_(i).AddInteractionRow(nb, new_row, new_val);
01661   }
01662 
01663 
01665   // MATRIX<ARRAY_ROWSYMSPARSE> //
01667 
01668 
01670 
01673   template <class T, class Prop, class Allocator>
01674   inline Matrix<T, Prop, ArrayRowSymSparse, Allocator>::Matrix()  throw():
01675     Matrix_ArraySparse<T, Prop, ArrayRowSymSparse, Allocator>()
01676   {
01677   }
01678 
01679 
01681 
01686   template <class T, class Prop, class Allocator>
01687   inline Matrix<T, Prop, ArrayRowSymSparse, Allocator>::Matrix(int i, int j):
01688     Matrix_ArraySparse<T, Prop, ArrayRowSymSparse, Allocator>(i, j)
01689   {
01690   }
01691 
01692 
01693   /**********************************
01694    * ELEMENT ACCESS AND AFFECTATION *
01695    **********************************/
01696 
01697 
01699 
01705   template <class T, class Prop, class Allocator>
01706   inline T
01707   Matrix<T, Prop, ArrayRowSymSparse, Allocator>::operator() (int i, int j)
01708     const
01709   {
01710 
01711 #ifdef SELDON_CHECK_BOUNDS
01712     if (i < 0 || i >= this->m_)
01713       throw WrongRow("Matrix_ArraySparse::operator()",
01714                      "Index should be in [0, "
01715                      + to_str(this->m_-1) + "], but is equal to "
01716                      + to_str(i) + ".");
01717     if (j < 0 || j >= this->n_)
01718       throw WrongCol("Matrix_ArraySparse::operator()",
01719                      "Index should be in [0, "
01720                      + to_str(this->n_-1) + "], but is equal to "
01721                      + to_str(j) + ".");
01722 #endif
01723 
01724     if (i <= j)
01725       return this->val_(i)(j);
01726 
01727     return this->val_(j)(i);
01728   }
01729 
01730 
01732 
01738   template <class T, class Prop, class Allocator>
01739   inline T&
01740   Matrix<T, Prop, ArrayRowSymSparse, Allocator>::operator() (int i, int j)
01741   {
01742 
01743 #ifdef SELDON_CHECK_BOUNDS
01744     if (i < 0 || i >= this->m_)
01745       throw WrongRow("Matrix::operator()", "Index should be in [0, "
01746                      + to_str(this->m_-1) + "], but is equal to "
01747                      + to_str(i) + ".");
01748     if (j < 0 || j >= this->n_)
01749       throw WrongCol("Matrix::operator()", "Index should be in [0, "
01750                      + to_str(this->n_-1) + "], but is equal to "
01751                      + to_str(j) + ".");
01752 #endif
01753 
01754     if (i <= j)
01755       return this->val_(i)(j);
01756 
01757     return this->val_(j)(i);
01758 
01759   }
01760 
01761 
01763   template <class T, class Prop, class Allocator>
01764   inline void Matrix<T, Prop, ArrayRowSymSparse, Allocator>::ClearRow(int i)
01765   {
01766     this->val_(i).Clear();
01767   }
01768 
01769 
01771 
01776   template <class T, class Prop, class Allocator>
01777   inline void Matrix<T, Prop, ArrayRowSymSparse, Allocator>::
01778   ReallocateRow(int i,int j)
01779   {
01780     this->val_(i).Reallocate(j);
01781   }
01782 
01783 
01785 
01789   template <class T, class Prop, class Allocator>
01790   inline void Matrix<T, Prop, ArrayRowSymSparse, Allocator>::
01791   ResizeRow(int i,int j)
01792   {
01793     this->val_(i).Resize(j);
01794   }
01795 
01796 
01798 
01802   template <class T, class Prop, class Allocator>
01803   inline void Matrix<T, Prop, ArrayRowSymSparse, Allocator>::
01804   SwapRow(int i,int j)
01805   {
01806     Swap(this->val_(i), this->val_(j));
01807   }
01808 
01809 
01811 
01815   template <class T, class Prop, class Allocator>
01816   inline void Matrix<T, Prop, ArrayRowSymSparse, Allocator>::
01817   ReplaceIndexRow(int i,IVect& new_index)
01818   {
01819     for (int j = 0; j < this->val_(i).GetM(); j++)
01820       this->val_(i).Index(j) = new_index(j);
01821   }
01822 
01823 
01825 
01829   template <class T, class Prop, class Allocator>
01830   inline int Matrix<T, Prop, ArrayRowSymSparse, Allocator>::GetRowSize(int i)
01831     const
01832   {
01833     return this->val_(i).GetSize();
01834   }
01835 
01836 
01838   template <class T, class Prop, class Allocator>
01839   inline void Matrix<T, Prop, ArrayRowSymSparse, Allocator>::PrintRow(int i)
01840     const
01841   {
01842     this->val_(i).Print();
01843   }
01844 
01845 
01847 
01852   template <class T, class Prop, class Allocator>
01853   inline void Matrix<T, Prop, ArrayRowSymSparse, Allocator>
01854   ::AssembleRow(int i)
01855   {
01856     this->val_(i).Assemble();
01857   }
01858 
01859 
01861 
01866   template <class T, class Prop, class Allocator>
01867   inline void Matrix<T, Prop, ArrayRowSymSparse, Allocator>::
01868   AddInteraction(int i, int j, const T& val)
01869   {
01870     if (i <= j)
01871       this->val_(i).AddInteraction(j, val);
01872   }
01873 
01874 
01876 
01882   template <class T, class Prop, class Allocator>
01883   inline void Matrix<T, Prop, ArrayRowSymSparse, Allocator>::
01884   AddInteractionRow(int i, int nb, int* col_, T* value_)
01885   {
01886     IVect col;
01887     col.SetData(nb, col_);
01888     Vector<T> val;
01889     val.SetData(nb, value_);
01890     AddInteractionRow(i, nb, col, val);
01891     col.Nullify();
01892     val.Nullify();
01893   }
01894 
01895 
01897 
01903   template <class T, class Prop, class Allocator>
01904   inline void Matrix<T, Prop, ArrayRowSymSparse, Allocator>::
01905   AddInteractionColumn(int i, int nb, int* row_, T* value_)
01906   {
01907     IVect row;
01908     row.SetData(nb, row_);
01909     Vector<T> val;
01910     val.SetData(nb, value_);
01911     AddInteractionColumn(i, nb, row, val);
01912     row.Nullify();
01913     val.Nullify();
01914   }
01915 
01916 
01918 
01924   template <class T, class Prop, class Allocator> template <class Alloc1>
01925   inline void Matrix<T, Prop, ArrayRowSymSparse, Allocator>::
01926   AddInteractionRow(int i, int nb, const IVect& col,
01927                     const Vector<T, VectFull, Alloc1>& val)
01928   {
01929     IVect new_col(nb);
01930     Vector<T, VectFull, Alloc1> new_val(nb);
01931     nb = 0;
01932     for (int j = 0; j < new_col.GetM(); j++)
01933       if (i <= col(j))
01934         {
01935           new_col(nb) = col(j);
01936           new_val(nb) = val(j); nb++;
01937         }
01938 
01939     this->val_(i).AddInteractionRow(nb, new_col, new_val);
01940   }
01941 
01942 
01944 
01950   template <class T, class Prop, class Allocator> template <class Alloc1>
01951   inline void Matrix<T, Prop, ArrayRowSymSparse, Allocator>::
01952   AddInteractionColumn(int i, int nb, const IVect& row,
01953                        const Vector<T,VectFull,Alloc1>& val)
01954   {
01955     // Symmetric matrix, row = column.
01956     AddInteractionRow(i, nb, row, val);
01957   }
01958 
01959 
01960   template <class T, class Prop, class Allocator>
01961   ostream& operator <<(ostream& out,
01962                        const Matrix<T, Prop, ArrayRowSparse, Allocator>& A)
01963   {
01964     A.WriteText(out);
01965 
01966     return out;
01967   }
01968 
01969 
01970   template <class T, class Prop, class Allocator>
01971   ostream& operator <<(ostream& out,
01972                        const Matrix<T, Prop, ArrayColSparse, Allocator>& A)
01973   {
01974     A.WriteText(out);
01975 
01976     return out;
01977   }
01978 
01979 
01980   template <class T, class Prop, class Allocator>
01981   ostream& operator <<(ostream& out,
01982                        const Matrix<T, Prop, ArrayRowSymSparse, Allocator>& A)
01983   {
01984     A.WriteText(out);
01985 
01986     return out;
01987   }
01988 
01989 
01990   template <class T, class Prop, class Allocator>
01991   ostream& operator <<(ostream& out,
01992                        const Matrix<T, Prop, ArrayColSymSparse, Allocator>& A)
01993   {
01994     A.WriteText(out);
01995 
01996     return out;
01997   }
01998 
01999 
02000 } // namespace Seldon
02001 
02002 #define SELDON_FILE_MATRIX_ARRAY_SPARSE_CXX
02003 #endif