Reference documentation for deal.II version 9.1.0-pre
lapack_full_matrix.h
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2005 - 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.md at
12 // the top level directory of deal.II.
13 //
14 // ---------------------------------------------------------------------
15 
16 #ifndef dealii_lapack_full_matrix_h
17 #define dealii_lapack_full_matrix_h
18 
19 
20 #include <deal.II/base/config.h>
21 
22 #include <deal.II/base/smartpointer.h>
23 #include <deal.II/base/table.h>
24 #include <deal.II/base/thread_management.h>
25 
26 #include <deal.II/lac/lapack_support.h>
27 #include <deal.II/lac/vector_memory.h>
28 
29 #include <complex>
30 #include <memory>
31 #include <vector>
32 
33 DEAL_II_NAMESPACE_OPEN
34 
35 // forward declarations
36 template <typename number>
37 class Vector;
38 template <typename number>
39 class BlockVector;
40 template <typename number>
41 class FullMatrix;
42 template <typename number>
43 class SparseMatrix;
44 
45 
58 template <typename number>
59 class LAPACKFullMatrix : public TransposeTable<number>
60 {
61 public:
65  using size_type = std::make_unsigned<types::blas_int>::type;
66 
76  explicit LAPACKFullMatrix(const size_type size = 0);
77 
78 
83  LAPACKFullMatrix(const size_type rows, const size_type cols);
84 
85 
96 
102 
109  template <typename number2>
112 
119  template <typename number2>
122 
129  operator=(const number d);
130 
135  operator*=(const number factor);
136 
141  operator/=(const number factor);
142 
153  void
154  set(const size_type i, const size_type j, const number value);
155 
160  void
161  add(const number a, const LAPACKFullMatrix<number> &B);
162 
175  void
176  rank1_update(const number a, const Vector<number> &v);
177 
184  template <typename MatrixType>
185  void
186  copy_from(const MatrixType &);
187 
193  void
194  reinit(const size_type size);
195 
218  void
220 
240  void
241  remove_row_and_column(const size_type row, const size_type col);
242 
248  void
249  reinit(const size_type rows, const size_type cols);
250 
254  void
256 
262  size_type
263  m() const;
264 
270  size_type
271  n() const;
272 
286  template <typename MatrixType>
287  void
288  fill(const MatrixType &src,
289  const size_type dst_offset_i = 0,
290  const size_type dst_offset_j = 0,
291  const size_type src_offset_i = 0,
292  const size_type src_offset_j = 0,
293  const number factor = 1.,
294  const bool transpose = false);
295 
296 
324  template <typename number2>
325  void
326  vmult(Vector<number2> & w,
327  const Vector<number2> &v,
328  const bool adding = false) const;
329 
333  void
334  vmult(Vector<number> & w,
335  const Vector<number> &v,
336  const bool adding = false) const;
337 
344  template <typename number2>
345  void
346  vmult_add(Vector<number2> &w, const Vector<number2> &v) const;
347 
351  void
352  vmult_add(Vector<number> &w, const Vector<number> &v) const;
353 
365  template <typename number2>
366  void
367  Tvmult(Vector<number2> & w,
368  const Vector<number2> &v,
369  const bool adding = false) const;
370 
374  void
376  const Vector<number> &v,
377  const bool adding = false) const;
378 
385  template <typename number2>
386  void
387  Tvmult_add(Vector<number2> &w, const Vector<number2> &v) const;
388 
392  void
393  Tvmult_add(Vector<number> &w, const Vector<number> &v) const;
394 
395 
410  void
412  const LAPACKFullMatrix<number> &B,
413  const bool adding = false) const;
414 
419  void
421  const LAPACKFullMatrix<number> &B,
422  const bool adding = false) const;
423 
438  void
440  const LAPACKFullMatrix<number> &B,
441  const bool adding = false) const;
442 
447  void
449  const LAPACKFullMatrix<number> &B,
450  const bool adding = false) const;
451 
467  void
469  const LAPACKFullMatrix<number> &B,
470  const Vector<number> & V,
471  const bool adding = false) const;
472 
487  void
489  const LAPACKFullMatrix<number> &B,
490  const bool adding = false) const;
491 
496  void
498  const LAPACKFullMatrix<number> &B,
499  const bool adding = false) const;
500 
516  void
518  const LAPACKFullMatrix<number> &B,
519  const bool adding = false) const;
520 
525  void
527  const LAPACKFullMatrix<number> &B,
528  const bool adding = false) const;
529 
535  void
536  scale_rows(const Vector<number> &V);
537 
541  void
543 
550  void
552 
572  number
573  reciprocal_condition_number(const number l1_norm) const;
574 
582  number
584 
590  number
591  determinant() const;
592 
596  number
597  l1_norm() const;
598 
602  number
603  linfty_norm() const;
604 
608  number
609  frobenius_norm() const;
610 
615  number
616  trace() const;
617 
623  void
624  invert();
625 
634  void
635  solve(Vector<number> &v, const bool transposed = false) const;
636 
641  void
642  solve(LAPACKFullMatrix<number> &B, const bool transposed = false) const;
643 
654  DEAL_II_DEPRECATED
655  void
656  apply_lu_factorization(Vector<number> &v, const bool transposed) const;
657 
669  DEAL_II_DEPRECATED
670  void
672  const bool transposed) const;
673 
692  void
693  compute_eigenvalues(const bool right_eigenvectors = false,
694  const bool left_eigenvectors = false);
695 
715  void
716  compute_eigenvalues_symmetric(const number lower_bound,
717  const number upper_bound,
718  const number abs_accuracy,
721 
748  void
751  const number lower_bound,
752  const number upper_bound,
753  const number abs_accuracy,
755  std::vector<Vector<number>> &eigenvectors,
756  const types::blas_int itype = 1);
757 
773  void
776  std::vector<Vector<number>> &eigenvectors,
777  const types::blas_int itype = 1);
778 
787  void
788  compute_svd();
789 
809  void
810  compute_inverse_svd(const double threshold = 0.);
811 
816  void
817  compute_inverse_svd_with_kernel(const unsigned int kernel_size);
818 
822  std::complex<number>
823  eigenvalue(const size_type i) const;
824 
829  number
830  singular_value(const size_type i) const;
831 
858  void
859  print_formatted(std::ostream & out,
860  const unsigned int precision = 3,
861  const bool scientific = true,
862  const unsigned int width = 0,
863  const char * zero_string = " ",
864  const double denominator = 1.,
865  const double threshold = 0.) const;
866 
867 private:
871  number
872  norm(const char type) const;
873 
879 
885 
889  mutable std::vector<number> work;
890 
894  mutable std::vector<types::blas_int> iwork;
895 
902  std::vector<types::blas_int> ipiv;
903 
907  std::vector<number> inv_work;
908 
913  std::vector<typename numbers::NumberTraits<number>::real_type> wr;
914 
919  std::vector<number> wi;
920 
924  std::vector<number> vl;
925 
929  std::vector<number> vr;
930 
935  std::unique_ptr<LAPACKFullMatrix<number>> svd_u;
936 
941  std::unique_ptr<LAPACKFullMatrix<number>> svd_vt;
942 
947 };
948 
949 
950 
957 template <typename number>
959 {
960 public:
961  void
962  initialize(const LAPACKFullMatrix<number> &);
963  void
964  initialize(const LAPACKFullMatrix<number> &, VectorMemory<Vector<number>> &);
965  void
966  vmult(Vector<number> &, const Vector<number> &) const;
967  void
968  Tvmult(Vector<number> &, const Vector<number> &) const;
969  void
971  void
973 
974 private:
977 };
978 
979 /*---------------------- Inline functions -----------------------------------*/
980 
981 template <typename number>
982 inline void
984  const size_type j,
985  const number value)
986 {
987  (*this)(i, j) = value;
988 }
989 
990 
991 template <typename number>
994 {
995  return static_cast<size_type>(this->n_rows());
996 }
997 
998 template <typename number>
1001 {
1002  return static_cast<size_type>(this->n_cols());
1003 }
1004 
1005 template <typename number>
1006 template <typename MatrixType>
1007 inline void
1009 {
1010  this->reinit(M.m(), M.n());
1011 
1012  // loop over the elements of the argument matrix row by row, as suggested
1013  // in the documentation of the sparse matrix iterator class, and
1014  // copy them into the current object
1015  for (size_type row = 0; row < M.m(); ++row)
1016  {
1017  const typename MatrixType::const_iterator end_row = M.end(row);
1018  for (typename MatrixType::const_iterator entry = M.begin(row);
1019  entry != end_row;
1020  ++entry)
1021  this->el(row, entry->column()) = entry->value();
1022  }
1023 
1025 }
1026 
1027 
1028 
1029 template <typename number>
1030 template <typename MatrixType>
1031 inline void
1033  const size_type dst_offset_i,
1034  const size_type dst_offset_j,
1035  const size_type src_offset_i,
1036  const size_type src_offset_j,
1037  const number factor,
1038  const bool transpose)
1039 {
1040  // loop over the elements of the argument matrix row by row, as suggested
1041  // in the documentation of the sparse matrix iterator class
1042  for (size_type row = src_offset_i; row < M.m(); ++row)
1043  {
1044  const typename MatrixType::const_iterator end_row = M.end(row);
1045  for (typename MatrixType::const_iterator entry = M.begin(row);
1046  entry != end_row;
1047  ++entry)
1048  {
1049  const size_type i = transpose ? entry->column() : row;
1050  const size_type j = transpose ? row : entry->column();
1051 
1052  const size_type dst_i = dst_offset_i + i - src_offset_i;
1053  const size_type dst_j = dst_offset_j + j - src_offset_j;
1054  if (dst_i < this->n_rows() && dst_j < this->n_cols())
1055  (*this)(dst_i, dst_j) = factor * entry->value();
1056  }
1057  }
1058 
1060 }
1061 
1062 
1063 template <typename number>
1064 template <typename number2>
1065 void
1067  const Vector<number2> &,
1068  const bool) const
1069 {
1070  Assert(false,
1071  ExcMessage("LAPACKFullMatrix<number>::vmult must be called with a "
1072  "matching Vector<double> vector type."));
1073 }
1074 
1075 
1076 template <typename number>
1077 template <typename number2>
1078 void
1080  const Vector<number2> &) const
1081 {
1082  Assert(false,
1083  ExcMessage("LAPACKFullMatrix<number>::vmult_add must be called with a "
1084  "matching Vector<double> vector type."));
1085 }
1086 
1087 
1088 template <typename number>
1089 template <typename number2>
1090 void
1092  const Vector<number2> &,
1093  const bool) const
1094 {
1095  Assert(false,
1096  ExcMessage("LAPACKFullMatrix<number>::Tvmult must be called with a "
1097  "matching Vector<double> vector type."));
1098 }
1099 
1100 
1101 template <typename number>
1102 template <typename number2>
1103 void
1105  const Vector<number2> &) const
1106 {
1107  Assert(false,
1108  ExcMessage(
1109  "LAPACKFullMatrix<number>::Tvmult_add must be called with a "
1110  "matching Vector<double> vector type."));
1111 }
1112 
1113 
1114 template <typename number>
1115 inline std::complex<number>
1117 {
1119  Assert(wr.size() == this->n_rows(), ExcInternalError());
1120  Assert(wi.size() == this->n_rows(), ExcInternalError());
1121  AssertIndexRange(i, this->n_rows());
1122 
1124  return std::complex<number>(wi[i]);
1125  else
1126  return std::complex<number>(wr[i], wi[i]);
1127 }
1128 
1129 
1130 template <typename number>
1131 inline number
1133 {
1136  AssertIndexRange(i, wr.size());
1137 
1138  return wr[i];
1139 }
1140 
1141 
1142 
1143 DEAL_II_NAMESPACE_CLOSE
1144 
1145 #endif
LAPACKFullMatrix(const size_type size=0)
void Tmmult(LAPACKFullMatrix< number > &C, const LAPACKFullMatrix< number > &B, const bool adding=false) const
size_type n_rows() const
std::vector< number > work
void rank1_update(const number a, const Vector< number > &v)
number linfty_norm() const
void mTmult(LAPACKFullMatrix< number > &C, const LAPACKFullMatrix< number > &B, const bool adding=false) const
std::unique_ptr< LAPACKFullMatrix< number > > svd_vt
LAPACKFullMatrix< number > & operator/=(const number factor)
size_type n() const
number reciprocal_condition_number() const
Contents is actually a matrix.
std::array< std::pair< Number, Tensor< 1, dim, Number > >, std::integral_constant< int, dim >::value > eigenvectors(const SymmetricTensor< 2, dim, Number > &T, const SymmetricTensorEigenvectorMethod method=SymmetricTensorEigenvectorMethod::ql_implicit_shifts)
number singular_value(const size_type i) const
std::array< Number, 1 > eigenvalues(const SymmetricTensor< 2, 1, Number > &T)
LAPACKSupport::State state
typename TableBase< 2, T >::size_type size_type
Definition: table.h:1770
void remove_row_and_column(const size_type row, const size_type col)
Threads::Mutex mutex
std::vector< types::blas_int > ipiv
#define AssertIndexRange(index, range)
Definition: exceptions.h:1407
number norm(const char type) const
std::vector< number > vr
size_type m() const
void vmult(Vector< number2 > &w, const Vector< number2 > &v, const bool adding=false) const
void solve(Vector< number > &v, const bool transposed=false) const
void vmult_add(Vector< number2 > &w, const Vector< number2 > &v) const
void compute_eigenvalues_symmetric(const number lower_bound, const number upper_bound, const number abs_accuracy, Vector< number > &eigenvalues, FullMatrix< number > &eigenvectors)
void reinit(const size_type size)
void Tvmult_add(Vector< number2 > &w, const Vector< number2 > &v) 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 double threshold=0.) const
number trace() const
void apply_lu_factorization(Vector< number > &v, const bool transposed) const
const TableIndices< N > & size() const
std::vector< types::blas_int > iwork
static::ExceptionBase & ExcState(State arg1)
void set(const size_type i, const size_type j, const number value)
static::ExceptionBase & ExcInvalidState()
static::ExceptionBase & ExcMessage(std::string arg1)
#define Assert(cond, exc)
Definition: exceptions.h:1227
void compute_inverse_svd_with_kernel(const unsigned int kernel_size)
void copy_from(const MatrixType &)
std::make_unsigned< types::blas_int >::type size_type
void TmTmult(LAPACKFullMatrix< number > &C, const LAPACKFullMatrix< number > &B, const bool adding=false) const
number frobenius_norm() const
void add(const number a, const LAPACKFullMatrix< number > &B)
std::vector< number > inv_work
Matrix is the inverse of a singular value decomposition.
std::vector< number > vl
std::vector< number > wi
SymmetricTensor< rank_, dim, Number > transpose(const SymmetricTensor< rank_, dim, Number > &t)
std::unique_ptr< LAPACKFullMatrix< number > > svd_u
void grow_or_shrink(const size_type size)
void scale_rows(const Vector< number > &V)
LAPACKFullMatrix< number > & operator*=(const number factor)
void compute_inverse_svd(const double threshold=0.)
void Tvmult(Vector< number2 > &w, const Vector< number2 > &v, const bool adding=false) const
LAPACKFullMatrix< number > & operator=(const LAPACKFullMatrix< number > &)
int blas_int
void fill(const MatrixType &src, const size_type dst_offset_i=0, const size_type dst_offset_j=0, const size_type src_offset_i=0, const size_type src_offset_j=0, const number factor=1., const bool transpose=false)
std::vector< typename numbers::NumberTraits< number >::real_type > wr
Matrix contains singular value decomposition,.
void set_property(const LAPACKSupport::Property property)
reference el(const size_type i, const size_type j)
void compute_generalized_eigenvalues_symmetric(LAPACKFullMatrix< number > &B, const number lower_bound, const number upper_bound, const number abs_accuracy, Vector< number > &eigenvalues, std::vector< Vector< number >> &eigenvectors, const types::blas_int itype=1)
void compute_eigenvalues(const bool right_eigenvectors=false, const bool left_eigenvectors=false)
number determinant() const
std::complex< number > eigenvalue(const size_type i) const
size_type n_cols() const
void mmult(LAPACKFullMatrix< number > &C, const LAPACKFullMatrix< number > &B, const bool adding=false) const
Eigenvalue vector is filled.
LAPACKSupport::Property property
number l1_norm() const
static::ExceptionBase & ExcInternalError()