00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef SELDON_FILE_MATRIX_SYMSPARSE_CXX
00022
00023 #include "Matrix_SymSparse.hxx"
00024
00025 namespace Seldon
00026 {
00027
00028
00029
00030
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>(i, i)
00058 {
00059 nz_ = 0;
00060 ptr_ = NULL;
00061 ind_ = NULL;
00062 }
00063
00064
00066
00075 template <class T, class Prop, class Storage, class Allocator>
00076 inline Matrix_SymSparse<T, Prop, Storage, Allocator>::
00077 Matrix_SymSparse(int i, int j, int nz):
00078 Matrix_Base<T, Allocator>(i, i)
00079 {
00080 this->nz_ = nz;
00081
00082 #ifdef SELDON_CHECK_DIMENSIONS
00083 if (static_cast<long int>(2 * nz_ - 2) / static_cast<long int>(i + 1)
00084 >= static_cast<long int>(i))
00085 {
00086 this->m_ = 0;
00087 this->n_ = 0;
00088 nz_ = 0;
00089 ptr_ = NULL;
00090 ind_ = NULL;
00091 this->data_ = NULL;
00092 throw WrongDim("Matrix_SymSparse::Matrix_SymSparse(int, int, int)",
00093 string("There are more values (") + to_str(nz)
00094 + string(" values) than elements in the upper")
00095 + " part of the matrix ("
00096 + to_str(i) + " by " + to_str(i) + ").");
00097 }
00098 #endif
00099
00100 #ifdef SELDON_CHECK_MEMORY
00101 try
00102 {
00103 #endif
00104
00105 ptr_ = reinterpret_cast<int*>( calloc(i + 1, sizeof(int)) );
00106
00107 #ifdef SELDON_CHECK_MEMORY
00108 }
00109 catch (...)
00110 {
00111 this->m_ = 0;
00112 this->n_ = 0;
00113 nz_ = 0;
00114 ptr_ = NULL;
00115 ind_ = NULL;
00116 this->data_ = NULL;
00117 }
00118 if (ptr_ == NULL)
00119 {
00120 this->m_ = 0;
00121 this->n_ = 0;
00122 nz_ = 0;
00123 ind_ = NULL;
00124 this->data_ = NULL;
00125 }
00126 if (ptr_ == NULL && i != 0)
00127 throw NoMemory("Matrix_SymSparse::Matrix_SymSparse(int, int, int)",
00128 string("Unable to allocate ")
00129 + to_str(sizeof(int) * (i+1) ) + " bytes to store "
00130 + to_str(i+1) + " row or column start indices, for a "
00131 + to_str(i) + " by " + to_str(i) + " matrix.");
00132 #endif
00133
00134 #ifdef SELDON_CHECK_MEMORY
00135 try
00136 {
00137 #endif
00138
00139 ind_ = reinterpret_cast<int*>( calloc(nz_, sizeof(int)) );
00140
00141 #ifdef SELDON_CHECK_MEMORY
00142 }
00143 catch (...)
00144 {
00145 this->m_ = 0;
00146 this->n_ = 0;
00147 nz_ = 0;
00148 free(ptr_);
00149 ptr_ = NULL;
00150 ind_ = NULL;
00151 this->data_ = NULL;
00152 }
00153 if (ind_ == NULL)
00154 {
00155 this->m_ = 0;
00156 this->n_ = 0;
00157 nz_ = 0;
00158 free(ptr_);
00159 ptr_ = NULL;
00160 this->data_ = NULL;
00161 }
00162 if (ind_ == NULL && i != 0)
00163 throw NoMemory("Matrix_SymSparse::Matrix_SymSparse(int, int, int)",
00164 string("Unable to allocate ") + to_str(sizeof(int) * nz)
00165 + " bytes to store " + to_str(nz)
00166 + " row or column indices, for a "
00167 + to_str(i) + " by " + to_str(i) + " matrix.");
00168 #endif
00169
00170 #ifdef SELDON_CHECK_MEMORY
00171 try
00172 {
00173 #endif
00174
00175 this->data_ = this->allocator_.allocate(nz_, this);
00176
00177 #ifdef SELDON_CHECK_MEMORY
00178 }
00179 catch (...)
00180 {
00181 this->m_ = 0;
00182 this->n_ = 0;
00183 free(ptr_);
00184 ptr_ = NULL;
00185 free(ind_);
00186 ind_ = NULL;
00187 this->data_ = NULL;
00188 }
00189 if (this->data_ == NULL)
00190 {
00191 this->m_ = 0;
00192 this->n_ = 0;
00193 free(ptr_);
00194 ptr_ = NULL;
00195 free(ind_);
00196 ind_ = NULL;
00197 }
00198 if (this->data_ == NULL && i != 0)
00199 throw NoMemory("Matrix_SymSparse::Matrix_SymSparse(int, int, int)",
00200 string("Unable to allocate ") + to_str(sizeof(int) * nz)
00201 + " bytes to store " + to_str(nz) + " values, for a "
00202 + to_str(i) + " by " + to_str(i) + " matrix.");
00203 #endif
00204
00205 }
00206
00207
00209
00221 template <class T, class Prop, class Storage, class Allocator>
00222 template <class Storage0, class Allocator0,
00223 class Storage1, class Allocator1,
00224 class Storage2, class Allocator2>
00225 inline Matrix_SymSparse<T, Prop, Storage, Allocator>::
00226 Matrix_SymSparse(int i, int j,
00227 Vector<T, Storage0, Allocator0>& values,
00228 Vector<int, Storage1, Allocator1>& ptr,
00229 Vector<int, Storage2, Allocator2>& ind):
00230 Matrix_Base<T, Allocator>(i, j)
00231 {
00232 nz_ = values.GetLength();
00233
00234 #ifdef SELDON_CHECK_DIMENSIONS
00235
00236
00237 if (ind.GetLength() != nz_)
00238 {
00239 this->m_ = 0;
00240 this->n_ = 0;
00241 nz_ = 0;
00242 ptr_ = NULL;
00243 ind_ = NULL;
00244 this->data_ = NULL;
00245 throw WrongDim(string("Matrix_SymSparse::Matrix_SymSparse(int, int, ")
00246 + "const Vector&, const Vector&, const Vector&)",
00247 string("There are ") + to_str(nz_) + " values but "
00248 + to_str(ind.GetLength()) + " row or column indices.");
00249 }
00250
00251 if (ptr.GetLength() - 1 != i)
00252 {
00253 this->m_ = 0;
00254 this->n_ = 0;
00255 nz_ = 0;
00256 ptr_ = NULL;
00257 ind_ = NULL;
00258 this->data_ = NULL;
00259 throw WrongDim(string("Matrix_SymSparse::Matrix_SymSparse(int, int, ")
00260 + "const Vector&, const Vector&, const Vector&)",
00261 string("The vector of start indices contains ")
00262 + to_str(ptr.GetLength()-1) + string(" row or column ")
00263 + string("start indices (plus the number of non-zero")
00264 + " entries) but there are " + to_str(i)
00265 + " rows or columns ("
00266 + to_str(i) + " by " + to_str(i) + " matrix).");
00267 }
00268
00269 if (static_cast<long int>(2 * nz_ - 2) / static_cast<long int>(i + 1)
00270 >= static_cast<long int>(i))
00271 {
00272 this->m_ = 0;
00273 this->n_ = 0;
00274 nz_ = 0;
00275 ptr_ = NULL;
00276 ind_ = NULL;
00277 this->data_ = NULL;
00278 throw WrongDim(string("Matrix_SymSparse::Matrix_SymSparse(int, int, ")
00279 + "const Vector&, const Vector&, const Vector&)",
00280 string("There are more values (")
00281 + to_str(values.GetLength())
00282 + " values) than elements in the matrix ("
00283 + to_str(i) + " by " + to_str(i) + ").");
00284 }
00285 #endif
00286
00287 this->ptr_ = ptr.GetData();
00288 this->ind_ = ind.GetData();
00289 this->data_ = values.GetData();
00290
00291 ptr.Nullify();
00292 ind.Nullify();
00293 values.Nullify();
00294 }
00295
00296
00298 template <class T, class Prop, class Storage, class Allocator>
00299 inline Matrix_SymSparse<T, Prop, Storage, Allocator>::
00300 Matrix_SymSparse(const Matrix_SymSparse<T, Prop, Storage, Allocator>& A)
00301 {
00302 this->m_ = 0;
00303 this->n_ = 0;
00304 this->nz_ = 0;
00305 ptr_ = NULL;
00306 ind_ = NULL;
00307 this->Copy(A);
00308 }
00309
00310
00311
00312
00313
00314
00315
00317 template <class T, class Prop, class Storage, class Allocator>
00318 inline Matrix_SymSparse<T, Prop, Storage, Allocator>::~Matrix_SymSparse()
00319 {
00320 this->m_ = 0;
00321 this->n_ = 0;
00322
00323 #ifdef SELDON_CHECK_MEMORY
00324 try
00325 {
00326 #endif
00327
00328 if (ptr_ != NULL)
00329 {
00330 free(ptr_);
00331 ptr_ = NULL;
00332 }
00333
00334 #ifdef SELDON_CHECK_MEMORY
00335 }
00336 catch (...)
00337 {
00338 ptr_ = NULL;
00339 }
00340 #endif
00341
00342 #ifdef SELDON_CHECK_MEMORY
00343 try
00344 {
00345 #endif
00346
00347 if (ind_ != NULL)
00348 {
00349 free(ind_);
00350 ind_ = NULL;
00351 }
00352
00353 #ifdef SELDON_CHECK_MEMORY
00354 }
00355 catch (...)
00356 {
00357 ind_ = NULL;
00358 }
00359 #endif
00360
00361 #ifdef SELDON_CHECK_MEMORY
00362 try
00363 {
00364 #endif
00365
00366 if (this->data_ != NULL)
00367 {
00368 this->allocator_.deallocate(this->data_, nz_);
00369 this->data_ = NULL;
00370 }
00371
00372 #ifdef SELDON_CHECK_MEMORY
00373 }
00374 catch (...)
00375 {
00376 this->nz_ = 0;
00377 this->data_ = NULL;
00378 }
00379 #endif
00380
00381 this->nz_ = 0;
00382 }
00383
00384
00386
00389 template <class T, class Prop, class Storage, class Allocator>
00390 inline void Matrix_SymSparse<T, Prop, Storage, Allocator>::Clear()
00391 {
00392 this->~Matrix_SymSparse();
00393 }
00394
00395
00396
00397
00398
00399
00400
00402
00413 template <class T, class Prop, class Storage, class Allocator>
00414 template <class Storage0, class Allocator0,
00415 class Storage1, class Allocator1,
00416 class Storage2, class Allocator2>
00417 void Matrix_SymSparse<T, Prop, Storage, Allocator>::
00418 SetData(int i, int j,
00419 Vector<T, Storage0, Allocator0>& values,
00420 Vector<int, Storage1, Allocator1>& ptr,
00421 Vector<int, Storage2, Allocator2>& ind)
00422 {
00423 this->Clear();
00424 this->m_ = i;
00425 this->n_ = i;
00426 this->nz_ = values.GetLength();
00427
00428 #ifdef SELDON_CHECK_DIMENSIONS
00429
00430
00431 if (ind.GetLength() != nz_)
00432 {
00433 this->m_ = 0;
00434 this->n_ = 0;
00435 nz_ = 0;
00436 ptr_ = NULL;
00437 ind_ = NULL;
00438 this->data_ = NULL;
00439 throw WrongDim(string("Matrix_SymSparse::Reallocate(int, int, ")
00440 + "const Vector&, const Vector&, const Vector&)",
00441 string("There are ") + to_str(nz_) + " values but "
00442 + to_str(ind.GetLength()) + " row or column indices.");
00443 }
00444
00445 if (ptr.GetLength()-1 != i)
00446 {
00447 this->m_ = 0;
00448 this->n_ = 0;
00449 nz_ = 0;
00450 ptr_ = NULL;
00451 ind_ = NULL;
00452 this->data_ = NULL;
00453 throw WrongDim(string("Matrix_SymSparse::Reallocate(int, int, ")
00454 + "const Vector&, const Vector&, const Vector&)",
00455 string("The vector of start indices contains ")
00456 + to_str(ptr.GetLength()-1) + string(" row or column")
00457 + string(" start indices (plus the number of")
00458 + string(" non-zero entries) but there are ")
00459 + to_str(i) + " rows or columns ("
00460 + to_str(i) + " by " + to_str(i) + " matrix).");
00461 }
00462
00463 if (static_cast<long int>(2 * nz_ - 2) / static_cast<long int>(i + 1)
00464 >= static_cast<long int>(i))
00465 {
00466 this->m_ = 0;
00467 this->n_ = 0;
00468 nz_ = 0;
00469 ptr_ = NULL;
00470 ind_ = NULL;
00471 this->data_ = NULL;
00472 throw WrongDim(string("Matrix_SymSparse::Reallocate(int, int, ")
00473 + "const Vector&, const Vector&, const Vector&)",
00474 string("There are more values (")
00475 + to_str(values.GetLength())
00476 + " values) than elements in the matrix ("
00477 + to_str(i) + " by " + to_str(i) + ").");
00478 }
00479 #endif
00480
00481 this->ptr_ = ptr.GetData();
00482 this->ind_ = ind.GetData();
00483 this->data_ = values.GetData();
00484
00485 ptr.Nullify();
00486 ind.Nullify();
00487 values.Nullify();
00488 }
00489
00490
00492
00506 template <class T, class Prop, class Storage, class Allocator>
00507 inline void Matrix_SymSparse<T, Prop, Storage, Allocator>
00508 ::SetData(int i, int j, int nz,
00509 typename Matrix_SymSparse<T, Prop, Storage, Allocator>
00510 ::pointer values,
00511 int* ptr,
00512 int* ind)
00513 {
00514 this->Clear();
00515
00516 this->m_ = i;
00517 this->n_ = i;
00518
00519 this->nz_ = nz;
00520
00521 this->data_ = values;
00522 ind_ = ind;
00523 ptr_ = ptr;
00524 }
00525
00526
00528
00532 template <class T, class Prop, class Storage, class Allocator>
00533 inline void Matrix_SymSparse<T, Prop, Storage, Allocator>::Nullify()
00534 {
00535 this->data_ = NULL;
00536 this->m_ = 0;
00537 this->n_ = 0;
00538 nz_ = 0;
00539 ptr_ = NULL;
00540 ind_ = NULL;
00541 }
00542
00543
00545 template <class T, class Prop, class Storage, class Allocator>
00546 inline void Matrix_SymSparse<T, Prop, Storage, Allocator>::
00547 Copy(const Matrix_SymSparse<T, Prop, Storage, Allocator>& A)
00548 {
00549 this->Clear();
00550 int nz = A.GetNonZeros();
00551 int i = A.GetM();
00552 int j = A.GetN();
00553 this->nz_ = nz;
00554 this->m_ = i;
00555 this->n_ = j;
00556 if ((i == 0)||(j == 0))
00557 {
00558 this->m_ = 0;
00559 this->n_ = 0;
00560 this->nz_ = 0;
00561 return;
00562 }
00563
00564 #ifdef SELDON_CHECK_DIMENSIONS
00565 if (static_cast<long int>(2 * nz_ - 2) / static_cast<long int>(i + 1)
00566 >= static_cast<long int>(i))
00567 {
00568 this->m_ = 0;
00569 this->n_ = 0;
00570 nz_ = 0;
00571 ptr_ = NULL;
00572 ind_ = NULL;
00573 this->data_ = NULL;
00574 throw WrongDim("Matrix_SymSparse::Matrix_SymSparse(int, int, int)",
00575 string("There are more values (") + to_str(nz)
00576 + string(" values) than elements in the upper")
00577 + " part of the matrix ("
00578 + to_str(i) + " by " + to_str(i) + ").");
00579 }
00580 #endif
00581
00582 #ifdef SELDON_CHECK_MEMORY
00583 try
00584 {
00585 #endif
00586
00587 ptr_ = reinterpret_cast<int*>( calloc(i + 1, sizeof(int)) );
00588 memcpy(this->ptr_, A.ptr_, (i + 1) * sizeof(int));
00589
00590 #ifdef SELDON_CHECK_MEMORY
00591 }
00592 catch (...)
00593 {
00594 this->m_ = 0;
00595 this->n_ = 0;
00596 nz_ = 0;
00597 ptr_ = NULL;
00598 ind_ = NULL;
00599 this->data_ = NULL;
00600 }
00601 if (ptr_ == NULL)
00602 {
00603 this->m_ = 0;
00604 this->n_ = 0;
00605 nz_ = 0;
00606 ind_ = NULL;
00607 this->data_ = NULL;
00608 }
00609 if (ptr_ == NULL && i != 0)
00610 throw NoMemory("Matrix_SymSparse::Matrix_SymSparse(int, int, int)",
00611 string("Unable to allocate ")
00612 + to_str(sizeof(int) * (i+1) ) + " bytes to store "
00613 + to_str(i+1) + " row or column start indices, for a "
00614 + to_str(i) + " by " + to_str(i) + " matrix.");
00615 #endif
00616
00617 #ifdef SELDON_CHECK_MEMORY
00618 try
00619 {
00620 #endif
00621
00622 ind_ = reinterpret_cast<int*>( calloc(nz_, sizeof(int)) );
00623 memcpy(this->ind_, A.ind_, nz_ * sizeof(int));
00624
00625 #ifdef SELDON_CHECK_MEMORY
00626 }
00627 catch (...)
00628 {
00629 this->m_ = 0;
00630 this->n_ = 0;
00631 nz_ = 0;
00632 free(ptr_);
00633 ptr_ = NULL;
00634 ind_ = NULL;
00635 this->data_ = NULL;
00636 }
00637 if (ind_ == NULL)
00638 {
00639 this->m_ = 0;
00640 this->n_ = 0;
00641 nz_ = 0;
00642 free(ptr_);
00643 ptr_ = NULL;
00644 this->data_ = NULL;
00645 }
00646 if (ind_ == NULL && i != 0)
00647 throw NoMemory("Matrix_SymSparse::Matrix_SymSparse(int, int, int)",
00648 string("Unable to allocate ") + to_str(sizeof(int) * nz)
00649 + " bytes to store " + to_str(nz)
00650 + " row or column indices, for a "
00651 + to_str(i) + " by " + to_str(i) + " matrix.");
00652 #endif
00653
00654 #ifdef SELDON_CHECK_MEMORY
00655 try
00656 {
00657 #endif
00658
00659 this->data_ = this->allocator_.allocate(nz_, this);
00660 this->allocator_.memorycpy(this->data_, A.data_, nz_);
00661
00662 #ifdef SELDON_CHECK_MEMORY
00663 }
00664 catch (...)
00665 {
00666 this->m_ = 0;
00667 this->n_ = 0;
00668 free(ptr_);
00669 ptr_ = NULL;
00670 free(ind_);
00671 ind_ = NULL;
00672 this->data_ = NULL;
00673 }
00674 if (this->data_ == NULL)
00675 {
00676 this->m_ = 0;
00677 this->n_ = 0;
00678 free(ptr_);
00679 ptr_ = NULL;
00680 free(ind_);
00681 ind_ = NULL;
00682 }
00683 if (this->data_ == NULL && i != 0)
00684 throw NoMemory("Matrix_SymSparse::Matrix_SymSparse(int, int, int)",
00685 string("Unable to allocate ") + to_str(sizeof(int) * nz)
00686 + " bytes to store " + to_str(nz) + " values, for a "
00687 + to_str(i) + " by " + to_str(i) + " matrix.");
00688 #endif
00689
00690 }
00691
00692
00693
00694
00695
00696
00697
00699
00703 template <class T, class Prop, class Storage, class Allocator>
00704 int Matrix_SymSparse<T, Prop, Storage, Allocator>::GetNonZeros() const
00705 {
00706 return nz_;
00707 }
00708
00709
00711
00715 template <class T, class Prop, class Storage, class Allocator>
00716 int Matrix_SymSparse<T, Prop, Storage, Allocator>::GetDataSize() const
00717 {
00718 return nz_;
00719 }
00720
00721
00723
00727 template <class T, class Prop, class Storage, class Allocator>
00728 int* Matrix_SymSparse<T, Prop, Storage, Allocator>::GetPtr() const
00729 {
00730 return ptr_;
00731 }
00732
00733
00735
00742 template <class T, class Prop, class Storage, class Allocator>
00743 int* Matrix_SymSparse<T, Prop, Storage, Allocator>::GetInd() const
00744 {
00745 return ind_;
00746 }
00747
00748
00750
00753 template <class T, class Prop, class Storage, class Allocator>
00754 int Matrix_SymSparse<T, Prop, Storage, Allocator>::GetPtrSize() const
00755 {
00756 return (this->m_ + 1);
00757 }
00758
00759
00761
00770 template <class T, class Prop, class Storage, class Allocator>
00771 int Matrix_SymSparse<T, Prop, Storage, Allocator>::GetIndSize() const
00772 {
00773 return nz_;
00774 }
00775
00776
00777
00778
00779
00780
00781
00783
00789 template <class T, class Prop, class Storage, class Allocator>
00790 inline typename Matrix_SymSparse<T, Prop, Storage, Allocator>::value_type
00791 Matrix_SymSparse<T, Prop, Storage, Allocator>::operator() (int i,
00792 int j) const
00793 {
00794
00795 #ifdef SELDON_CHECK_BOUNDS
00796 if (i < 0 || i >= this->m_)
00797 throw WrongRow("Matrix_SymSparse::operator()",
00798 string("Index should be in [0, ") + to_str(this->m_-1)
00799 + "], but is equal to " + to_str(i) + ".");
00800 if (j < 0 || j >= this->n_)
00801 throw WrongCol("Matrix_SymSparse::operator()",
00802 string("Index should be in [0, ") + to_str(this->n_-1)
00803 + "], but is equal to " + to_str(j) + ".");
00804 #endif
00805
00806 int k, l;
00807 int a, b;
00808
00809
00810 if (i>j)
00811 {
00812 l = i;
00813 i = j;
00814 j = l;
00815 }
00816
00817 a = ptr_[Storage::GetFirst(i, j)];
00818 b = ptr_[Storage::GetFirst(i, j) + 1];
00819
00820 if (a == b)
00821 return T(0);
00822
00823 l = Storage::GetSecond(i, j);
00824
00825 for (k = a; (k<b-1) && (ind_[k]<l); k++);
00826
00827 if (ind_[k] == l)
00828 return this->data_[k];
00829 else
00830 return T(0);
00831 }
00832
00833
00835
00843 template <class T, class Prop, class Storage, class Allocator>
00844 inline typename Matrix_SymSparse<T, Prop, Storage, Allocator>::value_type&
00845 Matrix_SymSparse<T, Prop, Storage, Allocator>::Val(int i, int j)
00846 {
00847
00848 #ifdef SELDON_CHECK_BOUNDS
00849 if (i < 0 || i >= this->m_)
00850 throw WrongRow("Matrix_SymSparse::Val(int, int)",
00851 string("Index should be in [0, ") + to_str(this->m_-1)
00852 + "], but is equal to " + to_str(i) + ".");
00853 if (j < 0 || j >= this->n_)
00854 throw WrongCol("Matrix_SymSparse::Val(int, int)",
00855 string("Index should be in [0, ") + to_str(this->n_-1)
00856 + "], but is equal to " + to_str(j) + ".");
00857 #endif
00858
00859 int k, l;
00860 int a, b;
00861
00862
00863 if (i>j)
00864 {
00865 l = i;
00866 i = j;
00867 j = l;
00868 }
00869
00870 a = ptr_[Storage::GetFirst(i, j)];
00871 b = ptr_[Storage::GetFirst(i, j) + 1];
00872
00873 if (a == b)
00874 throw WrongArgument("Matrix_SymSparse::Val(int, int)",
00875 "No reference to element (" + to_str(i) + ", "
00876 + to_str(j)
00877 + ") can be returned: it is a zero entry.");
00878
00879 l = Storage::GetSecond(i, j);
00880
00881 for (k = a; (k<b-1) && (ind_[k]<l); k++);
00882
00883 if (ind_[k] == l)
00884 return this->data_[k];
00885 else
00886 throw WrongArgument("Matrix_SymSparse::Val(int, int)",
00887 "No reference to element (" + to_str(i) + ", "
00888 + to_str(j)
00889 + ") can be returned: it is a zero entry.");
00890 }
00891
00892
00894
00902 template <class T, class Prop, class Storage, class Allocator>
00903 inline
00904 const typename Matrix_SymSparse<T, Prop, Storage, Allocator>::value_type&
00905 Matrix_SymSparse<T, Prop, Storage, Allocator>::Val(int i, int j) const
00906 {
00907
00908 #ifdef SELDON_CHECK_BOUNDS
00909 if (i < 0 || i >= this->m_)
00910 throw WrongRow("Matrix_SymSparse::Val(int, int)",
00911 string("Index should be in [0, ") + to_str(this->m_-1)
00912 + "], but is equal to " + to_str(i) + ".");
00913 if (j < 0 || j >= this->n_)
00914 throw WrongCol("Matrix_SymSparse::Val(int, int)",
00915 string("Index should be in [0, ") + to_str(this->n_-1)
00916 + "], but is equal to " + to_str(j) + ".");
00917 #endif
00918
00919 int k, l;
00920 int a, b;
00921
00922
00923 if (i>j)
00924 {
00925 l = i;
00926 i = j;
00927 j = l;
00928 }
00929
00930 a = ptr_[Storage::GetFirst(i, j)];
00931 b = ptr_[Storage::GetFirst(i, j) + 1];
00932
00933 if (a == b)
00934 throw WrongArgument("Matrix_SymSparse::Val(int, int)",
00935 "No reference to element (" + to_str(i) + ", "
00936 + to_str(j)
00937 + ") can be returned: it is a zero entry.");
00938
00939 l = Storage::GetSecond(i, j);
00940
00941 for (k = a; (k<b-1) && (ind_[k]<l); k++);
00942
00943 if (ind_[k] == l)
00944 return this->data_[k];
00945 else
00946 throw WrongArgument("Matrix_SymSparse::Val(int, int)",
00947 "No reference to element (" + to_str(i) + ", "
00948 + to_str(j)
00949 + ") can be returned: it is a zero entry.");
00950 }
00951
00952
00954
00959 template <class T, class Prop, class Storage, class Allocator>
00960 inline Matrix_SymSparse<T, Prop, Storage, Allocator>&
00961 Matrix_SymSparse<T, Prop, Storage, Allocator>
00962 ::operator= (const Matrix_SymSparse<T, Prop, Storage, Allocator>& A)
00963 {
00964 this->Copy(A);
00965
00966 return *this;
00967 }
00968
00969
00970
00971
00972
00973
00974
00976
00981 template <class T, class Prop, class Storage, class Allocator>
00982 void Matrix_SymSparse<T, Prop, Storage, Allocator>::Print() const
00983 {
00984 for (int i = 0; i < this->m_; i++)
00985 {
00986 for (int j = 0; j < this->n_; j++)
00987 cout << (*this)(i, j) << "\t";
00988 cout << endl;
00989 }
00990 }
00991
00992
00994
00999 template <class T, class Prop, class Storage, class Allocator>
01000 void Matrix_SymSparse<T, Prop, Storage, Allocator>
01001 ::WriteText(string FileName) const
01002 {
01003 ofstream FileStream; FileStream.precision(14);
01004 FileStream.open(FileName.c_str());
01005
01006 #ifdef SELDON_CHECK_IO
01007
01008 if (!FileStream.is_open())
01009 throw IOError("Matrix_SymSparse::WriteText(string FileName)",
01010 string("Unable to open file \"") + FileName + "\".");
01011 #endif
01012
01013 this->WriteText(FileStream);
01014
01015 FileStream.close();
01016 }
01017
01018
01020
01025 template <class T, class Prop, class Storage, class Allocator>
01026 void Matrix_SymSparse<T, Prop, Storage, Allocator>
01027 ::WriteText(ostream& FileStream) const
01028 {
01029
01030 #ifdef SELDON_CHECK_IO
01031
01032 if (!FileStream.good())
01033 throw IOError("Matrix_SymSparse::WriteText(ofstream& FileStream)",
01034 "Stream is not ready.");
01035 #endif
01036
01037
01038 IVect IndRow, IndCol;
01039 Vector<T> Value;
01040 const Matrix<T, Prop, Storage, Allocator>& leaf_class =
01041 static_cast<const Matrix<T, Prop, Storage, Allocator>& >(*this);
01042
01043 ConvertMatrix_to_Coordinates(leaf_class, IndRow, IndCol,
01044 Value, 1, true);
01045
01046 for (int i = 0; i < IndRow.GetM(); i++)
01047 FileStream << IndRow(i) << " " << IndCol(i) << " " << Value(i) << '\n';
01048 }
01049
01050
01052
01054
01055
01056
01057
01058
01059
01061
01064 template <class T, class Prop, class Allocator>
01065 Matrix<T, Prop, ColSymSparse, Allocator>::Matrix() throw():
01066 Matrix_SymSparse<T, Prop, ColSymSparse, Allocator>()
01067 {
01068 }
01069
01070
01072
01076 template <class T, class Prop, class Allocator>
01077 Matrix<T, Prop, ColSymSparse, Allocator>::Matrix(int i, int j):
01078 Matrix_SymSparse<T, Prop, ColSymSparse, Allocator>(i, j, 0)
01079 {
01080 }
01081
01082
01084
01091 template <class T, class Prop, class Allocator>
01092 Matrix<T, Prop, ColSymSparse, Allocator>::Matrix(int i, int j, int nz):
01093 Matrix_SymSparse<T, Prop, ColSymSparse, Allocator>(i, j, nz)
01094 {
01095 }
01096
01097
01099
01111 template <class T, class Prop, class Allocator>
01112 template <class Storage0, class Allocator0,
01113 class Storage1, class Allocator1,
01114 class Storage2, class Allocator2>
01115 Matrix<T, Prop, ColSymSparse, Allocator>::
01116 Matrix(int i, int j,
01117 Vector<T, Storage0, Allocator0>& values,
01118 Vector<int, Storage1, Allocator1>& ptr,
01119 Vector<int, Storage2, Allocator2>& ind):
01120 Matrix_SymSparse<T, Prop, ColSymSparse, Allocator>(i, j, values, ptr, ind)
01121 {
01122 }
01123
01124
01125
01127
01129
01130
01131
01132
01133
01134
01135
01137
01140 template <class T, class Prop, class Allocator>
01141 Matrix<T, Prop, RowSymSparse, Allocator>::Matrix() throw():
01142 Matrix_SymSparse<T, Prop, RowSymSparse, Allocator>()
01143 {
01144 }
01145
01146
01148
01152 template <class T, class Prop, class Allocator>
01153 Matrix<T, Prop, RowSymSparse, Allocator>::Matrix(int i, int j):
01154 Matrix_SymSparse<T, Prop, RowSymSparse, Allocator>(i, j, 0)
01155 {
01156 }
01157
01158
01160
01167 template <class T, class Prop, class Allocator>
01168 Matrix<T, Prop, RowSymSparse, Allocator>::Matrix(int i, int j, int nz):
01169 Matrix_SymSparse<T, Prop, RowSymSparse, Allocator>(i, j, nz)
01170 {
01171 }
01172
01173
01175
01187 template <class T, class Prop, class Allocator>
01188 template <class Storage0, class Allocator0,
01189 class Storage1, class Allocator1,
01190 class Storage2, class Allocator2>
01191 Matrix<T, Prop, RowSymSparse, Allocator>::
01192 Matrix(int i, int j,
01193 Vector<T, Storage0, Allocator0>& values,
01194 Vector<int, Storage1, Allocator1>& ptr,
01195 Vector<int, Storage2, Allocator2>& ind):
01196 Matrix_SymSparse<T, Prop, RowSymSparse, Allocator>(i, j, values, ptr, ind)
01197 {
01198 }
01199
01200
01201 }
01202
01203 #define SELDON_FILE_MATRIX_SYMSPARSE_CXX
01204 #endif