matrix_sparse/Matrix_SymComplexSparse.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_SYMCOMPLEXSPARSE_CXX
00022 
00023 #include "Matrix_SymComplexSparse.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_SymComplexSparse<T, Prop, Storage, Allocator>
00040   ::Matrix_SymComplexSparse(): Matrix_Base<T, Allocator>()
00041   {
00042     real_nz_ = 0;
00043     imag_nz_ = 0;
00044     real_ptr_ = NULL;
00045     imag_ptr_ = NULL;
00046     real_ind_ = NULL;
00047     imag_ind_ = NULL;
00048     real_data_ = NULL;
00049     imag_data_ = NULL;
00050   }
00051 
00052 
00054 
00060   template <class T, class Prop, class Storage, class Allocator>
00061   inline Matrix_SymComplexSparse<T, Prop, Storage, Allocator>
00062   ::Matrix_SymComplexSparse(int i, int j): Matrix_Base<T, Allocator>(i, i)
00063   {
00064     real_nz_ = 0;
00065     imag_nz_ = 0;
00066     real_ptr_ = NULL;
00067     imag_ptr_ = NULL;
00068     real_ind_ = NULL;
00069     imag_ind_ = NULL;
00070     real_data_ = NULL;
00071     imag_data_ = NULL;
00072   }
00073 
00074 
00076 
00088   template <class T, class Prop, class Storage, class Allocator>
00089   inline Matrix_SymComplexSparse<T, Prop, Storage, Allocator>
00090   ::Matrix_SymComplexSparse(int i, int j, int real_nz, int imag_nz):
00091     Matrix_Base<T, Allocator>(i, i)
00092   {
00093     this->real_nz_ = real_nz;
00094     this->imag_nz_ = imag_nz;
00095 
00096 #ifdef SELDON_CHECK_DIMENSIONS
00097     if ( (static_cast<long int>(2 * real_nz_ - 2) / static_cast<long int>(i+1)
00098           >= static_cast<long int>(i)) ||
00099          (static_cast<long int>(2 * imag_nz_ - 2) / static_cast<long int>(i+1)
00100           >= static_cast<long int>(i)) )
00101       {
00102         this->m_ = 0;
00103         this->n_ = 0;
00104         real_nz_ = 0;
00105         imag_nz_ = 0;
00106         real_ptr_ = NULL;
00107         imag_ptr_ = NULL;
00108         real_ind_ = NULL;
00109         imag_ind_ = NULL;
00110         this->real_data_ = NULL;
00111         this->imag_data_ = NULL;
00112         throw WrongDim(string("Matrix_SymComplexSparse::")
00113                        + "Matrix_SymComplexSparse(int, int, int, int)",
00114                        string("There are more values to be stored (")
00115                        + to_str(real_nz) + " values for the real part and "
00116                        + to_str(imag_nz) + string(" values for the imaginary")
00117                        + " part) than elements in the matrix ("
00118                        + to_str(i) + " by " + to_str(j) + ").");
00119       }
00120 #endif
00121 
00122 #ifdef SELDON_CHECK_MEMORY
00123     try
00124       {
00125 #endif
00126 
00127         real_ptr_ = reinterpret_cast<int*>( calloc(i + 1, sizeof(int)) );
00128 
00129 #ifdef SELDON_CHECK_MEMORY
00130       }
00131     catch (...)
00132       {
00133         this->m_ = 0;
00134         this->n_ = 0;
00135         real_nz_ = 0;
00136         imag_nz_ = 0;
00137         real_ptr_ = NULL;
00138         imag_ptr_ = NULL;
00139         real_ind_ = NULL;
00140         imag_ind_ = NULL;
00141         this->real_data_ = NULL;
00142         this->imag_data_ = NULL;
00143       }
00144     if (real_ptr_ == NULL)
00145       {
00146         this->m_ = 0;
00147         this->n_ = 0;
00148         real_nz_ = 0;
00149         imag_nz_ = 0;
00150         imag_ptr_ = 0;
00151         real_ind_ = NULL;
00152         imag_ind_ = NULL;
00153         this->real_data_ = NULL;
00154         this->imag_data_ = NULL;
00155       }
00156     if (real_ptr_ == NULL && i != 0)
00157       throw NoMemory(string("Matrix_SymComplexSparse::")
00158                      + "Matrix_SymComplexSparse(int, int, int, int)",
00159                      string("Unable to allocate ")
00160                      + to_str(sizeof(int) * (i + 1)) + " bytes to store "
00161                      + to_str(i + 1) + string(" row or column")
00162                      + " start indices (for the real part), for a "
00163                      + to_str(i) + " by " + to_str(i) + " matrix.");
00164 #endif
00165 
00166 #ifdef SELDON_CHECK_MEMORY
00167     try
00168       {
00169 #endif
00170 
00171         imag_ptr_ = reinterpret_cast<int*>( calloc(i + 1, sizeof(int)) );
00172 
00173 #ifdef SELDON_CHECK_MEMORY
00174       }
00175     catch (...)
00176       {
00177         this->m_ = 0;
00178         this->n_ = 0;
00179         real_nz_ = 0;
00180         imag_nz_ = 0;
00181         free(real_ptr_);
00182         real_ptr_ = NULL;
00183         imag_ptr_ = NULL;
00184         real_ind_ = NULL;
00185         imag_ind_ = NULL;
00186         this->real_data_ = NULL;
00187         this->imag_data_ = NULL;
00188       }
00189     if (imag_ptr_ == NULL)
00190       {
00191         this->m_ = 0;
00192         this->n_ = 0;
00193         real_nz_ = 0;
00194         imag_nz_ = 0;
00195         free(real_ptr_);
00196         real_ptr_ = 0;
00197         real_ind_ = NULL;
00198         imag_ind_ = NULL;
00199         this->real_data_ = NULL;
00200         this->imag_data_ = NULL;
00201       }
00202     if (imag_ptr_ == NULL && i != 0)
00203       throw NoMemory(string("Matrix_SymComplexSparse::")
00204                      + "Matrix_SymComplexSparse(int, int, int, int)",
00205                      string("Unable to allocate ")
00206                      + to_str(sizeof(int) * (i + 1) ) + " bytes to store "
00207                      + to_str(i + 1) + string(" row or column")
00208                      + " start indices (for the imaginary part), for a "
00209                      + to_str(i) + " by " + to_str(i) + " matrix.");
00210 #endif
00211 
00212 #ifdef SELDON_CHECK_MEMORY
00213     try
00214       {
00215 #endif
00216 
00217         real_ind_ = reinterpret_cast<int*>( calloc(real_nz_, sizeof(int)) );
00218 
00219 #ifdef SELDON_CHECK_MEMORY
00220       }
00221     catch (...)
00222       {
00223         this->m_ = 0;
00224         this->n_ = 0;
00225         real_nz_ = 0;
00226         imag_nz_ = 0;
00227         free(real_ptr_);
00228         free(imag_ptr_);
00229         real_ptr_ = NULL;
00230         imag_ptr_ = NULL;
00231         real_ind_ = NULL;
00232         imag_ind_ = NULL;
00233         this->real_data_ = NULL;
00234         this->imag_data_ = NULL;
00235       }
00236     if (real_ind_ == NULL)
00237       {
00238         this->m_ = 0;
00239         this->n_ = 0;
00240         real_nz_ = 0;
00241         imag_nz_ = 0;
00242         free(real_ptr_);
00243         free(imag_ptr_);
00244         real_ptr_ = NULL;
00245         imag_ptr_ = NULL;
00246         this->real_data_ = NULL;
00247         this->imag_data_ = NULL;
00248       }
00249     if (real_ind_ == NULL && i != 0)
00250       throw NoMemory(string("Matrix_SymComplexSparse::")
00251                      + "Matrix_SymComplexSparse(int, int, int, int)",
00252                      string("Unable to allocate ")
00253                      + to_str(sizeof(int) * real_nz) + " bytes to store "
00254                      + to_str(real_nz)
00255                      + " row or column indices (real part), for a "
00256                      + to_str(i) + " by " + to_str(i) + " matrix.");
00257 #endif
00258 
00259 #ifdef SELDON_CHECK_MEMORY
00260     try
00261       {
00262 #endif
00263 
00264         imag_ind_ = reinterpret_cast<int*>( calloc(imag_nz_, sizeof(int)) );
00265 
00266 #ifdef SELDON_CHECK_MEMORY
00267       }
00268     catch (...)
00269       {
00270         this->m_ = 0;
00271         this->n_ = 0;
00272         real_nz_ = 0;
00273         imag_nz_ = 0;
00274         free(real_ptr_);
00275         free(imag_ptr_);
00276         real_ptr_ = NULL;
00277         imag_ptr_ = NULL;
00278         free(imag_ind_);
00279         real_ind_ = NULL;
00280         imag_ind_ = NULL;
00281         this->real_data_ = NULL;
00282         this->imag_data_ = NULL;
00283       }
00284     if (real_ind_ == NULL)
00285       {
00286         this->m_ = 0;
00287         this->n_ = 0;
00288         real_nz_ = 0;
00289         imag_nz_ = 0;
00290         free(real_ptr_);
00291         free(imag_ptr_);
00292         real_ptr_ = NULL;
00293         imag_ptr_ = NULL;
00294         free(imag_ind_);
00295         imag_ind_ = NULL;
00296         this->real_data_ = NULL;
00297         this->imag_data_ = NULL;
00298       }
00299     if (imag_ind_ == NULL && i != 0)
00300       throw NoMemory(string("Matrix_SymComplexSparse::")
00301                      + "Matrix_SymComplexSparse(int, int, int, int)",
00302                      string("Unable to allocate ")
00303                      + to_str(sizeof(int) * imag_nz) + " bytes to store "
00304                      + to_str(imag_nz)
00305                      + " row or column indices (imaginary part), for a "
00306                      + to_str(i) + " by " + to_str(i) + " matrix.");
00307 #endif
00308 
00309 #ifdef SELDON_CHECK_MEMORY
00310     try
00311       {
00312 #endif
00313 
00314         this->real_data_ = this->allocator_.allocate(real_nz_, this);
00315 
00316 #ifdef SELDON_CHECK_MEMORY
00317       }
00318     catch (...)
00319       {
00320         this->m_ = 0;
00321         this->n_ = 0;
00322         free(real_ptr_);
00323         free(imag_ptr_);
00324         real_ptr_ = NULL;
00325         imag_ptr_ = NULL;
00326         free(real_ind_);
00327         free(imag_ind_);
00328         real_ind_ = NULL;
00329         imag_ind_ = NULL;
00330         this->real_data_ = NULL;
00331         this->imag_data_ = NULL;
00332       }
00333     if (real_data_ == NULL)
00334       {
00335         this->m_ = 0;
00336         this->n_ = 0;
00337         free(real_ptr_);
00338         free(imag_ptr_);
00339         real_ptr_ = NULL;
00340         imag_ptr_ = NULL;
00341         free(real_ind_);
00342         free(imag_ind_);
00343         real_ind_ = NULL;
00344         imag_ind_ = NULL;
00345         imag_data_ = NULL;
00346       }
00347     if (real_data_ == NULL && i != 0)
00348       throw NoMemory(string("Matrix_SymComplexSparse::")
00349                      + "Matrix_SymComplexSparse(int, int, int, int)",
00350                      string("Unable to allocate ")
00351                      + to_str(sizeof(int) * real_nz) + " bytes to store "
00352                      + to_str(real_nz) + " values (real part), for a "
00353                      + to_str(i) + " by " + to_str(i) + " matrix.");
00354 #endif
00355 
00356 #ifdef SELDON_CHECK_MEMORY
00357     try
00358       {
00359 #endif
00360 
00361         this->imag_data_ = this->allocator_.allocate(imag_nz_, this);
00362 
00363 #ifdef SELDON_CHECK_MEMORY
00364       }
00365     catch (...)
00366       {
00367         this->m_ = 0;
00368         this->n_ = 0;
00369         free(real_ptr_);
00370         free(imag_ptr_);
00371         real_ptr_ = NULL;
00372         imag_ptr_ = NULL;
00373         free(real_ind_);
00374         free(imag_ind_);
00375         real_ind_ = NULL;
00376         imag_ind_ = NULL;
00377         this->allocator_.deallocate(this->real_data_, real_nz_);
00378         this->real_data_ = NULL;
00379         this->imag_data_ = NULL;
00380       }
00381     if (real_data_ == NULL)
00382       {
00383         this->m_ = 0;
00384         this->n_ = 0;
00385         free(real_ptr_);
00386         free(imag_ptr_);
00387         real_ptr_ = NULL;
00388         imag_ptr_ = NULL;
00389         free(real_ind_);
00390         free(imag_ind_);
00391         real_ind_ = NULL;
00392         imag_ind_ = NULL;
00393         this->allocator_.deallocate(this->real_data_, real_nz_);
00394         real_data_ = NULL;
00395       }
00396     if (imag_data_ == NULL && i != 0)
00397       throw NoMemory(string("Matrix_SymComplexSparse::")
00398                      + "Matrix_SymComplexSparse(int, int, int, int)",
00399                      string("Unable to allocate ")
00400                      + to_str(sizeof(int) * imag_nz) + " bytes to store "
00401                      + to_str(imag_nz) + " values (imaginary part), for a "
00402                      + to_str(i) + " by " + to_str(i) + " matrix.");
00403 #endif
00404 
00405   }
00406 
00407 
00409 
00428   template <class T, class Prop, class Storage, class Allocator>
00429   template <class Storage0, class Allocator0,
00430             class Storage1, class Allocator1,
00431             class Storage2, class Allocator2>
00432   inline Matrix_SymComplexSparse<T, Prop, Storage, Allocator>::
00433   Matrix_SymComplexSparse(int i, int j,
00434                           Vector<T, Storage0, Allocator0>& real_values,
00435                           Vector<int, Storage1, Allocator1>& real_ptr,
00436                           Vector<int, Storage2, Allocator2>& real_ind,
00437                           Vector<T, Storage0, Allocator0>& imag_values,
00438                           Vector<int, Storage1, Allocator1>& imag_ptr,
00439                           Vector<int, Storage2, Allocator2>& imag_ind):
00440     Matrix_Base<T, Allocator>(i, j)
00441   {
00442     real_nz_ = real_values.GetLength();
00443     imag_nz_ = imag_values.GetLength();
00444 
00445 #ifdef SELDON_CHECK_DIMENSIONS
00446     // Checks whether vector sizes are acceptable.
00447 
00448     if (real_ind.GetLength() != real_nz_)
00449       {
00450         this->m_ = 0;
00451         this->n_ = 0;
00452         real_nz_ = 0;
00453         imag_nz_ = 0;
00454         real_ptr_ = NULL;
00455         imag_ptr_ = NULL;
00456         real_ind_ = NULL;
00457         imag_ind_ = NULL;
00458         this->real_data_ = NULL;
00459         this->imag_data_ = NULL;
00460         throw WrongDim(string("Matrix_SymComplexSparse::")
00461                        + string("Matrix_SymComplexSparse(int, int, ")
00462                        + string("const Vector&, const Vector&, const Vector&")
00463                        + ", const Vector&, const Vector&, const Vector&)",
00464                        string("There are ") + to_str(real_nz_)
00465                        + " values (real part) but "
00466                        + to_str(real_ind.GetLength())
00467                        + " row or column indices.");
00468       }
00469 
00470     if (imag_ind.GetLength() != imag_nz_)
00471       {
00472         this->m_ = 0;
00473         this->n_ = 0;
00474         real_nz_ = 0;
00475         imag_nz_ = 0;
00476         real_ptr_ = NULL;
00477         imag_ptr_ = NULL;
00478         real_ind_ = NULL;
00479         imag_ind_ = NULL;
00480         this->real_data_ = NULL;
00481         this->imag_data_ = NULL;
00482         throw WrongDim(string("Matrix_SymComplexSparse::")
00483                        + string("Matrix_SymComplexSparse(int, int, ")
00484                        + string("const Vector&, const Vector&, const Vector&")
00485                        + ", const Vector&, const Vector&, const Vector&)",
00486                        string("There are ") + to_str(imag_nz_)
00487                        + " values (imaginary part) but "
00488                        + to_str(imag_ind.GetLength())
00489                        + " row or column indices.");
00490       }
00491 
00492     if (real_ptr.GetLength() - 1 != i)
00493       {
00494         this->m_ = 0;
00495         this->n_ = 0;
00496         real_nz_ = 0;
00497         imag_nz_ = 0;
00498         real_ptr_ = NULL;
00499         imag_ptr_ = NULL;
00500         real_ind_ = NULL;
00501         imag_ind_ = NULL;
00502         this->real_data_ = NULL;
00503         this->imag_data_ = NULL;
00504         throw WrongDim(string("Matrix_SymComplexSparse::")
00505                        + string("Matrix_SymComplexSparse(int, int, ")
00506                        + string("const Vector&, const Vector&, const Vector&")
00507                        + ", const Vector&, const Vector&, const Vector&)",
00508                        string("The vector of start indices (real part)")
00509                        + " contains " + to_str(real_ptr.GetLength()-1)
00510                        + string(" row or column start indices (plus the")
00511                        + " number of non-zero entries) but there are "
00512                        + to_str(i) + " rows or columns ("
00513                        + to_str(i) + " by " + to_str(i) + " matrix).");
00514       }
00515 
00516     if (imag_ptr.GetLength() - 1 != i)
00517       {
00518         this->m_ = 0;
00519         this->n_ = 0;
00520         real_nz_ = 0;
00521         imag_nz_ = 0;
00522         real_ptr_ = NULL;
00523         imag_ptr_ = NULL;
00524         real_ind_ = NULL;
00525         imag_ind_ = NULL;
00526         this->real_data_ = NULL;
00527         this->imag_data_ = NULL;
00528         throw WrongDim(string("Matrix_SymComplexSparse::")
00529                        + string("Matrix_SymComplexSparse(int, int, ")
00530                        + string("const Vector&, const Vector&, const Vector&")
00531                        + ", const Vector&, const Vector&, const Vector&)",
00532                        string("The vector of start indices (imaginary part)")
00533                        + " contains " + to_str(imag_ptr.GetLength()-1)
00534                        + string(" row or column start indices (plus the")
00535                        + " number of non-zero entries) but there are "
00536                        + to_str(i) + " rows or columns ("
00537                        + to_str(i) + " by " + to_str(i) + " matrix).");
00538       }
00539 
00540     if ( (static_cast<long int>(2 * real_nz_ - 2)
00541           / static_cast<long int>(i + 1)
00542           >= static_cast<long int>(i)) ||
00543          (static_cast<long int>(2 * imag_nz_ - 2)
00544           / static_cast<long int>(i + 1)
00545           >= static_cast<long int>(i)) )
00546       {
00547         this->m_ = 0;
00548         this->n_ = 0;
00549         real_nz_ = 0;
00550         imag_nz_ = 0;
00551         real_ptr_ = NULL;
00552         imag_ptr_ = NULL;
00553         real_ind_ = NULL;
00554         imag_ind_ = NULL;
00555         this->real_data_ = NULL;
00556         this->imag_data_ = NULL;
00557         throw WrongDim(string("Matrix_SymComplexSparse::")
00558                        + string("Matrix_SymComplexSparse(int, int, ")
00559                        + string("const Vector&, const Vector&, const Vector&")
00560                        + ", const Vector&, const Vector&, const Vector&)",
00561                        string("There are more values (")
00562                        + to_str(real_values.GetLength())
00563                        + " values for the real part and "
00564                        + to_str(real_values.GetLength()) + " values for"
00565                        + string(" the imaginary part) than elements in the")
00566                        + " matrix (" + to_str(i) + " by " + to_str(i) + ").");
00567       }
00568 #endif
00569 
00570     this->real_ptr_ = real_ptr.GetData();
00571     this->imag_ptr_ = imag_ptr.GetData();
00572     this->real_ind_ = real_ind.GetData();
00573     this->imag_ind_ = imag_ind.GetData();
00574     this->real_data_ = real_values.GetData();
00575     this->imag_data_ = imag_values.GetData();
00576 
00577     real_ptr.Nullify();
00578     imag_ptr.Nullify();
00579     real_ind.Nullify();
00580     imag_ind.Nullify();
00581     real_values.Nullify();
00582     imag_values.Nullify();
00583   }
00584 
00585 
00587   template <class T, class Prop, class Storage, class Allocator>
00588   Matrix_SymComplexSparse<T, Prop, Storage, Allocator>
00589   ::Matrix_SymComplexSparse(const Matrix_SymComplexSparse<T, Prop,
00590                             Storage, Allocator>& A)
00591   {
00592     this->m_ = 0;
00593     this->n_ = 0;
00594     real_nz_ = 0;
00595     imag_nz_ = 0;
00596     real_ptr_ = NULL;
00597     imag_ptr_ = NULL;
00598     real_ind_ = NULL;
00599     imag_ind_ = NULL;
00600     real_data_ = NULL;
00601     imag_data_ = NULL;
00602 
00603     this->Copy(A);
00604   }
00605 
00606 
00607   /**************
00608    * DESTRUCTOR *
00609    **************/
00610 
00611 
00613   template <class T, class Prop, class Storage, class Allocator>
00614   inline Matrix_SymComplexSparse<T, Prop, Storage, Allocator>
00615   ::~Matrix_SymComplexSparse()
00616   {
00617     this->m_ = 0;
00618     this->n_ = 0;
00619 
00620 #ifdef SELDON_CHECK_MEMORY
00621     try
00622       {
00623 #endif
00624 
00625         if (real_ptr_ != NULL)
00626           {
00627             free(real_ptr_);
00628             real_ptr_ = NULL;
00629           }
00630 
00631 #ifdef SELDON_CHECK_MEMORY
00632       }
00633     catch (...)
00634       {
00635         real_ptr_ = NULL;
00636       }
00637 #endif
00638 
00639 #ifdef SELDON_CHECK_MEMORY
00640     try
00641       {
00642 #endif
00643 
00644         if (imag_ptr_ != NULL)
00645           {
00646             free(imag_ptr_);
00647             imag_ptr_ = NULL;
00648           }
00649 
00650 #ifdef SELDON_CHECK_MEMORY
00651       }
00652     catch (...)
00653       {
00654         imag_ptr_ = NULL;
00655       }
00656 #endif
00657 
00658 #ifdef SELDON_CHECK_MEMORY
00659     try
00660       {
00661 #endif
00662 
00663         if (real_ind_ != NULL)
00664           {
00665             free(real_ind_);
00666             real_ind_ = NULL;
00667           }
00668 
00669 #ifdef SELDON_CHECK_MEMORY
00670       }
00671     catch (...)
00672       {
00673         real_ind_ = NULL;
00674       }
00675 #endif
00676 
00677 #ifdef SELDON_CHECK_MEMORY
00678     try
00679       {
00680 #endif
00681 
00682         if (imag_ind_ != NULL)
00683           {
00684             free(imag_ind_);
00685             imag_ind_ = NULL;
00686           }
00687 
00688 #ifdef SELDON_CHECK_MEMORY
00689       }
00690     catch (...)
00691       {
00692         imag_ind_ = NULL;
00693       }
00694 #endif
00695 
00696 #ifdef SELDON_CHECK_MEMORY
00697     try
00698       {
00699 #endif
00700 
00701         if (this->real_data_ != NULL)
00702           {
00703             this->allocator_.deallocate(this->real_data_, real_nz_);
00704             this->real_data_ = NULL;
00705           }
00706 
00707 #ifdef SELDON_CHECK_MEMORY
00708       }
00709     catch (...)
00710       {
00711         this->real_nz_ = 0;
00712         this->real_data_ = NULL;
00713       }
00714 #endif
00715 
00716 #ifdef SELDON_CHECK_MEMORY
00717     try
00718       {
00719 #endif
00720 
00721         if (this->imag_data_ != NULL)
00722           {
00723             this->allocator_.deallocate(this->imag_data_, imag_nz_);
00724             this->imag_data_ = NULL;
00725           }
00726 
00727 #ifdef SELDON_CHECK_MEMORY
00728       }
00729     catch (...)
00730       {
00731         this->imag_nz_ = 0;
00732         this->imag_data_ = NULL;
00733       }
00734 #endif
00735 
00736     this->real_nz_ = 0;
00737     this->imag_nz_ = 0;
00738   }
00739 
00740 
00742 
00745   template <class T, class Prop, class Storage, class Allocator>
00746   inline void Matrix_SymComplexSparse<T, Prop, Storage, Allocator>::Clear()
00747   {
00748     this->~Matrix_SymComplexSparse();
00749   }
00750 
00751 
00752   /*********************
00753    * MEMORY MANAGEMENT *
00754    *********************/
00755 
00756 
00758 
00776   template <class T, class Prop, class Storage, class Allocator>
00777   template <class Storage0, class Allocator0,
00778             class Storage1, class Allocator1,
00779             class Storage2, class Allocator2>
00780   void Matrix_SymComplexSparse<T, Prop, Storage, Allocator>::
00781   SetData(int i, int j,
00782           Vector<T, Storage0, Allocator0>& real_values,
00783           Vector<int, Storage1, Allocator1>& real_ptr,
00784           Vector<int, Storage2, Allocator2>& real_ind,
00785           Vector<T, Storage0, Allocator0>& imag_values,
00786           Vector<int, Storage1, Allocator1>& imag_ptr,
00787           Vector<int, Storage2, Allocator2>& imag_ind)
00788   {
00789     this->Clear();
00790     this->m_ = i;
00791     this->n_ = i;
00792     real_nz_ = real_values.GetLength();
00793     imag_nz_ = imag_values.GetLength();
00794 
00795 #ifdef SELDON_CHECK_DIMENSIONS
00796     // Checks whether vector sizes are acceptable.
00797 
00798     if (real_ind.GetLength() != real_nz_)
00799       {
00800         this->m_ = 0;
00801         this->n_ = 0;
00802         real_nz_ = 0;
00803         imag_nz_ = 0;
00804         real_ptr_ = NULL;
00805         imag_ptr_ = NULL;
00806         real_ind_ = NULL;
00807         imag_ind_ = NULL;
00808         this->real_data_ = NULL;
00809         this->imag_data_ = NULL;
00810         throw WrongDim(string("Matrix_SymComplexSparse::SetData(int, int, ")
00811                        + string("const Vector&, const Vector&, const Vector&")
00812                        + ", const Vector&, const Vector&, const Vector&)",
00813                        string("There are ") + to_str(real_nz_)
00814                        + " values (real part) but "
00815                        + to_str(real_ind.GetLength())
00816                        + " row or column indices.");
00817       }
00818 
00819     if (imag_ind.GetLength() != imag_nz_)
00820       {
00821         this->m_ = 0;
00822         this->n_ = 0;
00823         real_nz_ = 0;
00824         imag_nz_ = 0;
00825         real_ptr_ = NULL;
00826         imag_ptr_ = NULL;
00827         real_ind_ = NULL;
00828         imag_ind_ = NULL;
00829         this->real_data_ = NULL;
00830         this->imag_data_ = NULL;
00831         throw WrongDim(string("Matrix_SymComplexSparse::SetData(int, int, ")
00832                        + string("const Vector&, const Vector&, const Vector&")
00833                        + ", const Vector&, const Vector&, const Vector&)",
00834                        string("There are ") + to_str(imag_nz_)
00835                        + " values (imaginary part) but "
00836                        + to_str(imag_ind.GetLength())
00837                        + " row or column indices.");
00838       }
00839 
00840     if (real_ptr.GetLength() - 1 != i)
00841       {
00842         this->m_ = 0;
00843         this->n_ = 0;
00844         real_nz_ = 0;
00845         imag_nz_ = 0;
00846         real_ptr_ = NULL;
00847         imag_ptr_ = NULL;
00848         real_ind_ = NULL;
00849         imag_ind_ = NULL;
00850         this->real_data_ = NULL;
00851         this->imag_data_ = NULL;
00852         throw WrongDim(string("Matrix_SymComplexSparse::SetData(int, int, ")
00853                        + string("const Vector&, const Vector&, const Vector&")
00854                        + ", const Vector&, const Vector&, const Vector&)",
00855                        string("The vector of start indices (real part)")
00856                        + " contains " + to_str(real_ptr.GetLength() - 1)
00857                        + string(" row or column start indices (plus the")
00858                        + " number of non-zero entries) but there are "
00859                        + to_str(i) + " rows or columns ("
00860                        + to_str(i) + " by " + to_str(i) + " matrix).");
00861       }
00862 
00863     if (imag_ptr.GetLength() - 1 != i)
00864       {
00865         this->m_ = 0;
00866         this->n_ = 0;
00867         real_nz_ = 0;
00868         imag_nz_ = 0;
00869         real_ptr_ = NULL;
00870         imag_ptr_ = NULL;
00871         real_ind_ = NULL;
00872         imag_ind_ = NULL;
00873         this->real_data_ = NULL;
00874         this->imag_data_ = NULL;
00875         throw WrongDim(string("Matrix_SymComplexSparse::SetData(int, int, ")
00876                        + string("const Vector&, const Vector&, const Vector&")
00877                        + ", const Vector&, const Vector&, const Vector&)",
00878                        string("The vector of start indices (imaginary part)")
00879                        + " contains " + to_str(imag_ptr.GetLength()-1)
00880                        + string(" row or column start indices (plus the")
00881                        + " number of non-zero entries) but there are "
00882                        + to_str(i) + " rows or columns ("
00883                        + to_str(i) + " by " + to_str(i) + " matrix).");
00884       }
00885 
00886     if ( (static_cast<long int>(2 * real_nz_ - 2) / static_cast<long int>(i)
00887           >= static_cast<long int>(i + 1)) ||
00888          (static_cast<long int>(2 * imag_nz_ - 2) / static_cast<long int>(i)
00889           >= static_cast<long int>(i + 1)) )
00890       {
00891         this->m_ = 0;
00892         this->n_ = 0;
00893         real_nz_ = 0;
00894         imag_nz_ = 0;
00895         real_ptr_ = NULL;
00896         imag_ptr_ = NULL;
00897         real_ind_ = NULL;
00898         imag_ind_ = NULL;
00899         this->real_data_ = NULL;
00900         this->imag_data_ = NULL;
00901         throw WrongDim(string("Matrix_SymComplexSparse::SetData(int, int, ")
00902                        + string("const Vector&, const Vector&, const Vector&")
00903                        + ", const Vector&, const Vector&, const Vector&)",
00904                        string("There are more values (")
00905                        + to_str(real_values.GetLength())
00906                        + " values for the real part and "
00907                        + to_str(real_values.GetLength()) + string(" values")
00908                        + string(" for the imaginary part) than elements in")
00909                        + " the matrix (" + to_str(i)
00910                        + " by " + to_str(i) + ").");
00911       }
00912 #endif
00913 
00914     this->real_ptr_ = real_ptr.GetData();
00915     this->imag_ptr_ = imag_ptr.GetData();
00916     this->real_ind_ = real_ind.GetData();
00917     this->imag_ind_ = imag_ind.GetData();
00918     this->real_data_ = real_values.GetData();
00919     this->imag_data_ = imag_values.GetData();
00920 
00921     real_ptr.Nullify();
00922     imag_ptr.Nullify();
00923     real_ind.Nullify();
00924     imag_ind.Nullify();
00925     real_values.Nullify();
00926     imag_values.Nullify();
00927   }
00928 
00929 
00931 
00953   template <class T, class Prop, class Storage, class Allocator>
00954   inline void Matrix_SymComplexSparse<T, Prop, Storage, Allocator>::
00955   SetData(int i, int j, int real_nz,
00956           typename Matrix_SymComplexSparse<T, Prop, Storage, Allocator>
00957           ::pointer real_values,
00958           int* real_ptr, int* real_ind, int imag_nz,
00959           typename Matrix_SymComplexSparse<T, Prop, Storage, Allocator>
00960           ::pointer imag_values,
00961           int* imag_ptr, int* imag_ind)
00962   {
00963     this->Clear();
00964 
00965     this->m_ = i;
00966     this->n_ = i;
00967 
00968     this->real_nz_ = real_nz;
00969     this->imag_nz_ = imag_nz;
00970 
00971     real_data_ = real_values;
00972     imag_data_ = imag_values;
00973     real_ind_ = real_ind;
00974     imag_ind_ = imag_ind;
00975     real_ptr_ = real_ptr;
00976     imag_ptr_ = imag_ptr;
00977   }
00978 
00979 
00981 
00985   template <class T, class Prop, class Storage, class Allocator>
00986   inline void Matrix_SymComplexSparse<T, Prop, Storage, Allocator>::Nullify()
00987   {
00988     this->data_ = NULL;
00989     this->m_ = 0;
00990     this->n_ = 0;
00991     real_nz_ = 0;
00992     real_ptr_ = NULL;
00993     real_ind_ = NULL;
00994     imag_nz_ = 0;
00995     imag_ptr_ = NULL;
00996     imag_ind_ = NULL;
00997     real_data_ = NULL;
00998     imag_data_ = NULL;
00999   }
01000 
01001 
01003   template <class T, class Prop, class Storage, class Allocator>
01004   inline void Matrix_SymComplexSparse<T, Prop, Storage, Allocator>::
01005   Copy(const Matrix_SymComplexSparse<T, Prop, Storage, Allocator>& A)
01006   {
01007     this->Clear();
01008     int i = A.m_;
01009     int j = A.n_;
01010     real_nz_ = A.real_nz_;
01011     imag_nz_ = A.imag_nz_;
01012     this->m_ = i;
01013     this->n_ = j;
01014     if ((i == 0)||(j == 0))
01015       {
01016         this->m_ = 0;
01017         this->n_ = 0;
01018         this->real_nz_ = 0;
01019         this->imag_nz_ = 0;
01020         return;
01021       }
01022 
01023 #ifdef SELDON_CHECK_DIMENSIONS
01024     if ( (static_cast<long int>(2 * real_nz_ - 2) / static_cast<long int>(i+1)
01025           >= static_cast<long int>(i)) ||
01026          (static_cast<long int>(2 * imag_nz_ - 2) / static_cast<long int>(i+1)
01027           >= static_cast<long int>(i)) )
01028       {
01029         this->m_ = 0;
01030         this->n_ = 0;
01031         real_nz_ = 0;
01032         imag_nz_ = 0;
01033         real_ptr_ = NULL;
01034         imag_ptr_ = NULL;
01035         real_ind_ = NULL;
01036         imag_ind_ = NULL;
01037         this->real_data_ = NULL;
01038         this->imag_data_ = NULL;
01039         throw WrongDim(string("Matrix_SymComplexSparse::")
01040                        + "Matrix_SymComplexSparse(int, int, int, int)",
01041                        string("There are more values to be stored (")
01042                        + to_str(real_nz_) + " values for the real part and "
01043                        + to_str(imag_nz_) + string(" values for the imaginary")
01044                        + " part) than elements in the matrix ("
01045                        + to_str(i) + " by " + to_str(j) + ").");
01046       }
01047 #endif
01048 
01049 #ifdef SELDON_CHECK_MEMORY
01050     try
01051       {
01052 #endif
01053 
01054         real_ptr_ = reinterpret_cast<int*>( calloc(i + 1, sizeof(int)) );
01055         memcpy(this->real_ptr_, A.real_ptr_, (i + 1) * sizeof(int));
01056 
01057 #ifdef SELDON_CHECK_MEMORY
01058       }
01059     catch (...)
01060       {
01061         this->m_ = 0;
01062         this->n_ = 0;
01063         real_nz_ = 0;
01064         imag_nz_ = 0;
01065         real_ptr_ = NULL;
01066         imag_ptr_ = NULL;
01067         real_ind_ = NULL;
01068         imag_ind_ = NULL;
01069         this->real_data_ = NULL;
01070         this->imag_data_ = NULL;
01071       }
01072     if (real_ptr_ == NULL)
01073       {
01074         this->m_ = 0;
01075         this->n_ = 0;
01076         real_nz_ = 0;
01077         imag_nz_ = 0;
01078         imag_ptr_ = 0;
01079         real_ind_ = NULL;
01080         imag_ind_ = NULL;
01081         this->real_data_ = NULL;
01082         this->imag_data_ = NULL;
01083       }
01084     if (real_ptr_ == NULL && i != 0)
01085       throw NoMemory(string("Matrix_SymComplexSparse::")
01086                      + "Matrix_SymComplexSparse(int, int, int, int)",
01087                      string("Unable to allocate ")
01088                      + to_str(sizeof(int) * (i + 1)) + " bytes to store "
01089                      + to_str(i + 1) + string(" row or column")
01090                      + " start indices (for the real part), for a "
01091                      + to_str(i) + " by " + to_str(i) + " matrix.");
01092 #endif
01093 
01094 #ifdef SELDON_CHECK_MEMORY
01095     try
01096       {
01097 #endif
01098 
01099         imag_ptr_ = reinterpret_cast<int*>( calloc(i + 1, sizeof(int)) );
01100         memcpy(this->imag_ptr_, A.imag_ptr_, (i + 1) * sizeof(int));
01101 
01102 #ifdef SELDON_CHECK_MEMORY
01103       }
01104     catch (...)
01105       {
01106         this->m_ = 0;
01107         this->n_ = 0;
01108         real_nz_ = 0;
01109         imag_nz_ = 0;
01110         free(real_ptr_);
01111         real_ptr_ = NULL;
01112         imag_ptr_ = NULL;
01113         real_ind_ = NULL;
01114         imag_ind_ = NULL;
01115         this->real_data_ = NULL;
01116         this->imag_data_ = NULL;
01117       }
01118     if (imag_ptr_ == NULL)
01119       {
01120         this->m_ = 0;
01121         this->n_ = 0;
01122         real_nz_ = 0;
01123         imag_nz_ = 0;
01124         free(real_ptr_);
01125         real_ptr_ = 0;
01126         real_ind_ = NULL;
01127         imag_ind_ = NULL;
01128         this->real_data_ = NULL;
01129         this->imag_data_ = NULL;
01130       }
01131     if (imag_ptr_ == NULL && i != 0)
01132       throw NoMemory(string("Matrix_SymComplexSparse::")
01133                      + "Matrix_SymComplexSparse(int, int, int, int)",
01134                      string("Unable to allocate ")
01135                      + to_str(sizeof(int) * (i + 1) ) + " bytes to store "
01136                      + to_str(i + 1) + string(" row or column")
01137                      + " start indices (for the imaginary part), for a "
01138                      + to_str(i) + " by " + to_str(i) + " matrix.");
01139 #endif
01140 
01141 #ifdef SELDON_CHECK_MEMORY
01142     try
01143       {
01144 #endif
01145 
01146         real_ind_ = reinterpret_cast<int*>( calloc(real_nz_, sizeof(int)) );
01147         memcpy(this->real_ind_, A.real_ind_, real_nz_ * sizeof(int));
01148 
01149 #ifdef SELDON_CHECK_MEMORY
01150       }
01151     catch (...)
01152       {
01153         this->m_ = 0;
01154         this->n_ = 0;
01155         real_nz_ = 0;
01156         imag_nz_ = 0;
01157         free(real_ptr_);
01158         free(imag_ptr_);
01159         real_ptr_ = NULL;
01160         imag_ptr_ = NULL;
01161         real_ind_ = NULL;
01162         imag_ind_ = NULL;
01163         this->real_data_ = NULL;
01164         this->imag_data_ = NULL;
01165       }
01166     if (real_ind_ == NULL)
01167       {
01168         this->m_ = 0;
01169         this->n_ = 0;
01170         real_nz_ = 0;
01171         imag_nz_ = 0;
01172         free(real_ptr_);
01173         free(imag_ptr_);
01174         real_ptr_ = NULL;
01175         imag_ptr_ = NULL;
01176         this->real_data_ = NULL;
01177         this->imag_data_ = NULL;
01178       }
01179     if (real_ind_ == NULL && i != 0)
01180       throw NoMemory(string("Matrix_SymComplexSparse::")
01181                      + "Matrix_SymComplexSparse(int, int, int, int)",
01182                      string("Unable to allocate ")
01183                      + to_str(sizeof(int) * real_nz_) + " bytes to store "
01184                      + to_str(real_nz_)
01185                      + " row or column indices (real part), for a "
01186                      + to_str(i) + " by " + to_str(i) + " matrix.");
01187 #endif
01188 
01189 #ifdef SELDON_CHECK_MEMORY
01190     try
01191       {
01192 #endif
01193 
01194         imag_ind_ = reinterpret_cast<int*>( calloc(imag_nz_, sizeof(int)) );
01195         memcpy(this->imag_ind_, A.imag_ind_, imag_nz_ * sizeof(int));
01196 
01197 #ifdef SELDON_CHECK_MEMORY
01198       }
01199     catch (...)
01200       {
01201         this->m_ = 0;
01202         this->n_ = 0;
01203         real_nz_ = 0;
01204         imag_nz_ = 0;
01205         free(real_ptr_);
01206         free(imag_ptr_);
01207         real_ptr_ = NULL;
01208         imag_ptr_ = NULL;
01209         free(imag_ind_);
01210         real_ind_ = NULL;
01211         imag_ind_ = NULL;
01212         this->real_data_ = NULL;
01213         this->imag_data_ = NULL;
01214       }
01215     if (real_ind_ == NULL)
01216       {
01217         this->m_ = 0;
01218         this->n_ = 0;
01219         real_nz_ = 0;
01220         imag_nz_ = 0;
01221         free(real_ptr_);
01222         free(imag_ptr_);
01223         real_ptr_ = NULL;
01224         imag_ptr_ = NULL;
01225         free(imag_ind_);
01226         imag_ind_ = NULL;
01227         this->real_data_ = NULL;
01228         this->imag_data_ = NULL;
01229       }
01230     if (imag_ind_ == NULL && i != 0)
01231       throw NoMemory(string("Matrix_SymComplexSparse::")
01232                      + "Matrix_SymComplexSparse(int, int, int, int)",
01233                      string("Unable to allocate ")
01234                      + to_str(sizeof(int) * imag_nz_) + " bytes to store "
01235                      + to_str(imag_nz_)
01236                      + " row or column indices (imaginary part), for a "
01237                      + to_str(i) + " by " + to_str(i) + " matrix.");
01238 #endif
01239 
01240 #ifdef SELDON_CHECK_MEMORY
01241     try
01242       {
01243 #endif
01244 
01245         this->real_data_ = this->allocator_.allocate(real_nz_, this);
01246         this->allocator_.memorycpy(this->real_data_, A.real_data_, real_nz_);
01247 
01248 #ifdef SELDON_CHECK_MEMORY
01249       }
01250     catch (...)
01251       {
01252         this->m_ = 0;
01253         this->n_ = 0;
01254         free(real_ptr_);
01255         free(imag_ptr_);
01256         real_ptr_ = NULL;
01257         imag_ptr_ = NULL;
01258         free(real_ind_);
01259         free(imag_ind_);
01260         real_ind_ = NULL;
01261         imag_ind_ = NULL;
01262         this->real_data_ = NULL;
01263         this->imag_data_ = NULL;
01264       }
01265     if (real_data_ == NULL)
01266       {
01267         this->m_ = 0;
01268         this->n_ = 0;
01269         free(real_ptr_);
01270         free(imag_ptr_);
01271         real_ptr_ = NULL;
01272         imag_ptr_ = NULL;
01273         free(real_ind_);
01274         free(imag_ind_);
01275         real_ind_ = NULL;
01276         imag_ind_ = NULL;
01277         imag_data_ = NULL;
01278       }
01279     if (real_data_ == NULL && i != 0)
01280       throw NoMemory(string("Matrix_SymComplexSparse::")
01281                      + "Matrix_SymComplexSparse(int, int, int, int)",
01282                      string("Unable to allocate ")
01283                      + to_str(sizeof(int) * real_nz_) + " bytes to store "
01284                      + to_str(real_nz_) + " values (real part), for a "
01285                      + to_str(i) + " by " + to_str(i) + " matrix.");
01286 #endif
01287 
01288 #ifdef SELDON_CHECK_MEMORY
01289     try
01290       {
01291 #endif
01292 
01293         this->imag_data_ = this->allocator_.allocate(imag_nz_, this);
01294         this->allocator_.memorycpy(this->imag_data_, A.imag_data_, imag_nz_);
01295 
01296 #ifdef SELDON_CHECK_MEMORY
01297       }
01298     catch (...)
01299       {
01300         this->m_ = 0;
01301         this->n_ = 0;
01302         free(real_ptr_);
01303         free(imag_ptr_);
01304         real_ptr_ = NULL;
01305         imag_ptr_ = NULL;
01306         free(real_ind_);
01307         free(imag_ind_);
01308         real_ind_ = NULL;
01309         imag_ind_ = NULL;
01310         this->allocator_.deallocate(this->real_data_, real_nz_);
01311         this->real_data_ = NULL;
01312         this->imag_data_ = NULL;
01313       }
01314     if (real_data_ == NULL)
01315       {
01316         this->m_ = 0;
01317         this->n_ = 0;
01318         free(real_ptr_);
01319         free(imag_ptr_);
01320         real_ptr_ = NULL;
01321         imag_ptr_ = NULL;
01322         free(real_ind_);
01323         free(imag_ind_);
01324         real_ind_ = NULL;
01325         imag_ind_ = NULL;
01326         this->allocator_.deallocate(this->real_data_, real_nz_);
01327         real_data_ = NULL;
01328       }
01329     if (imag_data_ == NULL && i != 0)
01330       throw NoMemory(string("Matrix_SymComplexSparse::")
01331                      + "Matrix_SymComplexSparse(int, int, int, int)",
01332                      string("Unable to allocate ")
01333                      + to_str(sizeof(int) * imag_nz_) + " bytes to store "
01334                      + to_str(imag_nz_) + " values (imaginary part), for a "
01335                      + to_str(i) + " by " + to_str(i) + " matrix.");
01336 #endif
01337 
01338   }
01339 
01340 
01341   /*******************
01342    * BASIC FUNCTIONS *
01343    *******************/
01344 
01345 
01347 
01353   template <class T, class Prop, class Storage, class Allocator>
01354   int Matrix_SymComplexSparse<T, Prop, Storage, Allocator>
01355   ::GetDataSize() const
01356   {
01357     return real_nz_ + imag_nz_;
01358   }
01359 
01360 
01362 
01366   template <class T, class Prop, class Storage, class Allocator>
01367   int* Matrix_SymComplexSparse<T, Prop, Storage, Allocator>
01368   ::GetRealPtr() const
01369   {
01370     return real_ptr_;
01371   }
01372 
01373 
01375 
01379   template <class T, class Prop, class Storage, class Allocator>
01380   int* Matrix_SymComplexSparse<T, Prop, Storage, Allocator>
01381   ::GetImagPtr() const
01382   {
01383     return imag_ptr_;
01384   }
01385 
01386 
01388 
01395   template <class T, class Prop, class Storage, class Allocator>
01396   int* Matrix_SymComplexSparse<T, Prop, Storage, Allocator>
01397   ::GetRealInd() const
01398   {
01399     return real_ind_;
01400   }
01401 
01402 
01405 
01412   template <class T, class Prop, class Storage, class Allocator>
01413   int* Matrix_SymComplexSparse<T, Prop, Storage, Allocator>
01414   ::GetImagInd() const
01415   {
01416     return imag_ind_;
01417   }
01418 
01419 
01421 
01424   template <class T, class Prop, class Storage, class Allocator>
01425   int Matrix_SymComplexSparse<T, Prop, Storage, Allocator>
01426   ::GetRealPtrSize() const
01427   {
01428     return (this->m_ + 1);
01429   }
01430 
01431 
01433 
01436   template <class T, class Prop, class Storage, class Allocator>
01437   int Matrix_SymComplexSparse<T, Prop, Storage, Allocator>
01438   ::GetImagPtrSize() const
01439   {
01440     return (this->m_ + 1);
01441   }
01442 
01443 
01446 
01456   template <class T, class Prop, class Storage, class Allocator>
01457   int Matrix_SymComplexSparse<T, Prop, Storage, Allocator>
01458   ::GetRealIndSize() const
01459   {
01460     return real_nz_;
01461   }
01462 
01463 
01466 
01476   template <class T, class Prop, class Storage, class Allocator>
01477   int Matrix_SymComplexSparse<T, Prop, Storage, Allocator>
01478   ::GetImagIndSize() const
01479   {
01480     return imag_nz_;
01481   }
01482 
01483 
01485 
01488   template <class T, class Prop, class Storage, class Allocator>
01489   T* Matrix_SymComplexSparse<T, Prop, Storage, Allocator>::GetRealData() const
01490   {
01491     return real_data_;
01492   }
01493 
01494 
01496 
01499   template <class T, class Prop, class Storage, class Allocator>
01500   T* Matrix_SymComplexSparse<T, Prop, Storage, Allocator>::GetImagData() const
01501   {
01502     return imag_data_;
01503   }
01504 
01505 
01506   /**********************************
01507    * ELEMENT ACCESS AND AFFECTATION *
01508    **********************************/
01509 
01510 
01512 
01518   template <class T, class Prop, class Storage, class Allocator>
01519   inline complex<typename Matrix_SymComplexSparse<T, Prop, Storage, Allocator>
01520                  ::value_type>
01521   Matrix_SymComplexSparse<T, Prop, Storage, Allocator>
01522   ::operator() (int i, int j) const
01523   {
01524 
01525 #ifdef SELDON_CHECK_BOUNDS
01526     if (i < 0 || i >= this->m_)
01527       throw WrongRow("Matrix_SymComplexSparse::operator()",
01528                      string("Index should be in [0, ") + to_str(this->m_-1)
01529                      + "], but is equal to " + to_str(i) + ".");
01530     if (j < 0 || j >= this->n_)
01531       throw WrongCol("Matrix_SymComplexSparse::operator()",
01532                      string("Index should be in [0, ") + to_str(this->n_-1)
01533                      + "], but is equal to " + to_str(j) + ".");
01534 #endif
01535 
01536     int real_k, imag_k, l;
01537     int real_a, real_b;
01538     int imag_a, imag_b;
01539 
01540     // Only the upper part is stored.
01541     if (i > j)
01542       {
01543         l = i;
01544         i = j;
01545         j = l;
01546       }
01547 
01548     real_a = real_ptr_[Storage::GetFirst(i, j)];
01549     real_b = real_ptr_[Storage::GetFirst(i, j) + 1];
01550 
01551     imag_a = imag_ptr_[Storage::GetFirst(i, j)];
01552     imag_b = imag_ptr_[Storage::GetFirst(i, j) + 1];
01553 
01554     if (real_a != real_b)
01555       {
01556         l = Storage::GetSecond(i, j);
01557         for (real_k = real_a;
01558              (real_k < real_b - 1) && (real_ind_[real_k] < l);
01559              real_k++);
01560         if (imag_a != imag_b)
01561           {
01562             for (imag_k = imag_a;
01563                  (imag_k < imag_b - 1) && (imag_ind_[imag_k] < l);
01564                  imag_k++);
01565             if (real_ind_[real_k] == l)
01566               {
01567                 if (imag_ind_[imag_k] == l)
01568                   return complex<T>(real_data_[real_k], imag_data_[imag_k]);
01569                 else
01570                   return complex<T>(real_data_[real_k], T(0));
01571               }
01572             else
01573               if (imag_ind_[imag_k] == l)
01574                 return complex<T>(T(0), imag_data_[imag_k]);
01575               else
01576                 return complex<T>(T(0), T(0));
01577           }
01578         else
01579           {
01580             if (real_ind_[real_k] == l)
01581               return complex<T>(real_data_[real_k], T(0));
01582             else
01583               return complex<T>(T(0), T(0));
01584           }
01585       }
01586     else
01587       {
01588         if (imag_a != imag_b)
01589           {
01590             l = Storage::GetSecond(i, j);
01591             for (imag_k = imag_a;
01592                  (imag_k < imag_b - 1) && (imag_ind_[imag_k] < l);
01593                  imag_k++);
01594             if (imag_ind_[imag_k] == l)
01595               return complex<T>(T(0), imag_data_[imag_k]);
01596             else
01597               return complex<T>(T(0), T(0));
01598           }
01599         else
01600           return complex<T>(T(0), T(0));
01601       }
01602   }
01603 
01604 
01606 
01612   template <class T, class Prop, class Storage, class Allocator>
01613   inline complex<typename Matrix_SymComplexSparse<T, Prop, Storage, Allocator>
01614                  ::value_type>&
01615   Matrix_SymComplexSparse<T, Prop, Storage, Allocator>
01616   ::Val(int i, int j)
01617   {
01618     throw Undefined("Matrix_SymComplexSparse::Val(int i, int j)");
01619   }
01620 
01621 
01623 
01629   template <class T, class Prop, class Storage, class Allocator>
01630   inline
01631   const complex<typename Matrix_SymComplexSparse<T, Prop, Storage, Allocator>
01632                 ::value_type>&
01633   Matrix_SymComplexSparse<T, Prop, Storage, Allocator>
01634   ::Val(int i, int j) const
01635   {
01636     throw Undefined("Matrix_SymComplexSparse::Val(int i, int j)");
01637   }
01638 
01639 
01641 
01646   template <class T, class Prop, class Storage, class Allocator>
01647   inline Matrix_SymComplexSparse<T, Prop, Storage, Allocator>&
01648   Matrix_SymComplexSparse<T, Prop, Storage, Allocator>
01649   ::operator= (const Matrix_SymComplexSparse<T, Prop, Storage, Allocator>& A)
01650   {
01651     this->Copy(A);
01652 
01653     return *this;
01654   }
01655 
01656 
01657   /************************
01658    * CONVENIENT FUNCTIONS *
01659    ************************/
01660 
01661 
01663 
01668   template <class T, class Prop, class Storage, class Allocator>
01669   void Matrix_SymComplexSparse<T, Prop, Storage, Allocator>::Print() const
01670   {
01671     for (int i = 0; i < this->m_; i++)
01672       {
01673         for (int j = 0; j < this->n_; j++)
01674           cout << (*this)(i, j) << "\t";
01675         cout << endl;
01676       }
01677   }
01678 
01679 
01680 
01682   // MATRIX<COLSYMCOMPLEXSPARSE> //
01684 
01685 
01686   /****************
01687    * CONSTRUCTORS *
01688    ****************/
01689 
01691 
01694   template <class T, class Prop, class Allocator>
01695   Matrix<T, Prop, ColSymComplexSparse, Allocator>::Matrix()  throw():
01696     Matrix_SymComplexSparse<T, Prop, ColSymComplexSparse, Allocator>()
01697   {
01698   }
01699 
01700 
01702 
01706   template <class T, class Prop, class Allocator>
01707   Matrix<T, Prop, ColSymComplexSparse, Allocator>
01708   ::Matrix(int i, int j):
01709     Matrix_SymComplexSparse<T, Prop, ColSymComplexSparse, Allocator>(i, j,
01710                                                                      0, 0)
01711   {
01712   }
01713 
01714 
01716 
01727   template <class T, class Prop, class Allocator>
01728   Matrix<T, Prop, ColSymComplexSparse, Allocator>::Matrix(int i, int j,
01729                                                           int real_nz,
01730                                                           int imag_nz):
01731     Matrix_SymComplexSparse<T, Prop,
01732     ColSymComplexSparse, Allocator>(i, j,
01733                                     real_nz, imag_nz)
01734   {
01735   }
01736 
01737 
01739 
01758   template <class T, class Prop, class Allocator>
01759   template <class Storage0, class Allocator0,
01760             class Storage1, class Allocator1,
01761             class Storage2, class Allocator2>
01762   Matrix<T, Prop, ColSymComplexSparse, Allocator>::
01763   Matrix(int i, int j,
01764          Vector<T, Storage0, Allocator0>& real_values,
01765          Vector<int, Storage1, Allocator1>& real_ptr,
01766          Vector<int, Storage2, Allocator2>& real_ind,
01767          Vector<T, Storage0, Allocator0>& imag_values,
01768          Vector<int, Storage1, Allocator1>& imag_ptr,
01769          Vector<int, Storage2, Allocator2>& imag_ind):
01770     Matrix_SymComplexSparse<T, Prop,
01771     ColSymComplexSparse, Allocator>(i, j,
01772                                     real_values,
01773                                     real_ptr,
01774                                     real_ind,
01775                                     imag_values,
01776                                     imag_ptr,
01777                                     imag_ind)
01778   {
01779   }
01780 
01781 
01782 
01784   // MATRIX<ROWSYMCOMPLEXSPARSE> //
01786 
01787 
01788   /****************
01789    * CONSTRUCTORS *
01790    ****************/
01791 
01793 
01796   template <class T, class Prop, class Allocator>
01797   Matrix<T, Prop, RowSymComplexSparse, Allocator>::Matrix()  throw():
01798     Matrix_SymComplexSparse<T, Prop, RowSymComplexSparse, Allocator>()
01799   {
01800   }
01801 
01802 
01804 
01808   template <class T, class Prop, class Allocator>
01809   Matrix<T, Prop, RowSymComplexSparse, Allocator>
01810   ::Matrix(int i, int j):
01811     Matrix_SymComplexSparse<T, Prop, RowSymComplexSparse, Allocator>(i, j,
01812                                                                      0, 0)
01813   {
01814   }
01815 
01816 
01828   template <class T, class Prop, class Allocator>
01829   Matrix<T, Prop, RowSymComplexSparse, Allocator>
01830   ::Matrix(int i, int j, int real_nz, int imag_nz):
01831     Matrix_SymComplexSparse<T, Prop, RowSymComplexSparse, Allocator>(i, j,
01832                                                                      real_nz,
01833                                                                      imag_nz)
01834   {
01835   }
01836 
01837 
01839 
01858   template <class T, class Prop, class Allocator>
01859   template <class Storage0, class Allocator0,
01860             class Storage1, class Allocator1,
01861             class Storage2, class Allocator2>
01862   Matrix<T, Prop, RowSymComplexSparse, Allocator>::
01863   Matrix(int i, int j,
01864          Vector<T, Storage0, Allocator0>& real_values,
01865          Vector<int, Storage1, Allocator1>& real_ptr,
01866          Vector<int, Storage2, Allocator2>& real_ind,
01867          Vector<T, Storage0, Allocator0>& imag_values,
01868          Vector<int, Storage1, Allocator1>& imag_ptr,
01869          Vector<int, Storage2, Allocator2>& imag_ind):
01870     Matrix_SymComplexSparse<T, Prop,
01871     RowSymComplexSparse, Allocator>(i, j,
01872                                     real_values,
01873                                     real_ptr,
01874                                     real_ind,
01875                                     imag_values,
01876                                     imag_ptr,
01877                                     imag_ind)
01878   {
01879   }
01880 
01881 
01882 } // namespace Seldon.
01883 
01884 #define SELDON_FILE_MATRIX_SYMCOMPLEXSPARSE_CXX
01885 #endif