Reference documentation for deal.II version 9.0.0
sparse_matrix.h
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 1999 - 2018 by the deal.II authors
4 //
5 // This file is part of the deal.II library.
6 //
7 // The deal.II library is free software; you can use it, redistribute
8 // it, and/or modify it under the terms of the GNU Lesser General
9 // Public License as published by the Free Software Foundation; either
10 // version 2.1 of the License, or (at your option) any later version.
11 // The full text of the license can be found in the file LICENSE at
12 // the top level of the deal.II distribution.
13 //
14 // ---------------------------------------------------------------------
15 
16 #ifndef dealii_sparse_matrix_h
17 #define dealii_sparse_matrix_h
18 
19 
20 #include <deal.II/base/config.h>
21 #include <deal.II/base/subscriptor.h>
22 #include <deal.II/base/smartpointer.h>
23 #include <deal.II/lac/sparsity_pattern.h>
24 #include <deal.II/lac/identity_matrix.h>
25 #include <deal.II/lac/exceptions.h>
26 #include <deal.II/lac/vector_operation.h>
27 #ifdef DEAL_II_WITH_MPI
28 #include <mpi.h>
29 #endif
30 
31 #include <memory>
32 
33 
34 DEAL_II_NAMESPACE_OPEN
35 
36 template <typename number> class Vector;
37 template <typename number> class FullMatrix;
38 template <typename Matrix> class BlockMatrixBase;
39 template <typename number> class SparseILU;
40 #ifdef DEAL_II_WITH_MPI
41 namespace Utilities
42 {
43  namespace MPI
44  {
45  template <typename Number> void sum (const SparseMatrix<Number> &, const MPI_Comm &, SparseMatrix<Number> &);
46  }
47 }
48 #endif
49 
50 #ifdef DEAL_II_WITH_TRILINOS
51 namespace TrilinosWrappers
52 {
53  class SparseMatrix;
54 }
55 #endif
56 
67 {
72 
73  // forward declaration
74  template <typename number, bool Constness>
75  class Iterator;
76 
87  template <typename number, bool Constness>
89  {
90  public:
94  number value() const;
95 
99  number &value();
100 
105  const SparseMatrix<number> &get_matrix () const;
106  };
107 
108 
109 
116  template <typename number>
117  class Accessor<number,true> : public SparsityPatternIterators::Accessor
118  {
119  public:
125 
129  Accessor (MatrixType *matrix,
130  const std::size_t index_within_matrix);
131 
135  Accessor (MatrixType *matrix);
136 
141 
145  number value() const;
146 
151  const MatrixType &get_matrix () const;
152 
153  private:
158 
163 
167  template <typename, bool>
168  friend class Iterator;
169  };
170 
171 
178  template <typename number>
179  class Accessor<number,false> : public SparsityPatternIterators::Accessor
180  {
181  private:
206  class Reference
207  {
208  public:
213  Reference (const Accessor *accessor,
214  const bool dummy);
215 
219  operator number () const;
220 
224  const Reference &operator = (const number n) const;
225 
229  const Reference &operator += (const number n) const;
230 
234  const Reference &operator -= (const number n) const;
235 
239  const Reference &operator *= (const number n) const;
240 
244  const Reference &operator /= (const number n) const;
245 
246  private:
252  };
253 
254  public:
260 
264  Accessor (MatrixType *matrix,
265  const std::size_t index);
266 
270  Accessor (MatrixType *matrix);
271 
275  Reference value() const;
276 
281  MatrixType &get_matrix () const;
282 
283  private:
288 
293 
297  template <typename, bool>
298  friend class Iterator;
299  };
300 
301 
302 
332  template <typename number, bool Constness>
333  class Iterator
334  {
335  public:
339  typedef
342 
347  typedef
349 
354  Iterator (MatrixType *matrix,
355  const std::size_t index_within_matrix);
356 
360  Iterator (MatrixType *matrix);
361 
367 
372 
376  Iterator operator++ (int);
377 
381  const Accessor<number,Constness> &operator* () const;
382 
387 
391  bool operator == (const Iterator &) const;
392 
396  bool operator != (const Iterator &) const;
397 
405  bool operator < (const Iterator &) const;
406 
411  bool operator > (const Iterator &) const;
412 
419  int operator - (const Iterator &p) const;
420 
424  Iterator operator + (const size_type n) const;
425 
426  private:
431  };
432 
433 }
434 
440 //TODO: Add multithreading to the other vmult functions.
441 
470 template <typename number>
471 class SparseMatrix : public virtual Subscriptor
472 {
473 public:
478 
483  typedef number value_type;
484 
495 
500  typedef
503 
510  typedef
513 
520  struct Traits
521  {
526  static const bool zero_addition_can_be_elided = true;
527  };
528 
543  SparseMatrix ();
544 
553  SparseMatrix (const SparseMatrix &);
554 
562  SparseMatrix (SparseMatrix<number> &&m) noexcept;
563 
577  explicit SparseMatrix (const SparsityPattern &sparsity);
578 
585  SparseMatrix (const SparsityPattern &sparsity,
586  const IdentityMatrix &id);
587 
592  virtual ~SparseMatrix ();
593 
604 
610 
618  operator= (const IdentityMatrix &id);
619 
631  SparseMatrix &operator = (const double d);
632 
646  virtual void reinit (const SparsityPattern &sparsity);
647 
653  virtual void clear ();
655 
663  bool empty () const;
664 
669  size_type m () const;
670 
675  size_type n () const;
676 
680  size_type get_row_length (const size_type row) const;
681 
687  std::size_t n_nonzero_elements () const;
688 
698  std::size_t n_actually_nonzero_elements (const double threshold = 0.) const;
699 
708  const SparsityPattern &get_sparsity_pattern () const;
709 
714  std::size_t memory_consumption () const;
715 
720 
722 
731  void set (const size_type i,
732  const size_type j,
733  const number value);
734 
750  template <typename number2>
751  void set (const std::vector<size_type> &indices,
752  const FullMatrix<number2> &full_matrix,
753  const bool elide_zero_values = false);
754 
760  template <typename number2>
761  void set (const std::vector<size_type> &row_indices,
762  const std::vector<size_type> &col_indices,
763  const FullMatrix<number2> &full_matrix,
764  const bool elide_zero_values = false);
765 
776  template <typename number2>
777  void set (const size_type row,
778  const std::vector<size_type> &col_indices,
779  const std::vector<number2> &values,
780  const bool elide_zero_values = false);
781 
791  template <typename number2>
792  void set (const size_type row,
793  const size_type n_cols,
794  const size_type *col_indices,
795  const number2 *values,
796  const bool elide_zero_values = false);
797 
803  void add (const size_type i,
804  const size_type j,
805  const number value);
806 
821  template <typename number2>
822  void add (const std::vector<size_type> &indices,
823  const FullMatrix<number2> &full_matrix,
824  const bool elide_zero_values = true);
825 
831  template <typename number2>
832  void add (const std::vector<size_type> &row_indices,
833  const std::vector<size_type> &col_indices,
834  const FullMatrix<number2> &full_matrix,
835  const bool elide_zero_values = true);
836 
846  template <typename number2>
847  void add (const size_type row,
848  const std::vector<size_type> &col_indices,
849  const std::vector<number2> &values,
850  const bool elide_zero_values = true);
851 
861  template <typename number2>
862  void add (const size_type row,
863  const size_type n_cols,
864  const size_type *col_indices,
865  const number2 *values,
866  const bool elide_zero_values = true,
867  const bool col_indices_are_sorted = false);
868 
872  SparseMatrix &operator *= (const number factor);
873 
877  SparseMatrix &operator /= (const number factor);
878 
891  void symmetrize ();
892 
909  template <typename somenumber>
911  copy_from (const SparseMatrix<somenumber> &source);
912 
929  template <typename ForwardIterator>
930  void copy_from (const ForwardIterator begin,
931  const ForwardIterator end);
932 
938  template <typename somenumber>
939  void copy_from (const FullMatrix<somenumber> &matrix);
940 
941 #ifdef DEAL_II_WITH_TRILINOS
942 
953 #endif
954 
966  template <typename somenumber>
967  void add (const number factor,
968  const SparseMatrix<somenumber> &matrix);
969 
971 
975 
989  const number &operator () (const size_type i,
990  const size_type j) const;
991 
995  number &operator () (const size_type i,
996  const size_type j);
997 
1010  number el (const size_type i,
1011  const size_type j) const;
1012 
1022  number diag_element (const size_type i) const;
1023 
1028  number &diag_element (const size_type i);
1029 
1031 
1051  template <class OutVector, class InVector>
1052  void vmult (OutVector &dst,
1053  const InVector &src) const;
1054 
1070  template <class OutVector, class InVector>
1071  void Tvmult (OutVector &dst,
1072  const InVector &src) const;
1073 
1090  template <class OutVector, class InVector>
1091  void vmult_add (OutVector &dst,
1092  const InVector &src) const;
1093 
1109  template <class OutVector, class InVector>
1110  void Tvmult_add (OutVector &dst,
1111  const InVector &src) const;
1112 
1130  template <typename somenumber>
1131  somenumber matrix_norm_square (const Vector<somenumber> &v) const;
1132 
1138  template <typename somenumber>
1139  somenumber matrix_scalar_product (const Vector<somenumber> &u,
1140  const Vector<somenumber> &v) const;
1141 
1151  template <typename somenumber>
1152  somenumber residual (Vector<somenumber> &dst,
1153  const Vector<somenumber> &x,
1154  const Vector<somenumber> &b) const;
1155 
1191  template <typename numberB, typename numberC>
1192  void mmult (SparseMatrix<numberC> &C,
1193  const SparseMatrix<numberB> &B,
1194  const Vector<number> &V = Vector<number>(),
1195  const bool rebuild_sparsity_pattern = true) const;
1196 
1221  template <typename numberB, typename numberC>
1222  void Tmmult (SparseMatrix<numberC> &C,
1223  const SparseMatrix<numberB> &B,
1224  const Vector<number> &V = Vector<number>(),
1225  const bool rebuild_sparsity_pattern = true) const;
1226 
1228 
1232 
1240  real_type l1_norm () const;
1241 
1249  real_type linfty_norm () const;
1250 
1255  real_type frobenius_norm () const;
1257 
1261 
1267  template <typename somenumber>
1268  void precondition_Jacobi (Vector<somenumber> &dst,
1269  const Vector<somenumber> &src,
1270  const number omega = 1.) const;
1271 
1278  template <typename somenumber>
1279  void precondition_SSOR (Vector<somenumber> &dst,
1280  const Vector<somenumber> &src,
1281  const number omega = 1.,
1282  const std::vector<std::size_t> &pos_right_of_diagonal=std::vector<std::size_t>()) const;
1283 
1287  template <typename somenumber>
1288  void precondition_SOR (Vector<somenumber> &dst,
1289  const Vector<somenumber> &src,
1290  const number om = 1.) const;
1291 
1295  template <typename somenumber>
1296  void precondition_TSOR (Vector<somenumber> &dst,
1297  const Vector<somenumber> &src,
1298  const number om = 1.) const;
1299 
1305  template <typename somenumber>
1306  void SSOR (Vector<somenumber> &v,
1307  const number omega = 1.) const;
1308 
1313  template <typename somenumber>
1314  void SOR (Vector<somenumber> &v,
1315  const number om = 1.) const;
1316 
1321  template <typename somenumber>
1322  void TSOR (Vector<somenumber> &v,
1323  const number om = 1.) const;
1324 
1335  template <typename somenumber>
1336  void PSOR (Vector<somenumber> &v,
1337  const std::vector<size_type> &permutation,
1338  const std::vector<size_type> &inverse_permutation,
1339  const number om = 1.) const;
1340 
1351  template <typename somenumber>
1352  void TPSOR (Vector<somenumber> &v,
1353  const std::vector<size_type> &permutation,
1354  const std::vector<size_type> &inverse_permutation,
1355  const number om = 1.) const;
1356 
1362  template <typename somenumber>
1363  void Jacobi_step (Vector<somenumber> &v,
1364  const Vector<somenumber> &b,
1365  const number om = 1.) const;
1366 
1371  template <typename somenumber>
1372  void SOR_step (Vector<somenumber> &v,
1373  const Vector<somenumber> &b,
1374  const number om = 1.) const;
1375 
1380  template <typename somenumber>
1381  void TSOR_step (Vector<somenumber> &v,
1382  const Vector<somenumber> &b,
1383  const number om = 1.) const;
1384 
1389  template <typename somenumber>
1390  void SSOR_step (Vector<somenumber> &v,
1391  const Vector<somenumber> &b,
1392  const number om = 1.) const;
1394 
1398 
1405  const_iterator begin () const;
1406 
1410  iterator begin ();
1411 
1415  const_iterator end () const;
1416 
1420  iterator end ();
1421 
1431  const_iterator begin (const size_type r) const;
1432 
1436  iterator begin (const size_type r);
1437 
1447  const_iterator end (const size_type r) const;
1448 
1452  iterator end (const size_type r);
1454 
1458 
1470  template <class StreamType>
1471  void print (StreamType &out,
1472  const bool across = false,
1473  const bool diagonal_first = true) const;
1474 
1495  void print_formatted (std::ostream &out,
1496  const unsigned int precision = 3,
1497  const bool scientific = true,
1498  const unsigned int width = 0,
1499  const char *zero_string = " ",
1500  const double denominator = 1.) const;
1501 
1507  void print_pattern(std::ostream &out,
1508  const double threshold = 0.) const;
1509 
1520  void block_write (std::ostream &out) const;
1521 
1538  void block_read (std::istream &in);
1540 
1549  int, int,
1550  << "You are trying to access the matrix entry with index <"
1551  << arg1 << ',' << arg2
1552  << ">, but this entry does not exist in the sparsity pattern "
1553  "of this matrix."
1554  "\n\n"
1555  "The most common cause for this problem is that you used "
1556  "a method to build the sparsity pattern that did not "
1557  "(completely) take into account all of the entries you "
1558  "will later try to write into. An example would be "
1559  "building a sparsity pattern that does not include "
1560  "the entries you will write into due to constraints "
1561  "on degrees of freedom such as hanging nodes or periodic "
1562  "boundary conditions. In such cases, building the "
1563  "sparsity pattern will succeed, but you will get errors "
1564  "such as the current one at one point or other when "
1565  "trying to write into the entries of the matrix.");
1570  "When copying one sparse matrix into another, "
1571  "or when adding one sparse matrix to another, "
1572  "both matrices need to refer to the same "
1573  "sparsity pattern.");
1578  int, int,
1579  << "The iterators denote a range of " << arg1
1580  << " elements, but the given number of rows was " << arg2);
1585  "You are attempting an operation on two matrices that "
1586  "are the same object, but the operation requires that the "
1587  "two objects are in fact different.");
1589 
1590 protected:
1601  void prepare_add();
1602 
1607  void prepare_set();
1608 
1609 private:
1616 
1624  std::unique_ptr<number[]> val;
1625 
1632  std::size_t max_len;
1633 
1634  // make all other sparse matrices friends
1635  template <typename somenumber> friend class SparseMatrix;
1636  template <typename somenumber> friend class SparseLUDecomposition;
1637  template <typename> friend class SparseILU;
1638 
1642  template <typename> friend class BlockMatrixBase;
1643 
1647  template <typename,bool> friend class SparseMatrixIterators::Iterator;
1648  template <typename,bool> friend class SparseMatrixIterators::Accessor;
1649 
1650 #ifdef DEAL_II_WITH_MPI
1651 
1654  template <typename Number> friend void Utilities::MPI::sum (const SparseMatrix<Number> &, const MPI_Comm &, SparseMatrix<Number> &);
1655 #endif
1656 };
1657 
1658 #ifndef DOXYGEN
1659 /*---------------------- Inline functions -----------------------------------*/
1660 
1661 
1662 
1663 template <typename number>
1664 inline
1666 {
1667  Assert (cols != nullptr, ExcNotInitialized());
1668  return cols->rows;
1669 }
1670 
1671 
1672 template <typename number>
1673 inline
1675 {
1676  Assert (cols != nullptr, ExcNotInitialized());
1677  return cols->cols;
1678 }
1679 
1680 
1681 // Inline the set() and add() functions, since they will be called frequently.
1682 template <typename number>
1683 inline
1684 void
1686  const size_type j,
1687  const number value)
1688 {
1690 
1691  const size_type index = cols->operator()(i, j);
1692 
1693  // it is allowed to set elements of the matrix that are not part of the
1694  // sparsity pattern, if the value to which we set it is zero
1696  {
1698  (value == number()),
1699  ExcInvalidIndex(i, j));
1700  return;
1701  }
1702 
1703  val[index] = value;
1704 }
1705 
1706 
1707 
1708 template <typename number>
1709 template <typename number2>
1710 inline
1711 void
1712 SparseMatrix<number>::set (const std::vector<size_type> &indices,
1713  const FullMatrix<number2> &values,
1714  const bool elide_zero_values)
1715 {
1716  Assert (indices.size() == values.m(),
1717  ExcDimensionMismatch(indices.size(), values.m()));
1718  Assert (values.m() == values.n(), ExcNotQuadratic());
1719 
1720  for (size_type i=0; i<indices.size(); ++i)
1721  set (indices[i], indices.size(), indices.data(), &values(i,0),
1722  elide_zero_values);
1723 }
1724 
1725 
1726 
1727 template <typename number>
1728 template <typename number2>
1729 inline
1730 void
1731 SparseMatrix<number>::set (const std::vector<size_type> &row_indices,
1732  const std::vector<size_type> &col_indices,
1733  const FullMatrix<number2> &values,
1734  const bool elide_zero_values)
1735 {
1736  Assert (row_indices.size() == values.m(),
1737  ExcDimensionMismatch(row_indices.size(), values.m()));
1738  Assert (col_indices.size() == values.n(),
1739  ExcDimensionMismatch(col_indices.size(), values.n()));
1740 
1741  for (size_type i=0; i<row_indices.size(); ++i)
1742  set (row_indices[i], col_indices.size(), col_indices.data(), &values(i,0),
1743  elide_zero_values);
1744 }
1745 
1746 
1747 
1748 template <typename number>
1749 template <typename number2>
1750 inline
1751 void
1753  const std::vector<size_type> &col_indices,
1754  const std::vector<number2> &values,
1755  const bool elide_zero_values)
1756 {
1757  Assert (col_indices.size() == values.size(),
1758  ExcDimensionMismatch(col_indices.size(), values.size()));
1759 
1760  set (row, col_indices.size(), col_indices.data(), values.data(),
1761  elide_zero_values);
1762 }
1763 
1764 
1765 
1766 template <typename number>
1767 inline
1768 void
1770  const size_type j,
1771  const number value)
1772 {
1774 
1775  if (value == number())
1776  return;
1777 
1778  const size_type index = cols->operator()(i, j);
1779 
1780  // it is allowed to add elements to the matrix that are not part of the
1781  // sparsity pattern, if the value to which we set it is zero
1783  {
1785  (value == number()),
1786  ExcInvalidIndex(i, j));
1787  return;
1788  }
1789 
1790  val[index] += value;
1791 }
1792 
1793 
1794 
1795 template <typename number>
1796 template <typename number2>
1797 inline
1798 void
1799 SparseMatrix<number>::add (const std::vector<size_type> &indices,
1800  const FullMatrix<number2> &values,
1801  const bool elide_zero_values)
1802 {
1803  Assert (indices.size() == values.m(),
1804  ExcDimensionMismatch(indices.size(), values.m()));
1805  Assert (values.m() == values.n(), ExcNotQuadratic());
1806 
1807  for (size_type i=0; i<indices.size(); ++i)
1808  add (indices[i], indices.size(), indices.data(), &values(i,0),
1809  elide_zero_values);
1810 }
1811 
1812 
1813 
1814 template <typename number>
1815 template <typename number2>
1816 inline
1817 void
1818 SparseMatrix<number>::add (const std::vector<size_type> &row_indices,
1819  const std::vector<size_type> &col_indices,
1820  const FullMatrix<number2> &values,
1821  const bool elide_zero_values)
1822 {
1823  Assert (row_indices.size() == values.m(),
1824  ExcDimensionMismatch(row_indices.size(), values.m()));
1825  Assert (col_indices.size() == values.n(),
1826  ExcDimensionMismatch(col_indices.size(), values.n()));
1827 
1828  for (size_type i=0; i<row_indices.size(); ++i)
1829  add (row_indices[i], col_indices.size(), col_indices.data(), &values(i,0),
1830  elide_zero_values);
1831 }
1832 
1833 
1834 
1835 template <typename number>
1836 template <typename number2>
1837 inline
1838 void
1840  const std::vector<size_type> &col_indices,
1841  const std::vector<number2> &values,
1842  const bool elide_zero_values)
1843 {
1844  Assert (col_indices.size() == values.size(),
1845  ExcDimensionMismatch(col_indices.size(), values.size()));
1846 
1847  add (row, col_indices.size(), col_indices.data(), values.data(),
1848  elide_zero_values);
1849 }
1850 
1851 
1852 
1853 template <typename number>
1854 inline
1856 SparseMatrix<number>::operator *= (const number factor)
1857 {
1858  Assert (cols != nullptr, ExcNotInitialized());
1859  Assert (val != nullptr, ExcNotInitialized());
1860 
1861  number *val_ptr = val.get();
1862  const number *const end_ptr = val.get() + cols->n_nonzero_elements();
1863 
1864  while (val_ptr != end_ptr)
1865  *val_ptr++ *= factor;
1866 
1867  return *this;
1868 }
1869 
1870 
1871 
1872 template <typename number>
1873 inline
1875 SparseMatrix<number>::operator /= (const number factor)
1876 {
1877  Assert (cols != nullptr, ExcNotInitialized());
1878  Assert (val != nullptr, ExcNotInitialized());
1879  Assert (factor != number(), ExcDivideByZero());
1880 
1881  const number factor_inv = number(1.) / factor;
1882 
1883  number *val_ptr = val.get();
1884  const number *const end_ptr = val.get() + cols->n_nonzero_elements();
1885 
1886  while (val_ptr != end_ptr)
1887  *val_ptr++ *= factor_inv;
1888 
1889  return *this;
1890 }
1891 
1892 
1893 
1894 template <typename number>
1895 inline
1896 const number &SparseMatrix<number>::operator () (const size_type i,
1897  const size_type j) const
1898 {
1899  Assert (cols != nullptr, ExcNotInitialized());
1900  Assert (cols->operator()(i,j) != SparsityPattern::invalid_entry,
1901  ExcInvalidIndex(i,j));
1902  return val[cols->operator()(i,j)];
1903 }
1904 
1905 
1906 
1907 template <typename number>
1908 inline
1910  const size_type j)
1911 {
1912  Assert (cols != nullptr, ExcNotInitialized());
1913  Assert (cols->operator()(i,j) != SparsityPattern::invalid_entry,
1914  ExcInvalidIndex(i,j));
1915  return val[cols->operator()(i,j)];
1916 }
1917 
1918 
1919 
1920 template <typename number>
1921 inline
1922 number SparseMatrix<number>::el (const size_type i,
1923  const size_type j) const
1924 {
1925  Assert (cols != nullptr, ExcNotInitialized());
1926  const size_type index = cols->operator()(i,j);
1927 
1929  return val[index];
1930  else
1931  return 0;
1932 }
1933 
1934 
1935 
1936 template <typename number>
1937 inline
1938 number SparseMatrix<number>::diag_element (const size_type i) const
1939 {
1940  Assert (cols != nullptr, ExcNotInitialized());
1941  Assert (m() == n(), ExcNotQuadratic());
1942  AssertIndexRange(i, m());
1943 
1944  // Use that the first element in each row of a quadratic matrix is the main
1945  // diagonal
1946  return val[cols->rowstart[i]];
1947 }
1948 
1949 
1950 
1951 template <typename number>
1952 inline
1954 {
1955  Assert (cols != nullptr, ExcNotInitialized());
1956  Assert (m() == n(), ExcNotQuadratic());
1957  AssertIndexRange(i, m());
1958 
1959  // Use that the first element in each row of a quadratic matrix is the main
1960  // diagonal
1961  return val[cols->rowstart[i]];
1962 }
1963 
1964 
1965 
1966 template <typename number>
1967 template <typename ForwardIterator>
1968 void
1969 SparseMatrix<number>::copy_from (const ForwardIterator begin,
1970  const ForwardIterator end)
1971 {
1972  Assert (static_cast<size_type>(std::distance (begin, end)) == m(),
1973  ExcIteratorRange (std::distance (begin, end), m()));
1974 
1975  // for use in the inner loop, we define a typedef to the type of the inner
1976  // iterators
1977  typedef typename std::iterator_traits<ForwardIterator>::value_type::const_iterator inner_iterator;
1978  size_type row=0;
1979  for (ForwardIterator i=begin; i!=end; ++i, ++row)
1980  {
1981  const inner_iterator end_of_row = i->end();
1982  for (inner_iterator j=i->begin(); j!=end_of_row; ++j)
1983  // write entries
1984  set (row, j->first, j->second);
1985  };
1986 }
1987 
1988 
1989 //---------------------------------------------------------------------------
1990 
1991 
1992 namespace SparseMatrixIterators
1993 {
1994  template <typename number>
1995  inline
1997  Accessor (const MatrixType *matrix,
1998  const std::size_t index_within_matrix)
1999  :
2000  SparsityPatternIterators::Accessor (&matrix->get_sparsity_pattern(),
2001  index_within_matrix),
2002  matrix (matrix)
2003  {}
2004 
2005 
2006 
2007  template <typename number>
2008  inline
2009  Accessor<number,true>::
2010  Accessor (const MatrixType *matrix)
2011  :
2012  SparsityPatternIterators::Accessor (&matrix->get_sparsity_pattern()),
2013  matrix (matrix)
2014  {}
2015 
2016 
2017 
2018  template <typename number>
2019  inline
2020  Accessor<number,true>::
2022  :
2023  SparsityPatternIterators::Accessor (a),
2024  matrix (&a.get_matrix())
2025  {}
2026 
2027 
2028 
2029  template <typename number>
2030  inline
2031  number
2032  Accessor<number, true>::value () const
2033  {
2034  AssertIndexRange(index_within_sparsity, matrix->n_nonzero_elements());
2035  return matrix->val[index_within_sparsity];
2036  }
2037 
2038 
2039 
2040  template <typename number>
2041  inline
2042  const typename Accessor<number, true>::MatrixType &
2043  Accessor<number, true>::get_matrix () const
2044  {
2045  return *matrix;
2046  }
2047 
2048 
2049 
2050  template <typename number>
2051  inline
2052  Accessor<number, false>::Reference::Reference (
2053  const Accessor *accessor,
2054  const bool)
2055  :
2056  accessor (accessor)
2057  {}
2058 
2059 
2060  template <typename number>
2061  inline
2062  Accessor<number, false>::Reference::operator number() const
2063  {
2064  AssertIndexRange(accessor->index_within_sparsity, accessor->matrix->n_nonzero_elements());
2065  return accessor->matrix->val[accessor->index_within_sparsity];
2066  }
2067 
2068 
2069 
2070  template <typename number>
2071  inline
2072  const typename Accessor<number, false>::Reference &
2073  Accessor<number, false>::Reference::operator = (const number n) const
2074  {
2075  AssertIndexRange(accessor->index_within_sparsity, accessor->matrix->n_nonzero_elements());
2076  accessor->matrix->val[accessor->index_within_sparsity] = n;
2077  return *this;
2078  }
2079 
2080 
2081 
2082  template <typename number>
2083  inline
2084  const typename Accessor<number, false>::Reference &
2085  Accessor<number, false>::Reference::operator += (const number n) const
2086  {
2087  AssertIndexRange(accessor->index_within_sparsity, accessor->matrix->n_nonzero_elements());
2088  accessor->matrix->val[accessor->index_within_sparsity] += n;
2089  return *this;
2090  }
2091 
2092 
2093 
2094  template <typename number>
2095  inline
2096  const typename Accessor<number, false>::Reference &
2097  Accessor<number, false>::Reference::operator -= (const number n) const
2098  {
2099  AssertIndexRange(accessor->index_within_sparsity, accessor->matrix->n_nonzero_elements());
2100  accessor->matrix->val[accessor->index_within_sparsity] -= n;
2101  return *this;
2102  }
2103 
2104 
2105 
2106  template <typename number>
2107  inline
2108  const typename Accessor<number, false>::Reference &
2109  Accessor<number, false>::Reference::operator *= (const number n) const
2110  {
2111  AssertIndexRange(accessor->index_within_sparsity, accessor->matrix->n_nonzero_elements());
2112  accessor->matrix->val[accessor->index_within_sparsity] *= n;
2113  return *this;
2114  }
2115 
2116 
2117 
2118  template <typename number>
2119  inline
2120  const typename Accessor<number, false>::Reference &
2121  Accessor<number, false>::Reference::operator /= (const number n) const
2122  {
2123  AssertIndexRange(accessor->index_within_sparsity, accessor->matrix->n_nonzero_elements());
2124  accessor->matrix->val[accessor->index_within_sparsity] /= n;
2125  return *this;
2126  }
2127 
2128 
2129 
2130  template <typename number>
2131  inline
2132  Accessor<number,false>::
2133  Accessor (MatrixType *matrix,
2134  const std::size_t index)
2135  :
2136  SparsityPatternIterators::Accessor (&matrix->get_sparsity_pattern(),
2137  index),
2138  matrix (matrix)
2139  {}
2140 
2141 
2142 
2143  template <typename number>
2144  inline
2145  Accessor<number,false>::
2146  Accessor (MatrixType *matrix)
2147  :
2148  SparsityPatternIterators::Accessor (&matrix->get_sparsity_pattern()),
2149  matrix (matrix)
2150  {}
2151 
2152 
2153 
2154  template <typename number>
2155  inline
2156  typename Accessor<number, false>::Reference
2157  Accessor<number, false>::value() const
2158  {
2159  return Reference(this,true);
2160  }
2161 
2162 
2163 
2164 
2165  template <typename number>
2166  inline
2167  typename Accessor<number, false>::MatrixType &
2168  Accessor<number, false>::get_matrix () const
2169  {
2170  return *matrix;
2171  }
2172 
2173 
2174 
2175  template <typename number, bool Constness>
2176  inline
2177  Iterator<number, Constness>::
2178  Iterator (MatrixType *matrix,
2179  const std::size_t index)
2180  :
2181  accessor(matrix, index)
2182  {}
2183 
2184 
2185 
2186  template <typename number, bool Constness>
2187  inline
2188  Iterator<number, Constness>::
2189  Iterator (MatrixType *matrix)
2190  :
2191  accessor(matrix)
2192  {}
2193 
2194 
2195 
2196  template <typename number, bool Constness>
2197  inline
2198  Iterator<number, Constness>::
2200  :
2201  accessor(*i)
2202  {}
2203 
2204 
2205 
2206  template <typename number, bool Constness>
2207  inline
2208  Iterator<number, Constness> &
2209  Iterator<number,Constness>::operator++ ()
2210  {
2211  accessor.advance ();
2212  return *this;
2213  }
2214 
2215 
2216  template <typename number, bool Constness>
2217  inline
2218  Iterator<number,Constness>
2219  Iterator<number,Constness>::operator++ (int)
2220  {
2221  const Iterator iter = *this;
2222  accessor.advance ();
2223  return iter;
2224  }
2225 
2226 
2227  template <typename number, bool Constness>
2228  inline
2229  const Accessor<number,Constness> &
2231  {
2232  return accessor;
2233  }
2234 
2235 
2236  template <typename number, bool Constness>
2237  inline
2238  const Accessor<number,Constness> *
2239  Iterator<number,Constness>::operator-> () const
2240  {
2241  return &accessor;
2242  }
2243 
2244 
2245  template <typename number, bool Constness>
2246  inline
2247  bool
2248  Iterator<number,Constness>::
2249  operator == (const Iterator &other) const
2250  {
2251  return (accessor == other.accessor);
2252  }
2253 
2254 
2255  template <typename number, bool Constness>
2256  inline
2257  bool
2258  Iterator<number,Constness>::
2259  operator != (const Iterator &other) const
2260  {
2261  return ! (*this == other);
2262  }
2263 
2264 
2265  template <typename number, bool Constness>
2266  inline
2267  bool
2268  Iterator<number,Constness>::
2269  operator < (const Iterator &other) const
2270  {
2271  Assert (&accessor.get_matrix() == &other.accessor.get_matrix(),
2272  ExcInternalError());
2273 
2274  return (accessor < other.accessor);
2275  }
2276 
2277 
2278  template <typename number, bool Constness>
2279  inline
2280  bool
2281  Iterator<number,Constness>::
2282  operator > (const Iterator &other) const
2283  {
2284  return (other < *this);
2285  }
2286 
2287 
2288  template <typename number, bool Constness>
2289  inline
2290  int
2292  operator - (const Iterator &other) const
2293  {
2294  Assert (&accessor.get_matrix() == &other.accessor.get_matrix(),
2295  ExcInternalError());
2296 
2297  return (*this)->index_within_sparsity - other->index_within_sparsity;
2298  }
2299 
2300 
2301 
2302  template <typename number, bool Constness>
2303  inline
2304  Iterator<number,Constness>
2306  operator + (const size_type n) const
2307  {
2308  Iterator x = *this;
2309  for (size_type i=0; i<n; ++i)
2310  ++x;
2311 
2312  return x;
2313  }
2314 
2315 }
2316 
2317 
2318 
2319 template <typename number>
2320 inline
2323 {
2324  return const_iterator(this, 0);
2325 }
2326 
2327 
2328 template <typename number>
2329 inline
2332 {
2333  return const_iterator(this);
2334 }
2335 
2336 
2337 template <typename number>
2338 inline
2341 {
2342  return iterator (this, 0);
2343 }
2344 
2345 
2346 template <typename number>
2347 inline
2350 {
2351  return iterator(this, cols->rowstart[cols->rows]);
2352 }
2353 
2354 
2355 template <typename number>
2356 inline
2358 SparseMatrix<number>::begin (const size_type r) const
2359 {
2360  Assert (r<m(), ExcIndexRange(r,0,m()));
2361 
2362  return const_iterator(this, cols->rowstart[r]);
2363 }
2364 
2365 
2366 
2367 template <typename number>
2368 inline
2370 SparseMatrix<number>::end (const size_type r) const
2371 {
2372  Assert (r<m(), ExcIndexRange(r,0,m()));
2373 
2374  return const_iterator(this, cols->rowstart[r+1]);
2375 }
2376 
2377 
2378 
2379 template <typename number>
2380 inline
2382 SparseMatrix<number>::begin (const size_type r)
2383 {
2384  Assert (r<m(), ExcIndexRange(r,0,m()));
2385 
2386  return iterator(this, cols->rowstart[r]);
2387 }
2388 
2389 
2390 
2391 template <typename number>
2392 inline
2394 SparseMatrix<number>::end (const size_type r)
2395 {
2396  Assert (r<m(), ExcIndexRange(r,0,m()));
2397 
2398  return iterator(this, cols->rowstart[r+1]);
2399 }
2400 
2401 
2402 
2403 template <typename number>
2404 template <class StreamType>
2405 inline
2406 void SparseMatrix<number>::print (StreamType &out,
2407  const bool across,
2408  const bool diagonal_first) const
2409 {
2410  Assert (cols != nullptr, ExcNotInitialized());
2411  Assert (val != nullptr, ExcNotInitialized());
2412 
2413  bool hanging_diagonal = false;
2414  number diagonal = number();
2415 
2416  for (size_type i=0; i<cols->rows; ++i)
2417  {
2418  for (size_type j=cols->rowstart[i]; j<cols->rowstart[i+1]; ++j)
2419  {
2420  if (!diagonal_first && i == cols->colnums[j])
2421  {
2422  diagonal = val[j];
2423  hanging_diagonal = true;
2424  }
2425  else
2426  {
2427  if (hanging_diagonal && cols->colnums[j]>i)
2428  {
2429  if (across)
2430  out << ' ' << i << ',' << i << ':' << diagonal;
2431  else
2432  out << '(' << i << ',' << i << ") " << diagonal << std::endl;
2433  hanging_diagonal = false;
2434  }
2435  if (across)
2436  out << ' ' << i << ',' << cols->colnums[j] << ':' << val[j];
2437  else
2438  out << "(" << i << "," << cols->colnums[j] << ") " << val[j] << std::endl;
2439  }
2440  }
2441  if (hanging_diagonal)
2442  {
2443  if (across)
2444  out << ' ' << i << ',' << i << ':' << diagonal;
2445  else
2446  out << '(' << i << ',' << i << ") " << diagonal << std::endl;
2447  hanging_diagonal = false;
2448  }
2449  }
2450  if (across)
2451  out << std::endl;
2452 }
2453 
2454 
2455 template <typename number>
2456 inline
2457 void
2459 prepare_add()
2460 {
2461  //nothing to do here
2462 }
2463 
2464 
2465 
2466 template <typename number>
2467 inline
2468 void
2470 prepare_set()
2471 {
2472  //nothing to do here
2473 }
2474 
2475 #endif // DOXYGEN
2476 
2477 
2478 /*---------------------------- sparse_matrix.h ---------------------------*/
2479 
2480 DEAL_II_NAMESPACE_CLOSE
2481 
2482 #endif
2483 /*---------------------------- sparse_matrix.h ---------------------------*/
void PSOR(Vector< somenumber > &v, const std::vector< size_type > &permutation, const std::vector< size_type > &inverse_permutation, const number om=1.) 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
void Tvmult_add(OutVector &dst, const InVector &src) const
size_type m() const
SparseMatrix & operator/=(const number factor)
void precondition_TSOR(Vector< somenumber > &dst, const Vector< somenumber > &src, const number om=1.) const
real_type l1_norm() const
size_type get_row_length(const size_type row) const
const Accessor< number, Constness > & operator*() const
#define DeclException2(Exception2, type1, type2, outsequence)
Definition: exceptions.h:358
static ::ExceptionBase & ExcInvalidIndex(int arg1, int arg2)
numbers::NumberTraits< number >::real_type real_type
int operator-(const Iterator &p) const
void prepare_add()
const_iterator end() const
Accessor< number, Constness >::MatrixType MatrixType
Contents is actually a matrix.
SparseMatrix< number > & operator=(const SparseMatrix< number > &)
std::size_t n_actually_nonzero_elements(const double threshold=0.) const
static const size_type invalid_entry
std::unique_ptr< number[]> val
const SparseMatrix< number > & get_matrix() const
Iterator(MatrixType *matrix, const std::size_t index_within_matrix)
void set(const size_type i, const size_type j, const number value)
void TSOR_step(Vector< somenumber > &v, const Vector< somenumber > &b, const number om=1.) const
#define AssertIndexRange(index, range)
Definition: exceptions.h:1284
void block_read(std::istream &in)
const Accessor< number, Constness > * operator->() const
somenumber matrix_norm_square(const Vector< somenumber > &v) const
bool operator!=(const Iterator &) const
SparseMatrixIterators::Iterator< number, false > iterator
void TPSOR(Vector< somenumber > &v, const std::vector< size_type > &permutation, const std::vector< size_type > &inverse_permutation, const number om=1.) const
static ::ExceptionBase & ExcNotInitialized()
void vmult_add(OutVector &dst, const InVector &src) const
bool empty() const
SymmetricTensor< rank_, dim, typename ProductType< Number, OtherNumber >::type > operator+(const SymmetricTensor< rank_, dim, Number > &left, const SymmetricTensor< rank_, dim, OtherNumber > &right)
static ::ExceptionBase & ExcDifferentSparsityPatterns()
static ::ExceptionBase & ExcIndexRange(int arg1, int arg2, int arg3)
SymmetricTensor< rank_, dim, Number > operator*(const SymmetricTensor< rank_, dim, Number > &t, const Number &factor)
virtual void reinit(const SparsityPattern &sparsity)
static ::ExceptionBase & ExcDivideByZero()
void mmult(SparseMatrix< numberC > &C, const SparseMatrix< numberB > &B, const Vector< number > &V=Vector< number >(), const bool rebuild_sparsity_pattern=true) const
void SOR_step(Vector< somenumber > &v, const Vector< somenumber > &b, const number om=1.) const
std::size_t n_nonzero_elements() const
std::size_t memory_consumption() const
Matrix is diagonal.
size_type n() const
void precondition_SOR(Vector< somenumber > &dst, const Vector< somenumber > &src, const number om=1.) const
void symmetrize()
size_type n() const
bool operator>(const Iterator &) const
T sum(const T &t, const MPI_Comm &mpi_communicator)
unsigned int global_dof_index
Definition: types.h:88
number diag_element(const size_type i) const
Iterator operator+(const size_type n) const
#define Assert(cond, exc)
Definition: exceptions.h:1142
bool operator<(const Iterator &) const
void vmult(OutVector &dst, const InVector &src) const
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
void print(StreamType &out, const bool across=false, const bool diagonal_first=true) const
types::global_dof_index size_type
Definition: sparse_matrix.h:71
#define DeclExceptionMsg(Exception, defaulttext)
Definition: exceptions.h:335
number value_type
somenumber matrix_scalar_product(const Vector< somenumber > &u, const Vector< somenumber > &v) const
somenumber residual(Vector< somenumber > &dst, const Vector< somenumber > &x, const Vector< somenumber > &b) const
void Tmmult(SparseMatrix< numberC > &C, const SparseMatrix< numberB > &B, const Vector< number > &V=Vector< number >(), const bool rebuild_sparsity_pattern=true) const
void precondition_SSOR(Vector< somenumber > &dst, const Vector< somenumber > &src, const number omega=1., const std::vector< std::size_t > &pos_right_of_diagonal=std::vector< std::size_t >()) const
static ::ExceptionBase & ExcIteratorRange(int arg1, int arg2)
void prepare_set()
bool operator==(const Iterator &) const
void SOR(Vector< somenumber > &v, const number om=1.) const
void SSOR(Vector< somenumber > &v, const number omega=1.) const
void add(const size_type i, const size_type j, const number value)
const Accessor< number, Constness > & value_type
Accessor< number, Constness > accessor
void Jacobi_step(Vector< somenumber > &v, const Vector< somenumber > &b, const number om=1.) const
SparseMatrixIterators::Iterator< number, true > const_iterator
static ::ExceptionBase & ExcNotQuadratic()
Definition: cuda.h:31
types::global_dof_index size_type
void SSOR_step(Vector< somenumber > &v, const Vector< somenumber > &b, const number om=1.) const
number el(const size_type i, const size_type j) const
SmartPointer< const SparsityPattern, SparseMatrix< number > > cols
void precondition_Jacobi(Vector< somenumber > &dst, const Vector< somenumber > &src, const number omega=1.) const
virtual ~SparseMatrix()
size_type m() const
void TSOR(Vector< somenumber > &v, const number om=1.) const
Accessor(const SparsityPattern *matrix, const std::size_t index_within_sparsity)
static const bool zero_addition_can_be_elided
const SparsityPattern & get_sparsity_pattern() const
const_iterator begin() const
SparseMatrix< number > & copy_from(const SparseMatrix< somenumber > &source)
const number & operator()(const size_type i, const size_type j) const
void print_pattern(std::ostream &out, const double threshold=0.) const
real_type frobenius_norm() const
SymmetricTensor< rank_, dim, typename ProductType< Number, OtherNumber >::type > operator-(const SymmetricTensor< rank_, dim, Number > &left, const SymmetricTensor< rank_, dim, OtherNumber > &right)
virtual void clear()
#define AssertIsFinite(number)
Definition: exceptions.h:1299
real_type linfty_norm() const
void Tvmult(OutVector &dst, const InVector &src) const
std::size_t max_len
void compress(::VectorOperation::values)
static ::ExceptionBase & ExcSourceEqualsDestination()
SparseMatrix & operator*=(const number factor)
static ::ExceptionBase & ExcInternalError()
void block_write(std::ostream &out) const