20 #ifndef LIBMESH_DENSE_MATRIX_H 21 #define LIBMESH_DENSE_MATRIX_H 24 #include "libmesh/libmesh_common.h" 25 #include "libmesh/dense_matrix_base.h" 26 #include "libmesh/int_range.h" 29 #if (LIBMESH_HAVE_PETSC) 30 # include "libmesh/petsc_macro.h" 32 # define LIBMESH_SAW_I 35 #include "libmesh/ignore_warnings.h" 36 # include <petscsys.h> 37 #include "libmesh/restore_warnings.h" 39 # ifndef LIBMESH_SAW_I 40 # undef I // Avoid complex.h contamination 47 #include <initializer_list> 49 #ifdef LIBMESH_HAVE_METAPHYSICL 50 #include "metaphysicl/dualnumber_decl.h" 51 #include "metaphysicl/raw_type.h" 58 template <
typename T>
class DenseVector;
71 class DenseMatrix :
public DenseMatrixBase<T>
79 const unsigned int new_n=0);
86 template <
typename T2>
89 std::initializer_list<T2> init_list);
106 virtual void zero() override final;
112 unsigned int col_id,
unsigned int col_size) const;
117 T operator() (const
unsigned int i,
118 const
unsigned int j) const;
123 T & operator() (const
unsigned int i,
124 const
unsigned int j);
126 virtual T
el(const
unsigned int i,
127 const
unsigned int j) const override final
128 {
return (*
this)(i,j); }
130 virtual T &
el(
const unsigned int i,
131 const unsigned int j)
override final 132 {
return (*
this)(i,j); }
139 template <
typename T2>
147 template <
typename T2>
162 template <
typename T2>
178 template <
typename T2>
195 template <
typename T2,
typename T3>
238 template <
typename T2>
253 void resize(
const unsigned int new_m,
254 const unsigned int new_n);
259 void scale (
const T factor);
264 void scale_column (
const unsigned int col,
const T factor);
278 template<
typename T2,
typename T3>
348 template <typename T2>
361 template <typename T2>
368 const
unsigned int j) const;
396 const unsigned int j,
439 template <
typename T2>
487 Real rcond=std::numeric_limits<Real>::epsilon())
const;
633 template <
typename T2>
713 std::vector<Real> & sigma_val,
714 std::vector<Number> & U_val,
715 std::vector<Number> & VT_val);
735 #if (LIBMESH_HAVE_PETSC && LIBMESH_USE_REAL_NUMBERS) 769 bool trans=
false)
const;
775 template <
typename T2>
782 template <
typename T2>
794 namespace DenseMatrices
816 using namespace DenseMatrices;
821 #if defined(LIBMESH_HAVE_PETSC) && \ 822 defined(LIBMESH_USE_REAL_NUMBERS) && \ 823 defined(LIBMESH_DEFAULT_DOUBLE_PRECISION) 827 static const bool value =
true;
837 const unsigned int new_n) :
841 _decomposition_type(NONE)
843 this->resize(new_m,new_n);
846 template <
typename T>
847 template <
typename T2>
850 std::initializer_list<T2> init_list) :
853 _val(init_list.begin(), init_list.end()),
854 _decomposition_type(NONE)
858 libmesh_assert_equal_to(nrow * ncol, init_list.size());
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;
876 template <
typename T>
877 template <
typename T2>
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);
896 const unsigned int new_n)
913 _decomposition_type = NONE;
915 std::fill (_val.begin(), _val.end(),
static_cast<T
>(0));
923 unsigned int col_id,
unsigned int col_size)
const 925 libmesh_assert_less (row_id + row_size - 1, this->_m);
926 libmesh_assert_less (col_id + col_size - 1, this->_n);
931 sub._val.resize(row_size * col_size);
933 unsigned int end_col = this->_n - col_size - col_id;
934 unsigned int p = row_id * this->_n;
936 for (
unsigned int i=0; i<row_size; i++)
940 for (
unsigned int j=0; j<col_size; j++)
941 sub._val[q++] = _val[p++];
954 const unsigned int j)
const 956 libmesh_assert_less (i*j, _val.size());
957 libmesh_assert_less (i, this->_m);
958 libmesh_assert_less (j, this->_n);
962 return _val[(i)*(this->_n) + (j)];
970 const unsigned int j)
972 libmesh_assert_less (i*j, _val.size());
973 libmesh_assert_less (i, this->_m);
974 libmesh_assert_less (j, this->_n);
977 return _val[(i)*(this->_n) + (j)];
988 for (
auto & v : _val)
998 (*this)(i, col) *= factor;
1003 template<
typename T>
1007 this->
scale(factor);
1013 template<
typename T>
1014 template<
typename T2,
typename T3>
1021 libmesh_assert_equal_to (this->m(), mat.m());
1022 libmesh_assert_equal_to (this->n(), mat.n());
1026 (*
this)(i,j) += factor * mat(i,j);
1031 template<
typename T>
1036 if (_val[i] != mat._val[i])
1044 template<
typename T>
1049 if (_val[i] != mat._val[i])
1057 template<
typename T>
1062 _val[i] += mat._val[i];
1069 template<
typename T>
1074 _val[i] -= mat._val[i];
1081 template<
typename T>
1089 for (
unsigned int i=0; i!=this->_m; i++)
1091 for (
unsigned int j=0; j!=this->_n; j++)
1094 my_min = (my_min < current? my_min : current);
1102 template<
typename T>
1110 for (
unsigned int i=0; i!=this->_m; i++)
1112 for (
unsigned int j=0; j!=this->_n; j++)
1115 my_max = (my_max > current? my_max : current);
1123 template<
typename T>
1131 for (
unsigned int i=0; i!=this->_m; i++)
1133 columnsum +=
std::abs((*
this)(i,0));
1135 auto my_max = columnsum;
1136 for (
unsigned int j=1; j!=this->_n; j++)
1139 for (
unsigned int i=0; i!=this->_m; i++)
1141 columnsum +=
std::abs((*
this)(i,j));
1143 my_max = (my_max > columnsum? my_max : columnsum);
1150 template<
typename T>
1158 for (
unsigned int j=0; j!=this->_n; j++)
1162 auto my_max = rowsum;
1163 for (
unsigned int i=1; i!=this->_m; i++)
1166 for (
unsigned int j=0; j!=this->_n; j++)
1170 my_max = (my_max > rowsum? my_max : rowsum);
1177 template<
typename T>
1180 const unsigned int j)
const 1183 return (*
this)(j,i);
1223 #ifdef LIBMESH_HAVE_METAPHYSICL 1226 template <
typename T>
1233 const auto m = in.
m(), n = in.
n();
1235 for (
unsigned int i = 0; i < m; ++i)
1236 for (
unsigned int j = 0; j < n; ++j)
1237 ret(i,j) = raw_value(in(i,j));
1246 #endif // LIBMESH_DENSE_MATRIX_H
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 _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 _lu_back_substitute(const DenseVector< T > &b, DenseVector< T > &x) const
Solves the system Ax=b through back substitution.
T transpose(const unsigned int i, const unsigned int j) const
void swap(DenseMatrix< T > &other_matrix)
STL-like swap method.
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.
DenseMatrix< Complex > ComplexDenseMatrix
This typedef may be either a real-only matrix, or a truly complex matrix, depending on how Number was...
void _lu_decompose_lapack()
Computes an LU factorization of the matrix using the Lapack routine "getrf".
auto max() const -> decltype(libmesh_real(T(0)))
_BLAS_Multiply_Flag
Enumeration used to determine the behavior of the _multiply_blas function.
virtual void zero() override final
Sets all elements of the matrix to 0 and resets any decomposition flag which may have been previously...
DenseMatrix< T > & operator+=(const DenseMatrix< T > &mat)
Adds mat to this matrix.
DecompositionType _decomposition_type
This flag keeps track of which type of decomposition has been performed on the matrix.
void _svd_solve_lapack(const DenseVector< T > &rhs, DenseVector< T > &x, Real rcond) const
Called by svd_solve(rhs).
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...
virtual ~DenseMatrix()=default
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...
auto l1_norm() const -> decltype(std::abs(T(0)))
DenseMatrix< T > & operator-=(const DenseMatrix< T > &mat)
Subtracts mat from this matrix.
The libMesh namespace provides an interface to certain functionality in the library.
bool use_blas_lapack
Computes the inverse of the dense matrix (assuming it is invertible) by first computing the LU decomp...
bool operator==(const variant_filter_iterator< Predicate, Type, ReferenceType, PointerType, OtherConstType, OtherConstReferenceType, OtherConstPointerType > &x, const variant_filter_iterator< Predicate, Type, ReferenceType, PointerType, OtherConstType, OtherConstReferenceType, OtherConstPointerType > &y)
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. ...
DenseMatrix(const unsigned int new_m=0, const unsigned int new_n=0)
Constructor.
const std::vector< T > & get_values() const
void outer_product(const DenseVector< T > &a, const DenseVector< T > &b)
Computes the outer (dyadic) product of two vectors and stores in (*this).
void vector_mult_transpose(DenseVector< T > &dest, const DenseVector< T > &arg) const
Performs the matrix-vector multiplication, dest := (*this)^T * arg.
ADRealEigenVector< T, D, asd > abs(const ADRealEigenVector< T, D, asd > &)
void scale_column(const unsigned int col, const T factor)
Multiplies every element in the column col matrix by factor.
DenseMatrix & operator=(const DenseMatrix &)=default
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. ...
virtual T el(const unsigned int i, const unsigned int j) const override final
void _lu_back_substitute_lapack(const DenseVector< T > &b, DenseVector< T > &x)
Companion function to _lu_decompose_lapack().
void svd(DenseVector< Real > &sigma)
Compute the singular value decomposition of the matrix.
auto linfty_norm() const -> decltype(std::abs(T(0)))
void _lu_decompose()
Form the LU decomposition of the matrix.
void get_transpose(DenseMatrix< T > &dest) const
Put the tranposed matrix into dest.
boostcopy::enable_if_c< ScalarTraits< T2 >::value, void >::type add(const T2 factor, const DenseMatrix< T3 > &mat)
Adds factor times mat to this matrix.
DenseMatrix< Real > RealDenseMatrix
Convenient definition of a real-only dense matrix.
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 _cholesky_decompose()
Decomposes a symmetric positive definite matrix into a product of two lower triangular matrices accor...
bool operator!=(const variant_filter_iterator< Predicate, Type, ReferenceType, PointerType, OtherConstType, OtherConstReferenceType, OtherConstPointerType > &x, const variant_filter_iterator< Predicate, Type, ReferenceType, PointerType, OtherConstType, OtherConstReferenceType, OtherConstPointerType > &y)
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.
void _svd_lapack(DenseVector< Real > &sigma)
Computes an SVD of the matrix using the Lapack routine "getsvd".
std::vector< T > & get_values()
bool operator==(const DenseMatrix< T > &mat) const
void right_multiply_transpose(const DenseMatrix< T > &A)
Right multiplies by the transpose of the matrix A.
void scale(const T factor)
Multiplies every element in the matrix by factor.
void lu_solve(const DenseVector< T > &b, DenseVector< T > &x)
Solve the system Ax=b given the input vector b.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
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".
void evd(DenseVector< T > &lambda_real, DenseVector< T > &lambda_imag)
Compute the eigenvalues (both real and imaginary parts) of a general matrix.
void left_multiply_transpose(const DenseMatrix< T > &A)
Left multiplies by the transpose of the matrix A.
virtual void right_multiply(const DenseMatrixBase< T > &M2) override final
Performs the operation: (*this) <- (*this) * M3.
void _left_multiply_transpose(const DenseMatrix< T2 > &A)
Left multiplies by the transpose of the matrix A which may contain a different numerical type...
Helper structure for determining whether to use blas_lapack.
void resize(const unsigned int new_m, const unsigned int new_n)
Resizes the matrix to the specified size and calls zero().
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...
auto min() const -> decltype(libmesh_real(T(0)))
std::vector< T > _val
The actual data values, stored as a 1D array.
Defines a dense vector for use in Finite Element-type computations.
void cholesky_solve(const DenseVector< T2 > &b, DenseVector< T2 > &x)
For symmetric positive definite (SPD) matrices.
void _right_multiply_transpose(const DenseMatrix< T2 > &A)
Right multiplies by the transpose of the matrix A which may contain a different numerical type...
DenseMatrix< T > & operator*=(const T factor)
Multiplies every element in the matrix by factor.
Defines an abstract dense matrix base class for use in Finite Element-type computations.
bool operator!=(const DenseMatrix< T > &mat) const
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.
DecompositionType
The decomposition schemes above change the entries of the matrix A.
Defines a dense matrix for use in Finite Element-type computations.
std::vector< pivot_index_t > _pivots
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 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.
PetscBLASInt pivot_index_t
Array used to store pivot indices.
auto index_range(const T &sizable)
Helper function that returns an IntRange<std::size_t> representing all the indices of the passed-in v...
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.
virtual void left_multiply(const DenseMatrixBase< T > &M2) override final
Performs the operation: (*this) <- M2 * (*this)
virtual T & el(const unsigned int i, const unsigned int j) override final
void vector_mult(DenseVector< T > &dest, const DenseVector< T > &arg) const
Performs the matrix-vector multiplication, dest := (*this) * arg.