21 #ifndef SELDON_FILE_MATRIX_SYMSPARSE_CXX
23 #include "Matrix_SymSparse.hxx"
47 template <
class T,
class Prop,
class Storage,
class Allocator>
48 template <
class Storage0,
class Allocator0,
49 class Storage1,
class Allocator1,
50 class Storage2,
class Allocator2>
58 nz_ = values.GetLength();
60 #ifdef SELDON_CHECK_DIMENSIONS
63 if (ind.GetLength() != nz_)
71 throw WrongDim(
string(
"Matrix_SymSparse::Matrix_SymSparse(int, int, ")
72 +
"const Vector&, const Vector&, const Vector&)",
73 string(
"There are ") +
to_str(nz_) +
" values but "
74 +
to_str(ind.GetLength()) +
" row or column indices.");
77 if (ptr.GetLength() - 1 != i)
85 throw WrongDim(
string(
"Matrix_SymSparse::Matrix_SymSparse(int, int, ")
86 +
"const Vector&, const Vector&, const Vector&)",
87 string(
"The vector of start indices contains ")
88 +
to_str(ptr.GetLength()-1) +
string(
" row or column ")
89 +
string(
"start indices (plus the number of non-zero")
90 +
" entries) but there are " +
to_str(i)
91 +
" rows or columns ("
95 if (
static_cast<long int>(2 * nz_ - 2) /
static_cast<long int>(i + 1)
96 >=
static_cast<long int>(i))
104 throw WrongDim(
string(
"Matrix_SymSparse::Matrix_SymSparse(int, int, ")
105 +
"const Vector&, const Vector&, const Vector&)",
106 string(
"There are more values (")
107 +
to_str(values.GetLength())
108 +
" values) than elements in the matrix ("
113 this->ptr_ = ptr.GetData();
114 this->ind_ = ind.GetData();
115 this->data_ = values.GetData();
124 template <
class T,
class Prop,
class Storage,
class Allocator>
142 template <
class T,
class Prop,
class Storage,
class Allocator>
145 #ifdef SELDON_CHECK_MEMORY
152 AllocatorLong::deallocate(ptr_, this->m_+1);
156 #ifdef SELDON_CHECK_MEMORY
164 #ifdef SELDON_CHECK_MEMORY
171 AllocatorInt::deallocate(ind_, this->nz_);
175 #ifdef SELDON_CHECK_MEMORY
183 #ifdef SELDON_CHECK_MEMORY
188 if (this->data_ != NULL)
190 Allocator::deallocate(this->data_, nz_);
194 #ifdef SELDON_CHECK_MEMORY
221 template <
class T,
class Prop,
class Storage,
class Allocator>
222 template <
class Storage0,
class Allocator0,
223 class Storage1,
class Allocator1,
224 class Storage2,
class Allocator2>
234 this->nz_ = values.GetLength();
236 #ifdef SELDON_CHECK_DIMENSIONS
239 if (ind.GetM() != nz_)
247 throw WrongDim(
string(
"Matrix_SymSparse::Reallocate(int, int, ")
248 +
"const Vector&, const Vector&, const Vector&)",
249 string(
"There are ") +
to_str(nz_) +
" values but "
250 +
to_str(ind.GetLength()) +
" row or column indices.");
253 if (ptr.GetM()-1 != i)
261 throw WrongDim(
string(
"Matrix_SymSparse::Reallocate(int, int, ")
262 +
"const Vector&, const Vector&, const Vector&)",
263 string(
"The vector of start indices contains ")
264 +
to_str(ptr.GetLength()-1) +
string(
" row or column")
265 +
string(
" start indices (plus the number of")
266 +
string(
" non-zero entries) but there are ")
267 +
to_str(i) +
" rows or columns ("
271 if (
static_cast<long int>(2 * nz_ - 2) /
static_cast<long int>(i + 1)
272 >=
static_cast<long int>(i))
280 throw WrongDim(
string(
"Matrix_SymSparse::Reallocate(int, int, ")
281 +
"const Vector&, const Vector&, const Vector&)",
282 string(
"There are more values (")
283 +
to_str(values.GetLength())
284 +
" values) than elements in the matrix ("
289 this->ptr_ = ptr.GetData();
290 this->ind_ = ind.GetData();
291 this->data_ = values.GetData();
314 template <
class T,
class Prop,
class Storage,
class Allocator>
318 ::pointer values,
long* ptr,
int* ind)
327 this->data_ = values;
338 template <
class T,
class Prop,
class Storage,
class Allocator>
355 template <
class T,
class Prop,
class Storage,
class Allocator>
365 #ifdef SELDON_CHECK_MEMORY
370 ptr_ =
reinterpret_cast<long*
>( AllocatorLong::
371 allocate(i+1,
this) );
373 #ifdef SELDON_CHECK_MEMORY
392 if (ptr_ == NULL && i != 0 && j != 0)
393 throw NoMemory(
"Matrix_SymSparse::Reallocate(int, int)",
394 string(
"Unable to allocate ")
395 +
to_str(
sizeof(
int) * (i+1) )
396 +
" bytes to store " +
to_str(i+1)
397 +
" row or column start indices, for a "
402 for (
int k = 0; k <= i; k++)
413 template <
class T,
class Prop,
class Storage,
class Allocator>
424 #ifdef SELDON_CHECK_DIMENSIONS
425 if (
static_cast<long int>(2 * nz_ - 2) /
static_cast<long int>(i + 1)
426 >=
static_cast<long int>(i))
434 throw WrongDim(
"Matrix_SymSparse::Matrix_SymSparse(int, int, int)",
435 string(
"There are more values (") +
to_str(nz)
436 +
string(
" values) than elements in the upper")
437 +
" part of the matrix ("
442 #ifdef SELDON_CHECK_MEMORY
447 ptr_ =
reinterpret_cast<long*
>( AllocatorLong::
448 allocate(i + 1,
this) );
450 #ifdef SELDON_CHECK_MEMORY
469 if (ptr_ == NULL && i != 0)
470 throw NoMemory(
"Matrix_SymSparse::Matrix_SymSparse(int, int, int)",
471 string(
"Unable to allocate ")
472 +
to_str(
sizeof(
int) * (i+1) ) +
" bytes to store "
473 +
to_str(i+1) +
" row or column start indices, for a "
477 #ifdef SELDON_CHECK_MEMORY
482 ind_ =
reinterpret_cast<int*
>( AllocatorInt::
483 allocate(nz_,
this) );
485 #ifdef SELDON_CHECK_MEMORY
492 AllocatorLong::deallocate(ptr_, i+1);
502 AllocatorLong::deallocate(ptr_, i+1);
506 if (ind_ == NULL && i != 0)
507 throw NoMemory(
"Matrix_SymSparse::Matrix_SymSparse(int, int, int)",
508 string(
"Unable to allocate ") +
to_str(
sizeof(
int) * nz)
509 +
" bytes to store " +
to_str(nz)
510 +
" row or column indices, for a "
514 #ifdef SELDON_CHECK_MEMORY
519 this->data_ = Allocator::allocate(nz_,
this);
521 #ifdef SELDON_CHECK_MEMORY
527 AllocatorLong::deallocate(ptr_, i+1);
529 AllocatorInt::deallocate(ind_, nz);
533 if (this->data_ == NULL)
537 AllocatorLong::deallocate(ptr_, i+1);
539 AllocatorInt::deallocate(ind_, nz);
542 if (this->data_ == NULL && i != 0)
543 throw NoMemory(
"Matrix_SymSparse::Matrix_SymSparse(int, int, int)",
544 string(
"Unable to allocate ") +
to_str(
sizeof(
int) * nz)
545 +
" bytes to store " +
to_str(nz) +
" values, for a "
550 for (
int k = 0; k <= i; k++)
560 template <
class T,
class Prop,
class Storage,
class Allocator>
564 Resize(i, i, ptr_[i]);
576 template <
class T,
class Prop,
class Storage,
class Allocator>
581 #ifdef SELDON_CHECK_DIMENSIONS
582 if (
static_cast<long int>(2 * nz - 2) /
static_cast<long int>(i + 1)
583 >=
static_cast<long int>(i))
591 throw WrongDim(
"Matrix_SymSparse::Matrix_SymSparse(int, int, int)",
592 string(
"There are more values (") +
to_str(nz)
593 +
string(
" values) than elements in the upper")
594 +
" part of the matrix ("
602 #ifdef SELDON_CHECK_MEMORY
607 ind_ =
reinterpret_cast<int*
>( AllocatorInt::reallocate(ind_, nz) );
609 #ifdef SELDON_CHECK_MEMORY
616 AllocatorLong::deallocate(ptr_, i+1);
626 AllocatorLong::deallocate(ptr_, i+1);
630 if (ind_ == NULL && i != 0 && j != 0)
631 throw NoMemory(
"Matrix_SymSparse::Resize(int, int, int)",
632 string(
"Unable to allocate ") +
to_str(
sizeof(
int) * nz)
633 +
" bytes to store " +
to_str(nz)
634 +
" row or column indices, for a "
639 val.SetData(nz_, this->data_);
650 #ifdef SELDON_CHECK_MEMORY
655 ptr_ =
reinterpret_cast<long*
>( AllocatorLong::reallocate(ptr_, i+1) );
657 #ifdef SELDON_CHECK_MEMORY
676 if (ptr_ == NULL && i != 0 && j != 0)
677 throw NoMemory(
"Matrix_SymSparse::Resize(int, int)",
678 string(
"Unable to allocate ")
679 +
to_str(
sizeof(
int) * (i+1) )
680 +
" bytes to store " +
to_str(i+1)
681 +
" row or column start indices, for a "
686 for (
int k = this->m_; k <= i; k++)
696 template <
class T,
class Prop,
class Storage,
class Allocator>
707 if ((i == 0)||(j == 0))
715 #ifdef SELDON_CHECK_DIMENSIONS
716 if (
static_cast<long int>(2 * nz_ - 2) /
static_cast<long int>(i + 1)
717 >=
static_cast<long int>(i))
725 throw WrongDim(
"Matrix_SymSparse::Matrix_SymSparse(int, int, int)",
726 string(
"There are more values (") +
to_str(nz)
727 +
string(
" values) than elements in the upper")
728 +
" part of the matrix ("
733 #ifdef SELDON_CHECK_MEMORY
738 ptr_ =
reinterpret_cast<long*
>( AllocatorLong::allocate(i + 1,
this) );
739 AllocatorLong::memorycpy(this->ptr_, A.ptr_, (i + 1));
741 #ifdef SELDON_CHECK_MEMORY
760 if (ptr_ == NULL && i != 0)
761 throw NoMemory(
"Matrix_SymSparse::Matrix_SymSparse(int, int, int)",
762 string(
"Unable to allocate ")
763 +
to_str(
sizeof(
int) * (i+1) ) +
" bytes to store "
764 +
to_str(i+1) +
" row or column start indices, for a "
768 #ifdef SELDON_CHECK_MEMORY
773 ind_ =
reinterpret_cast<int*
>( AllocatorInt::allocate(nz_,
this) );
774 AllocatorInt::memorycpy(this->ind_, A.ind_, nz_);
776 #ifdef SELDON_CHECK_MEMORY
783 AllocatorLong::deallocate(ptr_, i+1);
793 AllocatorLong::deallocate(ptr_, i+1);
797 if (ind_ == NULL && i != 0)
798 throw NoMemory(
"Matrix_SymSparse::Matrix_SymSparse(int, int, int)",
799 string(
"Unable to allocate ") +
to_str(
sizeof(
int) * nz)
800 +
" bytes to store " +
to_str(nz)
801 +
" row or column indices, for a "
805 #ifdef SELDON_CHECK_MEMORY
810 this->data_ = Allocator::allocate(nz_,
this);
811 Allocator::memorycpy(this->data_, A.data_, nz_);
813 #ifdef SELDON_CHECK_MEMORY
819 AllocatorLong::deallocate(ptr_, i+1);
821 AllocatorInt::deallocate(ind_, nz);
825 if (this->data_ == NULL)
829 AllocatorLong::deallocate(ptr_, i+1);
831 AllocatorInt::deallocate(ind_, nz);
834 if (this->data_ == NULL && i != 0)
835 throw NoMemory(
"Matrix_SymSparse::Matrix_SymSparse(int, int, int)",
836 string(
"Unable to allocate ") +
to_str(
sizeof(
int) * nz)
837 +
" bytes to store " +
to_str(nz) +
" values, for a "
845 template<
class T,
class Prop,
class Storage,
class Allocator>
848 size_t taille =
sizeof(*this) + this->GetPtrSize()*
sizeof(long);
849 int coef =
sizeof(T) +
sizeof(
int);
850 taille += coef*size_t(this->nz_);
856 template<
class T,
class Prop,
class Storage,
class Allocator>
859 Ptr.Reallocate(this->m_+1);
860 for (
int i = 0; i <= this->m_; i++)
877 template <
class T,
class Prop,
class Storage,
class Allocator>
879 Matrix_SymSparse<T, Prop, Storage, Allocator>::value_type
884 #ifdef SELDON_CHECK_BOUNDS
885 if (i < 0 || i >= this->m_)
886 throw WrongRow(
"Matrix_SymSparse::operator()",
887 string(
"Index should be in [0, ") +
to_str(this->m_-1)
888 +
"], but is equal to " +
to_str(i) +
".");
889 if (j < 0 || j >= this->n_)
890 throw WrongCol(
"Matrix_SymSparse::operator()",
891 string(
"Index should be in [0, ") +
to_str(this->n_-1)
892 +
"], but is equal to " +
to_str(j) +
".");
898 SetComplexZero(zero);
908 a = ptr_[Storage::GetFirst(i, j)];
909 b = ptr_[Storage::GetFirst(i, j) + 1];
914 l = Storage::GetSecond(i, j);
916 for (k = a; (k<b-1) && (ind_[k]<l); k++);
919 return this->data_[k];
934 template <
class T,
class Prop,
class Storage,
class Allocator>
935 typename Matrix_SymSparse<T, Prop, Storage, Allocator>::value_type&
939 #ifdef SELDON_CHECK_BOUNDS
940 if (i < 0 || i >= this->m_)
941 throw WrongRow(
"Matrix_SymSparse::Val(int, int)",
942 string(
"Index should be in [0, ") +
to_str(this->m_-1)
943 +
"], but is equal to " +
to_str(i) +
".");
944 if (j < 0 || j >= this->n_)
945 throw WrongCol(
"Matrix_SymSparse::Val(int, int)",
946 string(
"Index should be in [0, ") +
to_str(this->n_-1)
947 +
"], but is equal to " +
to_str(j) +
".");
961 a = ptr_[Storage::GetFirst(i, j)];
962 b = ptr_[Storage::GetFirst(i, j) + 1];
966 "No reference to element (" +
to_str(i) +
", "
968 +
") can be returned: it is a zero entry.");
970 l = Storage::GetSecond(i, j);
972 for (k = a; (k<b-1) && (ind_[k]<l); k++);
975 return this->data_[k];
978 "No reference to element (" +
to_str(i) +
", "
980 +
") can be returned: it is a zero entry.");
993 template <
class T,
class Prop,
class Storage,
class Allocator>
994 const typename Matrix_SymSparse<T, Prop, Storage, Allocator>::value_type&
998 #ifdef SELDON_CHECK_BOUNDS
999 if (i < 0 || i >= this->m_)
1000 throw WrongRow(
"Matrix_SymSparse::Val(int, int)",
1001 string(
"Index should be in [0, ") +
to_str(this->m_-1)
1002 +
"], but is equal to " +
to_str(i) +
".");
1003 if (j < 0 || j >= this->n_)
1004 throw WrongCol(
"Matrix_SymSparse::Val(int, int)",
1005 string(
"Index should be in [0, ") +
to_str(this->n_-1)
1006 +
"], but is equal to " +
to_str(j) +
".");
1020 a = ptr_[Storage::GetFirst(i, j)];
1021 b = ptr_[Storage::GetFirst(i, j) + 1];
1025 "No reference to element (" +
to_str(i) +
", "
1027 +
") can be returned: it is a zero entry.");
1029 l = Storage::GetSecond(i, j);
1031 for (k = a; (k<b-1) && (ind_[k]<l); k++);
1034 return this->data_[k];
1037 "No reference to element (" +
to_str(i) +
", "
1039 +
") can be returned: it is a zero entry.");
1051 template <
class T,
class Prop,
class Storage,
class Allocator>
1052 typename Matrix_SymSparse<T, Prop, Storage, Allocator>::value_type&
1056 #ifdef SELDON_CHECK_BOUNDS
1057 if (i < 0 || i >= this->m_)
1058 throw WrongRow(
"Matrix_SymSparse::Get(int, int)",
1059 string(
"Index should be in [0, ") +
to_str(this->m_-1)
1060 +
"], but is equal to " +
to_str(i) +
".");
1061 if (j < 0 || j >= this->n_)
1062 throw WrongCol(
"Matrix_SymSparse::Get(int, int)",
1063 string(
"Index should be in [0, ") +
to_str(this->n_-1)
1064 +
"], but is equal to " +
to_str(j) +
".");
1077 a = ptr_[Storage::GetFirst(i, j)];
1078 b = ptr_[Storage::GetFirst(i, j) + 1];
1082 l = Storage::GetSecond(i, j);
1084 for (k = a; (k < b) && (ind_[k] < l); k++);
1086 if ( (k < b) && (ind_[k] == l))
1087 return this->data_[k];
1093 Resize(this->m_, this->n_, nz_+1);
1095 for (
int m = Storage::GetFirst(i, j)+1; m <= this->m_; m++)
1098 for (
long m = nz_-1; m >= k+1; m--)
1100 ind_[m] = ind_[m-1];
1101 this->data_[m] = this->data_[m-1];
1104 ind_[k] = Storage::GetSecond(i, j);
1107 SetComplexZero(this->data_[k]);
1109 return this->data_[k];
1120 template <
class T,
class Prop,
class Storage,
class Allocator>
1123 Allocator::memoryset(this->data_,
char(0),
1124 this->nz_ *
sizeof(value_type));
1131 template <
class T,
class Prop,
class Storage,
class Allocator>
1152 SetData(m, m, values, ptr, ind);
1160 template <
class T,
class Prop,
class Storage,
class Allocator>
1163 for (
long i = 0; i < this->GetDataSize(); i++)
1172 template <
class T,
class Prop,
class Storage,
class Allocator>
1178 for (
long i = 0; i < this->GetDataSize(); i++)
1179 this->data_[i] = x_;
1187 template <
class T,
class Prop,
class Storage,
class Allocator>
1190 #ifndef SELDON_WITHOUT_REINIT_RANDOM
1193 for (
long i = 0; i < this->GetDataSize(); i++)
1204 template <
class T,
class Prop,
class Storage,
class Allocator>
1207 for (
int i = 0; i < this->m_; i++)
1209 for (
int j = 0; j < this->n_; j++)
1210 cout << (*
this)(i, j) <<
"\t";
1221 template <
class T,
class Prop,
class Storage,
class Allocator>
1225 ofstream FileStream;
1226 FileStream.open(FileName.c_str(), ofstream::binary);
1228 #ifdef SELDON_CHECK_IO
1230 if (!FileStream.is_open())
1231 throw IOError(
"Matrix_SymSparse::Write(string FileName)",
1232 string(
"Unable to open file \"") + FileName +
"\".");
1235 this->Write(FileStream);
1246 template <
class T,
class Prop,
class Storage,
class Allocator>
1250 #ifdef SELDON_CHECK_IO
1252 if (!FileStream.good())
1253 throw IOError(
"Matrix_SymSparse::Write(ofstream& FileStream)",
1254 "Stream is not ready.");
1257 FileStream.write(
reinterpret_cast<char*
>(
const_cast<int*
>(&this->m_)),
1259 FileStream.write(
reinterpret_cast<char*
>(
const_cast<int*
>(&this->m_)),
1261 FileStream.write(
reinterpret_cast<char*
>(
const_cast<long*
>(&this->nz_)),
1264 FileStream.write(
reinterpret_cast<char*
>(this->ptr_),
1265 sizeof(
long)*(this->m_+1));
1266 FileStream.write(
reinterpret_cast<char*
>(this->ind_),
1267 sizeof(
int)*this->nz_);
1268 FileStream.write(
reinterpret_cast<char*
>(this->data_),
1269 sizeof(T)*this->nz_);
1282 template <
class T,
class Prop,
class Storage,
class Allocator>
1286 ofstream FileStream; FileStream.precision(14);
1287 FileStream.open(FileName.c_str());
1290 FileStream.precision(cout.precision());
1292 #ifdef SELDON_CHECK_IO
1294 if (!FileStream.is_open())
1295 throw IOError(
"Matrix_SymSparse::WriteText(string FileName)",
1296 string(
"Unable to open file \"") + FileName +
"\".");
1299 this->WriteText(FileStream, cplx);
1314 template <
class T,
class Prop,
class Storage,
class Allocator>
1319 #ifdef SELDON_CHECK_IO
1321 if (!FileStream.good())
1322 throw IOError(
"Matrix_SymSparse::WriteText(ofstream& FileStream)",
1323 "Stream is not ready.");
1330 T zero;
int index = 1;
1331 WriteCoordinateMatrix(leaf_class, FileStream, zero, index, cplx);
1340 template <
class T,
class Prop,
class Storage,
class Allocator>
1344 ifstream FileStream;
1345 FileStream.open(FileName.c_str(), ifstream::binary);
1347 #ifdef SELDON_CHECK_IO
1349 if (!FileStream.is_open())
1350 throw IOError(
"Matrix_SymSparse::Read(string FileName)",
1351 string(
"Unable to open file \"") + FileName +
"\".");
1354 this->Read(FileStream);
1365 template <
class T,
class Prop,
class Storage,
class Allocator>
1370 #ifdef SELDON_CHECK_IO
1372 if (!FileStream.good())
1373 throw IOError(
"Matrix_SymSparse::Read(ofstream& FileStream)",
1374 "Stream is not ready.");
1378 FileStream.read(
reinterpret_cast<char*
>(&m),
sizeof(
int));
1379 FileStream.read(
reinterpret_cast<char*
>(&n),
sizeof(
int));
1380 FileStream.read(
reinterpret_cast<char*
>(&nz),
sizeof(
long));
1382 Reallocate(m, m, nz);
1384 FileStream.read(
reinterpret_cast<char*
>(ptr_),
1385 sizeof(
long)*(m+1));
1386 FileStream.read(
reinterpret_cast<char*
>(ind_),
sizeof(
int)*nz);
1387 FileStream.read(
reinterpret_cast<char*
>(this->data_),
sizeof(T)*nz);
1389 #ifdef SELDON_CHECK_IO
1391 if (!FileStream.good())
1392 throw IOError(
"Matrix_SymSparse::Read(istream& FileStream)",
1393 string(
"Input operation failed.")
1394 +
string(
" The input file may have been removed")
1395 +
" or may not contain enough data.");
1409 template <
class T,
class Prop,
class Storage,
class Allocator>
1413 ifstream FileStream;
1414 FileStream.open(FileName.c_str());
1416 #ifdef SELDON_CHECK_IO
1418 if (!FileStream.is_open())
1419 throw IOError(
"Matrix_SymSparse::ReadText(string FileName)",
1420 string(
"Unable to open file \"") + FileName +
"\".");
1423 this->ReadText(FileStream, cplx);
1437 template <
class T,
class Prop,
class Storage,
class Allocator>
1444 T zero;
int index = 1;
1445 ReadCoordinateMatrix(leaf_class, FileStream, zero, index, -1, cplx);
1451 #define SELDON_FILE_MATRIX_SYMSPARSE_CXX