23 #ifndef COM_DAFER45_TBTK_SPARSE_MATRIX
24 #define COM_DAFER45_TBTK_SPARSE_MATRIX
34 template<
typename DataType>
69 void add(
unsigned int row,
unsigned int col,
const DataType &value);
186 DataType
trace()
const;
194 std::tuple<unsigned int, unsigned int, DataType>
198 int numRows, numCols;
202 bool allowDynamicDimensions;
209 unsigned int *csxXPointers;
219 int csxNumMatrixElements;
223 std::vector<std::tuple<unsigned int, DataType>>
229 std::vector<std::tuple<unsigned int, DataType>>
237 std::vector<std::tuple<unsigned int, DataType>>
263 template<
typename DataType>
265 csxXPointers =
nullptr;
270 template<
typename DataType>
272 this->storageFormat = storageFormat;
276 allowDynamicDimensions =
true;
278 csxXPointers =
nullptr;
281 csxNumMatrixElements = -1;
284 template<
typename DataType>
287 unsigned int numRows,
290 this->storageFormat = storageFormat;
292 this->numRows = numRows;
293 this->numCols = numCols;
294 allowDynamicDimensions =
false;
296 csxXPointers =
nullptr;
299 csxNumMatrixElements = -1;
302 template<
typename DataType>
306 storageFormat = sparseMatrix.storageFormat;
308 numRows = sparseMatrix.numRows;
309 numCols = sparseMatrix.numCols;
310 allowDynamicDimensions = sparseMatrix.allowDynamicDimensions;
312 csxNumMatrixElements = sparseMatrix.csxNumMatrixElements;
313 if(csxNumMatrixElements == -1){
315 sparseMatrix.csxXPointers ==
nullptr
316 && sparseMatrix.csxY ==
nullptr
317 && sparseMatrix.csxValues ==
nullptr,
318 "SparseMatrix::SparseMatrix()",
319 "Invalid pointers in the original SparseMatrix.",
320 "This should never happen, contact the developer."
323 csxXPointers =
nullptr;
329 sparseMatrix.csxXPointers !=
nullptr
330 && sparseMatrix.csxY !=
nullptr
331 && sparseMatrix.csxValues !=
nullptr,
332 "SparseMatrix::SparseMatrix()",
333 "Invalid pointers in the original SparseMatrix.",
334 "This should never happen, contact the developer."
337 switch(storageFormat){
338 case StorageFormat::CSR:
339 csxXPointers =
new unsigned int[numRows+1];
340 for(
int row = 0; row < numRows+1; row++){
342 = sparseMatrix.csxXPointers[row];
345 case StorageFormat::CSC:
346 csxXPointers =
new unsigned int[numCols+1];
347 for(
int col = 0; col < numCols+1; col++){
349 = sparseMatrix.csxXPointers[col];
354 "SparseMatrix::SparseMatrix()",
355 "Unknow StorageFormat.",
356 "This should never happen, contact the"
361 csxY =
new unsigned int[csxNumMatrixElements];
362 csxValues =
new DataType[csxNumMatrixElements];
363 for(
int n = 0; n < csxNumMatrixElements; n++){
364 csxY[n] = sparseMatrix.csxY[n];
365 csxValues[n] = sparseMatrix.csxValues[n];
370 template<
typename DataType>
374 storageFormat = sparseMatrix.storageFormat;
376 numRows = sparseMatrix.numRows;
377 numCols = sparseMatrix.numCols;
378 allowDynamicDimensions = sparseMatrix.allowDynamicDimensions;
380 csxNumMatrixElements = sparseMatrix.csxNumMatrixElements;
381 if(csxNumMatrixElements == -1){
383 sparseMatrix.csxXPointers ==
nullptr
384 && sparseMatrix.csxY ==
nullptr
385 && sparseMatrix.csxValues ==
nullptr,
386 "SparseMatrix::SparseMatrix()",
387 "Invalid pointers in the original SparseMatrix.",
388 "This should never happen, contact the developer."
391 csxXPointers =
nullptr;
397 sparseMatrix.csxXPointers !=
nullptr
398 && sparseMatrix.csxY !=
nullptr
399 && sparseMatrix.csxValues !=
nullptr,
400 "SparseMatrix::SparseMatrix()",
401 "Invalid pointers in the original SparseMatrix.",
402 "This should never happen, contact the developer."
405 csxXPointers = sparseMatrix.csxXPointers;
406 sparseMatrix.csxXPointers =
nullptr;
408 csxY = sparseMatrix.csxY;
409 sparseMatrix.csxY =
nullptr;
411 csxValues = sparseMatrix.csxValues;
412 sparseMatrix.csxValues =
nullptr;
416 template<
typename DataType>
418 if(csxXPointers !=
nullptr)
419 delete [] csxXPointers;
422 if(csxValues !=
nullptr)
426 template<
typename DataType>
431 storageFormat = rhs.storageFormat;
433 numRows = rhs.numRows;
434 numCols = rhs.numCols;
435 allowDynamicDimensions = rhs.allowDynamicDimensions;
437 if(csxXPointers !=
nullptr)
438 delete [] csxXPointers;
441 if(csxValues !=
nullptr)
444 csxNumMatrixElements = rhs.csxNumMatrixElements;
445 if(csxNumMatrixElements == -1){
447 rhs.csxXPointers ==
nullptr
448 && rhs.csxY ==
nullptr
449 && rhs.csxValues ==
nullptr,
450 "SparseMatrix::operator=()",
451 "Invalid pointers in the original SparseMatrix.",
452 "This should never happen, contact the developer."
455 csxXPointers =
nullptr;
461 rhs.csxXPointers !=
nullptr
462 && rhs.csxY !=
nullptr
463 && rhs.csxValues !=
nullptr,
464 "SparseMatrix::SparseMatrix()",
465 "Invalid pointers in the original SparseMatrix.",
466 "This should never happen, contact the developer."
469 switch(storageFormat){
470 case StorageFormat::CSR:
471 csxXPointers =
new unsigned int[numRows+1];
472 for(
unsigned int row = 0; row < numRows+1; row++){
474 = rhs.csxXPointers[row];
477 case StorageFormat::CSC:
478 csxXPointers =
new unsigned int[numCols+1];
479 for(
unsigned int col = 0; col < numCols+1; col++){
481 = rhs.csxXPointers[col];
486 "SparseMatrix::SparseMatrix()",
487 "Unknow StorageFormat.",
488 "This should never happen, contact the"
493 csxY =
new unsigned int[csxNumMatrixElements];
494 csxValues =
new DataType[csxNumMatrixElements];
495 for(
unsigned int n = 0; n < csxNumMatrixElements; n++){
496 csxY[n] = rhs.csxY[n];
497 csxValues[n] = rhs.csxValues[n];
505 template<
typename DataType>
510 storageFormat = rhs.storageFormat;
512 numRows = rhs.numRows;
513 numCols = rhs.numCols;
514 allowDynamicDimensions = rhs.allowDynamicDimensions;
516 if(csxXPointers !=
nullptr)
517 delete [] csxXPointers;
520 if(csxValues !=
nullptr)
523 csxNumMatrixElements = rhs.csxNumMatrixElements;
524 if(csxNumMatrixElements == -1){
526 rhs.csxXPointers ==
nullptr
527 && rhs.csxY ==
nullptr
528 && rhs.csxValues ==
nullptr,
529 "SparseMatrix::operator=()",
530 "Invalid pointers in the original SparseMatrix.",
531 "This should never happen, contact the developer."
534 csxXPointers =
nullptr;
540 rhs.csxXPointers !=
nullptr
541 && rhs.csxY !=
nullptr
542 && rhs.csxValues !=
nullptr,
543 "SparseMatrix::SparseMatrix()",
544 "Invalid pointers in the original SparseMatrix.",
545 "This should never happen, contact the developer."
548 csxXPointers = rhs.csxXPointers;
549 rhs.csxXPointers =
nullptr;
554 csxValues = rhs.csxValues;
555 rhs.csxValues =
nullptr;
562 template<
typename DataType>
566 const DataType &value
568 if(!allowDynamicDimensions){
570 (
int)row < numRows && (
int)col < numCols,
571 "SparseMatrix::add()",
572 "Invalid matrix entry. The matrix was constructed"
573 " specifiying that the matrix dimension is '"
574 << numRows <<
"x" << numCols <<
" but tried to add"
575 <<
" matrix element with index '(" << row <<
", "
577 "Ensure that the matrix elements are in range, or use"
578 <<
" a constructor which does not fix the matrix"
583 dictionaryOfKeys.push_back(std::make_tuple(row, col, value));
586 template<
typename DataType>
590 if(this->storageFormat != storageFormat){
592 this->storageFormat = storageFormat;
597 template<
typename DataType>
601 "SparseMatrix::getNumRows()",
602 "Number of rows not yet determined.",
606 return (
unsigned int)numRows;
609 template<
typename DataType>
613 "SparseMatrix::getNumRows()",
614 "Number of rows not yet determined.",
618 return (
unsigned int)numCols;
621 template<
typename DataType>
624 storageFormat == StorageFormat::CSR,
625 "SparseMatrix::getCSRNumMatrixElements()",
626 "Tried to access CSR number of matrix elements, but the matrix"
627 " is not on the CSR storage format.",
628 "Use SparseMatrix::setFormat() to change the storage format."
631 if(csxNumMatrixElements == -1)
634 return (
unsigned int)csxNumMatrixElements;
637 template<
typename DataType>
640 storageFormat == StorageFormat::CSC,
641 "SparseMatrix::getCSCNumMatrixElements()",
642 "Tried to access CSC number of matrix elements, but the matrix"
643 " is not on the CSC storage format.",
644 "Use SparseMatrix::setFormat() to change the storage format."
647 if(csxNumMatrixElements == -1)
650 return (
unsigned int)csxNumMatrixElements;
653 template<
typename DataType>
656 storageFormat == StorageFormat::CSR,
657 "SparseMatrix::getCSRRowPointers()",
658 "Tried to access CSR row pointers, but the matrix is not on"
659 " the CSR storage format.",
660 "Use SparseMatrix::setFormat() to change the storage format."
664 csxXPointers !=
nullptr,
665 "SparseMatrix::getCSRRowPointers()",
666 "Tried to access CSR row pointers, but row pointers have not"
667 <<
" been constructed yet.",
674 template<
typename DataType>
677 storageFormat == StorageFormat::CSC,
678 "SparseMatrix::getCSCColumnPointers()",
679 "Tried to access CSC row pointers, but the matrix is not on"
680 " the CSC storage format.",
681 "Use SparseMatrix::setFormat() to change the storage format."
685 csxXPointers !=
nullptr,
686 "SparseMatrix::getCSCColumnPointers()",
687 "Tried to access CSC column pointers, but column pointers have"
688 <<
" not been constructed yet.",
695 template<
typename DataType>
698 storageFormat == StorageFormat::CSR,
699 "SparseMatrix::getCSRColumns()",
700 "Tried to access CSR columns, but the matrix is not on the CSR"
701 <<
" storage format.",
702 "Use SparseMatrix::setFormat() to change the storage format."
707 "SparseMatrix::getCSRColumns()",
708 "Tried to access CSR columns, but columns have not been"
709 <<
" constructed yet.",
716 template<
typename DataType>
719 storageFormat == StorageFormat::CSC,
720 "SparseMatrix::getCSCRows()",
721 "Tried to access CSC rows, but the matrix is not on the CSC"
722 <<
" storage format.",
723 "Use SparseMatrix::setFormat() to change the storage format."
728 "SparseMatrix::getCSCRows()",
729 "Tried to access CSC rows, but rows have not been constructed"
737 template<
typename DataType>
740 storageFormat == StorageFormat::CSR,
741 "SparseMatrix::getCSRValues()",
742 "Tried to access CSR values, but the matrix is not on the CSR"
743 <<
" storage format.",
744 "Use SparseMatrix::setFormat() to change the storage format."
748 csxValues !=
nullptr,
749 "SparseMatrix::getCSRValues()",
750 "Tried to access CSR values, but values have not been"
751 <<
" constructed yet.",
758 template<
typename DataType>
761 storageFormat == StorageFormat::CSC,
762 "SparseMatrix::getCSCValues()",
763 "Tried to access CSC values, but the matrix is not on the CSC"
764 <<
" storage format.",
765 "Use SparseMatrix::setFormat() to change the storage format."
769 csxValues !=
nullptr,
770 "SparseMatrix::getCSCValues()",
771 "Tried to access CSC values, but values have not been"
772 <<
" constructed yet.",
779 template<
typename DataType>
784 template<
typename DataType>
789 csxNumMatrixElements != -1 && rhs.csxNumMatrixElements != -1,
790 "SparseMatrix::operator+=()",
791 "Unable to add matrices since the matrices have not yet been"
793 "Ensure that SparseMatrix::construct() has been called for"
797 storageFormat == rhs.storageFormat,
798 "SparseMatrix::operator+=()",
799 "The left and right hand sides must have the same storage"
800 <<
" format. But the left hand side has storage format '" << (
801 storageFormat == StorageFormat::CSR
802 ?
"StorageFormat::CSR"
803 :
"StorageFormat::CSC"
804 ) <<
"' while the right hand side has storage format '" << (
805 rhs.storageFormat == StorageFormat::CSR
806 ?
"StorageFormat::CSR"
807 :
"StorageFormat::CSC"
812 allowDynamicDimensions == rhs.allowDynamicDimensions,
813 "SparseMatrix::operator+=()",
814 "The left and right hand sides must either both have dynamic"
815 <<
" or both not have dynamic dimensions. But the left hand"
817 allowDynamicDimensions
818 ?
"has dynamic dimensions "
819 :
"does not have dynamic dimensions "
820 ) <<
" whilte the right hand side " << (
821 allowDynamicDimensions
822 ?
"has dynamic dimensions."
823 :
"does not have dynamic dimensions."
825 "Whether the SparseMatrix has dynamic dimensions or not"
826 <<
" depends on whether the number of rows and columns are"
827 <<
" passed to the SparseMatrix constructor or not."
830 if(!allowDynamicDimensions){
832 numRows == rhs.numRows && numCols == rhs.numCols,
833 "SparseMatrix::operator+=()",
834 "The left and right hand sides must have the same"
835 <<
" dimensions, but the left hand side has dimension"
836 <<
" '" << numRows <<
"x" << numCols <<
"' while the"
837 <<
" right hand side has dimensions '" << rhs.numRows
838 <<
"x" << numCols <<
"'.",
839 "If both matrices have dynamic dimensions their"
840 <<
" dimensions do not need to agree. To create"
841 <<
" matrices with dynamic dimensions, do not pass row"
842 <<
" and column numbers to the SparseMatrix"
849 switch(storageFormat){
850 case StorageFormat::CSR:
852 for(
int row = 0; row < rhs.numRows; row++){
854 int n = rhs.csxXPointers[row];
855 n < (
int)rhs.csxXPointers[row+1];
858 add(row, rhs.csxY[n], rhs.csxValues[n]);
863 case StorageFormat::CSC:
864 for(
int col = 0; col < rhs.numCols; col++){
866 int n = rhs.csxXPointers[col];
867 n < (
int)rhs.csxXPointers[col+1];
870 add(rhs.csxY[n], col, rhs.csxValues[n]);
876 "SparseMatrix::operator+=()",
877 "Unknown storage format.",
878 "This should never happen, contact the developer."
887 template<
typename DataType>
893 return sparseMatrix += rhs;
896 template<
typename DataType>
901 csxNumMatrixElements != -1 && rhs.csxNumMatrixElements != -1,
902 "SparseMatrix::operator-=()",
903 "Unable to subtract matrices since the matrices have not yet"
904 <<
" been constructed.",
905 "Ensure that SparseMatrix::construct() has been called for"
909 storageFormat == rhs.storageFormat,
910 "SparseMatrix::operator-=()",
911 "The left and right hand sides must have the same storage"
912 <<
" format. But the left hand side has storage format '" << (
913 storageFormat == StorageFormat::CSR
914 ?
"StorageFormat::CSR"
915 :
"StorageFormat::CSC"
916 ) <<
"' while the right hand side has storage format '" << (
917 rhs.storageFormat == StorageFormat::CSR
918 ?
"StorageFormat::CSR"
919 :
"StorageFormat::CSC"
924 allowDynamicDimensions == rhs.allowDynamicDimensions,
925 "SparseMatrix::operator-=()",
926 "The left and right hand sides must either both have dynamic"
927 <<
" or both not have dynamic dimensions. But the left hand"
929 allowDynamicDimensions
930 ?
"has dynamic dimensions "
931 :
"does not have dynamic dimensions "
932 ) <<
" whilte the right hand side " << (
933 allowDynamicDimensions
934 ?
"has dynamic dimensions."
935 :
"does not have dynamic dimensions."
937 "Whether the SparseMatrix has dynamic dimensions or not"
938 <<
" depends on whether the number of rows and columns are"
939 <<
" passed to the SparseMatrix constructor or not."
942 if(!allowDynamicDimensions){
944 numRows == rhs.numRows && numCols == rhs.numCols,
945 "SparseMatrix::operator-=()",
946 "The left and right hand sides must have the same"
947 <<
" dimensions, but the left hand side has dimension"
948 <<
" '" << numRows <<
"x" << numCols <<
"' while the"
949 <<
" right hand side has dimensions '" << rhs.numRows
950 <<
"x" << numCols <<
"'.",
951 "If both matrices have dynamic dimensions their"
952 <<
" dimensions do not need to agree. To create"
953 <<
" matrices with dynamic dimensions, do not pass row"
954 <<
" and column numbers to the SparseMatrix"
961 switch(storageFormat){
962 case StorageFormat::CSR:
964 for(
int row = 0; row < rhs.numRows; row++){
966 int n = rhs.csxXPointers[row];
967 n < (
int)rhs.csxXPointers[row+1];
970 add(row, rhs.csxY[n], -rhs.csxValues[n]);
975 case StorageFormat::CSC:
976 for(
int col = 0; col < rhs.numCols; col++){
978 int n = rhs.csxXPointers[col];
979 n < (
int)rhs.csxXPointers[col+1];
982 add(rhs.csxY[n], col, -rhs.csxValues[n]);
988 "SparseMatrix::operator-=()",
989 "Unknown storage format.",
990 "This should never happen, contact the developer."
999 template<
typename DataType>
1005 return sparseMatrix -= rhs;
1008 template<
typename DataType>
1013 csxNumMatrixElements != -1 && rhs.csxNumMatrixElements != -1,
1014 "SparseMatrix::operator*=()",
1015 "Unable to multiply matrices since the matrices have not yet"
1016 <<
" been constructed.",
1017 "Ensure that SparseMatrix::construct() has been called for"
1018 <<
" both matrices."
1021 storageFormat == rhs.storageFormat,
1022 "SparseMatrix::operator*=()",
1023 "The left and right hand sides must have the same storage"
1024 <<
" format. But the left hand side has storage format '" << (
1025 storageFormat == StorageFormat::CSR
1026 ?
"StorageFormat::CSR"
1027 :
"StorageFormat::CSC"
1028 ) <<
"' while the right hand side has storage format '" << (
1029 rhs.storageFormat == StorageFormat::CSR
1030 ?
"StorageFormat::CSR"
1031 :
"StorageFormat::CSC"
1036 allowDynamicDimensions == rhs.allowDynamicDimensions,
1037 "SparseMatrix::operator*=()",
1038 "The left and right hand sides must either both have dynamic,"
1039 <<
" or both not have dynamic dimensions. But the left hand"
1041 allowDynamicDimensions
1042 ?
"has dynamic dimensions "
1043 :
"does not have dynamic dimensions "
1044 ) <<
" whilte the right hand side " << (
1045 allowDynamicDimensions
1046 ?
"has dynamic dimensions."
1047 :
"does not have dynamic dimensions."
1049 "Whether the SparseMatrix has dynamic dimensions or not"
1050 <<
" depends on whether the number of rows and columns are"
1051 <<
" passed to the SparseMatrix constructor or not."
1054 if(!allowDynamicDimensions){
1056 numCols == rhs.numRows,
1057 "SparseMatrix::operator*=()",
1058 "The number of columns for the left hand side must be"
1059 <<
" equal to the number of rows for the right hand"
1060 <<
" side. But the left hand side has '" << numCols
1061 <<
"' columns while the right hand side has '"
1062 << rhs.numRows <<
"'.",
1063 "If both matrices have dynamic dimensions their"
1064 <<
" dimensions do not need to agree. To create"
1065 <<
" matrices with dynamic dimensions, do not pass row"
1066 <<
" and column numbers to the SparseMatrix"
1072 if(allowDynamicDimensions)
1075 result =
SparseMatrix(storageFormat, numRows, rhs.numCols);
1077 switch(storageFormat){
1078 case StorageFormat::CSR:
1082 multiply(*
this, rhsCSC, result);
1085 case StorageFormat::CSC:
1089 multiply(lhsCSR, rhs, result);
1094 "SparseMatrix::operator+=()",
1095 "Unknown storage format.",
1096 "This should never happen, contact the developer."
1105 template<
typename DataType>
1110 csxNumMatrixElements != -1,
1111 "SparseMatrix::operator*=()",
1112 "Matrix not yet constructed.",
1113 "First call SparseMatrix::construct()."
1116 for(
int row = 0; row < numRows; row++){
1118 int n = csxXPointers[row];
1119 n < (int)csxXPointers[row+1];
1122 csxValues[n] *= rhs;
1129 template<
typename DataType>
1135 return result *= rhs;
1138 template<
typename DataType>
1142 csxNumMatrixElements != -1,
1143 "SparseMatrix::hermitianConjugate()",
1144 "Matrix not yet constructed.",
1145 "First call SparseMatrix::construct()."
1149 if(allowDynamicDimensions)
1152 result =
SparseMatrix(storageFormat, numRows, numCols);
1154 switch(storageFormat){
1155 case StorageFormat::CSR:
1157 for(
int row = 0; row < numRows; row++){
1159 int n = csxXPointers[row];
1160 n < (int)csxXPointers[row+1];
1163 result.
add(csxY[n], row, conj(csxValues[n]));
1169 case StorageFormat::CSC:
1171 for(
int col = 0; col < numCols; col++){
1173 int n = csxXPointers[col];
1174 n < (int)csxXPointers[col+1];
1177 result.
add(col, csxY[n], conj(csxValues[n]));
1185 "SparseMatrix::hermitianConjugate()",
1186 "Unknown storage format.",
1187 "This should never happen, contact the developer."
1196 template<
typename DataType>
1199 csxNumMatrixElements != -1,
1200 "SparseMatrix::trace()",
1201 "Matrix not yet constructed.",
1202 "First call SparseMatrix::construct()."
1205 switch(storageFormat){
1206 case StorageFormat::CSR:
1208 DataType result = 0;
1209 for(
int row = 0; row < numRows; row++){
1211 int n = csxXPointers[row];
1212 n < (int)csxXPointers[row+1];
1215 if((
unsigned int)row == csxY[n])
1216 result += csxValues[n];
1222 case StorageFormat::CSC:
1224 DataType result = 0;
1225 for(
int col = 0; col < numCols; col++){
1227 int n = csxXPointers[col];
1228 n < (int)csxXPointers[col+1];
1231 if(csxY[n] == (
unsigned int)col)
1232 result += csxValues[n];
1240 "SparseMatrix::trace()",
1241 "Unknown storage format.",
1242 "This should never happen, contact the developer."
1247 template<
typename DataType>
1250 if(dictionaryOfKeys.size() == 0)
1252 for(
unsigned int n = 0; n < dictionaryOfKeys.size(); n++){
1253 unsigned int row = std::get<0>(dictionaryOfKeys[n]);
1254 unsigned int col = std::get<1>(dictionaryOfKeys[n]);
1255 const DataType &value = std::get<2>(dictionaryOfKeys[n]);
1256 Streams::out <<
"(" << row <<
", " << col <<
", " << value <<
")\n";
1260 switch(storageFormat){
1261 case StorageFormat::CSR:
1262 Streams::out <<
"### Compressed sparse row (CSR) ###\n";
1263 if(csxNumMatrixElements == -1){
1268 for(
int row = 0; row < numRows+1; row++)
1271 for(
int n = 0; n < csxNumMatrixElements; n++)
1274 for(
int n = 0; n < csxNumMatrixElements; n++)
1279 case StorageFormat::CSC:
1280 Streams::out <<
"### Compressed sparse column (CSC) ###\n";
1281 if(csxNumMatrixElements == -1){
1286 for(
int col = 0; col < numCols+1; col++)
1289 for(
int n = 0; n < csxNumMatrixElements; n++)
1292 for(
int n = 0; n < csxNumMatrixElements; n++)
1299 "SparseMatrix::print()",
1300 "Unknow StorageFormat.",
1301 "This should never happen, contact the developer."
1306 template<
typename DataType>
1308 std::vector<std::tuple<unsigned int, DataType>>
1310 unsigned int numRows = 0;
1311 unsigned int numCols = 0;
1312 for(
unsigned int n = 0; n < dictionaryOfKeys.size(); n++){
1313 unsigned int row = std::get<0>(dictionaryOfKeys[n]);
1314 unsigned int col = std::get<1>(dictionaryOfKeys[n]);
1322 std::vector<std::tuple<unsigned int, DataType>>
1325 switch(storageFormat){
1326 case StorageFormat::CSR:
1327 listOfLists.reserve(numRows);
1328 for(
unsigned int row = 0; row < numRows; row++){
1329 listOfLists.push_back(
1330 std::vector<std::tuple<unsigned int, DataType>>()
1334 for(
unsigned int n = 0; n < dictionaryOfKeys.size(); n++){
1335 unsigned int row = std::get<0>(dictionaryOfKeys[n]);
1336 unsigned int col = std::get<1>(dictionaryOfKeys[n]);
1337 const DataType &value = std::get<2>(dictionaryOfKeys[n]);
1339 listOfLists[row].push_back(std::make_tuple(col, value));
1342 case StorageFormat::CSC:
1343 listOfLists.reserve(numCols);
1344 for(
unsigned int col = 0; col < numCols; col++){
1345 listOfLists.push_back(
1346 std::vector<std::tuple<unsigned int, DataType>>()
1350 for(
unsigned int n = 0; n < dictionaryOfKeys.size(); n++){
1351 unsigned int row = std::get<0>(dictionaryOfKeys[n]);
1352 unsigned int col = std::get<1>(dictionaryOfKeys[n]);
1353 const DataType &value = std::get<2>(dictionaryOfKeys[n]);
1355 listOfLists[col].push_back(std::make_tuple(row, value));
1360 "SparseMatrix::constructLIL()",
1361 "Unknow StorageFormat.",
1362 "This should never happen, contact the developer."
1366 sortLIL(listOfLists);
1367 mergeLIL(listOfLists);
1369 dictionaryOfKeys.clear();
1374 template<
typename DataType>
1377 std::vector<std::tuple<unsigned int, DataType>>
1380 for(
unsigned int x = 0; x < listOfLists.size(); x++){
1382 listOfLists[x].begin(),
1383 listOfLists[x].end(),
1385 const std::tuple<unsigned int, DataType> &t1,
1386 const std::tuple<unsigned int, DataType> &t2
1388 return std::get<0>(t1) < std::get<0>(t2);
1394 template<
typename DataType>
1397 std::vector<std::tuple<unsigned int, DataType>>
1400 for(
unsigned int x = 0; x < listOfLists.size(); x++){
1401 for(
int y = listOfLists[x].size()-1; y > 0; y--){
1402 unsigned int y1 = std::get<0>(listOfLists[x][y]);
1403 unsigned int y2 = std::get<0>(listOfLists[x][y-1]);
1406 std::get<1>(listOfLists[x][y-1])
1407 += std::get<1>(listOfLists[x][y]);
1408 listOfLists[x].erase(
1409 listOfLists[x].begin() + y
1416 template<
typename DataType>
1422 std::vector<std::tuple<unsigned int, DataType>>
1423 > listOfLists = constructLIL();
1425 if(allowDynamicDimensions){
1426 switch(storageFormat){
1427 case StorageFormat::CSR:
1428 numRows = listOfLists.size();
1431 unsigned int row = 0;
1432 row < listOfLists.size();
1435 if(listOfLists[row].size() == 0)
1438 unsigned int maxCol = std::get<0>(
1439 listOfLists[row].back()
1441 if((
int)maxCol+1 > numCols)
1442 numCols = maxCol + 1;
1445 case StorageFormat::CSC:
1446 numCols = listOfLists.size();
1449 unsigned int col = 0;
1450 col < listOfLists.size();
1453 if(listOfLists[col].size() == 0)
1456 unsigned int maxRow = std::get<0>(
1457 listOfLists[col].back()
1459 if((
int)maxRow+1 > numRows)
1460 numRows = maxRow + 1;
1465 "SparseMatrix::constructCSX()",
1466 "Unknow StorageFormat.",
1467 "This should never happen, contact the"
1473 csxNumMatrixElements = 0;
1474 for(
unsigned int x = 0; x < listOfLists.size(); x++)
1475 csxNumMatrixElements += listOfLists[x].size();
1477 switch(storageFormat){
1478 case StorageFormat::CSR:
1479 csxXPointers =
new unsigned int[numRows+1];
1481 case StorageFormat::CSC:
1482 csxXPointers =
new unsigned int[numCols+1];
1486 "SparseMatrix::constructCSX()",
1487 "Unknow StorageFormat.",
1488 "This should never happen, contact the"
1492 csxY =
new unsigned int[csxNumMatrixElements];
1493 csxValues =
new DataType[csxNumMatrixElements];
1495 csxXPointers[0] = 0;
1496 unsigned int currentMatrixElement = 0;
1497 for(
unsigned int x = 0; x < listOfLists.size(); x++){
1500 + listOfLists[x].size();
1504 y < listOfLists[x].size();
1507 csxY[currentMatrixElement]
1508 = std::get<0>(listOfLists[x][y]);
1509 csxValues[currentMatrixElement]
1510 = std::get<1>(listOfLists[x][y]);
1512 currentMatrixElement++;
1516 switch(storageFormat){
1517 case StorageFormat::CSR:
1519 int row = listOfLists.size();
1523 csxXPointers[row+1] = csxXPointers[row];
1526 case StorageFormat::CSC:
1528 int col = listOfLists.size();
1532 csxXPointers[col+1] = csxXPointers[col];
1537 "SparseMatrix::constructCSX()",
1538 "Unknow StorageFormat.",
1539 "This should never happen, contact the"
1545 csxNumMatrixElements == (
int)currentMatrixElement,
1546 "SparseMatrix::constructCSX()",
1547 "Invalid number of matrix elements.",
1548 "This should never happen, contact the developer."
1553 template<
typename DataType>
1555 if(csxNumMatrixElements != -1){
1557 csxXPointers !=
nullptr
1559 && csxValues !=
nullptr,
1560 "SparseMatrix::convertCSXToLIL()",
1561 "'csxNumMatrixElements' is not -1, but a csx-pointer"
1562 <<
" is a nullptr.",
1563 "This should never happen, contact the developer."
1566 switch(storageFormat){
1567 case StorageFormat::CSR:
1569 unsigned int row = 0;
1570 for(
int n = 0; n < csxNumMatrixElements; n++){
1571 if((
int)csxXPointers[row+1] == n){
1578 if((
int)csxXPointers[r+1] > n)
1583 add(row, csxY[n], csxValues[n]);
1588 case StorageFormat::CSC:
1590 unsigned int col = 0;
1591 for(
int n = 0; n < csxNumMatrixElements; n++){
1592 if((
int)csxXPointers[col+1] == n){
1599 if((
int)csxXPointers[c+1] > n)
1604 add(csxY[n], col, csxValues[n]);
1611 "SparseMatrix::convertCSXToLIL()",
1612 "Unknow StorageFormat.",
1613 "This should never happen, contact the"
1618 delete [] csxXPointers;
1620 delete [] csxValues;
1621 csxXPointers =
nullptr;
1623 csxValues =
nullptr;
1624 csxNumMatrixElements = -1;
1628 template<
typename DataType>
1636 lhs.storageFormat == StorageFormat::CSR
1637 && rhs.storageFormat == StorageFormat::CSC
1639 "SparseMatrix::multiply()",
1640 "Storage format combination not supported.",
1641 "This should never happen, contact the developer."
1647 for(
int lhsRow = 0; lhsRow < lhs.numRows; lhsRow++){
1648 for(
int rhsCol = 0; rhsCol < rhs.numCols; rhsCol++){
1649 DataType scalarProduct = 0;
1650 int lhsElement = lhs.csxXPointers[lhsRow];
1651 int rhsElement = rhs.csxXPointers[rhsCol];
1652 int lhsTerminatingElement = lhs.csxXPointers[lhsRow+1];
1653 int rhsTerminatingElement = rhs.csxXPointers[rhsCol+1];
1656 lhsElement == lhsTerminatingElement
1657 || rhsElement == rhsTerminatingElement
1662 int difference = lhs.csxY[lhsElement]
1663 - rhs.csxY[rhsElement];
1668 else if(difference > 0){
1672 scalarProduct += lhs.csxValues[
1683 if(scalarProduct != DataType(0))
1684 result.
add(lhsRow, rhsCol, scalarProduct);