deal.II version GIT relicensing-6834-g5b78e6bcdf 2026-10-01 11: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
lapack_full_matrix.h
Go to the documentation of this file.
1// -----------------------------------------------------------------------------
2//
3// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception OR LGPL-2.1-or-later
4// Copyright (C) 2005 - 2025 by the deal.II authors
5//
6// This file is part of the deal.II library.
7//
8// Detailed license information governing the source code and contributions
9// can be found in LICENSE.md and CONTRIBUTING.md at the top level directory.
10//
11// -----------------------------------------------------------------------------
12
13#ifndef dealii_lapack_full_matrix_h
14#define dealii_lapack_full_matrix_h
15
16
17#include <deal.II/base/config.h>
18
19#include <deal.II/base/mutex.h>
21#include <deal.II/base/table.h>
22
25
26#include <complex>
27#include <memory>
28#include <vector>
29
31
32// forward declarations
33#ifndef DOXYGEN
34template <typename number>
35class Vector;
36template <typename number>
37class BlockVector;
38template <typename number>
39class FullMatrix;
40template <typename number>
41class SparseMatrix;
42#endif
43
55template <typename number>
56class LAPACKFullMatrix : public TransposeTable<number>
57{
58public:
62 using size_type = std::make_unsigned_t<types::blas_int>;
63
73 explicit LAPACKFullMatrix(const size_type size = 0);
74
79 LAPACKFullMatrix(const size_type rows, const size_type cols);
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
148 void
149 set(const size_type i, const size_type j, const number value);
150
155 void
156 add(const number a, const LAPACKFullMatrix<number> &B);
157
170 void
171 rank1_update(const number a, const Vector<number> &v);
172
187 void
188 apply_givens_rotation(const std::array<number, 3> &csr,
189 const size_type i,
190 const size_type k,
191 const bool left = true);
192
199 template <typename MatrixType>
200 void
201 copy_from(const MatrixType &);
202
208 void
209 reinit(const size_type size);
210
233 void
235
255 void
256 remove_row_and_column(const size_type row, const size_type col);
257
263 void
264 reinit(const size_type rows, const size_type cols);
265
269 void
271
278 m() const;
279
286 n() const;
287
301 template <typename MatrixType>
302 void
303 fill(const MatrixType &src,
304 const size_type dst_offset_i = 0,
305 const size_type dst_offset_j = 0,
306 const size_type src_offset_i = 0,
307 const size_type src_offset_j = 0,
308 const number factor = 1.,
309 const bool transpose = false);
310
311
339 template <typename number2>
340 void
342 const Vector<number2> &v,
343 const bool adding = false) const;
344
348 void
350 const Vector<number> &v,
351 const bool adding = false) const;
352
359 template <typename number2>
360 void
362
366 void
367 vmult_add(Vector<number> &w, const Vector<number> &v) const;
368
380 template <typename number2>
381 void
383 const Vector<number2> &v,
384 const bool adding = false) const;
385
389 void
391 const Vector<number> &v,
392 const bool adding = false) const;
393
400 template <typename number2>
401 void
403
407 void
408 Tvmult_add(Vector<number> &w, const Vector<number> &v) const;
409
410
425 void
428 const bool adding = false) const;
429
434 void
437 const bool adding = false) const;
438
453 void
456 const bool adding = false) const;
457
462 void
465 const bool adding = false) const;
466
483 void
486 const Vector<number> &V,
487 const bool adding = false) const;
488
503 void
506 const bool adding = false) const;
507
512 void
515 const bool adding = false) const;
516
532 void
535 const bool adding = false) const;
536
541 void
544 const bool adding = false) const;
545
555 void
557
563 void
564 scale_rows(const Vector<number> &V);
565
569 void
571
578 void
580
600 number
601 reciprocal_condition_number(const number l1_norm) const;
602
610 number
612
618 number
619 determinant() const;
620
624 number
625 l1_norm() const;
626
630 number
631 linfty_norm() const;
632
636 number
637 frobenius_norm() const;
638
643 number
644 trace() const;
645
651 void
652 invert();
653
662 void
663 solve(Vector<number> &v, const bool transposed = false) const;
664
669 void
670 solve(LAPACKFullMatrix<number> &B, const bool transposed = false) const;
671
690 void
691 compute_eigenvalues(const bool right_eigenvectors = false,
692 const bool left_eigenvectors = false);
693
713 void
714 compute_eigenvalues_symmetric(const number lower_bound,
715 const number upper_bound,
716 const number abs_accuracy,
719
746 void
749 const number lower_bound,
750 const number upper_bound,
751 const number abs_accuracy,
753 std::vector<Vector<number>> &eigenvectors,
754 const types::blas_int itype = 1);
755
771 void
774 std::vector<Vector<number>> &eigenvectors,
775 const types::blas_int itype = 1);
776
796 void
797 compute_svd();
798
818 void
819 compute_inverse_svd(const double threshold = 0.);
820
825 void
826 compute_inverse_svd_with_kernel(const unsigned int kernel_size);
827
834 std::complex<typename numbers::NumberTraits<number>::real_type>
835 eigenvalue(const size_type i) const;
836
848
855 get_left_eigenvectors() const;
856
861 number
862 singular_value(const size_type i) const;
863
868 inline const LAPACKFullMatrix<number> &
869 get_svd_u() const;
870
875 inline const LAPACKFullMatrix<number> &
876 get_svd_vt() const;
877
908 void
909 print_formatted(std::ostream &out,
910 const unsigned int precision = 3,
911 const bool scientific = true,
912 const unsigned int width = 0,
913 const char *zero_string = " ",
914 const double denominator = 1.,
915 const double threshold = 0.,
916 const char *separator = " ") const;
917
922 get_state() const;
923
924private:
928 number
929 norm(const char type) const;
930
936
942
946 mutable std::vector<number> work;
947
951 mutable std::vector<types::blas_int> iwork;
952
959 std::vector<types::blas_int> ipiv;
960
964 std::vector<number> inv_work;
965
970 std::vector<typename numbers::NumberTraits<number>::real_type> wr;
971
976 std::vector<number> wi;
977
981 std::vector<number> vl;
982
986 std::vector<number> vr;
987
992 std::unique_ptr<LAPACKFullMatrix<number>> svd_u;
993
998 std::unique_ptr<LAPACKFullMatrix<number>> svd_vt;
999
1004};
1005
1006
1007
1013template <typename number>
1035
1036/*---------------------- Inline functions -----------------------------------*/
1037
1038template <typename number>
1039inline void
1041 const size_type j,
1042 const number value)
1043{
1044 (*this)(i, j) = value;
1045}
1046
1047
1048
1049template <typename number>
1052{
1053 return static_cast<size_type>(this->n_rows());
1054}
1055
1056
1057
1058template <typename number>
1061{
1062 return static_cast<size_type>(this->n_cols());
1063}
1064
1065
1066
1067template <typename number>
1068template <typename MatrixType>
1069inline void
1071{
1072 this->reinit(M.m(), M.n());
1073
1074 // loop over the elements of the argument matrix row by row, as suggested
1075 // in the documentation of the sparse matrix iterator class, and
1076 // copy them into the current object
1077 for (size_type row = 0; row < M.m(); ++row)
1078 {
1079 const typename MatrixType::const_iterator end_row = M.end(row);
1080 for (typename MatrixType::const_iterator entry = M.begin(row);
1081 entry != end_row;
1082 ++entry)
1083 this->el(row, entry->column()) = entry->value();
1084 }
1085
1086 state = LAPACKSupport::matrix;
1087}
1088
1089
1090
1091template <typename number>
1092template <typename MatrixType>
1093inline void
1095 const size_type dst_offset_i,
1096 const size_type dst_offset_j,
1097 const size_type src_offset_i,
1098 const size_type src_offset_j,
1099 const number factor,
1100 const bool transpose)
1101{
1102 // loop over the elements of the argument matrix row by row, as suggested
1103 // in the documentation of the sparse matrix iterator class
1104 for (size_type row = src_offset_i; row < M.m(); ++row)
1105 {
1106 const typename MatrixType::const_iterator end_row = M.end(row);
1107 for (typename MatrixType::const_iterator entry = M.begin(row);
1108 entry != end_row;
1109 ++entry)
1110 {
1111 const size_type i = transpose ? entry->column() : row;
1112 const size_type j = transpose ? row : entry->column();
1113
1114 const size_type dst_i = dst_offset_i + i - src_offset_i;
1115 const size_type dst_j = dst_offset_j + j - src_offset_j;
1116 if (dst_i < this->n_rows() && dst_j < this->n_cols())
1117 (*this)(dst_i, dst_j) = factor * entry->value();
1118 }
1119 }
1120
1121 state = LAPACKSupport::matrix;
1122}
1123
1124
1125
1126template <typename number>
1127template <typename number2>
1128void
1130 const Vector<number2> &,
1131 const bool) const
1132{
1133 Assert(false,
1134 ExcMessage("LAPACKFullMatrix<number>::vmult must be called with a "
1135 "matching Vector<double> vector type."));
1136}
1137
1138
1139
1140template <typename number>
1141template <typename number2>
1142void
1144 const Vector<number2> &) const
1145{
1146 Assert(false,
1147 ExcMessage("LAPACKFullMatrix<number>::vmult_add must be called with a "
1148 "matching Vector<double> vector type."));
1149}
1150
1151
1152
1153template <typename number>
1154template <typename number2>
1155void
1157 const Vector<number2> &,
1158 const bool) const
1159{
1160 Assert(false,
1161 ExcMessage("LAPACKFullMatrix<number>::Tvmult must be called with a "
1162 "matching Vector<double> vector type."));
1163}
1164
1165
1166
1167template <typename number>
1168template <typename number2>
1169void
1171 const Vector<number2> &) const
1172{
1173 Assert(false,
1174 ExcMessage("LAPACKFullMatrix<number>::Tvmult_add must be called "
1175 "with a matching Vector<double> vector type."));
1176}
1177
1178
1179
1180namespace internal
1181{
1182 namespace LAPACKFullMatrixImplementation
1183 {
1184 template <typename RealNumber>
1185 std::complex<RealNumber>
1186 pack_complex(const RealNumber &real_part, const RealNumber &imaginary_part)
1187 {
1188 return std::complex<RealNumber>(real_part, imaginary_part);
1189 }
1190
1191 // The eigenvalues in LAPACKFullMatrix with complex-valued matrices are
1192 // contained in the 'wi' array, ignoring the 'wr' array.
1193 template <typename Number>
1194 std::complex<Number>
1195 pack_complex(const Number &, const std::complex<Number> &complex_number)
1196 {
1197 return complex_number;
1198 }
1199 } // namespace LAPACKFullMatrixImplementation
1200} // namespace internal
1201
1202
1203
1204template <typename number>
1205inline std::complex<typename numbers::NumberTraits<number>::real_type>
1207{
1209 Assert(wr.size() == this->n_rows(), ExcInternalError());
1210 Assert(wi.size() == this->n_rows(), ExcInternalError());
1211 AssertIndexRange(i, this->n_rows());
1212
1214}
1215
1216
1217
1218template <typename number>
1219inline number
1221{
1224 AssertIndexRange(i, wr.size());
1225
1226 return wr[i];
1227}
1228
1229
1230
1231template <typename number>
1232inline const LAPACKFullMatrix<number> &
1234{
1237
1238 return *svd_u;
1239}
1240
1241
1242
1243template <typename number>
1244inline const LAPACKFullMatrix<number> &
1246{
1249
1250 return *svd_vt;
1251}
1252
1253
1254
1256
1257#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:38
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:39
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)