Reference documentation for deal.II version 9.0.0
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 at
12 // the top level of the deal.II distribution.
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 #include <deal.II/base/smartpointer.h>
22 #include <deal.II/base/table.h>
23 #include <deal.II/lac/lapack_support.h>
24 #include <deal.II/lac/vector_memory.h>
25 #include <deal.II/base/thread_management.h>
26 
27 #include <memory>
28 #include <vector>
29 #include <complex>
30 
31 DEAL_II_NAMESPACE_OPEN
32 
33 // forward declarations
34 template <typename number> class Vector;
35 template <typename number> class BlockVector;
36 template <typename number> class FullMatrix;
37 template <typename number> class SparseMatrix;
38 
39 
52 template <typename number>
53 class LAPACKFullMatrix : public TransposeTable<number>
54 {
55 public:
56 
60  typedef std::make_unsigned<types::blas_int>::type size_type;
61 
71  explicit LAPACKFullMatrix (const size_type size = 0);
72 
73 
77  LAPACKFullMatrix (const size_type rows,
78  const size_type cols);
79 
80 
91 
97 
104  template <typename number2>
107 
114  template <typename number2>
117 
124  operator = (const number d);
125 
130  operator*= (const number factor);
131 
136  operator/= (const number factor);
137 
147  void set (const size_type i,
148  const size_type j,
149  const number value);
150 
154  void add (const number a,
155  const LAPACKFullMatrix<number> &B);
156 
169  void rank1_update(const number a,
170  const Vector<number> &v);
171 
178  template <typename MatrixType>
179  void copy_from (const MatrixType &);
180 
186  void reinit (const size_type size);
187 
213  void grow_or_shrink (const size_type size);
214 
234  void remove_row_and_column (const size_type row, const size_type col);
235 
241  void reinit (const size_type rows,
242  const size_type cols);
243 
248 
254  size_type m () const;
255 
261  size_type n () const;
262 
276  template <typename MatrixType>
277  void fill (const MatrixType &src,
278  const size_type dst_offset_i = 0,
279  const size_type dst_offset_j = 0,
280  const size_type src_offset_i = 0,
281  const size_type src_offset_j = 0,
282  const number factor = 1.,
283  const bool transpose = false);
284 
285 
313  template <typename number2>
314  void vmult (Vector<number2> &w,
315  const Vector<number2> &v,
316  const bool adding = false) const;
317 
321  void vmult (Vector<number> &w,
322  const Vector<number> &v,
323  const bool adding = false) const;
324 
330  template <typename number2>
331  void vmult_add (Vector<number2> &w,
332  const Vector<number2> &v) const;
333 
337  void vmult_add (Vector<number> &w,
338  const Vector<number> &v) const;
339 
351  template <typename number2>
352  void Tvmult (Vector<number2> &w,
353  const Vector<number2> &v,
354  const bool adding=false) const;
355 
359  void Tvmult (Vector<number> &w,
360  const Vector<number> &v,
361  const bool adding=false) const;
362 
368  template <typename number2>
369  void Tvmult_add (Vector<number2> &w,
370  const Vector<number2> &v) const;
371 
375  void Tvmult_add (Vector<number> &w,
376  const Vector<number> &v) const;
377 
378 
394  const LAPACKFullMatrix<number> &B,
395  const bool adding=false) const;
396 
401  void mmult (FullMatrix<number> &C,
402  const LAPACKFullMatrix<number> &B,
403  const bool adding=false) const;
404 
420  const LAPACKFullMatrix<number> &B,
421  const bool adding=false) const;
422 
427  void Tmmult (FullMatrix<number> &C,
428  const LAPACKFullMatrix<number> &B,
429  const bool adding=false) const;
430 
446  const LAPACKFullMatrix<number> &B,
447  const Vector<number> &V,
448  const bool adding=false) const;
449 
465  const LAPACKFullMatrix<number> &B,
466  const bool adding=false) const;
467 
472  void mTmult (FullMatrix<number> &C,
473  const LAPACKFullMatrix<number> &B,
474  const bool adding=false) const;
475 
492  const LAPACKFullMatrix<number> &B,
493  const bool adding=false) const;
494 
499  void TmTmult (FullMatrix<number> &C,
500  const LAPACKFullMatrix<number> &B,
501  const bool adding=false) const;
502 
507  void scale_rows(const Vector<number> &V);
508 
512  void compute_lu_factorization ();
513 
520 
539  number reciprocal_condition_number(const number l1_norm) const;
540 
547  number reciprocal_condition_number() const;
548 
554  number determinant () const;
555 
559  number l1_norm() const;
560 
564  number linfty_norm() const;
565 
569  number frobenius_norm() const;
570 
575  number trace() const;
576 
581  void invert ();
582 
591  void solve(Vector<number> &v,
592  const bool transposed = false) const;
593 
599  const bool transposed = false) const;
600 
611  DEAL_II_DEPRECATED
613  const bool transposed) const;
614 
626  DEAL_II_DEPRECATED
628  const bool transposed) const;
629 
648  void compute_eigenvalues (const bool right_eigenvectors = false,
649  const bool left_eigenvectors = false);
650 
668  void compute_eigenvalues_symmetric (const number lower_bound,
669  const number upper_bound,
670  const number abs_accuracy,
673 
699  const number lower_bound,
700  const number upper_bound,
701  const number abs_accuracy,
703  std::vector<Vector<number> > &eigenvectors,
704  const types::blas_int itype = 1);
705 
722  std::vector<Vector<number> > &eigenvectors,
723  const types::blas_int itype = 1);
724 
733  void compute_svd ();
734 
754  void compute_inverse_svd (const double threshold = 0.);
755 
760  void compute_inverse_svd_with_kernel (const unsigned int kernel_size);
761 
765  std::complex<number>
766  eigenvalue (const size_type i) const;
767 
772  number
773  singular_value (const size_type i) const;
774 
801  void print_formatted (std::ostream &out,
802  const unsigned int precision = 3,
803  const bool scientific = true,
804  const unsigned int width = 0,
805  const char *zero_string = " ",
806  const double denominator = 1.,
807  const double threshold = 0.) const;
808 
809 private:
813  number norm(const char type) const;
814 
820 
826 
830  mutable std::vector<number> work;
831 
835  mutable std::vector<types::blas_int> iwork;
836 
843  std::vector<types::blas_int> ipiv;
844 
848  std::vector<number> inv_work;
849 
854  std::vector<number> wr;
855 
859  std::vector<number> wi;
860 
864  std::vector<number> vl;
865 
869  std::vector<number> vr;
870 
875  std::unique_ptr<LAPACKFullMatrix<number> > svd_u;
876 
881  std::unique_ptr<LAPACKFullMatrix<number> > svd_vt;
882 
887 };
888 
889 
890 
897 template <typename number>
899  :
900  public Subscriptor
901 {
902 public:
903  void initialize(const LAPACKFullMatrix<number> &);
904  void initialize(const LAPACKFullMatrix<number> &,
906  void vmult(Vector<number> &, const Vector<number> &) const;
907  void Tvmult(Vector<number> &, const Vector<number> &) const;
908  void vmult(BlockVector<number> &,
909  const BlockVector<number> &) const;
910  void Tvmult(BlockVector<number> &,
911  const BlockVector<number> &) const;
912 private:
915 };
916 
917 /*---------------------- Inline functions -----------------------------------*/
918 
919 template <typename number>
920 inline
922  const size_type j,
923  const number value)
924 {
925  (*this)(i,j) = value;
926 }
927 
928 
929 template <typename number>
930 inline
933 {
934  return static_cast<size_type>(this->n_rows ());
935 }
936 
937 template <typename number>
938 inline
941 {
942  return static_cast<size_type>(this->n_cols ());
943 }
944 
945 template <typename number>
946 template <typename MatrixType>
947 inline void
949 {
950  this->reinit (M.m(), M.n());
951 
952  // loop over the elements of the argument matrix row by row, as suggested
953  // in the documentation of the sparse matrix iterator class, and
954  // copy them into the current object
955  for (size_type row = 0; row < M.m(); ++row)
956  {
957  const typename MatrixType::const_iterator end_row = M.end(row);
958  for (typename MatrixType::const_iterator entry = M.begin(row);
959  entry != end_row; ++entry)
960  this->el(row, entry->column()) = entry->value();
961  }
962 
963  state = LAPACKSupport::matrix;
964 }
965 
966 
967 
968 template <typename number>
969 template <typename MatrixType>
970 inline void
971 LAPACKFullMatrix<number>::fill (const MatrixType &M,
972  const size_type dst_offset_i,
973  const size_type dst_offset_j,
974  const size_type src_offset_i,
975  const size_type src_offset_j,
976  const number factor,
977  const bool transpose)
978 {
979  // loop over the elements of the argument matrix row by row, as suggested
980  // in the documentation of the sparse matrix iterator class
981  for (size_type row = src_offset_i; row < M.m(); ++row)
982  {
983  const typename MatrixType::const_iterator end_row = M.end(row);
984  for (typename MatrixType::const_iterator entry = M.begin(row);
985  entry != end_row; ++entry)
986  {
987  const size_type i = transpose ? entry->column() : row;
988  const size_type j = transpose ? row : entry->column();
989 
990  const size_type dst_i=dst_offset_i+i-src_offset_i;
991  const size_type dst_j=dst_offset_j+j-src_offset_j;
992  if (dst_i<this->n_rows() && dst_j<this->n_cols())
993  (*this)(dst_i, dst_j) = factor * entry->value();
994  }
995  }
996 
997  state = LAPACKSupport::matrix;
998 }
999 
1000 
1001 template <typename number>
1002 template <typename number2>
1003 void
1005  const Vector<number2> &,
1006  const bool) const
1007 {
1008  Assert(false,
1009  ExcMessage("LAPACKFullMatrix<number>::vmult must be called with a "
1010  "matching Vector<double> vector type."));
1011 }
1012 
1013 
1014 template <typename number>
1015 template <typename number2>
1016 void
1018  const Vector<number2> &) const
1019 {
1020  Assert(false,
1021  ExcMessage("LAPACKFullMatrix<number>::vmult_add must be called with a "
1022  "matching Vector<double> vector type."));
1023 }
1024 
1025 
1026 template <typename number>
1027 template <typename number2>
1028 void
1030  const Vector<number2> &,
1031  const bool) const
1032 {
1033  Assert(false,
1034  ExcMessage("LAPACKFullMatrix<number>::Tvmult must be called with a "
1035  "matching Vector<double> vector type."));
1036 }
1037 
1038 
1039 template <typename number>
1040 template <typename number2>
1041 void
1043  const Vector<number2> &) const
1044 {
1045  Assert(false,
1046  ExcMessage("LAPACKFullMatrix<number>::Tvmult_add must be called with a "
1047  "matching Vector<double> vector type."));
1048 }
1049 
1050 
1051 template <typename number>
1052 inline std::complex<number>
1054 {
1056  Assert (wr.size() == this->n_rows(), ExcInternalError());
1057  Assert (wi.size() == this->n_rows(), ExcInternalError());
1058  AssertIndexRange (i,this->n_rows());
1059 
1060  return std::complex<number>(wr[i], wi[i]);
1061 }
1062 
1063 
1064 template <typename number>
1065 inline number
1067 {
1069  AssertIndexRange(i,wr.size());
1070 
1071  return wr[i];
1072 }
1073 
1074 
1075 
1076 DEAL_II_NAMESPACE_CLOSE
1077 
1078 #endif
LAPACKFullMatrix(const size_type size=0)
std::vector< number > work
void rank1_update(const number a, const Vector< number > &v)
void TmTmult(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)
int blas_int
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)
void Tvmult(Vector< number2 > &w, const Vector< number2 > &v, const bool adding=false) const
std::array< Number, 1 > eigenvalues(const SymmetricTensor< 2, 1, Number > &T)
LAPACKSupport::State state
void remove_row_and_column(const size_type row, const size_type col)
Threads::Mutex mutex
std::vector< types::blas_int > ipiv
size_type n() const
const TableIndices< N > & size() const
std::complex< number > eigenvalue(const size_type i) const
#define AssertIndexRange(index, range)
Definition: exceptions.h:1284
size_type m() const
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)
std::vector< number > vr
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)
number norm(const char type) const
void Tmmult(LAPACKFullMatrix< number > &C, const LAPACKFullMatrix< number > &B, const bool adding=false) 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)
void mTmult(LAPACKFullMatrix< number > &C, const LAPACKFullMatrix< number > &B, const bool adding=false) const
TableBase< 2, T >::size_type size_type
Definition: table.h:1720
std::vector< number > wr
#define Assert(cond, exc)
Definition: exceptions.h:1142
void compute_inverse_svd_with_kernel(const unsigned int kernel_size)
void copy_from(const MatrixType &)
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)
void vmult(Vector< number2 > &w, const Vector< number2 > &v, const bool adding=false) const
std::unique_ptr< LAPACKFullMatrix< number > > svd_u
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
void grow_or_shrink(const size_type size)
void scale_rows(const Vector< number > &V)
number singular_value(const size_type i) const
LAPACKFullMatrix< number > & operator*=(const number factor)
void compute_inverse_svd(const double threshold=0.)
std::make_unsigned< types::blas_int >::type size_type
number linfty_norm() const
LAPACKFullMatrix< number > & operator=(const LAPACKFullMatrix< number > &)
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)
number determinant() const
number frobenius_norm() const
void Tvmult_add(Vector< number2 > &w, const Vector< number2 > &v) const
Matrix contains singular value decomposition,.
void set_property(const LAPACKSupport::Property property)
void solve(Vector< number > &v, const bool transposed=false) const
void compute_eigenvalues(const bool right_eigenvectors=false, const bool left_eigenvectors=false)
void apply_lu_factorization(Vector< number > &v, const bool transposed) const
number l1_norm() const
number reciprocal_condition_number() const
Eigenvalue vector is filled.
DerivativeForm< 1, spacedim, dim, Number > transpose(const DerivativeForm< 1, dim, spacedim, Number > &DF)
LAPACKSupport::Property property
void vmult_add(Vector< number2 > &w, const Vector< number2 > &v) const
void mmult(LAPACKFullMatrix< number > &C, const LAPACKFullMatrix< number > &B, const bool adding=false) const
number trace() const
static ::ExceptionBase & ExcInternalError()