deal.II version GIT relicensing-2659-g040196caa3 2025-02-18 14:20:01+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
25#include <deal.II/base/types.h>
26
28
29#include <vector>
30
32
33// Forward declarations
34#ifndef DOXYGEN
35template <typename number>
36class Vector;
37template <typename number>
38class FullMatrix;
39#endif
40
105template <typename number>
107{
108public:
113
118 struct Entry
119 {
123 Entry();
124
128 Entry(const size_type column, const number &value);
129
134
138 number value;
139
144 };
145
150 struct RowInfo
151 {
156
164 unsigned short length;
168 unsigned short diagonal;
172 static const unsigned short invalid_diagonal =
173 static_cast<unsigned short>(-1);
174 };
175
176public:
181 {
182 private:
187 {
188 public:
194 const size_type row,
195 const unsigned short index);
196
201 row() const;
202
206 unsigned short
207 index() const;
208
213 column() const;
214
218 number
219 value() const;
220
221 protected:
226
231
235 unsigned short a_index;
236
237 // Make enclosing class a friend.
238 friend class const_iterator;
239 };
240
241 public:
246 const size_type row,
247 const unsigned short index);
248
253 operator++();
254
258 const Accessor &
259 operator*() const;
260
264 const Accessor *
265 operator->() const;
266
270 bool
271 operator==(const const_iterator &) const;
275 bool
276 operator!=(const const_iterator &) const;
277
282 bool
283 operator<(const const_iterator &) const;
284
285 private:
290 };
291
296 using value_type = number;
297
306
315
322 explicit SparseMatrixEZ(const size_type n_rows,
323 const size_type n_columns,
325 const unsigned int default_increment = 1);
326
330 ~SparseMatrixEZ() override = default;
331
337
347 operator=(const double d);
348
356 void
357 reinit(const size_type n_rows,
358 const size_type n_columns,
360 unsigned int default_increment = 1,
361 size_type reserve = 0);
362
367 void
378 bool
379 empty() const;
380
386 m() const;
387
393 n() const;
394
399 get_row_length(const size_type row) const;
400
406
411 std::size_t
413
419 template <typename StreamType>
420 void
421 print_statistics(StreamType &s, bool full = false);
422
432 void
436 std::vector<size_type> &used_by_line,
437 const bool compute_by_line) const;
460 void
461 set(const size_type i,
462 const size_type j,
463 const number value,
464 const bool elide_zero_values = true);
465
476 void
477 add(const size_type i, const size_type j, const number value);
478
493 template <typename number2>
494 void
495 add(const std::vector<size_type> &indices,
497 const bool elide_zero_values = true);
498
504 template <typename number2>
505 void
506 add(const std::vector<size_type> &row_indices,
507 const std::vector<size_type> &col_indices,
509 const bool elide_zero_values = true);
510
520 template <typename number2>
521 void
522 add(const size_type row,
523 const std::vector<size_type> &col_indices,
524 const std::vector<number2> &values,
525 const bool elide_zero_values = true);
526
536 template <typename number2>
537 void
538 add(const size_type row,
539 const size_type n_cols,
540 const size_type *col_indices,
541 const number2 *values,
542 const bool elide_zero_values = true,
543 const bool col_indices_are_sorted = false);
544
566 template <typename MatrixType>
568 copy_from(const MatrixType &source, const bool elide_zero_values = true);
569
577 template <typename MatrixType>
578 void
579 add(const number factor, const MatrixType &matrix);
594 number
595 operator()(const size_type i, const size_type j) const;
596
601 number
602 el(const size_type i, const size_type j) const;
612 template <typename somenumber>
613 void
615
621 template <typename somenumber>
622 void
624
629 template <typename somenumber>
630 void
632
638 template <typename somenumber>
639 void
649 number
650 l2_norm() const;
661 template <typename somenumber>
662 void
664 const Vector<somenumber> &src,
665 const number omega = 1.) const;
666
670 template <typename somenumber>
671 void
673 const Vector<somenumber> &src,
674 const number om = 1.,
675 const std::vector<std::size_t> &pos_right_of_diagonal =
676 std::vector<std::size_t>()) const;
677
682 template <typename somenumber>
683 void
685 const Vector<somenumber> &src,
686 const number om = 1.) const;
687
692 template <typename somenumber>
693 void
695 const Vector<somenumber> &src,
696 const number om = 1.) const;
697
706 template <typename MatrixTypeA, typename MatrixTypeB>
707 void
708 conjugate_add(const MatrixTypeA &A,
709 const MatrixTypeB &B,
710 const bool transpose = false);
720 begin() const;
721
726 end() const;
727
733 begin(const size_type r) const;
734
740 end(const size_type r) const;
750 void
751 print(std::ostream &out) const;
752
775 void
776 print_formatted(std::ostream &out,
777 const unsigned int precision = 3,
778 const bool scientific = true,
779 const unsigned int width = 0,
780 const char *zero_string = " ",
781 const double denominator = 1.,
782 const char *separator = " ") const;
783
789 void
790 block_write(std::ostream &out) const;
791
802 void
803 block_read(std::istream &in);
815
820 int,
821 int,
822 << "The entry with index (" << arg1 << ',' << arg2
823 << ") does not exist.");
824
826 int,
827 int,
828 << "An entry with index (" << arg1 << ',' << arg2
829 << ") cannot be allocated.");
831private:
836 const Entry *
837 locate(const size_type row, const size_type col) const;
838
843 Entry *
844 locate(const size_type row, const size_type col);
845
849 Entry *
850 allocate(const size_type row, const size_type col);
851
857 template <typename somenumber>
858 void
860 const Vector<somenumber> &src,
861 const size_type begin_row,
862 const size_type end_row) const;
863
869 template <typename somenumber>
870 void
872 const size_type begin_row,
873 const size_type end_row,
874 somenumber *partial_sum) const;
875
881 template <typename somenumber>
882 void
884 const Vector<somenumber> &v,
885 const size_type begin_row,
886 const size_type end_row,
887 somenumber *partial_sum) const;
888
893
897 std::vector<RowInfo> row_info;
898
902 std::vector<Entry> data;
903
907 unsigned int increment;
908
913};
914
918/*---------------------- Inline functions -----------------------------------*/
919
920template <typename number>
922 const number &value)
923 : column(column)
924 , value(value)
925{}
926
927
928
929template <typename number>
931 : column(invalid)
932 , value(0)
933{}
934
935
936template <typename number>
938 : start(start)
939 , length(0)
940 , diagonal(invalid_diagonal)
941{}
942
943
944//---------------------------------------------------------------------------
945template <typename number>
947 const SparseMatrixEZ<number> *matrix,
948 const size_type r,
949 const unsigned short i)
950 : matrix(matrix)
951 , a_row(r)
952 , a_index(i)
953{}
954
955
956template <typename number>
962
963
964template <typename number>
967{
968 return matrix->data[matrix->row_info[a_row].start + a_index].column;
969}
970
971
972template <typename number>
973inline unsigned short
978
979
980
981template <typename number>
982inline number
984{
985 return matrix->data[matrix->row_info[a_row].start + a_index].value;
986}
987
988
989template <typename number>
991 const SparseMatrixEZ<number> *matrix,
992 const size_type r,
993 const unsigned short i)
994 : accessor(matrix, r, i)
995{
996 // Finish if this is the end()
997 if (r == accessor.matrix->m() && i == 0)
998 return;
999
1000 // Make sure we never construct an
1001 // iterator pointing to a
1002 // non-existing entry
1003
1004 // If the index points beyond the
1005 // end of the row, try the next
1006 // row.
1007 if (accessor.a_index >= accessor.matrix->row_info[accessor.a_row].length)
1008 {
1009 do
1010 {
1011 ++accessor.a_row;
1012 }
1013 // Beware! If the next row is
1014 // empty, iterate until a
1015 // non-empty row is found or we
1016 // hit the end of the matrix.
1017 while (accessor.a_row < accessor.matrix->m() &&
1018 accessor.matrix->row_info[accessor.a_row].length == 0);
1019 }
1020}
1021
1022
1023template <typename number>
1026{
1027 Assert(accessor.a_row < accessor.matrix->m(), ExcIteratorPastEnd());
1028
1029 // Increment column index
1030 ++(accessor.a_index);
1031 // If index exceeds number of
1032 // entries in this row, proceed
1033 // with next row.
1034 if (accessor.a_index >= accessor.matrix->row_info[accessor.a_row].length)
1035 {
1036 accessor.a_index = 0;
1037 // Do this loop to avoid
1038 // elements in empty rows
1039 do
1040 {
1041 ++accessor.a_row;
1042 }
1043 while (accessor.a_row < accessor.matrix->m() &&
1044 accessor.matrix->row_info[accessor.a_row].length == 0);
1045 }
1046 return *this;
1047}
1048
1049
1050template <typename number>
1053{
1054 return accessor;
1055}
1056
1057
1058template <typename number>
1061{
1062 return &accessor;
1063}
1064
1065
1066template <typename number>
1067inline bool
1069 const const_iterator &other) const
1070{
1071 return (accessor.row() == other.accessor.row() &&
1072 accessor.index() == other.accessor.index());
1073}
1074
1075
1076template <typename number>
1077inline bool
1079 const const_iterator &other) const
1080{
1081 return !(*this == other);
1082}
1083
1084
1085template <typename number>
1086inline bool
1088 const const_iterator &other) const
1089{
1090 return (accessor.row() < other.accessor.row() ||
1091 (accessor.row() == other.accessor.row() &&
1092 accessor.index() < other.accessor.index()));
1093}
1094
1095
1096//---------------------------------------------------------------------------
1097template <typename number>
1100{
1101 return row_info.size();
1102}
1103
1104
1105template <typename number>
1108{
1109 return n_columns;
1110}
1111
1112
1113template <typename number>
1114inline typename SparseMatrixEZ<number>::Entry *
1116{
1117 AssertIndexRange(row, m());
1118 AssertIndexRange(col, n());
1119
1120 const RowInfo &r = row_info[row];
1121 const size_type end = r.start + r.length;
1122 for (size_type i = r.start; i < end; ++i)
1123 {
1124 Entry *const entry = &data[i];
1125 if (entry->column == col)
1126 return entry;
1127 if (entry->column == Entry::invalid)
1128 return nullptr;
1129 }
1130 return nullptr;
1131}
1132
1133
1134
1135template <typename number>
1136inline const typename SparseMatrixEZ<number>::Entry *
1138{
1139 SparseMatrixEZ<number> *t = const_cast<SparseMatrixEZ<number> *>(this);
1140 return t->locate(row, col);
1141}
1142
1143
1144template <typename number>
1145inline typename SparseMatrixEZ<number>::Entry *
1147{
1148 AssertIndexRange(row, m());
1149 AssertIndexRange(col, n());
1150
1151 RowInfo &r = row_info[row];
1152 const size_type end = r.start + r.length;
1153
1154 size_type i = r.start;
1155 // If diagonal exists and this
1156 // column is higher, start only
1157 // after diagonal.
1158 if (r.diagonal != RowInfo::invalid_diagonal && col >= row)
1159 i += r.diagonal;
1160 // Find position of entry
1161 while (i < end && data[i].column < col)
1162 ++i;
1163
1164 // entry found
1165 if (i != end && data[i].column == col)
1166 return &data[i];
1167
1168 // Now, we must insert the new
1169 // entry and move all successive
1170 // entries back.
1171
1172 // If no more space is available
1173 // for this row, insert new
1174 // elements into the vector.
1175 // TODO:[GK] We should not extend this row if i<end
1176 if (row != row_info.size() - 1)
1177 {
1178 if (end >= row_info[row + 1].start)
1179 {
1180 // Failure if increment 0
1182
1183 // Insert new entries
1184 data.insert(data.begin() + end, increment, Entry());
1185 // Update starts of
1186 // following rows
1187 for (size_type rn = row + 1; rn < row_info.size(); ++rn)
1188 row_info[rn].start += increment;
1189 }
1190 }
1191 else
1192 {
1193 if (end >= data.size())
1194 {
1195 // Here, appending a block
1196 // does not increase
1197 // performance.
1198 data.push_back(Entry());
1199 }
1200 }
1201
1202 Entry *entry = &data[i];
1203 // Save original entry
1204 Entry temp = *entry;
1205 // Insert new entry here to
1206 // make sure all entries
1207 // are ordered by column
1208 // index
1209 entry->column = col;
1210 entry->value = 0;
1211 // Update row_info
1212 ++r.length;
1213 if (col == row)
1214 r.diagonal = i - r.start;
1215 else if (col < row && r.diagonal != RowInfo::invalid_diagonal)
1216 ++r.diagonal;
1217
1218 if (i == end)
1219 return entry;
1220
1221 // Move all entries in this
1222 // row up by one
1223 for (size_type j = i + 1; j < end; ++j)
1224 {
1225 // There should be no invalid
1226 // entry below end
1228
1229 // TODO[GK]: This could be done more efficiently by moving starting at the
1230 // top rather than swapping starting at the bottom
1231 std::swap(data[j], temp);
1232 }
1234
1235 data[end] = temp;
1236
1237 return entry;
1238}
1239
1240
1241
1242template <typename number>
1243inline void
1245 const size_type j,
1246 const number value,
1247 const bool elide_zero_values)
1248{
1249 AssertIsFinite(value);
1250
1251 AssertIndexRange(i, m());
1252 AssertIndexRange(j, n());
1253
1254 if (elide_zero_values && value == 0.)
1255 {
1256 Entry *entry = locate(i, j);
1257 if (entry != nullptr)
1258 entry->value = 0.;
1259 }
1260 else
1261 {
1262 Entry *entry = allocate(i, j);
1263 entry->value = value;
1264 }
1265}
1266
1267
1268
1269template <typename number>
1270inline void
1272 const size_type j,
1273 const number value)
1274{
1275 AssertIsFinite(value);
1276
1277 AssertIndexRange(i, m());
1278 AssertIndexRange(j, n());
1279
1280 // ignore zero additions
1281 if (std::abs(value) == 0.)
1282 return;
1283
1284 Entry *entry = allocate(i, j);
1285 entry->value += value;
1286}
1287
1288
1289template <typename number>
1290template <typename number2>
1291void
1292SparseMatrixEZ<number>::add(const std::vector<size_type> &indices,
1294 const bool elide_zero_values)
1295{
1296 // TODO: This function can surely be made more efficient
1297 for (size_type i = 0; i < indices.size(); ++i)
1298 for (size_type j = 0; j < indices.size(); ++j)
1299 if ((full_matrix(i, j) != 0) || (elide_zero_values == false))
1300 add(indices[i], indices[j], full_matrix(i, j));
1301}
1302
1303
1304
1305template <typename number>
1306template <typename number2>
1307void
1308SparseMatrixEZ<number>::add(const std::vector<size_type> &row_indices,
1309 const std::vector<size_type> &col_indices,
1311 const bool elide_zero_values)
1312{
1313 // TODO: This function can surely be made more efficient
1314 for (size_type i = 0; i < row_indices.size(); ++i)
1315 for (size_type j = 0; j < col_indices.size(); ++j)
1316 if ((full_matrix(i, j) != 0) || (elide_zero_values == false))
1317 add(row_indices[i], col_indices[j], full_matrix(i, j));
1318}
1319
1320
1321
1322template <typename number>
1323template <typename number2>
1324void
1326 const std::vector<size_type> &col_indices,
1327 const std::vector<number2> &values,
1328 const bool elide_zero_values)
1329{
1330 // TODO: This function can surely be made more efficient
1331 for (size_type j = 0; j < col_indices.size(); ++j)
1332 if ((values[j] != 0) || (elide_zero_values == false))
1333 add(row, col_indices[j], values[j]);
1334}
1335
1336
1337
1338template <typename number>
1339template <typename number2>
1340void
1342 const size_type n_cols,
1343 const size_type *col_indices,
1344 const number2 *values,
1345 const bool elide_zero_values,
1346 const bool /*col_indices_are_sorted*/)
1347{
1348 // TODO: This function can surely be made more efficient
1349 for (size_type j = 0; j < n_cols; ++j)
1350 if ((std::abs(values[j]) != 0) || (elide_zero_values == false))
1351 add(row, col_indices[j], values[j]);
1352}
1353
1354
1355
1356template <typename number>
1357inline number
1359{
1360 const Entry *entry = locate(i, j);
1361 if (entry)
1362 return entry->value;
1363 return 0.;
1364}
1365
1366
1367
1368template <typename number>
1369inline number
1371{
1372 const Entry *entry = locate(i, j);
1373 if (entry)
1374 return entry->value;
1375 Assert(false, ExcInvalidEntry(i, j));
1376 return 0.;
1377}
1378
1379
1380template <typename number>
1383{
1384 const_iterator result(this, 0, 0);
1385 return result;
1386}
1387
1388template <typename number>
1391{
1392 return const_iterator(this, m(), 0);
1393}
1394
1395template <typename number>
1398{
1399 AssertIndexRange(r, m());
1400 const_iterator result(this, r, 0);
1401 return result;
1402}
1403
1404template <typename number>
1407{
1408 AssertIndexRange(r, m());
1409 const_iterator result(this, r + 1, 0);
1410 return result;
1411}
1412
1413template <typename number>
1414template <typename MatrixType>
1417 const bool elide_zero_values)
1418{
1419 reinit(M.m(), M.n(), this->saved_default_row_length, this->increment);
1420
1421 // loop over the elements of the argument matrix row by row, as suggested
1422 // in the documentation of the sparse matrix iterator class, and
1423 // copy them into the current object
1424 for (size_type row = 0; row < M.m(); ++row)
1425 {
1426 const typename MatrixType::const_iterator end_row = M.end(row);
1427 for (typename MatrixType::const_iterator entry = M.begin(row);
1428 entry != end_row;
1429 ++entry)
1430 set(row, entry->column(), entry->value(), elide_zero_values);
1431 }
1432
1433 return *this;
1434}
1435
1436template <typename number>
1437template <typename MatrixType>
1438inline void
1439SparseMatrixEZ<number>::add(const number factor, const MatrixType &M)
1440{
1441 Assert(M.m() == m(), ExcDimensionMismatch(M.m(), m()));
1442 Assert(M.n() == n(), ExcDimensionMismatch(M.n(), n()));
1443
1444 if (factor == 0.)
1445 return;
1446
1447 // loop over the elements of the argument matrix row by row, as suggested
1448 // in the documentation of the sparse matrix iterator class, and
1449 // add them into the current object
1450 for (size_type row = 0; row < M.m(); ++row)
1451 {
1452 const typename MatrixType::const_iterator end_row = M.end(row);
1453 for (typename MatrixType::const_iterator entry = M.begin(row);
1454 entry != end_row;
1455 ++entry)
1456 if (entry->value() != 0)
1457 add(row, entry->column(), factor * entry->value());
1458 }
1459}
1460
1461
1462
1463template <typename number>
1464template <typename MatrixTypeA, typename MatrixTypeB>
1465inline void
1467 const MatrixTypeB &B,
1468 const bool transpose)
1469{
1470 // Compute the result
1471 // r_ij = \sum_kl b_ik b_jl a_kl
1472
1473 // Assert (n() == B.m(), ExcDimensionMismatch(n(), B.m()));
1474 // Assert (m() == B.m(), ExcDimensionMismatch(m(), B.m()));
1475 // Assert (A.n() == B.n(), ExcDimensionMismatch(A.n(), B.n()));
1476 // Assert (A.m() == B.n(), ExcDimensionMismatch(A.m(), B.n()));
1477
1478 // Somehow, we have to avoid making
1479 // this an operation of complexity
1480 // n^2. For the transpose case, we
1481 // can go through the non-zero
1482 // elements of A^-1 and use the
1483 // corresponding rows of B only.
1484 // For the non-transpose case, we
1485 // must find a trick.
1486 typename MatrixTypeB::const_iterator b1 = B.begin();
1487 const typename MatrixTypeB::const_iterator b_final = B.end();
1488 if (transpose)
1489 while (b1 != b_final)
1490 {
1491 const size_type i = b1->column();
1492 const size_type k = b1->row();
1493 typename MatrixTypeB::const_iterator b2 = B.begin();
1494 while (b2 != b_final)
1495 {
1496 const size_type j = b2->column();
1497 const size_type l = b2->row();
1498
1499 const typename MatrixTypeA::value_type a = A.el(k, l);
1500
1501 if (a != 0.)
1502 add(i, j, a * b1->value() * b2->value());
1503 ++b2;
1504 }
1505 ++b1;
1506 }
1507 else
1508 {
1509 // Determine minimal and
1510 // maximal row for a column in
1511 // advance.
1512
1513 std::vector<size_type> minrow(B.n(), B.m());
1514 std::vector<size_type> maxrow(B.n(), 0);
1515 while (b1 != b_final)
1516 {
1517 const size_type r = b1->row();
1518 if (r < minrow[b1->column()])
1519 minrow[b1->column()] = r;
1520 if (r > maxrow[b1->column()])
1521 maxrow[b1->column()] = r;
1522 ++b1;
1523 }
1524
1525 typename MatrixTypeA::const_iterator ai = A.begin();
1526 const typename MatrixTypeA::const_iterator ae = A.end();
1527
1528 while (ai != ae)
1529 {
1530 const typename MatrixTypeA::value_type a = ai->value();
1531 // Don't do anything if
1532 // this entry is zero.
1533 if (a == 0.)
1534 continue;
1535
1536 // Now, loop over all rows
1537 // having possibly a
1538 // nonzero entry in column
1539 // ai->row()
1540 b1 = B.begin(minrow[ai->row()]);
1541 const typename MatrixTypeB::const_iterator be1 =
1542 B.end(maxrow[ai->row()]);
1543 const typename MatrixTypeB::const_iterator be2 =
1544 B.end(maxrow[ai->column()]);
1545
1546 while (b1 != be1)
1547 {
1548 const double b1v = b1->value();
1549 // We need the product
1550 // of both. If it is
1551 // zero, we can save
1552 // the work
1553 if (b1->column() == ai->row() && (b1v != 0.))
1554 {
1555 const size_type i = b1->row();
1556
1557 typename MatrixTypeB::const_iterator b2 =
1558 B.begin(minrow[ai->column()]);
1559 while (b2 != be2)
1560 {
1561 if (b2->column() == ai->column())
1562 {
1563 const size_type j = b2->row();
1564 add(i, j, a * b1v * b2->value());
1565 }
1566 ++b2;
1567 }
1568 }
1569 ++b1;
1570 }
1571 ++ai;
1572 }
1573 }
1574}
1575
1576
1577template <typename number>
1578template <typename StreamType>
1579inline void
1581{
1582 size_type used;
1585 std::vector<size_type> used_by_line;
1586
1588
1589 out << "SparseMatrixEZ:used entries:" << used << std::endl
1590 << "SparseMatrixEZ:allocated entries:" << allocated << std::endl
1591 << "SparseMatrixEZ:reserved entries:" << reserved << std::endl;
1592
1593 if (full)
1594 {
1595 for (size_type i = 0; i < used_by_line.size(); ++i)
1596 if (used_by_line[i] != 0)
1597 out << "SparseMatrixEZ:entries\t" << i << "\trows\t"
1598 << used_by_line[i] << std::endl;
1599 }
1600}
1601
1602
1604
1605#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
std::conditional_t< rank_==1, Number, Tensor< rank_ - 1, dim, Number > > value_type
Definition tensor.h:506
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:518
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:519
DerivativeForm< 1, spacedim, dim, Number > transpose(const DerivativeForm< 1, dim, spacedim, Number > &DF)
#define DeclException0(Exception0)
Definition exceptions.h:468
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:536
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)
constexpr types::global_dof_index invalid_size_type
Definition types.h:244
::VectorizedArray< Number, width > abs(const ::VectorizedArray< Number, width > &)
unsigned int global_dof_index
Definition types.h:90
static const size_type invalid
static const unsigned short invalid_diagonal
RowInfo(const size_type start=Entry::invalid)