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_SPARSE_CXX
00022
00023 #include "Matrix_Sparse.hxx"
00024
00025 #include "../vector/Functions_Arrays.cxx"
00026
00027 #include <set>
00028
00029
00030 namespace Seldon
00031 {
00032
00033
00034
00035
00036
00037
00038
00040
00043 template <class T, class Prop, class Storage, class Allocator>
00044 inline Matrix_Sparse<T, Prop, Storage, Allocator>::Matrix_Sparse():
00045 Matrix_Base<T, Allocator>()
00046 {
00047 nz_ = 0;
00048 ptr_ = NULL;
00049 ind_ = NULL;
00050 }
00051
00052
00054
00059 template <class T, class Prop, class Storage, class Allocator>
00060 inline Matrix_Sparse<T, Prop, Storage, Allocator>::Matrix_Sparse(int i,
00061 int j):
00062 Matrix_Base<T, Allocator>()
00063 {
00064 nz_ = 0;
00065 ptr_ = NULL;
00066 ind_ = NULL;
00067
00068 Reallocate(i, j);
00069 }
00070
00071
00073
00080 template <class T, class Prop, class Storage, class Allocator>
00081 inline Matrix_Sparse<T, Prop, Storage, Allocator>::
00082 Matrix_Sparse(int i, int j, int nz):
00083 Matrix_Base<T, Allocator>()
00084 {
00085 this->nz_ = 0;
00086 ind_ = NULL;
00087 ptr_ = NULL;
00088
00089 Reallocate(i, j, nz);
00090 }
00091
00092
00094
00105 template <class T, class Prop, class Storage, class Allocator>
00106 template <class Storage0, class Allocator0,
00107 class Storage1, class Allocator1,
00108 class Storage2, class Allocator2>
00109 inline Matrix_Sparse<T, Prop, Storage, Allocator>::
00110 Matrix_Sparse(int i, int j,
00111 Vector<T, Storage0, Allocator0>& values,
00112 Vector<int, Storage1, Allocator1>& ptr,
00113 Vector<int, Storage2, Allocator2>& ind):
00114 Matrix_Base<T, Allocator>(i, j)
00115 {
00116 nz_ = values.GetLength();
00117
00118 #ifdef SELDON_CHECK_DIMENSIONS
00119
00120
00121 if (ind.GetLength() != nz_)
00122 {
00123 this->m_ = 0;
00124 this->n_ = 0;
00125 nz_ = 0;
00126 ptr_ = NULL;
00127 ind_ = NULL;
00128 this->data_ = NULL;
00129 throw WrongDim(string("Matrix_Sparse::Matrix_Sparse(int, int, ")
00130 + "const Vector&, const Vector&, const Vector&)",
00131 string("There are ") + to_str(nz_) + " values but "
00132 + to_str(ind.GetLength()) + " row or column indices.");
00133 }
00134
00135 if (ptr.GetLength()-1 != Storage::GetFirst(i, j))
00136 {
00137 this->m_ = 0;
00138 this->n_ = 0;
00139 nz_ = 0;
00140 ptr_ = NULL;
00141 ind_ = NULL;
00142 this->data_ = NULL;
00143 throw WrongDim(string("Matrix_Sparse::Matrix_Sparse(int, int, ")
00144 + "const Vector&, const Vector&, const Vector&)",
00145 string("The vector of start indices contains ")
00146 + to_str(ptr.GetLength()-1) + string(" row or column")
00147 + string(" start indices (plus the number")
00148 + " of non-zero entries) but there are "
00149 + to_str(Storage::GetFirst(i, j))
00150 + " rows or columns (" + to_str(i) + " by "
00151 + to_str(j) + " matrix).");
00152 }
00153
00154 if (nz_ > 0
00155 && (j == 0
00156 || static_cast<long int>(nz_-1) / static_cast<long int>(j)
00157 >= static_cast<long int>(i)))
00158 {
00159 this->m_ = 0;
00160 this->n_ = 0;
00161 nz_ = 0;
00162 ptr_ = NULL;
00163 ind_ = NULL;
00164 this->data_ = NULL;
00165 throw WrongDim(string("Matrix_Sparse::Matrix_Sparse(int, int, ")
00166 + "const Vector&, const Vector&, const Vector&)",
00167 string("There are more values (")
00168 + to_str(values.GetLength())
00169 + " values) than elements in the matrix ("
00170 + to_str(i) + " by " + to_str(j) + ").");
00171 }
00172 #endif
00173
00174 this->ptr_ = ptr.GetData();
00175 this->ind_ = ind.GetData();
00176 this->data_ = values.GetData();
00177
00178 ptr.Nullify();
00179 ind.Nullify();
00180 values.Nullify();
00181 }
00182
00183
00185 template <class T, class Prop, class Storage, class Allocator>
00186 inline Matrix_Sparse<T, Prop, Storage, Allocator>::
00187 Matrix_Sparse(const Matrix_Sparse<T, Prop, Storage, Allocator>& A):
00188 Matrix_Base<T, Allocator>(A)
00189 {
00190 this->m_ = 0;
00191 this->n_ = 0;
00192 this->nz_ = 0;
00193 ptr_ = NULL;
00194 ind_ = NULL;
00195 this->Copy(A);
00196 }
00197
00198
00199
00200
00201
00202
00203
00205 template <class T, class Prop, class Storage, class Allocator>
00206 inline Matrix_Sparse<T, Prop, Storage, Allocator>::~Matrix_Sparse()
00207 {
00208 this->m_ = 0;
00209 this->n_ = 0;
00210
00211 #ifdef SELDON_CHECK_MEMORY
00212 try
00213 {
00214 #endif
00215
00216 if (ptr_ != NULL)
00217 {
00218 free(ptr_);
00219 ptr_ = NULL;
00220 }
00221
00222 #ifdef SELDON_CHECK_MEMORY
00223 }
00224 catch (...)
00225 {
00226 ptr_ = NULL;
00227 }
00228 #endif
00229
00230 #ifdef SELDON_CHECK_MEMORY
00231 try
00232 {
00233 #endif
00234
00235 if (ind_ != NULL)
00236 {
00237 free(ind_);
00238 ind_ = NULL;
00239 }
00240
00241 #ifdef SELDON_CHECK_MEMORY
00242 }
00243 catch (...)
00244 {
00245 ind_ = NULL;
00246 }
00247 #endif
00248
00249 #ifdef SELDON_CHECK_MEMORY
00250 try
00251 {
00252 #endif
00253
00254 if (this->data_ != NULL)
00255 {
00256 this->allocator_.deallocate(this->data_, nz_);
00257 this->data_ = NULL;
00258 }
00259
00260 #ifdef SELDON_CHECK_MEMORY
00261 }
00262 catch (...)
00263 {
00264 this->nz_ = 0;
00265 this->data_ = NULL;
00266 }
00267 #endif
00268
00269 this->nz_ = 0;
00270 }
00271
00272
00274
00277 template <class T, class Prop, class Storage, class Allocator>
00278 inline void Matrix_Sparse<T, Prop, Storage, Allocator>::Clear()
00279 {
00280 this->~Matrix_Sparse();
00281 }
00282
00283
00284
00285
00286
00287
00288
00290
00300 template <class T, class Prop, class Storage, class Allocator>
00301 template <class Storage0, class Allocator0,
00302 class Storage1, class Allocator1,
00303 class Storage2, class Allocator2>
00304 void Matrix_Sparse<T, Prop, Storage, Allocator>::
00305 SetData(int i, int j,
00306 Vector<T, Storage0, Allocator0>& values,
00307 Vector<int, Storage1, Allocator1>& ptr,
00308 Vector<int, Storage2, Allocator2>& ind)
00309 {
00310 this->Clear();
00311 this->m_ = i;
00312 this->n_ = j;
00313 this->nz_ = values.GetLength();
00314
00315 #ifdef SELDON_CHECK_DIMENSIONS
00316
00317
00318 if (ind.GetLength() != nz_)
00319 {
00320 this->m_ = 0;
00321 this->n_ = 0;
00322 nz_ = 0;
00323 ptr_ = NULL;
00324 ind_ = NULL;
00325 this->data_ = NULL;
00326 throw WrongDim(string("Matrix_Sparse::SetData(int, int, ")
00327 + "const Vector&, const Vector&, const Vector&)",
00328 string("There are ") + to_str(nz_) + " values but "
00329 + to_str(ind.GetLength()) + " row or column indices.");
00330 }
00331
00332 if (ptr.GetLength()-1 != Storage::GetFirst(i, j))
00333 {
00334 this->m_ = 0;
00335 this->n_ = 0;
00336 nz_ = 0;
00337 ptr_ = NULL;
00338 ind_ = NULL;
00339 this->data_ = NULL;
00340 throw WrongDim(string("Matrix_Sparse::SetData(int, int, ")
00341 + "const Vector&, const Vector&, const Vector&)",
00342 string("The vector of start indices contains ")
00343 + to_str(ptr.GetLength()-1) + string(" row or column")
00344 + string(" start indices (plus the number")
00345 + " of non-zero entries) but there are "
00346 + to_str(Storage::GetFirst(i, j))
00347 + " rows or columns (" + to_str(i) + " by "
00348 + to_str(j) + " matrix).");
00349 }
00350
00351 if (nz_ > 0
00352 && (j == 0
00353 || static_cast<long int>(nz_-1) / static_cast<long int>(j)
00354 >= static_cast<long int>(i)))
00355 {
00356 this->m_ = 0;
00357 this->n_ = 0;
00358 nz_ = 0;
00359 ptr_ = NULL;
00360 ind_ = NULL;
00361 this->data_ = NULL;
00362 throw WrongDim(string("Matrix_Sparse::SetData(int, int, ")
00363 + "const Vector&, const Vector&, const Vector&)",
00364 string("There are more values (")
00365 + to_str(values.GetLength())
00366 + " values) than elements in the matrix ("
00367 + to_str(i) + " by " + to_str(j) + ").");
00368 }
00369 #endif
00370
00371 this->ptr_ = ptr.GetData();
00372 this->ind_ = ind.GetData();
00373 this->data_ = values.GetData();
00374
00375 ptr.Nullify();
00376 ind.Nullify();
00377 values.Nullify();
00378 }
00379
00380
00382
00395 template <class T, class Prop, class Storage, class Allocator>
00396 inline void Matrix_Sparse<T, Prop, Storage, Allocator>
00397 ::SetData(int i, int j, int nz,
00398 typename Matrix_Sparse<T, Prop, Storage, Allocator>
00399 ::pointer values,
00400 int* ptr, int* ind)
00401 {
00402 this->Clear();
00403
00404 this->m_ = i;
00405 this->n_ = j;
00406
00407 this->nz_ = nz;
00408
00409 this->data_ = values;
00410 ind_ = ind;
00411 ptr_ = ptr;
00412 }
00413
00414
00416
00420 template <class T, class Prop, class Storage, class Allocator>
00421 inline void Matrix_Sparse<T, Prop, Storage, Allocator>::Nullify()
00422 {
00423 this->data_ = NULL;
00424 this->m_ = 0;
00425 this->n_ = 0;
00426 nz_ = 0;
00427 ptr_ = NULL;
00428 ind_ = NULL;
00429 }
00430
00431
00433
00437 template <class T, class Prop, class Storage, class Allocator>
00438 void Matrix_Sparse<T, Prop, Storage, Allocator>::Reallocate(int i, int j)
00439 {
00440
00441 Clear();
00442
00443 this->m_ = i;
00444 this->n_ = j;
00445
00446
00447 #ifdef SELDON_CHECK_MEMORY
00448 try
00449 {
00450 #endif
00451
00452 ptr_ = reinterpret_cast<int*>( calloc(Storage::GetFirst(i, j)+1,
00453 sizeof(int)) );
00454
00455 #ifdef SELDON_CHECK_MEMORY
00456 }
00457 catch (...)
00458 {
00459 this->m_ = 0;
00460 this->n_ = 0;
00461 nz_ = 0;
00462 ptr_ = NULL;
00463 ind_ = NULL;
00464 this->data_ = NULL;
00465 }
00466 if (ptr_ == NULL)
00467 {
00468 this->m_ = 0;
00469 this->n_ = 0;
00470 nz_ = 0;
00471 ind_ = NULL;
00472 this->data_ = NULL;
00473 }
00474 if (ptr_ == NULL && i != 0 && j != 0)
00475 throw NoMemory("Matrix_Sparse::Reallocate(int, int)",
00476 string("Unable to allocate ")
00477 + to_str(sizeof(int) * (Storage::GetFirst(i, j)+1) )
00478 + " bytes to store " + to_str(Storage::GetFirst(i, j)+1)
00479 + " row or column start indices, for a "
00480 + to_str(i) + " by " + to_str(j) + " matrix.");
00481 #endif
00482
00483
00484 for (int k = 0; k <= Storage::GetFirst(i, j); k++)
00485 ptr_[k] = 0;
00486
00487 }
00488
00489
00491
00496 template <class T, class Prop, class Storage, class Allocator>
00497 void Matrix_Sparse<T, Prop, Storage, Allocator>::Reallocate(int i, int j, int nz)
00498 {
00499
00500 Clear();
00501
00502 this->nz_ = nz;
00503 this->m_ = i;
00504 this->n_ = j;
00505
00506 #ifdef SELDON_CHECK_DIMENSIONS
00507 if (nz_ < 0)
00508 {
00509 this->m_ = 0;
00510 this->n_ = 0;
00511 nz_ = 0;
00512 ptr_ = NULL;
00513 ind_ = NULL;
00514 this->data_ = NULL;
00515 throw WrongDim("Matrix_Sparse::Matrix_Sparse(int, int, int)",
00516 "Invalid number of non-zero elements: " + to_str(nz)
00517 + ".");
00518 }
00519 if (nz_ > 0
00520 && (j == 0
00521 || static_cast<long int>(nz_-1) / static_cast<long int>(j)
00522 >= static_cast<long int>(i)))
00523 {
00524 this->m_ = 0;
00525 this->n_ = 0;
00526 nz_ = 0;
00527 ptr_ = NULL;
00528 ind_ = NULL;
00529 this->data_ = NULL;
00530 throw WrongDim("Matrix_Sparse::Matrix_Sparse(int, int, int)",
00531 string("There are more values (") + to_str(nz)
00532 + " values) than elements in the matrix ("
00533 + to_str(i) + " by " + to_str(j) + ").");
00534 }
00535 #endif
00536
00537 #ifdef SELDON_CHECK_MEMORY
00538 try
00539 {
00540 #endif
00541
00542 ptr_ = reinterpret_cast<int*>( calloc(Storage::GetFirst(i, j)+1,
00543 sizeof(int)) );
00544
00545 #ifdef SELDON_CHECK_MEMORY
00546 }
00547 catch (...)
00548 {
00549 this->m_ = 0;
00550 this->n_ = 0;
00551 nz_ = 0;
00552 ptr_ = NULL;
00553 ind_ = NULL;
00554 this->data_ = NULL;
00555 }
00556 if (ptr_ == NULL)
00557 {
00558 this->m_ = 0;
00559 this->n_ = 0;
00560 nz_ = 0;
00561 ind_ = NULL;
00562 this->data_ = NULL;
00563 }
00564 if (ptr_ == NULL && i != 0 && j != 0)
00565 throw NoMemory("Matrix_Sparse::Matrix_Sparse(int, int, int)",
00566 string("Unable to allocate ")
00567 + to_str(sizeof(int) * (Storage::GetFirst(i, j)+1) )
00568 + " bytes to store " + to_str(Storage::GetFirst(i, j)+1)
00569 + " row or column start indices, for a "
00570 + to_str(i) + " by " + to_str(j) + " matrix.");
00571 #endif
00572
00573 #ifdef SELDON_CHECK_MEMORY
00574 try
00575 {
00576 #endif
00577
00578 ind_ = reinterpret_cast<int*>( calloc(nz_, sizeof(int)) );
00579
00580 #ifdef SELDON_CHECK_MEMORY
00581 }
00582 catch (...)
00583 {
00584 this->m_ = 0;
00585 this->n_ = 0;
00586 nz_ = 0;
00587 free(ptr_);
00588 ptr_ = NULL;
00589 ind_ = NULL;
00590 this->data_ = NULL;
00591 }
00592 if (ind_ == NULL)
00593 {
00594 this->m_ = 0;
00595 this->n_ = 0;
00596 nz_ = 0;
00597 free(ptr_);
00598 ptr_ = NULL;
00599 this->data_ = NULL;
00600 }
00601 if (ind_ == NULL && i != 0 && j != 0)
00602 throw NoMemory("Matrix_Sparse::Matrix_Sparse(int, int, int)",
00603 string("Unable to allocate ") + to_str(sizeof(int) * nz)
00604 + " bytes to store " + to_str(nz)
00605 + " row or column indices, for a "
00606 + to_str(i) + " by " + to_str(j) + " matrix.");
00607 #endif
00608
00609 #ifdef SELDON_CHECK_MEMORY
00610 try
00611 {
00612 #endif
00613
00614 this->data_ = this->allocator_.allocate(nz_, this);
00615
00616 #ifdef SELDON_CHECK_MEMORY
00617 }
00618 catch (...)
00619 {
00620 this->m_ = 0;
00621 this->n_ = 0;
00622 free(ptr_);
00623 ptr_ = NULL;
00624 free(ind_);
00625 ind_ = NULL;
00626 this->data_ = NULL;
00627 }
00628 if (this->data_ == NULL)
00629 {
00630 this->m_ = 0;
00631 this->n_ = 0;
00632 free(ptr_);
00633 ptr_ = NULL;
00634 free(ind_);
00635 ind_ = NULL;
00636 }
00637 if (this->data_ == NULL && i != 0 && j != 0)
00638 throw NoMemory("Matrix_Sparse::Matrix_Sparse(int, int, int)",
00639 string("Unable to allocate ") + to_str(sizeof(int) * nz)
00640 + " bytes to store " + to_str(nz) + " values, for a "
00641 + to_str(i) + " by " + to_str(j) + " matrix.");
00642 #endif
00643 }
00644
00645
00647
00652 template <class T, class Prop, class Storage, class Allocator>
00653 void Matrix_Sparse<T, Prop, Storage, Allocator>::Resize(int i, int j)
00654 {
00655 if (Storage::GetFirst(i, j) < Storage::GetFirst(this->m_, this->n_))
00656 Resize(i, j, ptr_[Storage::GetFirst(i, j)]);
00657 else
00658 Resize(i, j, nz_);
00659 }
00660
00661
00663
00669 template <class T, class Prop, class Storage, class Allocator>
00670 void Matrix_Sparse<T, Prop, Storage, Allocator>
00671 ::Resize(int i, int j, int nz)
00672 {
00673
00674 #ifdef SELDON_CHECK_DIMENSIONS
00675 if (nz < 0)
00676 {
00677 this->m_ = 0;
00678 this->n_ = 0;
00679 nz_ = 0;
00680 ptr_ = NULL;
00681 ind_ = NULL;
00682 this->data_ = NULL;
00683 throw WrongDim("Matrix_Sparse::Resize(int, int, int)",
00684 "Invalid number of non-zero elements: " + to_str(nz)
00685 + ".");
00686 }
00687 if (nz > 0
00688 && (j == 0
00689 || static_cast<long int>(nz_-1) / static_cast<long int>(j)
00690 >= static_cast<long int>(i)))
00691 {
00692 this->m_ = 0;
00693 this->n_ = 0;
00694 nz_ = 0;
00695 ptr_ = NULL;
00696 ind_ = NULL;
00697 this->data_ = NULL;
00698 throw WrongDim("Matrix_Sparse::Resize(int, int, int)",
00699 string("There are more values (") + to_str(nz)
00700 + " values) than elements in the matrix ("
00701 + to_str(i) + " by " + to_str(j) + ").");
00702 }
00703 #endif
00704
00705 if (nz != nz_)
00706 {
00707
00708 #ifdef SELDON_CHECK_MEMORY
00709 try
00710 {
00711 #endif
00712
00713 ind_
00714 = reinterpret_cast<int*>(realloc(reinterpret_cast<void*>(ind_),
00715 nz*sizeof(int)));
00716
00717 #ifdef SELDON_CHECK_MEMORY
00718 }
00719 catch (...)
00720 {
00721 this->m_ = 0;
00722 this->n_ = 0;
00723 nz_ = 0;
00724 free(ptr_);
00725 ptr_ = NULL;
00726 ind_ = NULL;
00727 this->data_ = NULL;
00728 }
00729 if (ind_ == NULL)
00730 {
00731 this->m_ = 0;
00732 this->n_ = 0;
00733 nz_ = 0;
00734 free(ptr_);
00735 ptr_ = NULL;
00736 this->data_ = NULL;
00737 }
00738 if (ind_ == NULL && i != 0 && j != 0)
00739 throw NoMemory("Matrix_Sparse::Resize(int, int, int)",
00740 string("Unable to allocate ") + to_str(sizeof(int) * nz)
00741 + " bytes to store " + to_str(nz)
00742 + " row or column indices, for a "
00743 + to_str(i) + " by " + to_str(j) + " matrix.");
00744 #endif
00745
00746 Vector<T, VectFull, Allocator> val;
00747 val.SetData(nz_, this->data_);
00748 val.Resize(nz);
00749
00750 this->data_ = val.GetData();
00751 nz_ = nz;
00752 val.Nullify();
00753 }
00754
00755
00756 if (Storage::GetFirst(this->m_, this->n_) != Storage::GetFirst(i, j))
00757 {
00758 #ifdef SELDON_CHECK_MEMORY
00759 try
00760 {
00761 #endif
00762
00763 ptr_ = reinterpret_cast<int*>( realloc(ptr_, (Storage::GetFirst(i, j)+1)*
00764 sizeof(int)) );
00765
00766 #ifdef SELDON_CHECK_MEMORY
00767 }
00768 catch (...)
00769 {
00770 this->m_ = 0;
00771 this->n_ = 0;
00772 nz_ = 0;
00773 ptr_ = NULL;
00774 ind_ = NULL;
00775 this->data_ = NULL;
00776 }
00777 if (ptr_ == NULL)
00778 {
00779 this->m_ = 0;
00780 this->n_ = 0;
00781 nz_ = 0;
00782 ind_ = NULL;
00783 this->data_ = NULL;
00784 }
00785 if (ptr_ == NULL && i != 0 && j != 0)
00786 throw NoMemory("Matrix_Sparse::Resize(int, int)",
00787 string("Unable to allocate ")
00788 + to_str(sizeof(int) * (Storage::GetFirst(i, j)+1) )
00789 + " bytes to store " + to_str(Storage::GetFirst(i, j)+1)
00790 + " row or column start indices, for a "
00791 + to_str(i) + " by " + to_str(j) + " matrix.");
00792 #endif
00793
00794
00795 for (int k = Storage::GetFirst(this->m_, this->n_);
00796 k <= Storage::GetFirst(i, j); k++)
00797 ptr_[k] = this->nz_;
00798 }
00799
00800 this->m_ = i;
00801 this->n_ = j;
00802 }
00803
00804
00806 template <class T, class Prop, class Storage, class Allocator>
00807 inline void Matrix_Sparse<T, Prop, Storage, Allocator>::
00808 Copy(const Matrix_Sparse<T, Prop, Storage, Allocator>& A)
00809 {
00810 this->Clear();
00811 int nz = A.nz_;
00812 int i = A.m_;
00813 int j = A.n_;
00814 this->nz_ = nz;
00815 this->m_ = i;
00816 this->n_ = j;
00817 if ((i == 0)||(j == 0))
00818 {
00819 this->m_ = 0;
00820 this->n_ = 0;
00821 this->nz_ = 0;
00822 return;
00823 }
00824
00825 #ifdef SELDON_CHECK_DIMENSIONS
00826 if (nz_ > 0
00827 && (j == 0
00828 || static_cast<long int>(nz_-1) / static_cast<long int>(j)
00829 >= static_cast<long int>(i)))
00830 {
00831 this->m_ = 0;
00832 this->n_ = 0;
00833 nz_ = 0;
00834 ptr_ = NULL;
00835 ind_ = NULL;
00836 this->data_ = NULL;
00837 throw WrongDim("Matrix_Sparse::Matrix_Sparse(int, int, int)",
00838 string("There are more values (") + to_str(nz)
00839 + " values) than elements in the matrix ("
00840 + to_str(i) + " by " + to_str(j) + ").");
00841 }
00842 #endif
00843
00844 #ifdef SELDON_CHECK_MEMORY
00845 try
00846 {
00847 #endif
00848
00849 ptr_ = reinterpret_cast<int*>( calloc(Storage::GetFirst(i, j)+1,
00850 sizeof(int)) );
00851 memcpy(this->ptr_, A.ptr_,
00852 (Storage::GetFirst(i, j) + 1) * sizeof(int));
00853 #ifdef SELDON_CHECK_MEMORY
00854 }
00855 catch (...)
00856 {
00857 this->m_ = 0;
00858 this->n_ = 0;
00859 nz_ = 0;
00860 ptr_ = NULL;
00861 ind_ = NULL;
00862 this->data_ = NULL;
00863 }
00864 if (ptr_ == NULL)
00865 {
00866 this->m_ = 0;
00867 this->n_ = 0;
00868 nz_ = 0;
00869 ind_ = NULL;
00870 this->data_ = NULL;
00871 }
00872 if (ptr_ == NULL && i != 0 && j != 0)
00873 throw NoMemory("Matrix_Sparse::Matrix_Sparse(int, int, int)",
00874 string("Unable to allocate ")
00875 + to_str(sizeof(int) * (Storage::GetFirst(i, j)+1) )
00876 + " bytes to store " + to_str(Storage::GetFirst(i, j)+1)
00877 + " row or column start indices, for a "
00878 + to_str(i) + " by " + to_str(j) + " matrix.");
00879 #endif
00880
00881 #ifdef SELDON_CHECK_MEMORY
00882 try
00883 {
00884 #endif
00885
00886 ind_ = reinterpret_cast<int*>( calloc(nz_, sizeof(int)) );
00887 memcpy(this->ind_, A.ind_, nz_ * sizeof(int));
00888
00889 #ifdef SELDON_CHECK_MEMORY
00890 }
00891 catch (...)
00892 {
00893 this->m_ = 0;
00894 this->n_ = 0;
00895 nz_ = 0;
00896 free(ptr_);
00897 ptr_ = NULL;
00898 ind_ = NULL;
00899 this->data_ = NULL;
00900 }
00901 if (ind_ == NULL)
00902 {
00903 this->m_ = 0;
00904 this->n_ = 0;
00905 nz_ = 0;
00906 free(ptr_);
00907 ptr_ = NULL;
00908 this->data_ = NULL;
00909 }
00910 if (ind_ == NULL && i != 0 && j != 0)
00911 throw NoMemory("Matrix_Sparse::Matrix_Sparse(int, int, int)",
00912 string("Unable to allocate ") + to_str(sizeof(int) * nz)
00913 + " bytes to store " + to_str(nz)
00914 + " row or column indices, for a "
00915 + to_str(i) + " by " + to_str(j) + " matrix.");
00916 #endif
00917
00918 #ifdef SELDON_CHECK_MEMORY
00919 try
00920 {
00921 #endif
00922
00923 this->data_ = this->allocator_.allocate(nz_, this);
00924 this->allocator_.memorycpy(this->data_, A.data_, nz_);
00925
00926 #ifdef SELDON_CHECK_MEMORY
00927 }
00928 catch (...)
00929 {
00930 this->m_ = 0;
00931 this->n_ = 0;
00932 free(ptr_);
00933 ptr_ = NULL;
00934 free(ind_);
00935 ind_ = NULL;
00936 this->data_ = NULL;
00937 }
00938 if (this->data_ == NULL)
00939 {
00940 this->m_ = 0;
00941 this->n_ = 0;
00942 free(ptr_);
00943 ptr_ = NULL;
00944 free(ind_);
00945 ind_ = NULL;
00946 }
00947 if (this->data_ == NULL && i != 0 && j != 0)
00948 throw NoMemory("Matrix_Sparse::Matrix_Sparse(int, int, int)",
00949 string("Unable to allocate ") + to_str(sizeof(int) * nz)
00950 + " bytes to store " + to_str(nz) + " values, for a "
00951 + to_str(i) + " by " + to_str(j) + " matrix.");
00952 #endif
00953
00954 }
00955
00956
00957
00958
00959
00960
00961
00963
00966 template <class T, class Prop, class Storage, class Allocator>
00967 int Matrix_Sparse<T, Prop, Storage, Allocator>::GetNonZeros() const
00968 {
00969 return nz_;
00970 }
00971
00972
00974
00979 template <class T, class Prop, class Storage, class Allocator>
00980 int Matrix_Sparse<T, Prop, Storage, Allocator>::GetDataSize() const
00981 {
00982 return nz_;
00983 }
00984
00985
00987
00991 template <class T, class Prop, class Storage, class Allocator>
00992 int* Matrix_Sparse<T, Prop, Storage, Allocator>::GetPtr() const
00993 {
00994 return ptr_;
00995 }
00996
00997
00999
01006 template <class T, class Prop, class Storage, class Allocator>
01007 int* Matrix_Sparse<T, Prop, Storage, Allocator>::GetInd() const
01008 {
01009 return ind_;
01010 }
01011
01012
01014
01017 template <class T, class Prop, class Storage, class Allocator>
01018 int Matrix_Sparse<T, Prop, Storage, Allocator>::GetPtrSize() const
01019 {
01020 return (Storage::GetFirst(this->m_, this->n_) + 1);
01021 }
01022
01023
01025
01033 template <class T, class Prop, class Storage, class Allocator>
01034 int Matrix_Sparse<T, Prop, Storage, Allocator>::GetIndSize() const
01035 {
01036 return nz_;
01037 }
01038
01039
01040
01041
01042
01043
01044
01046
01052 template <class T, class Prop, class Storage, class Allocator>
01053 inline typename Matrix_Sparse<T, Prop, Storage, Allocator>::value_type
01054 Matrix_Sparse<T, Prop, Storage, Allocator>::operator() (int i, int j) const
01055 {
01056
01057 #ifdef SELDON_CHECK_BOUNDS
01058 if (i < 0 || i >= this->m_)
01059 throw WrongRow("Matrix_Sparse::operator()",
01060 string("Index should be in [0, ") + to_str(this->m_-1)
01061 + "], but is equal to " + to_str(i) + ".");
01062 if (j < 0 || j >= this->n_)
01063 throw WrongCol("Matrix_Sparse::operator()",
01064 string("Index should be in [0, ") + to_str(this->n_-1)
01065 + "], but is equal to " + to_str(j) + ".");
01066 #endif
01067
01068 int k,l;
01069 int a,b;
01070
01071 a = ptr_[Storage::GetFirst(i, j)];
01072 b = ptr_[Storage::GetFirst(i, j) + 1];
01073
01074 if (a == b)
01075 return T(0);
01076
01077 l = Storage::GetSecond(i, j);
01078
01079 for (k = a; (k < b-1) && (ind_[k] < l); k++);
01080
01081 if (ind_[k] == l)
01082 return this->data_[k];
01083 else
01084 return T(0);
01085 }
01086
01087
01089
01097 template <class T, class Prop, class Storage, class Allocator>
01098 inline typename Matrix_Sparse<T, Prop, Storage, Allocator>::value_type&
01099 Matrix_Sparse<T, Prop, Storage, Allocator>::Val(int i, int j)
01100 {
01101
01102 #ifdef SELDON_CHECK_BOUNDS
01103 if (i < 0 || i >= this->m_)
01104 throw WrongRow("Matrix_Sparse::Val(int, int)",
01105 string("Index should be in [0, ") + to_str(this->m_-1)
01106 + "], but is equal to " + to_str(i) + ".");
01107 if (j < 0 || j >= this->n_)
01108 throw WrongCol("Matrix_Sparse::Val(int, int)",
01109 string("Index should be in [0, ") + to_str(this->n_-1)
01110 + "], but is equal to " + to_str(j) + ".");
01111 #endif
01112
01113 int k, l;
01114 int a, b;
01115
01116 a = ptr_[Storage::GetFirst(i, j)];
01117 b = ptr_[Storage::GetFirst(i, j) + 1];
01118
01119 if (a == b)
01120 throw WrongArgument("Matrix_Sparse::Val(int, int)",
01121 "No reference to element (" + to_str(i) + ", "
01122 + to_str(j)
01123 + ") can be returned: it is a zero entry.");
01124
01125 l = Storage::GetSecond(i, j);
01126
01127 for (k = a; (k < b-1) && (ind_[k] < l); k++);
01128
01129 if (ind_[k] == l)
01130 return this->data_[k];
01131 else
01132 throw WrongArgument("Matrix_Sparse::Val(int, int)",
01133 "No reference to element (" + to_str(i) + ", "
01134 + to_str(j)
01135 + ") can be returned: it is a zero entry.");
01136 }
01137
01138
01140
01148 template <class T, class Prop, class Storage, class Allocator>
01149 inline
01150 const typename Matrix_Sparse<T, Prop, Storage, Allocator>::value_type&
01151 Matrix_Sparse<T, Prop, Storage, Allocator>::Val(int i, int j) const
01152 {
01153
01154 #ifdef SELDON_CHECK_BOUNDS
01155 if (i < 0 || i >= this->m_)
01156 throw WrongRow("Matrix_Sparse::Val(int, int)",
01157 string("Index should be in [0, ") + to_str(this->m_-1)
01158 + "], but is equal to " + to_str(i) + ".");
01159 if (j < 0 || j >= this->n_)
01160 throw WrongCol("Matrix_Sparse::Val(int, int)",
01161 string("Index should be in [0, ") + to_str(this->n_-1)
01162 + "], but is equal to " + to_str(j) + ".");
01163 #endif
01164
01165 int k, l;
01166 int a, b;
01167
01168 a = ptr_[Storage::GetFirst(i, j)];
01169 b = ptr_[Storage::GetFirst(i, j) + 1];
01170
01171 if (a == b)
01172 throw WrongArgument("Matrix_Sparse::Val(int, int)",
01173 "No reference to element (" + to_str(i) + ", "
01174 + to_str(j)
01175 + ") can be returned: it is a zero entry.");
01176
01177 l = Storage::GetSecond(i, j);
01178
01179 for (k = a; (k < b-1) && (ind_[k] < l); k++);
01180
01181 if (ind_[k] == l)
01182 return this->data_[k];
01183 else
01184 throw WrongArgument("Matrix_Sparse::Val(int, int)",
01185 "No reference to element (" + to_str(i) + ", "
01186 + to_str(j)
01187 + ") can be returned: it is a zero entry.");
01188 }
01189
01190
01192
01199 template <class T, class Prop, class Storage, class Allocator>
01200 inline typename Matrix_Sparse<T, Prop, Storage, Allocator>::value_type&
01201 Matrix_Sparse<T, Prop, Storage, Allocator>::Get(int i, int j)
01202 {
01203
01204 #ifdef SELDON_CHECK_BOUNDS
01205 if (i < 0 || i >= this->m_)
01206 throw WrongRow("Matrix_Sparse::Get(int, int)",
01207 string("Index should be in [0, ") + to_str(this->m_-1)
01208 + "], but is equal to " + to_str(i) + ".");
01209 if (j < 0 || j >= this->n_)
01210 throw WrongCol("Matrix_Sparse::Get(int, int)",
01211 string("Index should be in [0, ") + to_str(this->n_-1)
01212 + "], but is equal to " + to_str(j) + ".");
01213 #endif
01214
01215 int k, l;
01216 int a, b;
01217
01218 a = ptr_[Storage::GetFirst(i, j)];
01219 b = ptr_[Storage::GetFirst(i, j) + 1];
01220
01221 if (a < b)
01222 {
01223 l = Storage::GetSecond(i, j);
01224
01225 for (k = a; (k < b) && (ind_[k] < l); k++);
01226
01227 if ( (k < b) && (ind_[k] == l))
01228 return this->data_[k];
01229 }
01230 else
01231 k = a;
01232
01233
01234 Resize(this->m_, this->n_, nz_+1);
01235
01236 for (int m = Storage::GetFirst(i, j)+1;
01237 m <= Storage::GetFirst(this->m_, this->n_); m++)
01238 ptr_[m]++;
01239
01240 for (int m = nz_-1; m >= k+1; m--)
01241 {
01242 ind_[m] = ind_[m-1];
01243 this->data_[m] = this->data_[m-1];
01244 }
01245
01246 ind_[k] = Storage::GetSecond(i, j);
01247
01248
01249 SetComplexZero(this->data_[k]);
01250
01251 return this->data_[k];
01252 }
01253
01254
01256
01261 template <class T, class Prop, class Storage, class Allocator>
01262 inline const typename Matrix_Sparse<T, Prop, Storage, Allocator>::value_type&
01263 Matrix_Sparse<T, Prop, Storage, Allocator>::Get(int i, int j) const
01264 {
01265 return Val(i, j);
01266 }
01267
01268
01270
01277 template <class T, class Prop, class Storage, class Allocator>
01278 inline void Matrix_Sparse<T, Prop, Storage, Allocator>
01279 ::AddInteraction(int i, int j, const T& val)
01280 {
01281 Get(i, j) += val;
01282 }
01283
01284
01286
01291 template <class T, class Prop, class Storage, class Allocator>
01292 inline void Matrix_Sparse<T, Prop, Storage, Allocator>
01293 ::Set(int i, int j, const T& val)
01294 {
01295 Get(i, j) = val;
01296 }
01297
01298
01300
01305 template <class T, class Prop, class Storage, class Allocator>
01306 inline Matrix_Sparse<T, Prop, Storage, Allocator>&
01307 Matrix_Sparse<T, Prop, Storage, Allocator>
01308 ::operator= (const Matrix_Sparse<T, Prop, Storage, Allocator>& A)
01309 {
01310 this->Copy(A);
01311
01312 return *this;
01313 }
01314
01315
01316
01317
01318
01319
01320
01322
01323 template <class T, class Prop, class Storage, class Allocator>
01324 void Matrix_Sparse<T, Prop, Storage, Allocator>::Zero()
01325 {
01326 this->allocator_.memoryset(this->data_, char(0),
01327 this->nz_ * sizeof(value_type));
01328 }
01329
01330
01332
01335 template <class T, class Prop, class Storage, class Allocator>
01336 void Matrix_Sparse<T, Prop, Storage, Allocator>::SetIdentity()
01337 {
01338 int m = this->m_;
01339 int n = this->n_;
01340 int nz = min(m, n);
01341
01342 if (nz == 0)
01343 return;
01344
01345 Clear();
01346
01347 Vector<T, VectFull, Allocator> values(nz);
01348 Vector<int, VectFull, CallocAlloc<int> > ptr(Storage::GetFirst(m, n) + 1);
01349 Vector<int, VectFull, CallocAlloc<int> > ind(nz);
01350
01351 T one; SetComplexOne(one);
01352 values.Fill(one);
01353 ind.Fill();
01354 int i;
01355 for (i = 0; i < nz + 1; i++)
01356 ptr(i) = i;
01357 for (i = nz + 1; i < ptr.GetLength(); i++)
01358 ptr(i) = nz;
01359
01360 SetData(m, n, values, ptr, ind);
01361 }
01362
01363
01365
01368 template <class T, class Prop, class Storage, class Allocator>
01369 void Matrix_Sparse<T, Prop, Storage, Allocator>::Fill()
01370 {
01371 for (int i = 0; i < this->GetDataSize(); i++)
01372 this->data_[i] = i;
01373 }
01374
01375
01377
01380 template <class T, class Prop, class Storage, class Allocator>
01381 template <class T0>
01382 void Matrix_Sparse<T, Prop, Storage, Allocator>::Fill(const T0& x)
01383 {
01384 for (int i = 0; i < this->GetDataSize(); i++)
01385 this->data_[i] = x;
01386 }
01387
01388
01390
01393 template <class T, class Prop, class Storage, class Allocator>
01394 void Matrix_Sparse<T, Prop, Storage, Allocator>::FillRand()
01395 {
01396 srand(time(NULL));
01397 for (int i = 0; i < this->GetDataSize(); i++)
01398 this->data_[i] = rand();
01399 }
01400
01401
01403
01411 template <class T, class Prop, class Storage, class Allocator>
01412 void Matrix_Sparse<T, Prop, Storage, Allocator>
01413 ::FillRand(int Nelement)
01414 {
01415 if (this->m_ == 0 || this->n_ == 0)
01416 return;
01417
01418 Vector<int> i(Nelement), j(Nelement);
01419 Vector<T> value(Nelement);
01420
01421 set<pair<int, int> > skeleton;
01422 set<pair<int, int> >::iterator it;
01423
01424 srand(time(NULL));
01425
01426
01427 while (static_cast<int>(skeleton.size()) != Nelement)
01428 skeleton.insert(make_pair(rand() % this->m_, rand() % this->n_));
01429
01430 int l = 0;
01431 for (it = skeleton.begin(); it != skeleton.end(); it++)
01432 {
01433 i(l) = it->first;
01434 j(l) = it->second;
01435 value(l) = double(rand());
01436 l++;
01437 }
01438
01439
01440 Matrix<T, Prop, Storage, Allocator>& leaf_class =
01441 static_cast<Matrix<T, Prop, Storage, Allocator>& >(*this);
01442
01443 ConvertMatrix_from_Coordinates(i, j, value, leaf_class, 0);
01444 }
01445
01446
01448
01458 template <class T, class Prop, class Storage, class Allocator>
01459 void Matrix_Sparse<T, Prop, Storage, Allocator>
01460 ::FillRand(int Nelement, const T& x)
01461 {
01462 if (this->m_ == 0 || this->n_ == 0)
01463 return;
01464
01465 Vector<int> i(Nelement), j(Nelement);
01466 Vector<T> value(Nelement);
01467 value.Fill(x);
01468
01469 srand(time(NULL));
01470 for (int l = 0; l < Nelement; l++)
01471 {
01472 i(l) = rand() % this->m_;
01473 j(l) = rand() % this->n_;
01474 }
01475
01476
01477 Matrix<T, Prop, Storage, Allocator>& leaf_class =
01478 static_cast<Matrix<T, Prop, Storage, Allocator>& >(*this);
01479
01480 ConvertMatrix_from_Coordinates(i, j, value, leaf_class, 0);
01481 }
01482
01483
01485
01490 template <class T, class Prop, class Storage, class Allocator>
01491 void Matrix_Sparse<T, Prop, Storage, Allocator>::Print() const
01492 {
01493 for (int i = 0; i < this->m_; i++)
01494 {
01495 for (int j = 0; j < this->n_; j++)
01496 cout << (*this)(i, j) << "\t";
01497 cout << endl;
01498 }
01499 }
01500
01501
01503
01507 template <class T, class Prop, class Storage, class Allocator>
01508 void Matrix_Sparse<T, Prop, Storage, Allocator>
01509 ::Write(string FileName) const
01510 {
01511 ofstream FileStream;
01512 FileStream.open(FileName.c_str());
01513
01514 #ifdef SELDON_CHECK_IO
01515
01516 if (!FileStream.is_open())
01517 throw IOError("Matrix_Sparse::Write(string FileName)",
01518 string("Unable to open file \"") + FileName + "\".");
01519 #endif
01520
01521 this->Write(FileStream);
01522
01523 FileStream.close();
01524 }
01525
01526
01528
01532 template <class T, class Prop, class Storage, class Allocator>
01533 void Matrix_Sparse<T, Prop, Storage, Allocator>
01534 ::Write(ostream& FileStream) const
01535 {
01536 #ifdef SELDON_CHECK_IO
01537
01538 if (!FileStream.good())
01539 throw IOError("Matrix_Sparse::Write(ofstream& FileStream)",
01540 "Stream is not ready.");
01541 #endif
01542
01543 FileStream.write(reinterpret_cast<char*>(const_cast<int*>(&this->m_)),
01544 sizeof(int));
01545 FileStream.write(reinterpret_cast<char*>(const_cast<int*>(&this->n_)),
01546 sizeof(int));
01547 FileStream.write(reinterpret_cast<char*>(const_cast<int*>(&this->nz_)),
01548 sizeof(int));
01549
01550 FileStream.write(reinterpret_cast<char*>(this->ptr_),
01551 sizeof(int)*(Storage::GetFirst(this->m_, this->n_)+1));
01552 FileStream.write(reinterpret_cast<char*>(this->ind_),
01553 sizeof(int)*this->nz_);
01554 FileStream.write(reinterpret_cast<char*>(this->data_),
01555 sizeof(T)*this->nz_);
01556 }
01557
01558
01560
01566 template <class T, class Prop, class Storage, class Allocator>
01567 void Matrix_Sparse<T, Prop, Storage, Allocator>::
01568 WriteText(string FileName) const
01569 {
01570 ofstream FileStream; FileStream.precision(14);
01571 FileStream.open(FileName.c_str());
01572
01573 #ifdef SELDON_CHECK_IO
01574
01575 if (!FileStream.is_open())
01576 throw IOError("Matrix_Sparse::Write(string FileName)",
01577 string("Unable to open file \"") + FileName + "\".");
01578 #endif
01579
01580 this->WriteText(FileStream);
01581
01582 FileStream.close();
01583 }
01584
01585
01587
01593 template <class T, class Prop, class Storage, class Allocator>
01594 void Matrix_Sparse<T, Prop, Storage, Allocator>::
01595 WriteText(ostream& FileStream) const
01596 {
01597
01598 #ifdef SELDON_CHECK_IO
01599
01600 if (!FileStream.good())
01601 throw IOError("Matrix_Sparse::Write(ofstream& FileStream)",
01602 "Stream is not ready.");
01603 #endif
01604
01605
01606 IVect IndRow, IndCol; Vector<T> Value;
01607 const Matrix<T, Prop, Storage, Allocator>& leaf_class =
01608 static_cast<const Matrix<T, Prop, Storage, Allocator>& >(*this);
01609
01610 ConvertMatrix_to_Coordinates(leaf_class, IndRow, IndCol,
01611 Value, 1, true);
01612
01613 for (int i = 0; i < IndRow.GetM(); i++)
01614 FileStream << IndRow(i) << " " << IndCol(i) << " " << Value(i) << '\n';
01615
01616 }
01617
01618
01620
01624 template <class T, class Prop, class Storage, class Allocator>
01625 void Matrix_Sparse<T, Prop, Storage, Allocator>::
01626 Read(string FileName)
01627 {
01628 ifstream FileStream;
01629 FileStream.open(FileName.c_str());
01630
01631 #ifdef SELDON_CHECK_IO
01632
01633 if (!FileStream.is_open())
01634 throw IOError("Matrix_Sparse::Read(string FileName)",
01635 string("Unable to open file \"") + FileName + "\".");
01636 #endif
01637
01638 this->Read(FileStream);
01639
01640 FileStream.close();
01641 }
01642
01643
01645
01649 template <class T, class Prop, class Storage, class Allocator>
01650 void Matrix_Sparse<T, Prop, Storage, Allocator>::
01651 Read(istream& FileStream)
01652 {
01653
01654 #ifdef SELDON_CHECK_IO
01655
01656 if (!FileStream.good())
01657 throw IOError("Matrix_Sparse::Read(istream& FileStream)",
01658 "Stream is not ready.");
01659 #endif
01660
01661 int m, n, nz;
01662 FileStream.read(reinterpret_cast<char*>(&m), sizeof(int));
01663 FileStream.read(reinterpret_cast<char*>(&n), sizeof(int));
01664 FileStream.read(reinterpret_cast<char*>(&nz), sizeof(int));
01665
01666 Reallocate(m, n, nz);
01667
01668 FileStream.read(reinterpret_cast<char*>(ptr_),
01669 sizeof(int)*(Storage::GetFirst(m, n)+1));
01670 FileStream.read(reinterpret_cast<char*>(ind_), sizeof(int)*nz);
01671 FileStream.read(reinterpret_cast<char*>(this->data_), sizeof(T)*nz);
01672
01673 #ifdef SELDON_CHECK_IO
01674
01675 if (!FileStream.good())
01676 throw IOError("Matrix_Sparse::Read(istream& FileStream)",
01677 string("Input operation failed.")
01678 + string(" The input file may have been removed")
01679 + " or may not contain enough data.");
01680 #endif
01681
01682 }
01683
01684
01686
01690 template <class T, class Prop, class Storage, class Allocator>
01691 void Matrix_Sparse<T, Prop, Storage, Allocator>::
01692 ReadText(string FileName)
01693 {
01694 ifstream FileStream;
01695 FileStream.open(FileName.c_str());
01696
01697 #ifdef SELDON_CHECK_IO
01698
01699 if (!FileStream.is_open())
01700 throw IOError("Matrix_Sparse::ReadText(string FileName)",
01701 string("Unable to open file \"") + FileName + "\".");
01702 #endif
01703
01704 this->ReadText(FileStream);
01705
01706 FileStream.close();
01707 }
01708
01709
01711
01715 template <class T, class Prop, class Storage, class Allocator>
01716 void Matrix_Sparse<T, Prop, Storage, Allocator>::
01717 ReadText(istream& FileStream)
01718 {
01719 Matrix<T, Prop, Storage, Allocator>& leaf_class =
01720 static_cast<Matrix<T, Prop, Storage, Allocator>& >(*this);
01721
01722 T zero; int index = 1;
01723 ReadCoordinateMatrix(leaf_class, FileStream, zero, index);
01724 }
01725
01726
01728
01730
01731
01732
01733
01734
01735
01737
01740 template <class T, class Prop, class Allocator>
01741 Matrix<T, Prop, ColSparse, Allocator>::Matrix():
01742 Matrix_Sparse<T, Prop, ColSparse, Allocator>()
01743 {
01744 }
01745
01746
01748
01752 template <class T, class Prop, class Allocator>
01753 Matrix<T, Prop, ColSparse, Allocator>::Matrix(int i, int j):
01754 Matrix_Sparse<T, Prop, ColSparse, Allocator>(i, j, 0)
01755 {
01756 }
01757
01758
01760
01766 template <class T, class Prop, class Allocator>
01767 Matrix<T, Prop, ColSparse, Allocator>::Matrix(int i, int j, int nz):
01768 Matrix_Sparse<T, Prop, ColSparse, Allocator>(i, j, nz)
01769 {
01770 }
01771
01772
01774
01785 template <class T, class Prop, class Allocator>
01786 template <class Storage0, class Allocator0,
01787 class Storage1, class Allocator1,
01788 class Storage2, class Allocator2>
01789 Matrix<T, Prop, ColSparse, Allocator>::
01790 Matrix(int i, int j,
01791 Vector<T, Storage0, Allocator0>& values,
01792 Vector<int, Storage1, Allocator1>& ptr,
01793 Vector<int, Storage2, Allocator2>& ind):
01794 Matrix_Sparse<T, Prop, ColSparse, Allocator>(i, j, values, ptr, ind)
01795 {
01796 }
01797
01798
01799
01801
01803
01804
01805
01806
01807
01808
01810
01813 template <class T, class Prop, class Allocator>
01814 Matrix<T, Prop, RowSparse, Allocator>::Matrix():
01815 Matrix_Sparse<T, Prop, RowSparse, Allocator>()
01816 {
01817 }
01818
01819
01821
01825 template <class T, class Prop, class Allocator>
01826 Matrix<T, Prop, RowSparse, Allocator>::Matrix(int i, int j):
01827 Matrix_Sparse<T, Prop, RowSparse, Allocator>(i, j, 0)
01828 {
01829 }
01830
01831
01833
01839 template <class T, class Prop, class Allocator>
01840 Matrix<T, Prop, RowSparse, Allocator>::Matrix(int i, int j, int nz):
01841 Matrix_Sparse<T, Prop, RowSparse, Allocator>(i, j, nz)
01842 {
01843 }
01844
01845
01847
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, RowSparse, Allocator>::
01863 Matrix(int i, int j,
01864 Vector<T, Storage0, Allocator0>& values,
01865 Vector<int, Storage1, Allocator1>& ptr,
01866 Vector<int, Storage2, Allocator2>& ind):
01867 Matrix_Sparse<T, Prop, RowSparse, Allocator>(i, j, values, ptr, ind)
01868 {
01869 }
01870
01871
01873
01875
01876
01878
01884 template<class Tint, class AllocInt, class T, class Allocator>
01885 void ReadCoordinateMatrix(istream& FileStream,
01886 Vector<Tint, VectFull, AllocInt>& row_numbers,
01887 Vector<Tint, VectFull, AllocInt>& col_numbers,
01888 Vector<T, VectFull, Allocator>& values)
01889 {
01890 #ifdef SELDON_CHECK_IO
01891
01892 if (!FileStream.good())
01893 throw IOError("ReadCoordinateMatrix", "Stream is not ready.");
01894 #endif
01895
01896 T entry; int row = 0, col = 0;
01897 int nb_elt = 0;
01898 SetComplexZero(entry);
01899
01900 while (!FileStream.eof())
01901 {
01902
01903 FileStream >> row >> col >> entry;
01904
01905 if (FileStream.fail())
01906 break;
01907 else
01908 {
01909 #ifdef SELDON_CHECK_IO
01910 if (row < 1)
01911 throw IOError(string("ReadCoordinateMatrix"),
01912 string("Error : Row number should be greater ")
01913 + "than 0 but is equal to " + to_str(row));
01914
01915 if (col < 1)
01916 throw IOError(string("ReadCoordinateMatrix"),
01917 string("Error : Column number should be greater")
01918 + " than 0 but is equal to " + to_str(col));
01919 #endif
01920
01921 nb_elt++;
01922
01923
01924 if (nb_elt > values.GetM())
01925 {
01926 values.Resize(2*nb_elt);
01927 row_numbers.Resize(2*nb_elt);
01928 col_numbers.Resize(2*nb_elt);
01929 }
01930
01931 values(nb_elt-1) = entry;
01932 row_numbers(nb_elt-1) = row;
01933 col_numbers(nb_elt-1) = col;
01934 }
01935 }
01936
01937 if (nb_elt > 0)
01938 {
01939 row_numbers.Resize(nb_elt);
01940 col_numbers.Resize(nb_elt);
01941 values.Resize(nb_elt);
01942 }
01943 }
01944
01945
01947
01956 template<class Matrix1, class T>
01957 void ReadCoordinateMatrix(Matrix1& A, istream& FileStream, T& zero,
01958 int index, int nnz)
01959 {
01960
01961 A.Clear();
01962
01963 Vector<int> row_numbers, col_numbers;
01964 Vector<T> values;
01965 if (nnz >= 0)
01966 {
01967 values.Reallocate(nnz);
01968 row_numbers.Reallocate(nnz);
01969 col_numbers.Reallocate(nnz);
01970 }
01971
01972 ReadCoordinateMatrix(FileStream, row_numbers, col_numbers, values);
01973
01974 if (row_numbers.GetM() > 0)
01975 ConvertMatrix_from_Coordinates(row_numbers, col_numbers, values,
01976 A, index);
01977
01978 }
01979
01980 }
01981
01982 #define SELDON_FILE_MATRIX_SPARSE_CXX
01983 #endif