matrix_sparse/Matrix_SymSparse.cxx

00001 // Copyright (C) 2001-2009 Vivien Mallet
00002 // Copyright (C) 2003-2009 Marc Duruflé
00003 //
00004 // This file is part of the linear-algebra library Seldon,
00005 // http://seldon.sourceforge.net/.
00006 //
00007 // Seldon is free software; you can redistribute it and/or modify it under the
00008 // terms of the GNU Lesser General Public License as published by the Free
00009 // Software Foundation; either version 2.1 of the License, or (at your option)
00010 // any later version.
00011 //
00012 // Seldon is distributed in the hope that it will be useful, but WITHOUT ANY
00013 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00014 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
00015 // more details.
00016 //
00017 // You should have received a copy of the GNU Lesser General Public License
00018 // along with Seldon. If not, see http://www.gnu.org/licenses/.
00019 
00020 
00021 #ifndef SELDON_FILE_MATRIX_SYMSPARSE_CXX
00022 
00023 #include "Matrix_SymSparse.hxx"
00024 
00025 namespace Seldon
00026 {
00027 
00028 
00029   /****************
00030    * CONSTRUCTORS *
00031    ****************/
00032 
00033 
00035 
00038   template <class T, class Prop, class Storage, class Allocator>
00039   inline Matrix_SymSparse<T, Prop, Storage, Allocator>::Matrix_SymSparse():
00040     Matrix_Base<T, Allocator>()
00041   {
00042     nz_ = 0;
00043     ptr_ = NULL;
00044     ind_ = NULL;
00045   }
00046 
00047 
00049 
00055   template <class T, class Prop, class Storage, class Allocator>
00056   inline Matrix_SymSparse<T, Prop, Storage, Allocator>
00057   ::Matrix_SymSparse(int i, int j): Matrix_Base<T, Allocator>()
00058   {
00059     nz_ = 0;
00060     ptr_ = NULL;
00061     ind_ = NULL;
00062 
00063     Reallocate(i, j);
00064   }
00065 
00066 
00068 
00077   template <class T, class Prop, class Storage, class Allocator>
00078   inline Matrix_SymSparse<T, Prop, Storage, Allocator>::
00079   Matrix_SymSparse(int i, int j, int nz):
00080     Matrix_Base<T, Allocator>()
00081   {
00082     this->nz_ = 0;
00083     ind_ = NULL;
00084     ptr_ = NULL;
00085 
00086     Reallocate(i, j, nz);
00087   }
00088 
00089 
00091 
00103   template <class T, class Prop, class Storage, class Allocator>
00104   template <class Storage0, class Allocator0,
00105             class Storage1, class Allocator1,
00106             class Storage2, class Allocator2>
00107   inline Matrix_SymSparse<T, Prop, Storage, Allocator>::
00108   Matrix_SymSparse(int i, int j,
00109                    Vector<T, Storage0, Allocator0>& values,
00110                    Vector<int, Storage1, Allocator1>& ptr,
00111                    Vector<int, Storage2, Allocator2>& ind):
00112     Matrix_Base<T, Allocator>(i, j)
00113   {
00114     nz_ = values.GetLength();
00115 
00116 #ifdef SELDON_CHECK_DIMENSIONS
00117     // Checks whether vector sizes are acceptable.
00118 
00119     if (ind.GetLength() != nz_)
00120       {
00121         this->m_ = 0;
00122         this->n_ = 0;
00123         nz_ = 0;
00124         ptr_ = NULL;
00125         ind_ = NULL;
00126         this->data_ = NULL;
00127         throw WrongDim(string("Matrix_SymSparse::Matrix_SymSparse(int, int, ")
00128                        + "const Vector&, const Vector&, const Vector&)",
00129                        string("There are ") + to_str(nz_) + " values but "
00130                        + to_str(ind.GetLength()) + " row or column indices.");
00131       }
00132 
00133     if (ptr.GetLength() - 1 != i)
00134       {
00135         this->m_ = 0;
00136         this->n_ = 0;
00137         nz_ = 0;
00138         ptr_ = NULL;
00139         ind_ = NULL;
00140         this->data_ = NULL;
00141         throw WrongDim(string("Matrix_SymSparse::Matrix_SymSparse(int, int, ")
00142                        + "const Vector&, const Vector&, const Vector&)",
00143                        string("The vector of start indices contains ")
00144                        + to_str(ptr.GetLength()-1) + string(" row or column ")
00145                        + string("start  indices (plus the number of non-zero")
00146                        + " entries) but there are " + to_str(i)
00147                        + " rows or columns ("
00148                        + to_str(i) + " by " + to_str(i) + " matrix).");
00149       }
00150 
00151     if (static_cast<long int>(2 * nz_ - 2) / static_cast<long int>(i + 1)
00152         >= static_cast<long int>(i))
00153       {
00154         this->m_ = 0;
00155         this->n_ = 0;
00156         nz_ = 0;
00157         ptr_ = NULL;
00158         ind_ = NULL;
00159         this->data_ = NULL;
00160         throw WrongDim(string("Matrix_SymSparse::Matrix_SymSparse(int, int, ")
00161                        + "const Vector&, const Vector&, const Vector&)",
00162                        string("There are more values (")
00163                        + to_str(values.GetLength())
00164                        + " values) than elements in the matrix ("
00165                        + to_str(i) + " by " + to_str(i) + ").");
00166       }
00167 #endif
00168 
00169     this->ptr_ = ptr.GetData();
00170     this->ind_ = ind.GetData();
00171     this->data_ = values.GetData();
00172 
00173     ptr.Nullify();
00174     ind.Nullify();
00175     values.Nullify();
00176   }
00177 
00178 
00180   template <class T, class Prop, class Storage, class Allocator>
00181   inline Matrix_SymSparse<T, Prop, Storage, Allocator>::
00182   Matrix_SymSparse(const Matrix_SymSparse<T, Prop, Storage, Allocator>& A)
00183   {
00184     this->m_ = 0;
00185     this->n_ = 0;
00186     this->nz_ = 0;
00187     ptr_ = NULL;
00188     ind_ = NULL;
00189     this->Copy(A);
00190   }
00191 
00192 
00193   /**************
00194    * DESTRUCTOR *
00195    **************/
00196 
00197 
00199   template <class T, class Prop, class Storage, class Allocator>
00200   inline Matrix_SymSparse<T, Prop, Storage, Allocator>::~Matrix_SymSparse()
00201   {
00202     this->m_ = 0;
00203     this->n_ = 0;
00204 
00205 #ifdef SELDON_CHECK_MEMORY
00206     try
00207       {
00208 #endif
00209 
00210         if (ptr_ != NULL)
00211           {
00212             free(ptr_);
00213             ptr_ = NULL;
00214           }
00215 
00216 #ifdef SELDON_CHECK_MEMORY
00217       }
00218     catch (...)
00219       {
00220         ptr_ = NULL;
00221       }
00222 #endif
00223 
00224 #ifdef SELDON_CHECK_MEMORY
00225     try
00226       {
00227 #endif
00228 
00229         if (ind_ != NULL)
00230           {
00231             free(ind_);
00232             ind_ = NULL;
00233           }
00234 
00235 #ifdef SELDON_CHECK_MEMORY
00236       }
00237     catch (...)
00238       {
00239         ind_ = NULL;
00240       }
00241 #endif
00242 
00243 #ifdef SELDON_CHECK_MEMORY
00244     try
00245       {
00246 #endif
00247 
00248         if (this->data_ != NULL)
00249           {
00250             this->allocator_.deallocate(this->data_, nz_);
00251             this->data_ = NULL;
00252           }
00253 
00254 #ifdef SELDON_CHECK_MEMORY
00255       }
00256     catch (...)
00257       {
00258         this->nz_ = 0;
00259         this->data_ = NULL;
00260       }
00261 #endif
00262 
00263     this->nz_ = 0;
00264   }
00265 
00266 
00268 
00271   template <class T, class Prop, class Storage, class Allocator>
00272   inline void Matrix_SymSparse<T, Prop, Storage, Allocator>::Clear()
00273   {
00274     this->~Matrix_SymSparse();
00275   }
00276 
00277 
00278   /*********************
00279    * MEMORY MANAGEMENT *
00280    *********************/
00281 
00282 
00284 
00295   template <class T, class Prop, class Storage, class Allocator>
00296   template <class Storage0, class Allocator0,
00297             class Storage1, class Allocator1,
00298             class Storage2, class Allocator2>
00299   void Matrix_SymSparse<T, Prop, Storage, Allocator>::
00300   SetData(int i, int j,
00301           Vector<T, Storage0, Allocator0>& values,
00302           Vector<int, Storage1, Allocator1>& ptr,
00303           Vector<int, Storage2, Allocator2>& ind)
00304   {
00305     this->Clear();
00306     this->m_ = i;
00307     this->n_ = i;
00308     this->nz_ = values.GetLength();
00309 
00310 #ifdef SELDON_CHECK_DIMENSIONS
00311     // Checks whether vector sizes are acceptable.
00312 
00313     if (ind.GetLength() != nz_)
00314       {
00315         this->m_ = 0;
00316         this->n_ = 0;
00317         nz_ = 0;
00318         ptr_ = NULL;
00319         ind_ = NULL;
00320         this->data_ = NULL;
00321         throw WrongDim(string("Matrix_SymSparse::Reallocate(int, int, ")
00322                        + "const Vector&, const Vector&, const Vector&)",
00323                        string("There are ") + to_str(nz_) + " values but "
00324                        + to_str(ind.GetLength()) + " row or column indices.");
00325       }
00326 
00327     if (ptr.GetLength()-1 != i)
00328       {
00329         this->m_ = 0;
00330         this->n_ = 0;
00331         nz_ = 0;
00332         ptr_ = NULL;
00333         ind_ = NULL;
00334         this->data_ = NULL;
00335         throw WrongDim(string("Matrix_SymSparse::Reallocate(int, int, ")
00336                        + "const Vector&, const Vector&, const Vector&)",
00337                        string("The vector of start indices contains ")
00338                        + to_str(ptr.GetLength()-1) + string(" row or column")
00339                        + string(" start indices (plus the number of")
00340                        + string(" non-zero entries) but there are ")
00341                        + to_str(i) + " rows or columns ("
00342                        + to_str(i) + " by " + to_str(i) + " matrix).");
00343       }
00344 
00345     if (static_cast<long int>(2 * nz_ - 2) / static_cast<long int>(i + 1)
00346         >= static_cast<long int>(i))
00347       {
00348         this->m_ = 0;
00349         this->n_ = 0;
00350         nz_ = 0;
00351         ptr_ = NULL;
00352         ind_ = NULL;
00353         this->data_ = NULL;
00354         throw WrongDim(string("Matrix_SymSparse::Reallocate(int, int, ")
00355                        + "const Vector&, const Vector&, const Vector&)",
00356                        string("There are more values (")
00357                        + to_str(values.GetLength())
00358                        + " values) than elements in the matrix ("
00359                        + to_str(i) + " by " + to_str(i) + ").");
00360       }
00361 #endif
00362 
00363     this->ptr_ = ptr.GetData();
00364     this->ind_ = ind.GetData();
00365     this->data_ = values.GetData();
00366 
00367     ptr.Nullify();
00368     ind.Nullify();
00369     values.Nullify();
00370   }
00371 
00372 
00374 
00388   template <class T, class Prop, class Storage, class Allocator>
00389   inline void Matrix_SymSparse<T, Prop, Storage, Allocator>
00390   ::SetData(int i, int j, int nz,
00391             typename Matrix_SymSparse<T, Prop, Storage, Allocator>
00392             ::pointer values,
00393             int* ptr,
00394             int* ind)
00395   {
00396     this->Clear();
00397 
00398     this->m_ = i;
00399     this->n_ = i;
00400 
00401     this->nz_ = nz;
00402 
00403     this->data_ = values;
00404     ind_ = ind;
00405     ptr_ = ptr;
00406   }
00407 
00408 
00410 
00414   template <class T, class Prop, class Storage, class Allocator>
00415   inline void Matrix_SymSparse<T, Prop, Storage, Allocator>::Nullify()
00416   {
00417     this->data_ = NULL;
00418     this->m_ = 0;
00419     this->n_ = 0;
00420     nz_ = 0;
00421     ptr_ = NULL;
00422     ind_ = NULL;
00423   }
00424 
00425 
00427 
00431   template <class T, class Prop, class Storage, class Allocator>
00432   void Matrix_SymSparse<T, Prop, Storage, Allocator>::Reallocate(int i, int j)
00433   {
00434     // clearing previous entries
00435     Clear();
00436 
00437     this->m_ = i;
00438     this->n_ = i;
00439 
00440     // we try to allocate ptr_
00441 #ifdef SELDON_CHECK_MEMORY
00442     try
00443       {
00444 #endif
00445 
00446         ptr_ = reinterpret_cast<int*>( calloc(i+1, sizeof(int)) );
00447 
00448 #ifdef SELDON_CHECK_MEMORY
00449       }
00450     catch (...)
00451       {
00452         this->m_ = 0;
00453         this->n_ = 0;
00454         nz_ = 0;
00455         ptr_ = NULL;
00456         ind_ = NULL;
00457         this->data_ = NULL;
00458       }
00459     if (ptr_ == NULL)
00460       {
00461         this->m_ = 0;
00462         this->n_ = 0;
00463         nz_ = 0;
00464         ind_ = NULL;
00465         this->data_ = NULL;
00466       }
00467     if (ptr_ == NULL && i != 0 && j != 0)
00468       throw NoMemory("Matrix_SymSparse::Reallocate(int, int)",
00469                      string("Unable to allocate ")
00470                      + to_str(sizeof(int) * (i+1) )
00471                      + " bytes to store " + to_str(i+1)
00472                      + " row or column start indices, for a "
00473                      + to_str(i) + " by " + to_str(i) + " matrix.");
00474 #endif
00475 
00476     // then filing ptr_ with 0
00477     for (int k = 0; k <= i; k++)
00478       ptr_[k] = 0;
00479   }
00480 
00481 
00483 
00488   template <class T, class Prop, class Storage, class Allocator>
00489   void Matrix_SymSparse<T, Prop, Storage, Allocator>
00490   ::Reallocate(int i, int j, int nz)
00491   {
00492     // clearing previous entries
00493     Clear();
00494 
00495     this->nz_ = nz;
00496     this->m_ = i;
00497     this->n_ = i;
00498 
00499 #ifdef SELDON_CHECK_DIMENSIONS
00500     if (static_cast<long int>(2 * nz_ - 2) / static_cast<long int>(i + 1)
00501         >= static_cast<long int>(i))
00502       {
00503         this->m_ = 0;
00504         this->n_ = 0;
00505         nz_ = 0;
00506         ptr_ = NULL;
00507         ind_ = NULL;
00508         this->data_ = NULL;
00509         throw WrongDim("Matrix_SymSparse::Matrix_SymSparse(int, int, int)",
00510                        string("There are more values (") + to_str(nz)
00511                        + string(" values) than elements in the upper")
00512                        + " part of the matrix ("
00513                        + to_str(i) + " by " + to_str(i) + ").");
00514       }
00515 #endif
00516 
00517 #ifdef SELDON_CHECK_MEMORY
00518     try
00519       {
00520 #endif
00521 
00522         ptr_ = reinterpret_cast<int*>( calloc(i + 1, sizeof(int)) );
00523 
00524 #ifdef SELDON_CHECK_MEMORY
00525       }
00526     catch (...)
00527       {
00528         this->m_ = 0;
00529         this->n_ = 0;
00530         nz_ = 0;
00531         ptr_ = NULL;
00532         ind_ = NULL;
00533         this->data_ = NULL;
00534       }
00535     if (ptr_ == NULL)
00536       {
00537         this->m_ = 0;
00538         this->n_ = 0;
00539         nz_ = 0;
00540         ind_ = NULL;
00541         this->data_ = NULL;
00542       }
00543     if (ptr_ == NULL && i != 0)
00544       throw NoMemory("Matrix_SymSparse::Matrix_SymSparse(int, int, int)",
00545                      string("Unable to allocate ")
00546                      + to_str(sizeof(int) * (i+1) ) + " bytes to store "
00547                      + to_str(i+1) + " row or column start indices, for a "
00548                      + to_str(i) + " by " + to_str(i) + " matrix.");
00549 #endif
00550 
00551 #ifdef SELDON_CHECK_MEMORY
00552     try
00553       {
00554 #endif
00555 
00556         ind_ = reinterpret_cast<int*>( calloc(nz_, sizeof(int)) );
00557 
00558 #ifdef SELDON_CHECK_MEMORY
00559       }
00560     catch (...)
00561       {
00562         this->m_ = 0;
00563         this->n_ = 0;
00564         nz_ = 0;
00565         free(ptr_);
00566         ptr_ = NULL;
00567         ind_ = NULL;
00568         this->data_ = NULL;
00569       }
00570     if (ind_ == NULL)
00571       {
00572         this->m_ = 0;
00573         this->n_ = 0;
00574         nz_ = 0;
00575         free(ptr_);
00576         ptr_ = NULL;
00577         this->data_ = NULL;
00578       }
00579     if (ind_ == NULL && i != 0)
00580       throw NoMemory("Matrix_SymSparse::Matrix_SymSparse(int, int, int)",
00581                      string("Unable to allocate ") + to_str(sizeof(int) * nz)
00582                      + " bytes to store " + to_str(nz)
00583                      + " row or column indices, for a "
00584                      + to_str(i) + " by " + to_str(i) + " matrix.");
00585 #endif
00586 
00587 #ifdef SELDON_CHECK_MEMORY
00588     try
00589       {
00590 #endif
00591 
00592         this->data_ = this->allocator_.allocate(nz_, this);
00593 
00594 #ifdef SELDON_CHECK_MEMORY
00595       }
00596     catch (...)
00597       {
00598         this->m_ = 0;
00599         this->n_ = 0;
00600         free(ptr_);
00601         ptr_ = NULL;
00602         free(ind_);
00603         ind_ = NULL;
00604         this->data_ = NULL;
00605       }
00606     if (this->data_ == NULL)
00607       {
00608         this->m_ = 0;
00609         this->n_ = 0;
00610         free(ptr_);
00611         ptr_ = NULL;
00612         free(ind_);
00613         ind_ = NULL;
00614       }
00615     if (this->data_ == NULL && i != 0)
00616       throw NoMemory("Matrix_SymSparse::Matrix_SymSparse(int, int, int)",
00617                      string("Unable to allocate ") + to_str(sizeof(int) * nz)
00618                      + " bytes to store " + to_str(nz) + " values, for a "
00619                      + to_str(i) + " by " + to_str(i) + " matrix.");
00620 #endif
00621   }
00622 
00623 
00625 
00629   template <class T, class Prop, class Storage, class Allocator>
00630   void Matrix_SymSparse<T, Prop, Storage, Allocator>::Resize(int i, int j)
00631   {
00632     if (i < this->m_)
00633       Resize(i, i, ptr_[i]);
00634     else
00635       Resize(i, i, nz_);
00636   }
00637 
00638 
00640 
00645   template <class T, class Prop, class Storage, class Allocator>
00646   void Matrix_SymSparse<T, Prop, Storage, Allocator>
00647   ::Resize(int i, int j, int nz)
00648   {
00649 
00650 #ifdef SELDON_CHECK_DIMENSIONS
00651     if (static_cast<long int>(2 * nz - 2) / static_cast<long int>(i + 1)
00652         >= static_cast<long int>(i))
00653       {
00654         this->m_ = 0;
00655         this->n_ = 0;
00656         nz_ = 0;
00657         ptr_ = NULL;
00658         ind_ = NULL;
00659         this->data_ = NULL;
00660         throw WrongDim("Matrix_SymSparse::Matrix_SymSparse(int, int, int)",
00661                        string("There are more values (") + to_str(nz)
00662                        + string(" values) than elements in the upper")
00663                        + " part of the matrix ("
00664                        + to_str(i) + " by " + to_str(i) + ").");
00665       }
00666 #endif
00667 
00668     if (nz != nz_)
00669       {
00670         // trying to resize ind_ and data_
00671 #ifdef SELDON_CHECK_MEMORY
00672         try
00673           {
00674 #endif
00675 
00676             ind_ = reinterpret_cast<int*>( realloc(reinterpret_cast<void*>(ind_),
00677                                                    nz*sizeof(int)) );
00678 
00679 #ifdef SELDON_CHECK_MEMORY
00680           }
00681         catch (...)
00682           {
00683             this->m_ = 0;
00684             this->n_ = 0;
00685             nz_ = 0;
00686             free(ptr_);
00687             ptr_ = NULL;
00688             ind_ = NULL;
00689             this->data_ = NULL;
00690           }
00691         if (ind_ == NULL)
00692           {
00693             this->m_ = 0;
00694             this->n_ = 0;
00695             nz_ = 0;
00696             free(ptr_);
00697             ptr_ = NULL;
00698             this->data_ = NULL;
00699           }
00700         if (ind_ == NULL && i != 0 && j != 0)
00701           throw NoMemory("Matrix_SymSparse::Resize(int, int, int)",
00702                          string("Unable to allocate ") + to_str(sizeof(int) * nz)
00703                          + " bytes to store " + to_str(nz)
00704                          + " row or column indices, for a "
00705                          + to_str(i) + " by " + to_str(j) + " matrix.");
00706 #endif
00707 
00708         Vector<T, VectFull, Allocator> val;
00709         val.SetData(nz_, this->data_);
00710         val.Resize(nz);
00711 
00712         this->data_ = val.GetData();
00713         nz_ = nz;
00714         val.Nullify();
00715       }
00716 
00717 
00718     if (this->m_ != i)
00719       {
00720 #ifdef SELDON_CHECK_MEMORY
00721         try
00722           {
00723 #endif
00724             // trying to resize ptr_
00725             ptr_ = reinterpret_cast<int*>( realloc(ptr_, (i+1)*
00726                                                    sizeof(int)) );
00727 
00728 #ifdef SELDON_CHECK_MEMORY
00729           }
00730         catch (...)
00731           {
00732             this->m_ = 0;
00733             this->n_ = 0;
00734             nz_ = 0;
00735             ptr_ = NULL;
00736             ind_ = NULL;
00737             this->data_ = NULL;
00738           }
00739         if (ptr_ == NULL)
00740           {
00741             this->m_ = 0;
00742             this->n_ = 0;
00743             nz_ = 0;
00744             ind_ = NULL;
00745             this->data_ = NULL;
00746           }
00747         if (ptr_ == NULL && i != 0 && j != 0)
00748           throw NoMemory("Matrix_SymSparse::Resize(int, int)",
00749                          string("Unable to allocate ")
00750                          + to_str(sizeof(int) * (i+1) )
00751                          + " bytes to store " + to_str(i+1)
00752                          + " row or column start indices, for a "
00753                          + to_str(i) + " by " + to_str(i) + " matrix.");
00754 #endif
00755 
00756         // then filing last values of ptr_ with nz_
00757         for (int k = this->m_; k <= i; k++)
00758           ptr_[k] = this->nz_;
00759       }
00760 
00761     this->m_ = i;
00762     this->n_ = i;
00763   }
00764 
00765 
00767   template <class T, class Prop, class Storage, class Allocator>
00768   inline void Matrix_SymSparse<T, Prop, Storage, Allocator>::
00769   Copy(const Matrix_SymSparse<T, Prop, Storage, Allocator>& A)
00770   {
00771     this->Clear();
00772     int nz = A.GetNonZeros();
00773     int i = A.GetM();
00774     int j = A.GetN();
00775     this->nz_ = nz;
00776     this->m_ = i;
00777     this->n_ = j;
00778     if ((i == 0)||(j == 0))
00779       {
00780         this->m_ = 0;
00781         this->n_ = 0;
00782         this->nz_ = 0;
00783         return;
00784       }
00785 
00786 #ifdef SELDON_CHECK_DIMENSIONS
00787     if (static_cast<long int>(2 * nz_ - 2) / static_cast<long int>(i + 1)
00788         >= static_cast<long int>(i))
00789       {
00790         this->m_ = 0;
00791         this->n_ = 0;
00792         nz_ = 0;
00793         ptr_ = NULL;
00794         ind_ = NULL;
00795         this->data_ = NULL;
00796         throw WrongDim("Matrix_SymSparse::Matrix_SymSparse(int, int, int)",
00797                        string("There are more values (") + to_str(nz)
00798                        + string(" values) than elements in the upper")
00799                        + " part of the matrix ("
00800                        + to_str(i) + " by " + to_str(i) + ").");
00801       }
00802 #endif
00803 
00804 #ifdef SELDON_CHECK_MEMORY
00805     try
00806       {
00807 #endif
00808 
00809         ptr_ = reinterpret_cast<int*>( calloc(i + 1, sizeof(int)) );
00810         memcpy(this->ptr_, A.ptr_, (i + 1) * sizeof(int));
00811 
00812 #ifdef SELDON_CHECK_MEMORY
00813       }
00814     catch (...)
00815       {
00816         this->m_ = 0;
00817         this->n_ = 0;
00818         nz_ = 0;
00819         ptr_ = NULL;
00820         ind_ = NULL;
00821         this->data_ = NULL;
00822       }
00823     if (ptr_ == NULL)
00824       {
00825         this->m_ = 0;
00826         this->n_ = 0;
00827         nz_ = 0;
00828         ind_ = NULL;
00829         this->data_ = NULL;
00830       }
00831     if (ptr_ == NULL && i != 0)
00832       throw NoMemory("Matrix_SymSparse::Matrix_SymSparse(int, int, int)",
00833                      string("Unable to allocate ")
00834                      + to_str(sizeof(int) * (i+1) ) + " bytes to store "
00835                      + to_str(i+1) + " row or column start indices, for a "
00836                      + to_str(i) + " by " + to_str(i) + " matrix.");
00837 #endif
00838 
00839 #ifdef SELDON_CHECK_MEMORY
00840     try
00841       {
00842 #endif
00843 
00844         ind_ = reinterpret_cast<int*>( calloc(nz_, sizeof(int)) );
00845         memcpy(this->ind_, A.ind_, nz_ * sizeof(int));
00846 
00847 #ifdef SELDON_CHECK_MEMORY
00848       }
00849     catch (...)
00850       {
00851         this->m_ = 0;
00852         this->n_ = 0;
00853         nz_ = 0;
00854         free(ptr_);
00855         ptr_ = NULL;
00856         ind_ = NULL;
00857         this->data_ = NULL;
00858       }
00859     if (ind_ == NULL)
00860       {
00861         this->m_ = 0;
00862         this->n_ = 0;
00863         nz_ = 0;
00864         free(ptr_);
00865         ptr_ = NULL;
00866         this->data_ = NULL;
00867       }
00868     if (ind_ == NULL && i != 0)
00869       throw NoMemory("Matrix_SymSparse::Matrix_SymSparse(int, int, int)",
00870                      string("Unable to allocate ") + to_str(sizeof(int) * nz)
00871                      + " bytes to store " + to_str(nz)
00872                      + " row or column indices, for a "
00873                      + to_str(i) + " by " + to_str(i) + " matrix.");
00874 #endif
00875 
00876 #ifdef SELDON_CHECK_MEMORY
00877     try
00878       {
00879 #endif
00880 
00881         this->data_ = this->allocator_.allocate(nz_, this);
00882         this->allocator_.memorycpy(this->data_, A.data_, nz_);
00883 
00884 #ifdef SELDON_CHECK_MEMORY
00885       }
00886     catch (...)
00887       {
00888         this->m_ = 0;
00889         this->n_ = 0;
00890         free(ptr_);
00891         ptr_ = NULL;
00892         free(ind_);
00893         ind_ = NULL;
00894         this->data_ = NULL;
00895       }
00896     if (this->data_ == NULL)
00897       {
00898         this->m_ = 0;
00899         this->n_ = 0;
00900         free(ptr_);
00901         ptr_ = NULL;
00902         free(ind_);
00903         ind_ = NULL;
00904       }
00905     if (this->data_ == NULL && i != 0)
00906       throw NoMemory("Matrix_SymSparse::Matrix_SymSparse(int, int, int)",
00907                      string("Unable to allocate ") + to_str(sizeof(int) * nz)
00908                      + " bytes to store " + to_str(nz) + " values, for a "
00909                      + to_str(i) + " by " + to_str(i) + " matrix.");
00910 #endif
00911 
00912   }
00913 
00914 
00915   /*******************
00916    * BASIC FUNCTIONS *
00917    *******************/
00918 
00919 
00921 
00925   template <class T, class Prop, class Storage, class Allocator>
00926   int Matrix_SymSparse<T, Prop, Storage, Allocator>::GetNonZeros() const
00927   {
00928     return nz_;
00929   }
00930 
00931 
00933 
00937   template <class T, class Prop, class Storage, class Allocator>
00938   int Matrix_SymSparse<T, Prop, Storage, Allocator>::GetDataSize() const
00939   {
00940     return nz_;
00941   }
00942 
00943 
00945 
00949   template <class T, class Prop, class Storage, class Allocator>
00950   int* Matrix_SymSparse<T, Prop, Storage, Allocator>::GetPtr() const
00951   {
00952     return ptr_;
00953   }
00954 
00955 
00957 
00964   template <class T, class Prop, class Storage, class Allocator>
00965   int* Matrix_SymSparse<T, Prop, Storage, Allocator>::GetInd() const
00966   {
00967     return ind_;
00968   }
00969 
00970 
00972 
00975   template <class T, class Prop, class Storage, class Allocator>
00976   int Matrix_SymSparse<T, Prop, Storage, Allocator>::GetPtrSize() const
00977   {
00978     return (this->m_ + 1);
00979   }
00980 
00981 
00983 
00992   template <class T, class Prop, class Storage, class Allocator>
00993   int Matrix_SymSparse<T, Prop, Storage, Allocator>::GetIndSize() const
00994   {
00995     return nz_;
00996   }
00997 
00998 
00999   /**********************************
01000    * ELEMENT ACCESS AND AFFECTATION *
01001    **********************************/
01002 
01003 
01005 
01011   template <class T, class Prop, class Storage, class Allocator>
01012   inline typename Matrix_SymSparse<T, Prop, Storage, Allocator>::value_type
01013   Matrix_SymSparse<T, Prop, Storage, Allocator>::operator() (int i,
01014                                                              int j) const
01015   {
01016 
01017 #ifdef SELDON_CHECK_BOUNDS
01018     if (i < 0 || i >= this->m_)
01019       throw WrongRow("Matrix_SymSparse::operator()",
01020                      string("Index should be in [0, ") + to_str(this->m_-1)
01021                      + "], but is equal to " + to_str(i) + ".");
01022     if (j < 0 || j >= this->n_)
01023       throw WrongCol("Matrix_SymSparse::operator()",
01024                      string("Index should be in [0, ") + to_str(this->n_-1)
01025                      + "], but is equal to " + to_str(j) + ".");
01026 #endif
01027 
01028     int k, l;
01029     int a, b;
01030 
01031     // Only the upper part is stored.
01032     if (i > j)
01033       {
01034         l = i;
01035         i = j;
01036         j = l;
01037       }
01038 
01039     a = ptr_[Storage::GetFirst(i, j)];
01040     b = ptr_[Storage::GetFirst(i, j) + 1];
01041 
01042     if (a == b)
01043       return T(0);
01044 
01045     l = Storage::GetSecond(i, j);
01046 
01047     for (k = a; (k<b-1) && (ind_[k]<l); k++);
01048 
01049     if (ind_[k] == l)
01050       return this->data_[k];
01051     else
01052       return T(0);
01053   }
01054 
01055 
01057 
01065   template <class T, class Prop, class Storage, class Allocator>
01066   inline typename Matrix_SymSparse<T, Prop, Storage, Allocator>::value_type&
01067   Matrix_SymSparse<T, Prop, Storage, Allocator>::Val(int i, int j)
01068   {
01069 
01070 #ifdef SELDON_CHECK_BOUNDS
01071     if (i < 0 || i >= this->m_)
01072       throw WrongRow("Matrix_SymSparse::Val(int, int)",
01073                      string("Index should be in [0, ") + to_str(this->m_-1)
01074                      + "], but is equal to " + to_str(i) + ".");
01075     if (j < 0 || j >= this->n_)
01076       throw WrongCol("Matrix_SymSparse::Val(int, int)",
01077                      string("Index should be in [0, ") + to_str(this->n_-1)
01078                      + "], but is equal to " + to_str(j) + ".");
01079 #endif
01080 
01081     int k, l;
01082     int a, b;
01083 
01084     // Only the upper part is stored.
01085     if (i > j)
01086       {
01087         l = i;
01088         i = j;
01089         j = l;
01090       }
01091 
01092     a = ptr_[Storage::GetFirst(i, j)];
01093     b = ptr_[Storage::GetFirst(i, j) + 1];
01094 
01095     if (a == b)
01096       throw WrongArgument("Matrix_SymSparse::Val(int, int)",
01097                           "No reference to element (" + to_str(i) + ", "
01098                           + to_str(j)
01099                           + ") can be returned: it is a zero entry.");
01100 
01101     l = Storage::GetSecond(i, j);
01102 
01103     for (k = a; (k<b-1) && (ind_[k]<l); k++);
01104 
01105     if (ind_[k] == l)
01106       return this->data_[k];
01107     else
01108       throw WrongArgument("Matrix_SymSparse::Val(int, int)",
01109                           "No reference to element (" + to_str(i) + ", "
01110                           + to_str(j)
01111                           + ") can be returned: it is a zero entry.");
01112   }
01113 
01114 
01116 
01124   template <class T, class Prop, class Storage, class Allocator>
01125   inline
01126   const typename Matrix_SymSparse<T, Prop, Storage, Allocator>::value_type&
01127   Matrix_SymSparse<T, Prop, Storage, Allocator>::Val(int i, int j) const
01128   {
01129 
01130 #ifdef SELDON_CHECK_BOUNDS
01131     if (i < 0 || i >= this->m_)
01132       throw WrongRow("Matrix_SymSparse::Val(int, int)",
01133                      string("Index should be in [0, ") + to_str(this->m_-1)
01134                      + "], but is equal to " + to_str(i) + ".");
01135     if (j < 0 || j >= this->n_)
01136       throw WrongCol("Matrix_SymSparse::Val(int, int)",
01137                      string("Index should be in [0, ") + to_str(this->n_-1)
01138                      + "], but is equal to " + to_str(j) + ".");
01139 #endif
01140 
01141     int k, l;
01142     int a, b;
01143 
01144     // Only the upper part is stored.
01145     if (i > j)
01146       {
01147         l = i;
01148         i = j;
01149         j = l;
01150       }
01151 
01152     a = ptr_[Storage::GetFirst(i, j)];
01153     b = ptr_[Storage::GetFirst(i, j) + 1];
01154 
01155     if (a == b)
01156       throw WrongArgument("Matrix_SymSparse::Val(int, int)",
01157                           "No reference to element (" + to_str(i) + ", "
01158                           + to_str(j)
01159                           + ") can be returned: it is a zero entry.");
01160 
01161     l = Storage::GetSecond(i, j);
01162 
01163     for (k = a; (k<b-1) && (ind_[k]<l); k++);
01164 
01165     if (ind_[k] == l)
01166       return this->data_[k];
01167     else
01168       throw WrongArgument("Matrix_SymSparse::Val(int, int)",
01169                           "No reference to element (" + to_str(i) + ", "
01170                           + to_str(j)
01171                           + ") can be returned: it is a zero entry.");
01172   }
01173 
01174 
01176 
01183   template <class T, class Prop, class Storage, class Allocator>
01184   inline typename Matrix_SymSparse<T, Prop, Storage, Allocator>::value_type&
01185   Matrix_SymSparse<T, Prop, Storage, Allocator>::Get(int i, int j)
01186   {
01187 
01188 #ifdef SELDON_CHECK_BOUNDS
01189     if (i < 0 || i >= this->m_)
01190       throw WrongRow("Matrix_SymSparse::Get(int, int)",
01191                      string("Index should be in [0, ") + to_str(this->m_-1)
01192                      + "], but is equal to " + to_str(i) + ".");
01193     if (j < 0 || j >= this->n_)
01194       throw WrongCol("Matrix_SymSparse::Get(int, int)",
01195                      string("Index should be in [0, ") + to_str(this->n_-1)
01196                      + "], but is equal to " + to_str(j) + ".");
01197 #endif
01198 
01199     int k, l;
01200     int a, b;
01201     // Only the upper part is stored.
01202     if (i > j)
01203       {
01204         l = i;
01205         i = j;
01206         j = l;
01207       }
01208 
01209     a = ptr_[Storage::GetFirst(i, j)];
01210     b = ptr_[Storage::GetFirst(i, j) + 1];
01211 
01212     if (a < b)
01213       {
01214         l = Storage::GetSecond(i, j);
01215 
01216         for (k = a; (k < b) && (ind_[k] < l); k++);
01217 
01218         if ( (k < b) && (ind_[k] == l))
01219           return this->data_[k];
01220       }
01221     else
01222       k = a;
01223 
01224     // adding a non-zero entry
01225     Resize(this->m_, this->n_, nz_+1);
01226 
01227     for (int m = Storage::GetFirst(i, j)+1; m <= this->m_; m++)
01228       ptr_[m]++;
01229 
01230     for (int m = nz_-1; m >= k+1; m--)
01231       {
01232         ind_[m] = ind_[m-1];
01233         this->data_[m] = this->data_[m-1];
01234       }
01235 
01236     ind_[k] = Storage::GetSecond(i, j);
01237 
01238     // value of new non-zero entry is set to 0
01239     SetComplexZero(this->data_[k]);
01240 
01241     return this->data_[k];
01242   }
01243 
01244 
01246 
01251   template <class T, class Prop, class Storage, class Allocator>
01252   inline const typename Matrix_SymSparse<T, Prop, Storage, Allocator>::value_type&
01253   Matrix_SymSparse<T, Prop, Storage, Allocator>::Get(int i, int j) const
01254   {
01255     return Val(i, j);
01256   }
01257 
01258 
01260 
01267   template <class T, class Prop, class Storage, class Allocator>
01268   inline void Matrix_SymSparse<T, Prop, Storage, Allocator>
01269   ::AddInteraction(int i, int j, const T& val)
01270   {
01271     if (i <= j)
01272       Get(i, j) += val;
01273   }
01274 
01275 
01277 
01282   template <class T, class Prop, class Storage, class Allocator>
01283   inline void Matrix_SymSparse<T, Prop, Storage, Allocator>
01284   ::Set(int i, int j, const T& val)
01285   {
01286     Get(i, j) = val;
01287   }
01288 
01289 
01291 
01296   template <class T, class Prop, class Storage, class Allocator>
01297   inline Matrix_SymSparse<T, Prop, Storage, Allocator>&
01298   Matrix_SymSparse<T, Prop, Storage, Allocator>
01299   ::operator= (const Matrix_SymSparse<T, Prop, Storage, Allocator>& A)
01300   {
01301     this->Copy(A);
01302 
01303     return *this;
01304   }
01305 
01306 
01307   /************************
01308    * CONVENIENT FUNCTIONS *
01309    ************************/
01310 
01311 
01313 
01314   template <class T, class Prop, class Storage, class Allocator>
01315   void Matrix_SymSparse<T, Prop, Storage, Allocator>::Zero()
01316   {
01317     this->allocator_.memoryset(this->data_, char(0),
01318                                this->nz_ * sizeof(value_type));
01319   }
01320 
01321 
01323 
01325   template <class T, class Prop, class Storage, class Allocator>
01326   void Matrix_SymSparse<T, Prop, Storage, Allocator>::SetIdentity()
01327   {
01328     int m = this->m_;
01329     int nz = this->m_;
01330 
01331     if (nz == 0)
01332       return;
01333 
01334     Clear();
01335 
01336     Vector<T, VectFull, Allocator> values(nz);
01337     Vector<int, VectFull, CallocAlloc<int> > ptr(m + 1);
01338     Vector<int, VectFull, CallocAlloc<int> > ind(nz);
01339 
01340     values.Fill(T(1));
01341     ind.Fill();
01342     ptr.Fill();
01343 
01344     SetData(m, m, values, ptr, ind);
01345   }
01346 
01347 
01349 
01352   template <class T, class Prop, class Storage, class Allocator>
01353   void Matrix_SymSparse<T, Prop, Storage, Allocator>::Fill()
01354   {
01355     for (int i = 0; i < this->GetDataSize(); i++)
01356       this->data_[i] = i;
01357   }
01358 
01359 
01361 
01364   template <class T, class Prop, class Storage, class Allocator>
01365   template <class T0>
01366   void Matrix_SymSparse<T, Prop, Storage, Allocator>::Fill(const T0& x)
01367   {
01368     for (int i = 0; i < this->GetDataSize(); i++)
01369       this->data_[i] = x;
01370   }
01371 
01372 
01374 
01377   template <class T, class Prop, class Storage, class Allocator>
01378   void Matrix_SymSparse<T, Prop, Storage, Allocator>::FillRand()
01379   {
01380     srand(time(NULL));
01381     for (int i = 0; i < this->GetDataSize(); i++)
01382       this->data_[i] = rand();
01383   }
01384 
01385 
01387 
01392   template <class T, class Prop, class Storage, class Allocator>
01393   void Matrix_SymSparse<T, Prop, Storage, Allocator>::Print() const
01394   {
01395     for (int i = 0; i < this->m_; i++)
01396       {
01397         for (int j = 0; j < this->n_; j++)
01398           cout << (*this)(i, j) << "\t";
01399         cout << endl;
01400       }
01401   }
01402 
01403 
01405 
01409   template <class T, class Prop, class Storage, class Allocator>
01410   void Matrix_SymSparse<T, Prop, Storage, Allocator>
01411   ::Write(string FileName) const
01412   {
01413     ofstream FileStream;
01414     FileStream.open(FileName.c_str());
01415 
01416 #ifdef SELDON_CHECK_IO
01417     // Checks if the file was opened.
01418     if (!FileStream.is_open())
01419       throw IOError("Matrix_SymSparse::Write(string FileName)",
01420                     string("Unable to open file \"") + FileName + "\".");
01421 #endif
01422 
01423     this->Write(FileStream);
01424 
01425     FileStream.close();
01426   }
01427 
01428 
01430 
01434   template <class T, class Prop, class Storage, class Allocator>
01435   void Matrix_SymSparse<T, Prop, Storage, Allocator>
01436   ::Write(ostream& FileStream) const
01437   {
01438 #ifdef SELDON_CHECK_IO
01439     // Checks if the stream is ready.
01440     if (!FileStream.good())
01441       throw IOError("Matrix_SymSparse::Write(ofstream& FileStream)",
01442                     "Stream is not ready.");
01443 #endif
01444 
01445     FileStream.write(reinterpret_cast<char*>(const_cast<int*>(&this->m_)),
01446                      sizeof(int));
01447     FileStream.write(reinterpret_cast<char*>(const_cast<int*>(&this->m_)),
01448                      sizeof(int));
01449     FileStream.write(reinterpret_cast<char*>(const_cast<int*>(&this->nz_)),
01450                      sizeof(int));
01451 
01452     FileStream.write(reinterpret_cast<char*>(this->ptr_),
01453                      sizeof(int)*(this->m_+1));
01454     FileStream.write(reinterpret_cast<char*>(this->ind_),
01455                      sizeof(int)*this->nz_);
01456     FileStream.write(reinterpret_cast<char*>(this->data_),
01457                      sizeof(T)*this->nz_);
01458   }
01459 
01460 
01462 
01467   template <class T, class Prop, class Storage, class Allocator>
01468   void Matrix_SymSparse<T, Prop, Storage, Allocator>
01469   ::WriteText(string FileName) const
01470   {
01471     ofstream FileStream; FileStream.precision(14);
01472     FileStream.open(FileName.c_str());
01473 
01474 #ifdef SELDON_CHECK_IO
01475     // Checks if the file was opened.
01476     if (!FileStream.is_open())
01477       throw IOError("Matrix_SymSparse::WriteText(string FileName)",
01478                     string("Unable to open file \"") + FileName + "\".");
01479 #endif
01480 
01481     this->WriteText(FileStream);
01482 
01483     FileStream.close();
01484   }
01485 
01486 
01488 
01493   template <class T, class Prop, class Storage, class Allocator>
01494   void Matrix_SymSparse<T, Prop, Storage, Allocator>
01495   ::WriteText(ostream& FileStream) const
01496   {
01497 
01498 #ifdef SELDON_CHECK_IO
01499     // Checks if the stream is ready.
01500     if (!FileStream.good())
01501       throw IOError("Matrix_SymSparse::WriteText(ofstream& FileStream)",
01502                     "Stream is not ready.");
01503 #endif
01504 
01505     // Conversion to coordinate format (1-index convention).
01506     IVect IndRow, IndCol;
01507     Vector<T> Value;
01508     const Matrix<T, Prop, Storage, Allocator>& leaf_class =
01509       static_cast<const Matrix<T, Prop, Storage, Allocator>& >(*this);
01510 
01511     ConvertMatrix_to_Coordinates(leaf_class, IndRow, IndCol,
01512                                  Value, 1, true);
01513 
01514     for (int i = 0; i < IndRow.GetM(); i++)
01515       FileStream << IndRow(i) << " " << IndCol(i) << " " << Value(i) << '\n';
01516   }
01517 
01518 
01520 
01524   template <class T, class Prop, class Storage, class Allocator>
01525   void Matrix_SymSparse<T, Prop, Storage, Allocator>
01526   ::Read(string FileName)
01527   {
01528     ifstream FileStream;
01529     FileStream.open(FileName.c_str());
01530 
01531 #ifdef SELDON_CHECK_IO
01532     // Checks if the file was opened.
01533     if (!FileStream.is_open())
01534       throw IOError("Matrix_SymSparse::Read(string FileName)",
01535                     string("Unable to open file \"") + FileName + "\".");
01536 #endif
01537 
01538     this->Read(FileStream);
01539 
01540     FileStream.close();
01541   }
01542 
01543 
01545 
01549   template <class T, class Prop, class Storage, class Allocator>
01550   void Matrix_SymSparse<T, Prop, Storage, Allocator>::
01551   Read(istream& FileStream)
01552   {
01553 
01554 #ifdef SELDON_CHECK_IO
01555     // Checks if the stream is ready.
01556     if (!FileStream.good())
01557       throw IOError("Matrix_SymSparse::Read(ofstream& FileStream)",
01558                     "Stream is not ready.");
01559 #endif
01560 
01561     int m, n, nz;
01562     FileStream.read(reinterpret_cast<char*>(&m), sizeof(int));
01563     FileStream.read(reinterpret_cast<char*>(&n), sizeof(int));
01564     FileStream.read(reinterpret_cast<char*>(&nz), sizeof(int));
01565 
01566     Reallocate(m, m, nz);
01567 
01568     FileStream.read(reinterpret_cast<char*>(ptr_),
01569                     sizeof(int)*(m+1));
01570     FileStream.read(reinterpret_cast<char*>(ind_), sizeof(int)*nz);
01571     FileStream.read(reinterpret_cast<char*>(this->data_), sizeof(T)*nz);
01572 
01573 #ifdef SELDON_CHECK_IO
01574     // Checks if data was read.
01575     if (!FileStream.good())
01576       throw IOError("Matrix_SymSparse::Read(istream& FileStream)",
01577                     string("Input operation failed.")
01578                     + string(" The input file may have been removed")
01579                     + " or may not contain enough data.");
01580 #endif
01581 
01582   }
01583 
01584 
01586 
01590   template <class T, class Prop, class Storage, class Allocator>
01591   void Matrix_SymSparse<T, Prop, Storage, Allocator>::
01592   ReadText(string FileName)
01593   {
01594     ifstream FileStream;
01595     FileStream.open(FileName.c_str());
01596 
01597 #ifdef SELDON_CHECK_IO
01598     // Checks if the file was opened.
01599     if (!FileStream.is_open())
01600       throw IOError("Matrix_SymSparse::ReadText(string FileName)",
01601                     string("Unable to open file \"") + FileName + "\".");
01602 #endif
01603 
01604     this->ReadText(FileStream);
01605 
01606     FileStream.close();
01607   }
01608 
01609 
01611 
01615   template <class T, class Prop, class Storage, class Allocator>
01616   void Matrix_SymSparse<T, Prop, Storage, Allocator>::
01617   ReadText(istream& FileStream)
01618   {
01619     Matrix<T, Prop, Storage, Allocator>& leaf_class =
01620       static_cast<Matrix<T, Prop, Storage, Allocator>& >(*this);
01621 
01622     T zero; int index = 1;
01623     ReadCoordinateMatrix(leaf_class, FileStream, zero, index);
01624   }
01625 
01626 
01628   // MATRIX<COLSYMSPARSE> //
01630 
01631 
01632   /****************
01633    * CONSTRUCTORS *
01634    ****************/
01635 
01637 
01640   template <class T, class Prop, class Allocator>
01641   Matrix<T, Prop, ColSymSparse, Allocator>::Matrix():
01642     Matrix_SymSparse<T, Prop, ColSymSparse, Allocator>()
01643   {
01644   }
01645 
01646 
01648 
01652   template <class T, class Prop, class Allocator>
01653   Matrix<T, Prop, ColSymSparse, Allocator>::Matrix(int i, int j):
01654     Matrix_SymSparse<T, Prop, ColSymSparse, Allocator>(i, j, 0)
01655   {
01656   }
01657 
01658 
01660 
01667   template <class T, class Prop, class Allocator>
01668   Matrix<T, Prop, ColSymSparse, Allocator>::Matrix(int i, int j, int nz):
01669     Matrix_SymSparse<T, Prop, ColSymSparse, Allocator>(i, j, nz)
01670   {
01671   }
01672 
01673 
01675 
01687   template <class T, class Prop, class Allocator>
01688   template <class Storage0, class Allocator0,
01689             class Storage1, class Allocator1,
01690             class Storage2, class Allocator2>
01691   Matrix<T, Prop, ColSymSparse, Allocator>::
01692   Matrix(int i, int j,
01693          Vector<T, Storage0, Allocator0>& values,
01694          Vector<int, Storage1, Allocator1>& ptr,
01695          Vector<int, Storage2, Allocator2>& ind):
01696     Matrix_SymSparse<T, Prop, ColSymSparse, Allocator>(i, j, values, ptr, ind)
01697   {
01698   }
01699 
01700 
01701 
01703   // MATRIX<ROWSYMSPARSE> //
01705 
01706 
01707   /****************
01708    * CONSTRUCTORS *
01709    ****************/
01710 
01711 
01713 
01716   template <class T, class Prop, class Allocator>
01717   Matrix<T, Prop, RowSymSparse, Allocator>::Matrix():
01718     Matrix_SymSparse<T, Prop, RowSymSparse, Allocator>()
01719   {
01720   }
01721 
01722 
01724 
01728   template <class T, class Prop, class Allocator>
01729   Matrix<T, Prop, RowSymSparse, Allocator>::Matrix(int i, int j):
01730     Matrix_SymSparse<T, Prop, RowSymSparse, Allocator>(i, j, 0)
01731   {
01732   }
01733 
01734 
01736 
01743   template <class T, class Prop, class Allocator>
01744   Matrix<T, Prop, RowSymSparse, Allocator>::Matrix(int i, int j, int nz):
01745     Matrix_SymSparse<T, Prop, RowSymSparse, Allocator>(i, j, nz)
01746   {
01747   }
01748 
01749 
01751 
01763   template <class T, class Prop, class Allocator>
01764   template <class Storage0, class Allocator0,
01765             class Storage1, class Allocator1,
01766             class Storage2, class Allocator2>
01767   Matrix<T, Prop, RowSymSparse, Allocator>::
01768   Matrix(int i, int j,
01769          Vector<T, Storage0, Allocator0>& values,
01770          Vector<int, Storage1, Allocator1>& ptr,
01771          Vector<int, Storage2, Allocator2>& ind):
01772     Matrix_SymSparse<T, Prop, RowSymSparse, Allocator>(i, j, values, ptr, ind)
01773   {
01774   }
01775 
01776 
01777 } // namespace Seldon.
01778 
01779 #define SELDON_FILE_MATRIX_SYMSPARSE_CXX
01780 #endif