deal.II version GIT relicensing-2287-g6548a49e0a 2024-12-20 18:30:00+00:00
\(\newcommand{\dealvcentcolon}{\mathrel{\mathop{:}}}\) \(\newcommand{\dealcoloneq}{\dealvcentcolon\mathrel{\mkern-1.2mu}=}\) \(\newcommand{\jump}[1]{\left[\!\left[ #1 \right]\!\right]}\) \(\newcommand{\average}[1]{\left\{\!\left\{ #1 \right\}\!\right\}}\)
Loading...
Searching...
No Matches
lapack_full_matrix.h
Go to the documentation of this file.
1// ------------------------------------------------------------------------
2//
3// SPDX-License-Identifier: LGPL-2.1-or-later
4// Copyright (C) 2005 - 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_lapack_full_matrix_h
16#define dealii_lapack_full_matrix_h
17
18
19#include <deal.II/base/config.h>
20
21#include <deal.II/base/mutex.h>
23#include <deal.II/base/table.h>
24
27
28#include <complex>
29#include <memory>
30#include <vector>
31
33
34// forward declarations
35#ifndef DOXYGEN
36template <typename number>
37class Vector;
38template <typename number>
39class BlockVector;
40template <typename number>
41class FullMatrix;
42template <typename number>
43class SparseMatrix;
44#endif
45
57template <typename number>
58class LAPACKFullMatrix : public TransposeTable<number>
59{
60public:
64 using size_type = std::make_unsigned_t<types::blas_int>;
65
75 explicit LAPACKFullMatrix(const size_type size = 0);
76
81 LAPACKFullMatrix(const size_type rows, const size_type cols);
82
93
99
106 template <typename number2>
109
116 template <typename number2>
119
126 operator=(const number d);
127
132 operator*=(const number factor);
133
138 operator/=(const number factor);
139
150 void
151 set(const size_type i, const size_type j, const number value);
152
157 void
158 add(const number a, const LAPACKFullMatrix<number> &B);
159
172 void
173 rank1_update(const number a, const Vector<number> &v);
174
189 void
190 apply_givens_rotation(const std::array<number, 3> &csr,
191 const size_type i,
192 const size_type k,
193 const bool left = true);
194
201 template <typename MatrixType>
202 void
203 copy_from(const MatrixType &);
204
210 void
211 reinit(const size_type size);
212
235 void
237
257 void
258 remove_row_and_column(const size_type row, const size_type col);
259
265 void
266 reinit(const size_type rows, const size_type cols);
267
271 void
273
280 m() const;
281
288 n() const;
289
303 template <typename MatrixType>
304 void
305 fill(const MatrixType &src,
306 const size_type dst_offset_i = 0,
307 const size_type dst_offset_j = 0,
308 const size_type src_offset_i = 0,
309 const size_type src_offset_j = 0,
310 const number factor = 1.,
311 const bool transpose = false);
312
313
341 template <typename number2>
342 void
344 const Vector<number2> &v,
345 const bool adding = false) const;
346
350 void
352 const Vector<number> &v,
353 const bool adding = false) const;
354
361 template <typename number2>
362 void
364
368 void
369 vmult_add(Vector<number> &w, const Vector<number> &v) const;
370
382 template <typename number2>
383 void
385 const Vector<number2> &v,
386 const bool adding = false) const;
387
391 void
393 const Vector<number> &v,
394 const bool adding = false) const;
395
402 template <typename number2>
403 void
405
409 void
410 Tvmult_add(Vector<number> &w, const Vector<number> &v) const;
411
412
427 void
430 const bool adding = false) const;
431
436 void
439 const bool adding = false) const;
440
455 void
458 const bool adding = false) const;
459
464 void
467 const bool adding = false) const;
468
485 void
488 const Vector<number> &V,
489 const bool adding = false) const;
490
505 void
508 const bool adding = false) const;
509
514 void
517 const bool adding = false) const;
518
534 void
537 const bool adding = false) const;
538
543 void
546 const bool adding = false) const;
547
557 void
559
565 void
566 scale_rows(const Vector<number> &V);
567
571 void
573
580 void
582
602 number
603 reciprocal_condition_number(const number l1_norm) const;
604
612 number
614
620 number
621 determinant() const;
622
626 number
627 l1_norm() const;
628
632 number
633 linfty_norm() const;
634
638 number
639 frobenius_norm() const;
640
645 number
646 trace() const;
647
653 void
654 invert();
655
664 void
665 solve(Vector<number> &v, const bool transposed = false) const;
666
671 void
672 solve(LAPACKFullMatrix<number> &B, const bool transposed = false) 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
798 void
799 compute_svd();
800
820 void
821 compute_inverse_svd(const double threshold = 0.);
822
827 void
828 compute_inverse_svd_with_kernel(const unsigned int kernel_size);
829
836 std::complex<typename numbers::NumberTraits<number>::real_type>
837 eigenvalue(const size_type i) const;
838
850
857 get_left_eigenvectors() const;
858
863 number
864 singular_value(const size_type i) const;
865
870 inline const LAPACKFullMatrix<number> &
871 get_svd_u() const;
872
877 inline const LAPACKFullMatrix<number> &
878 get_svd_vt() const;
879
910 void
911 print_formatted(std::ostream &out,
912 const unsigned int precision = 3,
913 const bool scientific = true,
914 const unsigned int width = 0,
915 const char *zero_string = " ",
916 const double denominator = 1.,
917 const double threshold = 0.,
918 const char *separator = " ") const;
919
924 get_state() const;
925
926private:
930 number
931 norm(const char type) const;
932
938
944
948 mutable std::vector<number> work;
949
953 mutable std::vector<types::blas_int> iwork;
954
961 std::vector<types::blas_int> ipiv;
962
966 std::vector<number> inv_work;
967
972 std::vector<typename numbers::NumberTraits<number>::real_type> wr;
973
978 std::vector<number> wi;
979
983 std::vector<number> vl;
984
988 std::vector<number> vr;
989
994 std::unique_ptr<LAPACKFullMatrix<number>> svd_u;
995
1000 std::unique_ptr<LAPACKFullMatrix<number>> svd_vt;
1001
1006};
1007
1008
1009
1015template <typename number>
1037
1038/*---------------------- Inline functions -----------------------------------*/
1039
1040template <typename number>
1041inline void
1043 const size_type j,
1044 const number value)
1045{
1046 (*this)(i, j) = value;
1047}
1048
1049
1050
1051template <typename number>
1054{
1055 return static_cast<size_type>(this->n_rows());
1056}
1057
1058
1059
1060template <typename number>
1063{
1064 return static_cast<size_type>(this->n_cols());
1065}
1066
1067
1068
1069template <typename number>
1070template <typename MatrixType>
1071inline void
1073{
1074 this->reinit(M.m(), M.n());
1075
1076 // loop over the elements of the argument matrix row by row, as suggested
1077 // in the documentation of the sparse matrix iterator class, and
1078 // copy them into the current object
1079 for (size_type row = 0; row < M.m(); ++row)
1080 {
1081 const typename MatrixType::const_iterator end_row = M.end(row);
1082 for (typename MatrixType::const_iterator entry = M.begin(row);
1083 entry != end_row;
1084 ++entry)
1085 this->el(row, entry->column()) = entry->value();
1086 }
1087
1088 state = LAPACKSupport::matrix;
1089}
1090
1091
1092
1093template <typename number>
1094template <typename MatrixType>
1095inline void
1097 const size_type dst_offset_i,
1098 const size_type dst_offset_j,
1099 const size_type src_offset_i,
1100 const size_type src_offset_j,
1101 const number factor,
1102 const bool transpose)
1103{
1104 // loop over the elements of the argument matrix row by row, as suggested
1105 // in the documentation of the sparse matrix iterator class
1106 for (size_type row = src_offset_i; row < M.m(); ++row)
1107 {
1108 const typename MatrixType::const_iterator end_row = M.end(row);
1109 for (typename MatrixType::const_iterator entry = M.begin(row);
1110 entry != end_row;
1111 ++entry)
1112 {
1113 const size_type i = transpose ? entry->column() : row;
1114 const size_type j = transpose ? row : entry->column();
1115
1116 const size_type dst_i = dst_offset_i + i - src_offset_i;
1117 const size_type dst_j = dst_offset_j + j - src_offset_j;
1118 if (dst_i < this->n_rows() && dst_j < this->n_cols())
1119 (*this)(dst_i, dst_j) = factor * entry->value();
1120 }
1121 }
1122
1123 state = LAPACKSupport::matrix;
1124}
1125
1126
1127
1128template <typename number>
1129template <typename number2>
1130void
1132 const Vector<number2> &,
1133 const bool) const
1134{
1135 Assert(false,
1136 ExcMessage("LAPACKFullMatrix<number>::vmult must be called with a "
1137 "matching Vector<double> vector type."));
1138}
1139
1140
1141
1142template <typename number>
1143template <typename number2>
1144void
1146 const Vector<number2> &) const
1147{
1148 Assert(false,
1149 ExcMessage("LAPACKFullMatrix<number>::vmult_add must be called with a "
1150 "matching Vector<double> vector type."));
1151}
1152
1153
1154
1155template <typename number>
1156template <typename number2>
1157void
1159 const Vector<number2> &,
1160 const bool) const
1161{
1162 Assert(false,
1163 ExcMessage("LAPACKFullMatrix<number>::Tvmult must be called with a "
1164 "matching Vector<double> vector type."));
1165}
1166
1167
1168
1169template <typename number>
1170template <typename number2>
1171void
1173 const Vector<number2> &) const
1174{
1175 Assert(false,
1176 ExcMessage("LAPACKFullMatrix<number>::Tvmult_add must be called "
1177 "with a matching Vector<double> vector type."));
1178}
1179
1180
1181
1182namespace internal
1183{
1184 namespace LAPACKFullMatrixImplementation
1185 {
1186 template <typename RealNumber>
1187 std::complex<RealNumber>
1188 pack_complex(const RealNumber &real_part, const RealNumber &imaginary_part)
1189 {
1190 return std::complex<RealNumber>(real_part, imaginary_part);
1191 }
1192
1193 // The eigenvalues in LAPACKFullMatrix with complex-valued matrices are
1194 // contained in the 'wi' array, ignoring the 'wr' array.
1195 template <typename Number>
1196 std::complex<Number>
1197 pack_complex(const Number &, const std::complex<Number> &complex_number)
1198 {
1199 return complex_number;
1200 }
1201 } // namespace LAPACKFullMatrixImplementation
1202} // namespace internal
1203
1204
1205
1206template <typename number>
1207inline std::complex<typename numbers::NumberTraits<number>::real_type>
1209{
1211 Assert(wr.size() == this->n_rows(), ExcInternalError());
1212 Assert(wi.size() == this->n_rows(), ExcInternalError());
1213 AssertIndexRange(i, this->n_rows());
1214
1216}
1217
1218
1219
1220template <typename number>
1221inline number
1223{
1226 AssertIndexRange(i, wr.size());
1227
1228 return wr[i];
1229}
1230
1231
1232
1233template <typename number>
1234inline const LAPACKFullMatrix<number> &
1236{
1239
1240 return *svd_u;
1241}
1242
1243
1244
1245template <typename number>
1246inline const LAPACKFullMatrix<number> &
1248{
1251
1252 return *svd_vt;
1253}
1254
1255
1256
1258
1259#endif
LAPACKFullMatrix< number > & operator*=(const number factor)
number reciprocal_condition_number() const
void Tmmult(LAPACKFullMatrix< number > &C, const LAPACKFullMatrix< number > &B, const bool adding=false) const
void copy_from(const MatrixType &)
void scale_rows(const Vector< number > &V)
FullMatrix< std::complex< typename numbers::NumberTraits< number >::real_type > > get_right_eigenvectors() const
void add(const number a, const LAPACKFullMatrix< number > &B)
void Tvmult(Vector< number2 > &w, const Vector< number2 > &v, const bool adding=false) const
void transpose(LAPACKFullMatrix< number > &B) const
void mTmult(LAPACKFullMatrix< number > &C, const LAPACKFullMatrix< number > &B, const bool adding=false) const
std::vector< typename numbers::NumberTraits< number >::real_type > wr
LAPACKSupport::State get_state() const
void compute_eigenvalues_symmetric(const number lower_bound, const number upper_bound, const number abs_accuracy, Vector< number > &eigenvalues, FullMatrix< number > &eigenvectors)
const LAPACKFullMatrix< number > & get_svd_u() const
void vmult(Vector< number2 > &w, const Vector< number2 > &v, const bool adding=false) const
void reinit(const size_type size)
LAPACKFullMatrix< number > & operator=(const LAPACKFullMatrix< number > &)
FullMatrix< std::complex< typename numbers::NumberTraits< number >::real_type > > get_left_eigenvectors() const
std::unique_ptr< LAPACKFullMatrix< number > > svd_vt
std::vector< number > work
void grow_or_shrink(const size_type size)
void apply_givens_rotation(const std::array< number, 3 > &csr, const size_type i, const size_type k, const bool left=true)
void set_property(const LAPACKSupport::Property property)
std::complex< typename numbers::NumberTraits< number >::real_type > eigenvalue(const size_type i) const
number norm(const char type) const
void solve(Vector< number > &v, const bool transposed=false) const
void compute_eigenvalues(const bool right_eigenvectors=false, const bool left_eigenvectors=false)
LAPACKSupport::State state
std::make_unsigned_t< types::blas_int > size_type
std::vector< number > inv_work
number frobenius_norm() const
LAPACKSupport::Property property
std::vector< number > wi
size_type m() const
number singular_value(const size_type i) const
void set(const size_type i, const size_type j, const number value)
void compute_inverse_svd(const double threshold=0.)
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 vmult_add(Vector< number2 > &w, const Vector< number2 > &v) const
size_type n() const
number linfty_norm() const
void TmTmult(LAPACKFullMatrix< number > &C, const LAPACKFullMatrix< number > &B, const bool adding=false) const
const LAPACKFullMatrix< number > & get_svd_vt() const
std::unique_ptr< LAPACKFullMatrix< number > > svd_u
std::vector< number > vr
void compute_inverse_svd_with_kernel(const unsigned int kernel_size)
void Tvmult_add(Vector< number2 > &w, const Vector< number2 > &v) const
std::vector< types::blas_int > iwork
void rank1_update(const number a, const Vector< number > &v)
std::vector< types::blas_int > ipiv
void remove_row_and_column(const size_type row, const size_type col)
LAPACKFullMatrix< number > & operator/=(const number factor)
number determinant() const
std::vector< number > vl
void mmult(LAPACKFullMatrix< number > &C, const LAPACKFullMatrix< number > &B, const bool adding=false) 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 char *separator=" ") const
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)
void vmult(Vector< number > &, const Vector< number > &) const
void initialize(const LAPACKFullMatrix< number > &)
void Tvmult(Vector< number > &, const Vector< number > &) const
ObserverPointer< VectorMemory< Vector< number > >, PreconditionLU< number > > mem
ObserverPointer< const LAPACKFullMatrix< number >, PreconditionLU< number > > matrix
const TableIndices< N > & size() const
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:498
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:499
DerivativeForm< 1, spacedim, dim, Number > transpose(const DerivativeForm< 1, dim, spacedim, Number > &DF)
#define Assert(cond, exc)
#define AssertIndexRange(index, range)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcInvalidState()
static ::ExceptionBase & ExcMessage(std::string arg1)
static ::ExceptionBase & ExcState(State arg1)
@ matrix
Contents is actually a matrix.
@ svd
Matrix contains singular value decomposition,.
@ inverse_svd
Matrix is the inverse of a singular value decomposition.
@ eigenvalues
Eigenvalue vector is filled.
std::complex< RealNumber > pack_complex(const RealNumber &real_part, const RealNumber &imaginary_part)
std::array< Number, 1 > eigenvalues(const SymmetricTensor< 2, 1, Number > &T)
std::array< std::pair< Number, Tensor< 1, dim, Number > >, dim > eigenvectors(const SymmetricTensor< 2, dim, Number > &T, const SymmetricTensorEigenvectorMethod method=SymmetricTensorEigenvectorMethod::ql_implicit_shifts)