libMesh
Loading...
Searching...
No Matches
dense_matrix.h
Go to the documentation of this file.
1// The libMesh Finite Element Library.
2// Copyright (C) 2002-2026 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
3
4// This library is free software; you can redistribute it and/or
5// modify it under the terms of the GNU Lesser General Public
6// License as published by the Free Software Foundation; either
7// version 2.1 of the License, or (at your option) any later version.
8
9// This library is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12// Lesser General Public License for more details.
13
14// You should have received a copy of the GNU Lesser General Public
15// License along with this library; if not, write to the Free Software
16// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
18
19
20#ifndef LIBMESH_DENSE_MATRIX_H
21#define LIBMESH_DENSE_MATRIX_H
22
23// Local Includes
24#include "libmesh/libmesh_common.h"
25#include "libmesh/dense_matrix_base.h"
26#include "libmesh/int_range.h"
27
28// For the definition of PetscBLASInt.
29#if (LIBMESH_HAVE_PETSC)
30# include "libmesh/petsc_macro.h"
31# ifdef I
32# define LIBMESH_SAW_I
33# endif
34
35#include "libmesh/ignore_warnings.h"
36# include <petscsys.h>
37#include "libmesh/restore_warnings.h"
38
39# ifndef LIBMESH_SAW_I
40# undef I // Avoid complex.h contamination
41# endif
42#endif
43
44// C++ includes
45#include <vector>
46#include <algorithm>
47#include <initializer_list>
48
49#ifdef LIBMESH_HAVE_METAPHYSICL
50#include "metaphysicl/dualnumber_decl.h"
51#include "metaphysicl/raw_type.h"
52#endif
53
54namespace libMesh
55{
56
57// Forward Declarations
58template <typename T> class DenseVector;
59
70template<typename T>
72{
73public:
74
78 DenseMatrix(const unsigned int new_m=0,
79 const unsigned int new_n=0);
80
86 template <typename T2>
87 DenseMatrix(unsigned int nrow,
88 unsigned int ncol,
89 std::initializer_list<T2> init_list);
90
95 DenseMatrix (DenseMatrix &&) = default;
96 DenseMatrix (const DenseMatrix &) = default;
97 DenseMatrix & operator= (const DenseMatrix &) = default;
99 virtual ~DenseMatrix() = default;
100
106 virtual void zero() override final;
107
111 DenseMatrix sub_matrix(unsigned int row_id, unsigned int row_size,
112 unsigned int col_id, unsigned int col_size) const;
113
117 T operator() (const unsigned int i,
118 const unsigned int j) const;
119
123 T & operator() (const unsigned int i,
124 const unsigned int j);
125
126 virtual T el(const unsigned int i,
127 const unsigned int j) const override final
128 { return (*this)(i,j); }
129
130 virtual T & el(const unsigned int i,
131 const unsigned int j) override final
132 { return (*this)(i,j); }
133
134 virtual void left_multiply (const DenseMatrixBase<T> & M2) override final;
135
139 template <typename T2>
140 void left_multiply (const DenseMatrixBase<T2> & M2);
141
142 virtual void right_multiply (const DenseMatrixBase<T> & M2) override final;
143
147 template <typename T2>
148 void right_multiply (const DenseMatrixBase<T2> & M2);
149
154 void vector_mult (DenseVector<T> & dest,
155 const DenseVector<T> & arg) const;
156
162 template <typename T2>
164 const DenseVector<T2> & arg) const;
165
171 const DenseVector<T> & arg) const;
172
178 template <typename T2>
180 const DenseVector<T2> & arg) const;
181
186 void vector_mult_add (DenseVector<T> & dest,
187 const T factor,
188 const DenseVector<T> & arg) const;
189
195 template <typename T2, typename T3>
196 void vector_mult_add (DenseVector<typename CompareTypes<T, typename CompareTypes<T2,T3>::supertype>::supertype> & dest,
197 const T2 factor,
198 const DenseVector<T3> & arg) const;
199
203 void get_principal_submatrix (unsigned int sub_m, unsigned int sub_n, DenseMatrix<T> & dest) const;
204
208 void get_principal_submatrix (unsigned int sub_m, DenseMatrix<T> & dest) const;
209
227 void outer_product(const DenseVector<T> & a, const DenseVector<T> & b);
228
238 template <typename T2>
240
244 void swap(DenseMatrix<T> & other_matrix);
245
253 void resize(const unsigned int new_m,
254 const unsigned int new_n);
255
259 void scale (const T factor);
260
264 void scale_column (const unsigned int col, const T factor);
265
271 DenseMatrix<T> & operator *= (const T factor);
272
278 template<typename T2, typename T3>
279 typename std::enable_if<
280 ScalarTraits<T2>::value, void >::type add (const T2 factor,
281 const DenseMatrix<T3> & mat);
282
286 bool operator== (const DenseMatrix<T> & mat) const;
287
291 bool operator!= (const DenseMatrix<T> & mat) const;
292
299
306
311 auto min () const -> decltype(libmesh_real(T(0)));
312
317 auto max () const -> decltype(libmesh_real(T(0)));
318
327 auto l1_norm () const;
328
337 auto linfty_norm () const;
338
342 void left_multiply_transpose (const DenseMatrix<T> & A);
343
348 template <typename T2>
349 void left_multiply_transpose (const DenseMatrix<T2> & A);
350
351
355 void right_multiply_transpose (const DenseMatrix<T> & A);
356
361 template <typename T2>
362 void right_multiply_transpose (const DenseMatrix<T2> & A);
363
367 T transpose (const unsigned int i,
368 const unsigned int j) const;
369
373 void get_transpose(DenseMatrix<T> & dest) const;
374
382 std::vector<T> & get_values() { return _val; }
383
387 const std::vector<T> & get_values() const { return _val; }
388
395 void condense(const unsigned int i,
396 const unsigned int j,
397 const T val,
398 DenseVector<T> & rhs)
399 { DenseMatrixBase<T>::condense (i, j, val, rhs); }
400
415 void lu_solve (const DenseVector<T> & b,
416 DenseVector<T> & x);
417
439 template <typename T2>
440 void cholesky_solve(const DenseVector<T2> & b,
441 DenseVector<T2> & x);
442
451 void svd(DenseVector<Real> & sigma);
452
464 void svd(DenseVector<Real> & sigma,
467
485 void svd_solve(const DenseVector<T> & rhs,
486 DenseVector<T> & x,
487 Real rcond=std::numeric_limits<Real>::epsilon()) const;
488
496 void evd(DenseVector<T> & lambda_real,
497 DenseVector<T> & lambda_imag);
498
517 void evd_left(DenseVector<T> & lambda_real,
518 DenseVector<T> & lambda_imag,
519 DenseMatrix<T> & VL);
520
539 void evd_right(DenseVector<T> & lambda_real,
540 DenseVector<T> & lambda_imag,
541 DenseMatrix<T> & VR);
542
553 void evd_left_and_right(DenseVector<T> & lambda_real,
554 DenseVector<T> & lambda_imag,
555 DenseMatrix<T> & VL,
556 DenseMatrix<T> & VR);
557
565 T det();
566
578 // void inverse();
579
586
591 {
592 static const bool value = false;
593 };
594
595private:
596
600 std::vector<T> _val;
601
607 void _lu_decompose ();
608
615 DenseVector<T> & x) const;
616
624 void _cholesky_decompose();
625
633 template <typename T2>
635 DenseVector<T2> & x) const;
636
645
651
662
670 void _multiply_blas(const DenseMatrixBase<T> & other,
672
683
689 void _svd_lapack(DenseVector<Real> & sigma);
690
696 void _svd_lapack(DenseVector<Real> & sigma,
699
703 void _svd_solve_lapack(const DenseVector<T> & rhs,
704 DenseVector<T> & x,
705 Real rcond) const;
706
711 void _svd_helper (char JOBU,
712 char JOBVT,
713 std::vector<Real> & sigma_val,
714 std::vector<Number> & U_val,
715 std::vector<Number> & VT_val);
716
725 void _evd_lapack(DenseVector<T> & lambda_real,
726 DenseVector<T> & lambda_imag,
727 DenseMatrix<T> * VL = nullptr,
728 DenseMatrix<T> * VR = nullptr);
729
735#if (LIBMESH_HAVE_PETSC && LIBMESH_USE_REAL_NUMBERS)
736 typedef PetscBLASInt pivot_index_t;
737#else
738 typedef int pivot_index_t;
739#endif
740 std::vector<pivot_index_t> _pivots;
741
752 DenseVector<T> & x);
753
766 void _matvec_blas(T alpha, T beta,
767 DenseVector<T> & dest,
768 const DenseVector<T> & arg,
769 bool trans=false) const;
770
775 template <typename T2>
777
782 template <typename T2>
784};
785
786
787
788
789
790// ------------------------------------------------------------
794namespace DenseMatrices
795{
796
802
811
812}
813
814
815
816using namespace DenseMatrices;
817
818// The PETSc Lapack wrappers are only for PetscScalar, therefore we
819// can't e.g. get a Lapack version of DenseMatrix<Real>::lu_solve()
820// when libmesh/PETSc are compiled with complex numbers.
821#if defined(LIBMESH_HAVE_PETSC) && \
822 defined(LIBMESH_USE_REAL_NUMBERS) && \
823 defined(LIBMESH_DEFAULT_DOUBLE_PRECISION)
824template <>
825struct DenseMatrix<double>::UseBlasLapack
826{
827 static const bool value = true;
828};
829#endif
830
831
832// ------------------------------------------------------------
833// Dense Matrix member functions
834template<typename T>
835inline
836DenseMatrix<T>::DenseMatrix(const unsigned int new_m,
837 const unsigned int new_n) :
838 DenseMatrixBase<T>(new_m,new_n),
839 use_blas_lapack(DenseMatrix<T>::UseBlasLapack::value),
840 _val(),
841 _decomposition_type(NONE)
842{
843 this->resize(new_m,new_n);
844}
845
846template <typename T>
847template <typename T2>
849 unsigned int ncol,
850 std::initializer_list<T2> init_list) :
851 DenseMatrixBase<T>(nrow, ncol),
852 use_blas_lapack(DenseMatrix<T>::UseBlasLapack::value),
853 _val(init_list.begin(), init_list.end()),
854 _decomposition_type(NONE)
855{
856 // Make sure the user passed us an amount of data which is
857 // consistent with the size of the matrix.
858 libmesh_assert_equal_to(nrow * ncol, init_list.size());
859}
860
861
862
863template<typename T>
864inline
866{
867 std::swap(this->_m, other_matrix._m);
868 std::swap(this->_n, other_matrix._n);
869 _val.swap(other_matrix._val);
870 DecompositionType _temp = _decomposition_type;
871 _decomposition_type = other_matrix._decomposition_type;
872 other_matrix._decomposition_type = _temp;
873}
874
875
876template <typename T>
877template <typename T2>
878inline
881{
882 unsigned int mat_m = mat.m(), mat_n = mat.n();
883 this->resize(mat_m, mat_n);
884 for (unsigned int i=0; i<mat_m; i++)
885 for (unsigned int j=0; j<mat_n; j++)
886 (*this)(i,j) = mat(i,j);
887
888 return *this;
889}
890
891
892
893template<typename T>
894inline
895void DenseMatrix<T>::resize(const unsigned int new_m,
896 const unsigned int new_n)
897{
898 _val.resize(new_m*new_n);
899
900 this->_m = new_m;
901 this->_n = new_n;
902
903 // zero and set decomposition_type to NONE
904 this->zero();
905}
906
907
908
909template<typename T>
910inline
912{
913 _decomposition_type = NONE;
914
915 std::fill (_val.begin(), _val.end(), static_cast<T>(0));
916}
917
918
919
920template<typename T>
921inline
922DenseMatrix<T> DenseMatrix<T>::sub_matrix(unsigned int row_id, unsigned int row_size,
923 unsigned int col_id, unsigned int col_size) const
924{
925 libmesh_assert_less (row_id + row_size - 1, this->_m);
926 libmesh_assert_less (col_id + col_size - 1, this->_n);
927
928 DenseMatrix<T> sub;
929 sub._m = row_size;
930 sub._n = col_size;
931 sub._val.resize(row_size * col_size);
932
933 unsigned int end_col = this->_n - col_size - col_id;
934 unsigned int p = row_id * this->_n;
935 unsigned int q = 0;
936 for (unsigned int i=0; i<row_size; i++)
937 {
938 // skip the beginning columns
939 p += col_id;
940 for (unsigned int j=0; j<col_size; j++)
941 sub._val[q++] = _val[p++];
942 // skip the rest columns
943 p += end_col;
944 }
945
946 return sub;
947}
948
949
950
951template<typename T>
952inline
953T DenseMatrix<T>::operator () (const unsigned int i,
954 const unsigned int j) const
955{
956 libmesh_assert_less (i*j, _val.size());
957 libmesh_assert_less (i, this->_m);
958 libmesh_assert_less (j, this->_n);
959
960
961 // return _val[(i) + (this->_m)*(j)]; // col-major
962 return _val[(i)*(this->_n) + (j)]; // row-major
963}
964
965
966
967template<typename T>
968inline
969T & DenseMatrix<T>::operator () (const unsigned int i,
970 const unsigned int j)
971{
972 libmesh_assert_less (i*j, _val.size());
973 libmesh_assert_less (i, this->_m);
974 libmesh_assert_less (j, this->_n);
975
976 //return _val[(i) + (this->_m)*(j)]; // col-major
977 return _val[(i)*(this->_n) + (j)]; // row-major
978}
979
980
981
982
983
984template<typename T>
985inline
986void DenseMatrix<T>::scale (const T factor)
987{
988 for (auto & v : _val)
989 v *= factor;
990}
991
992
993template<typename T>
994inline
995void DenseMatrix<T>::scale_column (const unsigned int col, const T factor)
996{
997 for (auto i : make_range(this->m()))
998 (*this)(i, col) *= factor;
999}
1000
1001
1002
1003template<typename T>
1004inline
1006{
1007 this->scale(factor);
1008 return *this;
1009}
1010
1011
1012
1013template<typename T>
1014template<typename T2, typename T3>
1015inline
1016typename std::enable_if<
1017 ScalarTraits<T2>::value, void >::type
1018DenseMatrix<T>::add (const T2 factor,
1019 const DenseMatrix<T3> & mat)
1020{
1021 libmesh_assert_equal_to (this->m(), mat.m());
1022 libmesh_assert_equal_to (this->n(), mat.n());
1023
1024 for (auto i : make_range(this->m()))
1025 for (auto j : make_range(this->n()))
1026 (*this)(i,j) += factor * mat(i,j);
1027}
1028
1029
1030
1031template<typename T>
1032inline
1034{
1035 for (auto i : index_range(_val))
1036 if (_val[i] != mat._val[i])
1037 return false;
1038
1039 return true;
1040}
1041
1042
1043
1044template<typename T>
1045inline
1047{
1048 for (auto i : index_range(_val))
1049 if (_val[i] != mat._val[i])
1050 return true;
1051
1052 return false;
1053}
1054
1055
1056
1057template<typename T>
1058inline
1060{
1061 for (auto i : index_range(_val))
1062 _val[i] += mat._val[i];
1063
1064 return *this;
1065}
1066
1067
1068
1069template<typename T>
1070inline
1072{
1073 for (auto i : index_range(_val))
1074 _val[i] -= mat._val[i];
1075
1076 return *this;
1077}
1078
1079
1080
1081template<typename T>
1082inline
1083auto DenseMatrix<T>::min () const -> decltype(libmesh_real(T(0)))
1084{
1085 libmesh_assert (this->_m);
1086 libmesh_assert (this->_n);
1087 auto my_min = libmesh_real((*this)(0,0));
1088
1089 for (unsigned int i=0; i!=this->_m; i++)
1090 {
1091 for (unsigned int j=0; j!=this->_n; j++)
1092 {
1093 auto current = libmesh_real((*this)(i,j));
1094 my_min = (my_min < current? my_min : current);
1095 }
1096 }
1097 return my_min;
1098}
1099
1100
1101
1102template<typename T>
1103inline
1104auto DenseMatrix<T>::max () const -> decltype(libmesh_real(T(0)))
1105{
1106 libmesh_assert (this->_m);
1107 libmesh_assert (this->_n);
1108 auto my_max = libmesh_real((*this)(0,0));
1109
1110 for (unsigned int i=0; i!=this->_m; i++)
1111 {
1112 for (unsigned int j=0; j!=this->_n; j++)
1113 {
1114 auto current = libmesh_real((*this)(i,j));
1115 my_max = (my_max > current? my_max : current);
1116 }
1117 }
1118 return my_max;
1119}
1120
1121
1122
1123template<typename T>
1124inline
1126{
1127 libmesh_assert (this->_m);
1128 libmesh_assert (this->_n);
1129
1130 using std::abs;
1131 auto columnsum = abs(T(0));
1132 for (unsigned int i=0; i!=this->_m; i++)
1133 {
1134 columnsum += abs((*this)(i,0));
1135 }
1136 auto my_max = columnsum;
1137 for (unsigned int j=1; j!=this->_n; j++)
1138 {
1139 columnsum = 0.;
1140 for (unsigned int i=0; i!=this->_m; i++)
1141 {
1142 columnsum += abs((*this)(i,j));
1143 }
1144 my_max = (my_max > columnsum? my_max : columnsum);
1145 }
1146 return my_max;
1147}
1148
1149
1150
1151template<typename T>
1152inline
1154{
1155 libmesh_assert (this->_m);
1156 libmesh_assert (this->_n);
1157 using std::abs;
1158
1159 auto rowsum = abs(T(0));
1160 for (unsigned int j=0; j!=this->_n; j++)
1161 {
1162 rowsum += abs((*this)(0,j));
1163 }
1164 auto my_max = rowsum;
1165 for (unsigned int i=1; i!=this->_m; i++)
1166 {
1167 rowsum = 0.;
1168 for (unsigned int j=0; j!=this->_n; j++)
1169 {
1170 rowsum += abs((*this)(i,j));
1171 }
1172 my_max = (my_max > rowsum? my_max : rowsum);
1173 }
1174 return my_max;
1175}
1176
1177
1178
1179template<typename T>
1180inline
1181T DenseMatrix<T>::transpose (const unsigned int i,
1182 const unsigned int j) const
1183{
1184 // Implement in terms of operator()
1185 return (*this)(j,i);
1186}
1187
1188
1189
1190
1191
1192// template<typename T>
1193// inline
1194// void DenseMatrix<T>::condense(const unsigned int iv,
1195// const unsigned int jv,
1196// const T val,
1197// DenseVector<T> & rhs)
1198// {
1199// libmesh_assert_equal_to (this->_m, rhs.size());
1200// libmesh_assert_equal_to (iv, jv);
1201
1202
1203// // move the known value into the RHS
1204// // and zero the column
1205// for (auto i : make_range(this->m()))
1206// {
1207// rhs(i) -= ((*this)(i,jv))*val;
1208// (*this)(i,jv) = 0.;
1209// }
1210
1211// // zero the row
1212// for (auto j : make_range(this->n()))
1213// (*this)(iv,j) = 0.;
1214
1215// (*this)(iv,jv) = 1.;
1216// rhs(iv) = val;
1217
1218// }
1219
1220
1221// A matrix is finite iff every component is
1222template <typename T>
1223bool isfinite (const DenseMatrix<T> & var)
1224{
1225 using std::isfinite;
1226 using libMesh::isfinite; // for T==complex
1227 const auto m = var.m(), n = var.n();
1228 for (auto i : make_range(m))
1229 for (auto j : make_range(n))
1230 if (!isfinite(var(i,j)))
1231 return false;
1232 return true;
1233}
1234
1235
1236// A matrix is infinite iff some component is infinite but no
1237// component is NaN.
1238//
1239// This is arguably inconsistent with our std::complex overload (and
1240// the C99 Annex G recommendations for _Complex, and C++ std::complex
1241// arithmetic), which treats mixed (inf,NaN) pairs as infinite, but
1242// this is probably safer for users.
1243template <typename T>
1244bool isinf (const DenseMatrix<T> & var)
1245{
1246 using std::isinf;
1247 using libMesh::isinf; // for T==complex
1248 using std::isnan;
1249 using libMesh::isnan;
1250 const auto m = var.m(), n = var.n();
1251 bool has_inf = false;
1252 for (auto i : make_range(m))
1253 for (auto j : make_range(n))
1254 {
1255 // NaN anywhere makes us NaN, not inf
1256 if (isnan(var(i,j)))
1257 return false;
1258 has_inf = has_inf || isinf(var(i,j));
1259 }
1260 return has_inf;
1261}
1262
1263
1264
1265// A matrix is NaN iff some component is NaN
1266//
1267// This is arguably inconsistent with our std::complex overload (and
1268// the C99 Annex G recommendations for _Complex, and C++ std::complex
1269// arithmetic), which treats mixed (inf,NaN) pairs as infinite, but
1270// this is probably safer for users.
1271template <typename T>
1272bool isnan (const DenseMatrix<T> & var)
1273{
1274 using std::isnan;
1275 using libMesh::isnan; // for T==complex
1276 const auto m = var.m(), n = var.n();
1277 for (auto i : make_range(m))
1278 for (auto j : make_range(n))
1279 if (isnan(var(i,j)))
1280 return true;
1281 return false;
1282}
1283
1284
1285} // namespace libMesh
1286
1287#ifdef LIBMESH_HAVE_METAPHYSICL
1289{
1290template <typename T>
1291struct RawType<libMesh::DenseMatrix<T>>
1292{
1294
1296 {
1297 const auto m = in.m(), n = in.n();
1298 value_type ret(m, n);
1299 for (unsigned int i = 0; i < m; ++i)
1300 for (unsigned int j = 0; j < n; ++j)
1301 ret(i,j) = raw_value(in(i,j));
1302
1303 return ret;
1304 }
1305};
1306}
1307#endif
1308
1309
1310#endif // LIBMESH_DENSE_MATRIX_H
Defines an abstract dense matrix base class for use in Finite Element-type computations.
void condense(const unsigned int i, const unsigned int j, const T val, DenseVectorBase< T > &rhs)
Condense-out the (i,j) entry of the matrix, forcing it to take on the value val.
unsigned int _n
The column dimension.
unsigned int _m
The row dimension.
Defines a dense matrix for use in Finite Element-type computations.
void scale_column(const unsigned int col, const T factor)
Multiplies every element in the column col matrix by factor.
auto min() const -> decltype(libmesh_real(T(0)))
void _cholesky_decompose()
Decomposes a symmetric positive definite matrix into a product of two lower triangular matrices accor...
void _lu_decompose()
Form the LU decomposition of the matrix.
DenseMatrix(DenseMatrix &&)=default
The 5 special functions can be defaulted for this class, as it does not manage any memory itself.
void evd_left(DenseVector< T > &lambda_real, DenseVector< T > &lambda_imag, DenseMatrix< T > &VL)
Compute the eigenvalues (both real and imaginary parts) and left eigenvectors of a general matrix,...
void _lu_back_substitute(const DenseVector< T > &b, DenseVector< T > &x) const
Solves the system Ax=b through back substitution.
void right_multiply_transpose(const DenseMatrix< T > &A)
Right multiplies by the transpose of the matrix A.
DenseMatrix(const unsigned int new_m=0, const unsigned int new_n=0)
Constructor.
void _left_multiply_transpose(const DenseMatrix< T2 > &A)
Left multiplies by the transpose of the matrix A which may contain a different numerical type.
std::vector< T > & get_values()
virtual T & el(const unsigned int i, const unsigned int j) override final
void _right_multiply_transpose(const DenseMatrix< T2 > &A)
Right multiplies by the transpose of the matrix A which may contain a different numerical type.
void _evd_lapack(DenseVector< T > &lambda_real, DenseVector< T > &lambda_imag, DenseMatrix< T > *VL=nullptr, DenseMatrix< T > *VR=nullptr)
Computes the eigenvalues of the matrix using the Lapack routine "DGEEV".
DenseMatrix(unsigned int nrow, unsigned int ncol, std::initializer_list< T2 > init_list)
Constructor taking the number of rows, columns, and an initializer_list, which must be of length nrow...
DenseMatrix sub_matrix(unsigned int row_id, unsigned int row_size, unsigned int col_id, unsigned int col_size) const
Get submatrix with the smallest row and column indices and the submatrix size.
void _lu_decompose_lapack()
Computes an LU factorization of the matrix using the Lapack routine "getrf".
void svd_solve(const DenseVector< T > &rhs, DenseVector< T > &x, Real rcond=std::numeric_limits< Real >::epsilon()) const
Solve the system of equations for in the least-squares sense.
DenseMatrix & operator=(const DenseMatrix &)=default
void _svd_lapack(DenseVector< Real > &sigma)
Computes an SVD of the matrix using the Lapack routine "getsvd".
void vector_mult(DenseVector< T > &dest, const DenseVector< T > &arg) const
Performs the matrix-vector multiplication, dest := (*this) * arg.
void cholesky_solve(const DenseVector< T2 > &b, DenseVector< T2 > &x)
For symmetric positive definite (SPD) matrices.
bool operator!=(const DenseMatrix< T > &mat) const
DenseMatrix(const DenseMatrix &)=default
void _cholesky_back_substitute(const DenseVector< T2 > &b, DenseVector< T2 > &x) const
Solves the equation Ax=b for the unknown value x and rhs b based on the Cholesky factorization of A.
void resize(const unsigned int new_m, const unsigned int new_n)
Resizes the matrix to the specified size and calls zero().
void svd(DenseVector< Real > &sigma)
Compute the singular value decomposition of the matrix.
bool use_blas_lapack
Computes the inverse of the dense matrix (assuming it is invertible) by first computing the LU decomp...
std::vector< T > _val
The actual data values, stored as a 1D array.
void lu_solve(const DenseVector< T > &b, DenseVector< T > &x)
Solve the system Ax=b given the input vector b.
void _svd_solve_lapack(const DenseVector< T > &rhs, DenseVector< T > &x, Real rcond) const
Called by svd_solve(rhs).
T operator()(const unsigned int i, const unsigned int j) const
virtual void right_multiply(const DenseMatrixBase< T > &M2) override final
Performs the operation: (*this) <- (*this) * M3.
void get_principal_submatrix(unsigned int sub_m, unsigned int sub_n, DenseMatrix< T > &dest) const
Put the sub_m x sub_n principal submatrix into dest.
std::vector< pivot_index_t > _pivots
void evd_right(DenseVector< T > &lambda_real, DenseVector< T > &lambda_imag, DenseMatrix< T > &VR)
Compute the eigenvalues (both real and imaginary parts) and right eigenvectors of a general matrix,...
void get_transpose(DenseMatrix< T > &dest) const
Put the tranposed matrix into dest.
auto linfty_norm() const
virtual T el(const unsigned int i, const unsigned int j) const override final
void swap(DenseMatrix< T > &other_matrix)
STL-like swap method.
void vector_mult_transpose(DenseVector< T > &dest, const DenseVector< T > &arg) const
Performs the matrix-vector multiplication, dest := (*this)^T * arg.
DenseMatrix< T > & operator-=(const DenseMatrix< T > &mat)
Subtracts mat from this matrix.
T transpose(const unsigned int i, const unsigned int j) const
const std::vector< T > & get_values() const
DecompositionType _decomposition_type
This flag keeps track of which type of decomposition has been performed on the matrix.
void _svd_helper(char JOBU, char JOBVT, std::vector< Real > &sigma_val, std::vector< Number > &U_val, std::vector< Number > &VT_val)
Helper function that actually performs the SVD.
void scale(const T factor)
Multiplies every element in the matrix by factor.
virtual void left_multiply(const DenseMatrixBase< T > &M2) override final
Performs the operation: (*this) <- M2 * (*this)
void outer_product(const DenseVector< T > &a, const DenseVector< T > &b)
Computes the outer (dyadic) product of two vectors and stores in (*this).
PetscBLASInt pivot_index_t
Array used to store pivot indices.
void _matvec_blas(T alpha, T beta, DenseVector< T > &dest, const DenseVector< T > &arg, bool trans=false) const
Uses the BLAS GEMV function (through PETSc) to compute.
void condense(const unsigned int i, const unsigned int j, const T val, DenseVector< T > &rhs)
Condense-out the (i,j) entry of the matrix, forcing it to take on the value val.
void evd(DenseVector< T > &lambda_real, DenseVector< T > &lambda_imag)
Compute the eigenvalues (both real and imaginary parts) of a general matrix.
std::enable_if< ScalarTraits< T2 >::value, void >::type add(const T2 factor, const DenseMatrix< T3 > &mat)
Adds factor times mat to this matrix.
void evd_left_and_right(DenseVector< T > &lambda_real, DenseVector< T > &lambda_imag, DenseMatrix< T > &VL, DenseMatrix< T > &VR)
Compute the eigenvalues (both real and imaginary parts) as well as the left and right eigenvectors of...
virtual ~DenseMatrix()=default
bool operator==(const DenseMatrix< T > &mat) const
void _multiply_blas(const DenseMatrixBase< T > &other, _BLAS_Multiply_Flag flag)
The _multiply_blas function computes A <- op(A) * op(B) using BLAS gemm function.
void left_multiply_transpose(const DenseMatrix< T > &A)
Left multiplies by the transpose of the matrix A.
auto max() const -> decltype(libmesh_real(T(0)))
void vector_mult_add(DenseVector< T > &dest, const T factor, const DenseVector< T > &arg) const
Performs the scaled matrix-vector multiplication, dest += factor * (*this) * arg.
DenseMatrix< T > & operator*=(const T factor)
Multiplies every element in the matrix by factor.
DecompositionType
The decomposition schemes above change the entries of the matrix A.
DenseMatrix< T > & operator+=(const DenseMatrix< T > &mat)
Adds mat to this matrix.
void _lu_back_substitute_lapack(const DenseVector< T > &b, DenseVector< T > &x)
Companion function to _lu_decompose_lapack().
virtual void zero() override final
Sets all elements of the matrix to 0 and resets any decomposition flag which may have been previously...
_BLAS_Multiply_Flag
Enumeration used to determine the behavior of the _multiply_blas function.
Defines a dense vector for use in Finite Element-type computations.
static const Real b
DenseMatrix< Complex > ComplexDenseMatrix
This typedef may be either a real-only matrix, or a truly complex matrix, depending on how Number was...
DenseMatrix< Real > RealDenseMatrix
Convenient definition of a real-only dense matrix.
The libMesh namespace provides an interface to certain functionality in the library.
auto index_range(const T &sizable)
Helper function that returns an IntRange<std::size_t> representing all the indices of the passed-in v...
Definition int_range.h:153
T libmesh_real(T a)
libmesh_assert(ctx)
bool isfinite(std::complex< T > a)
bool isnan(std::complex< T > a)
const Number zero
.
Definition libmesh.h:297
bool isinf(std::complex< T > a)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
IntRange< T > make_range(T beg, T end)
The 2-parameter make_range() helper function returns an IntRange<T> when both input parameters are of...
Definition int_range.h:176
static value_type value(const libMesh::DenseMatrix< T > &in)
libMesh::DenseMatrix< typename RawType< T >::value_type > value_type
Helper structure for determining whether to use blas_lapack.
static const bool value
Definition xdr_io.C:55