deal.II version GIT relicensing-2167-g9622207b8f 2024-11-21 12:40:00+00:00
\(\newcommand{\dealvcentcolon}{\mathrel{\mathop{:}}}\) \(\newcommand{\dealcoloneq}{\dealvcentcolon\mathrel{\mkern-1.2mu}=}\) \(\newcommand{\jump}[1]{\left[\!\left[ #1 \right]\!\right]}\) \(\newcommand{\average}[1]{\left\{\!\left\{ #1 \right\}\!\right\}}\)
Loading...
Searching...
No Matches
sparse_matrix_ez.h
Go to the documentation of this file.
1// ------------------------------------------------------------------------
2//
3// SPDX-License-Identifier: LGPL-2.1-or-later
4// Copyright (C) 2002 - 2023 by the deal.II authors
5//
6// This file is part of the deal.II library.
7//
8// Part of the source code is dual licensed under Apache-2.0 WITH
9// LLVM-exception OR LGPL-2.1-or-later. Detailed license information
10// governing the source code and code contributions can be found in
11// LICENSE.md and CONTRIBUTING.md at the top level directory of deal.II.
12//
13// ------------------------------------------------------------------------
14
15#ifndef dealii_sparse_matrix_ez_h
16#define dealii_sparse_matrix_ez_h
17
18
19#include <deal.II/base/config.h>
20
23
25
26#include <vector>
27
29
30// Forward declarations
31#ifndef DOXYGEN
32template <typename number>
33class Vector;
34template <typename number>
35class FullMatrix;
36#endif
37
102template <typename number>
104{
105public:
110
115 struct Entry
116 {
120 Entry();
121
125 Entry(const size_type column, const number &value);
126
131
135 number value;
136
141 };
142
147 struct RowInfo
148 {
153
161 unsigned short length;
165 unsigned short diagonal;
169 static const unsigned short invalid_diagonal =
170 static_cast<unsigned short>(-1);
171 };
172
173public:
178 {
179 private:
184 {
185 public:
191 const size_type row,
192 const unsigned short index);
193
198 row() const;
199
203 unsigned short
204 index() const;
205
210 column() const;
211
215 number
216 value() const;
217
218 protected:
223
228
232 unsigned short a_index;
233
234 // Make enclosing class a friend.
235 friend class const_iterator;
236 };
237
238 public:
243 const size_type row,
244 const unsigned short index);
245
250 operator++();
251
255 const Accessor &
256 operator*() const;
257
261 const Accessor *
262 operator->() const;
263
267 bool
268 operator==(const const_iterator &) const;
272 bool
273 operator!=(const const_iterator &) const;
274
279 bool
280 operator<(const const_iterator &) const;
281
282 private:
287 };
288
293 using value_type = number;
294
303
312
319 explicit SparseMatrixEZ(const size_type n_rows,
320 const size_type n_columns,
321 const size_type default_row_length = 0,
322 const unsigned int default_increment = 1);
323
327 ~SparseMatrixEZ() override = default;
328
334
344 operator=(const double d);
345
353 void
354 reinit(const size_type n_rows,
355 const size_type n_columns,
356 size_type default_row_length = 0,
357 unsigned int default_increment = 1,
358 size_type reserve = 0);
359
364 void
375 bool
376 empty() const;
377
383 m() const;
384
390 n() const;
391
396 get_row_length(const size_type row) const;
397
403
408 std::size_t
410
416 template <typename StreamType>
417 void
418 print_statistics(StreamType &s, bool full = false);
419
429 void
431 size_type &allocated,
432 size_type &reserved,
433 std::vector<size_type> &used_by_line,
434 const bool compute_by_line) const;
457 void
458 set(const size_type i,
459 const size_type j,
460 const number value,
461 const bool elide_zero_values = true);
462
473 void
474 add(const size_type i, const size_type j, const number value);
475
490 template <typename number2>
491 void
492 add(const std::vector<size_type> &indices,
493 const FullMatrix<number2> &full_matrix,
494 const bool elide_zero_values = true);
495
501 template <typename number2>
502 void
503 add(const std::vector<size_type> &row_indices,
504 const std::vector<size_type> &col_indices,
505 const FullMatrix<number2> &full_matrix,
506 const bool elide_zero_values = true);
507
517 template <typename number2>
518 void
519 add(const size_type row,
520 const std::vector<size_type> &col_indices,
521 const std::vector<number2> &values,
522 const bool elide_zero_values = true);
523
533 template <typename number2>
534 void
535 add(const size_type row,
536 const size_type n_cols,
537 const size_type *col_indices,
538 const number2 *values,
539 const bool elide_zero_values = true,
540 const bool col_indices_are_sorted = false);
541
563 template <typename MatrixType>
565 copy_from(const MatrixType &source, const bool elide_zero_values = true);
566
574 template <typename MatrixType>
575 void
576 add(const number factor, const MatrixType &matrix);
591 number
592 operator()(const size_type i, const size_type j) const;
593
598 number
599 el(const size_type i, const size_type j) const;
609 template <typename somenumber>
610 void
612
618 template <typename somenumber>
619 void
621
626 template <typename somenumber>
627 void
629
635 template <typename somenumber>
636 void
646 number
647 l2_norm() const;
658 template <typename somenumber>
659 void
661 const Vector<somenumber> &src,
662 const number omega = 1.) const;
663
667 template <typename somenumber>
668 void
670 const Vector<somenumber> &src,
671 const number om = 1.,
672 const std::vector<std::size_t> &pos_right_of_diagonal =
673 std::vector<std::size_t>()) const;
674
679 template <typename somenumber>
680 void
682 const Vector<somenumber> &src,
683 const number om = 1.) const;
684
689 template <typename somenumber>
690 void
692 const Vector<somenumber> &src,
693 const number om = 1.) const;
694
703 template <typename MatrixTypeA, typename MatrixTypeB>
704 void
705 conjugate_add(const MatrixTypeA &A,
706 const MatrixTypeB &B,
707 const bool transpose = false);
717 begin() const;
718
723 end() const;
724
730 begin(const size_type r) const;
731
737 end(const size_type r) const;
747 void
748 print(std::ostream &out) const;
749
772 void
773 print_formatted(std::ostream &out,
774 const unsigned int precision = 3,
775 const bool scientific = true,
776 const unsigned int width = 0,
777 const char *zero_string = " ",
778 const double denominator = 1.,
779 const char *separator = " ") const;
780
786 void
787 block_write(std::ostream &out) const;
788
799 void
800 block_read(std::istream &in);
812
817 int,
818 int,
819 << "The entry with index (" << arg1 << ',' << arg2
820 << ") does not exist.");
821
823 int,
824 int,
825 << "An entry with index (" << arg1 << ',' << arg2
826 << ") cannot be allocated.");
828private:
833 const Entry *
834 locate(const size_type row, const size_type col) const;
835
840 Entry *
841 locate(const size_type row, const size_type col);
842
846 Entry *
847 allocate(const size_type row, const size_type col);
848
854 template <typename somenumber>
855 void
857 const Vector<somenumber> &src,
858 const size_type begin_row,
859 const size_type end_row) const;
860
866 template <typename somenumber>
867 void
869 const size_type begin_row,
870 const size_type end_row,
871 somenumber *partial_sum) const;
872
878 template <typename somenumber>
879 void
881 const Vector<somenumber> &v,
882 const size_type begin_row,
883 const size_type end_row,
884 somenumber *partial_sum) const;
885
890
894 std::vector<RowInfo> row_info;
895
899 std::vector<Entry> data;
900
904 unsigned int increment;
905
910};
911
915/*---------------------- Inline functions -----------------------------------*/
916
917template <typename number>
919 const number &value)
920 : column(column)
921 , value(value)
922{}
923
924
925
926template <typename number>
928 : column(invalid)
929 , value(0)
930{}
931
932
933template <typename number>
935 : start(start)
936 , length(0)
937 , diagonal(invalid_diagonal)
938{}
939
940
941//---------------------------------------------------------------------------
942template <typename number>
944 const SparseMatrixEZ<number> *matrix,
945 const size_type r,
946 const unsigned short i)
947 : matrix(matrix)
948 , a_row(r)
949 , a_index(i)
950{}
951
952
953template <typename number>
959
960
961template <typename number>
964{
965 return matrix->data[matrix->row_info[a_row].start + a_index].column;
966}
967
968
969template <typename number>
970inline unsigned short
975
976
977
978template <typename number>
979inline number
981{
982 return matrix->data[matrix->row_info[a_row].start + a_index].value;
983}
984
985
986template <typename number>
988 const SparseMatrixEZ<number> *matrix,
989 const size_type r,
990 const unsigned short i)
991 : accessor(matrix, r, i)
992{
993 // Finish if this is the end()
994 if (r == accessor.matrix->m() && i == 0)
995 return;
996
997 // Make sure we never construct an
998 // iterator pointing to a
999 // non-existing entry
1000
1001 // If the index points beyond the
1002 // end of the row, try the next
1003 // row.
1004 if (accessor.a_index >= accessor.matrix->row_info[accessor.a_row].length)
1005 {
1006 do
1007 {
1008 ++accessor.a_row;
1009 }
1010 // Beware! If the next row is
1011 // empty, iterate until a
1012 // non-empty row is found or we
1013 // hit the end of the matrix.
1014 while (accessor.a_row < accessor.matrix->m() &&
1015 accessor.matrix->row_info[accessor.a_row].length == 0);
1016 }
1017}
1018
1019
1020template <typename number>
1023{
1024 Assert(accessor.a_row < accessor.matrix->m(), ExcIteratorPastEnd());
1025
1026 // Increment column index
1027 ++(accessor.a_index);
1028 // If index exceeds number of
1029 // entries in this row, proceed
1030 // with next row.
1031 if (accessor.a_index >= accessor.matrix->row_info[accessor.a_row].length)
1032 {
1033 accessor.a_index = 0;
1034 // Do this loop to avoid
1035 // elements in empty rows
1036 do
1037 {
1038 ++accessor.a_row;
1039 }
1040 while (accessor.a_row < accessor.matrix->m() &&
1041 accessor.matrix->row_info[accessor.a_row].length == 0);
1042 }
1043 return *this;
1044}
1045
1046
1047template <typename number>
1050{
1051 return accessor;
1052}
1053
1054
1055template <typename number>
1058{
1059 return &accessor;
1060}
1061
1062
1063template <typename number>
1064inline bool
1066 const const_iterator &other) const
1067{
1068 return (accessor.row() == other.accessor.row() &&
1069 accessor.index() == other.accessor.index());
1070}
1071
1072
1073template <typename number>
1074inline bool
1076 const const_iterator &other) const
1077{
1078 return !(*this == other);
1079}
1080
1081
1082template <typename number>
1083inline bool
1085 const const_iterator &other) const
1086{
1087 return (accessor.row() < other.accessor.row() ||
1088 (accessor.row() == other.accessor.row() &&
1089 accessor.index() < other.accessor.index()));
1090}
1091
1092
1093//---------------------------------------------------------------------------
1094template <typename number>
1097{
1098 return row_info.size();
1099}
1100
1101
1102template <typename number>
1105{
1106 return n_columns;
1107}
1108
1109
1110template <typename number>
1111inline typename SparseMatrixEZ<number>::Entry *
1113{
1114 AssertIndexRange(row, m());
1115 AssertIndexRange(col, n());
1116
1117 const RowInfo &r = row_info[row];
1118 const size_type end = r.start + r.length;
1119 for (size_type i = r.start; i < end; ++i)
1120 {
1121 Entry *const entry = &data[i];
1122 if (entry->column == col)
1123 return entry;
1124 if (entry->column == Entry::invalid)
1125 return nullptr;
1126 }
1127 return nullptr;
1128}
1129
1130
1131
1132template <typename number>
1133inline const typename SparseMatrixEZ<number>::Entry *
1135{
1136 SparseMatrixEZ<number> *t = const_cast<SparseMatrixEZ<number> *>(this);
1137 return t->locate(row, col);
1138}
1139
1140
1141template <typename number>
1142inline typename SparseMatrixEZ<number>::Entry *
1144{
1145 AssertIndexRange(row, m());
1146 AssertIndexRange(col, n());
1147
1148 RowInfo &r = row_info[row];
1149 const size_type end = r.start + r.length;
1150
1151 size_type i = r.start;
1152 // If diagonal exists and this
1153 // column is higher, start only
1154 // after diagonal.
1155 if (r.diagonal != RowInfo::invalid_diagonal && col >= row)
1156 i += r.diagonal;
1157 // Find position of entry
1158 while (i < end && data[i].column < col)
1159 ++i;
1160
1161 // entry found
1162 if (i != end && data[i].column == col)
1163 return &data[i];
1164
1165 // Now, we must insert the new
1166 // entry and move all successive
1167 // entries back.
1168
1169 // If no more space is available
1170 // for this row, insert new
1171 // elements into the vector.
1172 // TODO:[GK] We should not extend this row if i<end
1173 if (row != row_info.size() - 1)
1174 {
1175 if (end >= row_info[row + 1].start)
1176 {
1177 // Failure if increment 0
1179
1180 // Insert new entries
1181 data.insert(data.begin() + end, increment, Entry());
1182 // Update starts of
1183 // following rows
1184 for (size_type rn = row + 1; rn < row_info.size(); ++rn)
1185 row_info[rn].start += increment;
1186 }
1187 }
1188 else
1189 {
1190 if (end >= data.size())
1191 {
1192 // Here, appending a block
1193 // does not increase
1194 // performance.
1195 data.push_back(Entry());
1196 }
1197 }
1198
1199 Entry *entry = &data[i];
1200 // Save original entry
1201 Entry temp = *entry;
1202 // Insert new entry here to
1203 // make sure all entries
1204 // are ordered by column
1205 // index
1206 entry->column = col;
1207 entry->value = 0;
1208 // Update row_info
1209 ++r.length;
1210 if (col == row)
1211 r.diagonal = i - r.start;
1212 else if (col < row && r.diagonal != RowInfo::invalid_diagonal)
1213 ++r.diagonal;
1214
1215 if (i == end)
1216 return entry;
1217
1218 // Move all entries in this
1219 // row up by one
1220 for (size_type j = i + 1; j < end; ++j)
1221 {
1222 // There should be no invalid
1223 // entry below end
1224 Assert(data[j].column != Entry::invalid, ExcInternalError());
1225
1226 // TODO[GK]: This could be done more efficiently by moving starting at the
1227 // top rather than swapping starting at the bottom
1228 std::swap(data[j], temp);
1229 }
1231
1232 data[end] = temp;
1233
1234 return entry;
1235}
1236
1237
1238
1239template <typename number>
1240inline void
1242 const size_type j,
1243 const number value,
1244 const bool elide_zero_values)
1245{
1246 AssertIsFinite(value);
1247
1248 AssertIndexRange(i, m());
1249 AssertIndexRange(j, n());
1250
1251 if (elide_zero_values && value == 0.)
1252 {
1253 Entry *entry = locate(i, j);
1254 if (entry != nullptr)
1255 entry->value = 0.;
1256 }
1257 else
1258 {
1259 Entry *entry = allocate(i, j);
1260 entry->value = value;
1261 }
1262}
1263
1264
1265
1266template <typename number>
1267inline void
1269 const size_type j,
1270 const number value)
1271{
1272 AssertIsFinite(value);
1273
1274 AssertIndexRange(i, m());
1275 AssertIndexRange(j, n());
1276
1277 // ignore zero additions
1278 if (std::abs(value) == 0.)
1279 return;
1280
1281 Entry *entry = allocate(i, j);
1282 entry->value += value;
1283}
1284
1285
1286template <typename number>
1287template <typename number2>
1288void
1289SparseMatrixEZ<number>::add(const std::vector<size_type> &indices,
1290 const FullMatrix<number2> &full_matrix,
1291 const bool elide_zero_values)
1292{
1293 // TODO: This function can surely be made more efficient
1294 for (size_type i = 0; i < indices.size(); ++i)
1295 for (size_type j = 0; j < indices.size(); ++j)
1296 if ((full_matrix(i, j) != 0) || (elide_zero_values == false))
1297 add(indices[i], indices[j], full_matrix(i, j));
1298}
1299
1300
1301
1302template <typename number>
1303template <typename number2>
1304void
1305SparseMatrixEZ<number>::add(const std::vector<size_type> &row_indices,
1306 const std::vector<size_type> &col_indices,
1307 const FullMatrix<number2> &full_matrix,
1308 const bool elide_zero_values)
1309{
1310 // TODO: This function can surely be made more efficient
1311 for (size_type i = 0; i < row_indices.size(); ++i)
1312 for (size_type j = 0; j < col_indices.size(); ++j)
1313 if ((full_matrix(i, j) != 0) || (elide_zero_values == false))
1314 add(row_indices[i], col_indices[j], full_matrix(i, j));
1315}
1316
1317
1318
1319template <typename number>
1320template <typename number2>
1321void
1323 const std::vector<size_type> &col_indices,
1324 const std::vector<number2> &values,
1325 const bool elide_zero_values)
1326{
1327 // TODO: This function can surely be made more efficient
1328 for (size_type j = 0; j < col_indices.size(); ++j)
1329 if ((values[j] != 0) || (elide_zero_values == false))
1330 add(row, col_indices[j], values[j]);
1331}
1332
1333
1334
1335template <typename number>
1336template <typename number2>
1337void
1339 const size_type n_cols,
1340 const size_type *col_indices,
1341 const number2 *values,
1342 const bool elide_zero_values,
1343 const bool /*col_indices_are_sorted*/)
1344{
1345 // TODO: This function can surely be made more efficient
1346 for (size_type j = 0; j < n_cols; ++j)
1347 if ((std::abs(values[j]) != 0) || (elide_zero_values == false))
1348 add(row, col_indices[j], values[j]);
1349}
1350
1351
1352
1353template <typename number>
1354inline number
1356{
1357 const Entry *entry = locate(i, j);
1358 if (entry)
1359 return entry->value;
1360 return 0.;
1361}
1362
1363
1364
1365template <typename number>
1366inline number
1368{
1369 const Entry *entry = locate(i, j);
1370 if (entry)
1371 return entry->value;
1372 Assert(false, ExcInvalidEntry(i, j));
1373 return 0.;
1374}
1375
1376
1377template <typename number>
1380{
1381 const_iterator result(this, 0, 0);
1382 return result;
1383}
1384
1385template <typename number>
1388{
1389 return const_iterator(this, m(), 0);
1390}
1391
1392template <typename number>
1395{
1396 AssertIndexRange(r, m());
1397 const_iterator result(this, r, 0);
1398 return result;
1399}
1400
1401template <typename number>
1404{
1405 AssertIndexRange(r, m());
1406 const_iterator result(this, r + 1, 0);
1407 return result;
1408}
1409
1410template <typename number>
1411template <typename MatrixType>
1414 const bool elide_zero_values)
1415{
1416 reinit(M.m(), M.n(), this->saved_default_row_length, this->increment);
1417
1418 // loop over the elements of the argument matrix row by row, as suggested
1419 // in the documentation of the sparse matrix iterator class, and
1420 // copy them into the current object
1421 for (size_type row = 0; row < M.m(); ++row)
1422 {
1423 const typename MatrixType::const_iterator end_row = M.end(row);
1424 for (typename MatrixType::const_iterator entry = M.begin(row);
1425 entry != end_row;
1426 ++entry)
1427 set(row, entry->column(), entry->value(), elide_zero_values);
1428 }
1429
1430 return *this;
1431}
1432
1433template <typename number>
1434template <typename MatrixType>
1435inline void
1436SparseMatrixEZ<number>::add(const number factor, const MatrixType &M)
1437{
1438 Assert(M.m() == m(), ExcDimensionMismatch(M.m(), m()));
1439 Assert(M.n() == n(), ExcDimensionMismatch(M.n(), n()));
1440
1441 if (factor == 0.)
1442 return;
1443
1444 // loop over the elements of the argument matrix row by row, as suggested
1445 // in the documentation of the sparse matrix iterator class, and
1446 // add them into the current object
1447 for (size_type row = 0; row < M.m(); ++row)
1448 {
1449 const typename MatrixType::const_iterator end_row = M.end(row);
1450 for (typename MatrixType::const_iterator entry = M.begin(row);
1451 entry != end_row;
1452 ++entry)
1453 if (entry->value() != 0)
1454 add(row, entry->column(), factor * entry->value());
1455 }
1456}
1457
1458
1459
1460template <typename number>
1461template <typename MatrixTypeA, typename MatrixTypeB>
1462inline void
1464 const MatrixTypeB &B,
1465 const bool transpose)
1466{
1467 // Compute the result
1468 // r_ij = \sum_kl b_ik b_jl a_kl
1469
1470 // Assert (n() == B.m(), ExcDimensionMismatch(n(), B.m()));
1471 // Assert (m() == B.m(), ExcDimensionMismatch(m(), B.m()));
1472 // Assert (A.n() == B.n(), ExcDimensionMismatch(A.n(), B.n()));
1473 // Assert (A.m() == B.n(), ExcDimensionMismatch(A.m(), B.n()));
1474
1475 // Somehow, we have to avoid making
1476 // this an operation of complexity
1477 // n^2. For the transpose case, we
1478 // can go through the non-zero
1479 // elements of A^-1 and use the
1480 // corresponding rows of B only.
1481 // For the non-transpose case, we
1482 // must find a trick.
1483 typename MatrixTypeB::const_iterator b1 = B.begin();
1484 const typename MatrixTypeB::const_iterator b_final = B.end();
1485 if (transpose)
1486 while (b1 != b_final)
1487 {
1488 const size_type i = b1->column();
1489 const size_type k = b1->row();
1490 typename MatrixTypeB::const_iterator b2 = B.begin();
1491 while (b2 != b_final)
1492 {
1493 const size_type j = b2->column();
1494 const size_type l = b2->row();
1495
1496 const typename MatrixTypeA::value_type a = A.el(k, l);
1497
1498 if (a != 0.)
1499 add(i, j, a * b1->value() * b2->value());
1500 ++b2;
1501 }
1502 ++b1;
1503 }
1504 else
1505 {
1506 // Determine minimal and
1507 // maximal row for a column in
1508 // advance.
1509
1510 std::vector<size_type> minrow(B.n(), B.m());
1511 std::vector<size_type> maxrow(B.n(), 0);
1512 while (b1 != b_final)
1513 {
1514 const size_type r = b1->row();
1515 if (r < minrow[b1->column()])
1516 minrow[b1->column()] = r;
1517 if (r > maxrow[b1->column()])
1518 maxrow[b1->column()] = r;
1519 ++b1;
1520 }
1521
1522 typename MatrixTypeA::const_iterator ai = A.begin();
1523 const typename MatrixTypeA::const_iterator ae = A.end();
1524
1525 while (ai != ae)
1526 {
1527 const typename MatrixTypeA::value_type a = ai->value();
1528 // Don't do anything if
1529 // this entry is zero.
1530 if (a == 0.)
1531 continue;
1532
1533 // Now, loop over all rows
1534 // having possibly a
1535 // nonzero entry in column
1536 // ai->row()
1537 b1 = B.begin(minrow[ai->row()]);
1538 const typename MatrixTypeB::const_iterator be1 =
1539 B.end(maxrow[ai->row()]);
1540 const typename MatrixTypeB::const_iterator be2 =
1541 B.end(maxrow[ai->column()]);
1542
1543 while (b1 != be1)
1544 {
1545 const double b1v = b1->value();
1546 // We need the product
1547 // of both. If it is
1548 // zero, we can save
1549 // the work
1550 if (b1->column() == ai->row() && (b1v != 0.))
1551 {
1552 const size_type i = b1->row();
1553
1554 typename MatrixTypeB::const_iterator b2 =
1555 B.begin(minrow[ai->column()]);
1556 while (b2 != be2)
1557 {
1558 if (b2->column() == ai->column())
1559 {
1560 const size_type j = b2->row();
1561 add(i, j, a * b1v * b2->value());
1562 }
1563 ++b2;
1564 }
1565 }
1566 ++b1;
1567 }
1568 ++ai;
1569 }
1570 }
1571}
1572
1573
1574template <typename number>
1575template <typename StreamType>
1576inline void
1578{
1579 size_type used;
1580 size_type allocated;
1581 size_type reserved;
1582 std::vector<size_type> used_by_line;
1583
1584 compute_statistics(used, allocated, reserved, used_by_line, full);
1585
1586 out << "SparseMatrixEZ:used entries:" << used << std::endl
1587 << "SparseMatrixEZ:allocated entries:" << allocated << std::endl
1588 << "SparseMatrixEZ:reserved entries:" << reserved << std::endl;
1589
1590 if (full)
1591 {
1592 for (size_type i = 0; i < used_by_line.size(); ++i)
1593 if (used_by_line[i] != 0)
1594 out << "SparseMatrixEZ:entries\t" << i << "\trows\t"
1595 << used_by_line[i] << std::endl;
1596 }
1597}
1598
1599
1601
1602#endif
const SparseMatrixEZ< number > * matrix
Accessor(const SparseMatrixEZ< number > *matrix, const size_type row, const unsigned short index)
const Accessor & operator*() const
const_iterator(const SparseMatrixEZ< number > *matrix, const size_type row, const unsigned short index)
bool operator<(const const_iterator &) const
bool operator==(const const_iterator &) const
bool operator!=(const const_iterator &) const
const Accessor * operator->() const
void print_formatted(std::ostream &out, const unsigned int precision=3, const bool scientific=true, const unsigned int width=0, const char *zero_string=" ", const double denominator=1., const char *separator=" ") const
void block_read(std::istream &in)
SparseMatrixEZ< number > & copy_from(const MatrixType &source, const bool elide_zero_values=true)
std::vector< Entry > data
void reinit(const size_type n_rows, const size_type n_columns, size_type default_row_length=0, unsigned int default_increment=1, size_type reserve=0)
void print_statistics(StreamType &s, bool full=false)
void Tvmult_add(Vector< somenumber > &dst, const Vector< somenumber > &src) const
void block_write(std::ostream &out) const
void compute_statistics(size_type &used, size_type &allocated, size_type &reserved, std::vector< size_type > &used_by_line, const bool compute_by_line) const
SparseMatrixEZ(const SparseMatrixEZ &)
bool empty() const
unsigned int increment
number operator()(const size_type i, const size_type j) const
const Entry * locate(const size_type row, const size_type col) const
size_type n() const
~SparseMatrixEZ() override=default
size_type m() const
Entry * allocate(const size_type row, const size_type col)
void threaded_matrix_scalar_product(const Vector< somenumber > &u, const Vector< somenumber > &v, const size_type begin_row, const size_type end_row, somenumber *partial_sum) const
size_type get_row_length(const size_type row) const
void precondition_TSOR(Vector< somenumber > &dst, const Vector< somenumber > &src, const number om=1.) const
std::size_t memory_consumption() const
size_type n_nonzero_elements() const
void print(std::ostream &out) const
SparseMatrixEZ< number > & operator=(const SparseMatrixEZ< number > &)
SparseMatrixEZ(const size_type n_rows, const size_type n_columns, const size_type default_row_length=0, const unsigned int default_increment=1)
void conjugate_add(const MatrixTypeA &A, const MatrixTypeB &B, const bool transpose=false)
void Tvmult(Vector< somenumber > &dst, const Vector< somenumber > &src) const
SparseMatrixEZ< number > & operator=(const double d)
void threaded_vmult(Vector< somenumber > &dst, const Vector< somenumber > &src, const size_type begin_row, const size_type end_row) const
void vmult_add(Vector< somenumber > &dst, const Vector< somenumber > &src) const
void precondition_Jacobi(Vector< somenumber > &dst, const Vector< somenumber > &src, const number omega=1.) const
const_iterator end() const
void precondition_SSOR(Vector< somenumber > &dst, const Vector< somenumber > &src, const number om=1., const std::vector< std::size_t > &pos_right_of_diagonal=std::vector< std::size_t >()) const
std::vector< RowInfo > row_info
number el(const size_type i, const size_type j) const
const_iterator begin() const
void threaded_matrix_norm_square(const Vector< somenumber > &v, const size_type begin_row, const size_type end_row, somenumber *partial_sum) const
number l2_norm() const
unsigned int saved_default_row_length
void set(const size_type i, const size_type j, const number value, const bool elide_zero_values=true)
void add(const size_type i, const size_type j, const number value)
void precondition_SOR(Vector< somenumber > &dst, const Vector< somenumber > &src, const number om=1.) const
void vmult(Vector< somenumber > &dst, const Vector< somenumber > &src) const
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:498
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:499
DerivativeForm< 1, spacedim, dim, Number > transpose(const DerivativeForm< 1, dim, spacedim, Number > &DF)
#define DeclException0(Exception0)
Definition exceptions.h:466
static ::ExceptionBase & ExcInvalidEntry(int arg1, int arg2)
static ::ExceptionBase & ExcNoDiagonal()
#define Assert(cond, exc)
static ::ExceptionBase & ExcIteratorPastEnd()
#define AssertIsFinite(number)
#define DeclException2(Exception2, type1, type2, outsequence)
Definition exceptions.h:534
static ::ExceptionBase & ExcEntryAllocationFailure(int arg1, int arg2)
#define AssertIndexRange(index, range)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
const types::global_dof_index invalid_size_type
Definition types.h:233
::VectorizedArray< Number, width > abs(const ::VectorizedArray< Number, width > &)
unsigned int global_dof_index
Definition types.h:81
static const size_type invalid
static const unsigned short invalid_diagonal
RowInfo(const size_type start=Entry::invalid)