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>()
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
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
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
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
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
00435 Clear();
00436
00437 this->m_ = i;
00438 this->n_ = i;
00439
00440
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
01500 if (!FileStream.good())
01501 throw IOError("Matrix_SymSparse::WriteText(ofstream& FileStream)",
01502 "Stream is not ready.");
01503 #endif
01504
01505
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
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
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
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
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
01630
01631
01632
01633
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
01705
01706
01707
01708
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 }
01778
01779 #define SELDON_FILE_MATRIX_SYMSPARSE_CXX
01780 #endif