5#ifndef DUNE_DENSEMATRIX_HH
6#define DUNE_DENSEMATRIX_HH
28 template<
typename M>
class DenseMatrix;
58 template<
class DenseMatrix,
class RHS >
65 template<
class DenseMatrix,
class RHS,
class =
void >
69 template<
class DenseMatrix,
class RHS >
80 template<
class DenseMatrix,
class RHS >
81 class DenseMatrixAssigner< DenseMatrix, RHS,
std::enable_if_t< !std::is_same< typename RHS::const_iterator, void >::value
82 && std::is_convertible< typename RHS::const_iterator::value_type, typename DenseMatrix::iterator::value_type >::value > >
85 static void apply ( DenseMatrix &denseMatrix,
const RHS &rhs )
89 typename DenseMatrix::iterator tIt = std::begin(denseMatrix);
90 typename RHS::const_iterator sIt = std::begin(rhs);
91 for(; sIt != std::end(rhs); ++tIt, ++sIt)
92 std::copy(std::begin(*sIt), std::end(*sIt), std::begin(*tIt));
100 template<
class DenseMatrix,
class RHS >
101 struct DenseMatrixAssigner
102 :
public Impl::DenseMatrixAssigner< DenseMatrix, RHS >
109 template<
class DenseMatrix,
class RHS >
112 std::false_type hasDenseMatrixAssigner ( ... );
116 template<
class DenseMatrix,
class RHS >
117 struct HasDenseMatrixAssigner
118 :
public decltype( Impl::hasDenseMatrixAssigner( std::declval< DenseMatrix & >(), std::declval< const RHS & >() ) )
138 template<
typename MAT>
144 constexpr MAT & asImp() {
return static_cast<MAT&
>(*this); }
145 constexpr const MAT & asImp()
const {
return static_cast<const MAT&
>(*this); }
191 return asImp().mat_access(
i);
196 return asImp().mat_access(
i);
213 typedef typename std::remove_reference<row_reference>::type::Iterator
ColIterator;
248 typedef typename std::remove_reference<const_row_reference>::type::ConstIterator
ConstColIterator;
288 template <
class Other>
311 template <
class Other>
337 template <
class Other>
342 (*
this)[
i ].axpy(
a,
x[
i ] );
347 template <
class Other>
352 if ((*
this)[
i]!=
x[
i])
357 template <
class Other>
367 template<
class X,
class Y>
370 auto&&
xx = Impl::asVector(
x);
371 auto&&
yy = Impl::asVector(
y);
386 template<
class X,
class Y >
389 auto&&
xx = Impl::asVector(
x);
390 auto&&
yy = Impl::asVector(
y);
405 template<
class X,
class Y>
408 auto&&
xx = Impl::asVector(
x);
409 auto&&
yy = Impl::asVector(
y);
418 template<
class X,
class Y>
421 auto&&
xx = Impl::asVector(
x);
422 auto&&
yy = Impl::asVector(
y);
431 template<
class X,
class Y>
434 auto&&
xx = Impl::asVector(
x);
435 auto&&
yy = Impl::asVector(
y);
444 template<
class X,
class Y>
447 auto&&
xx = Impl::asVector(
x);
448 auto&&
yy = Impl::asVector(
y);
457 template<
class X,
class Y>
460 auto&&
xx = Impl::asVector(
x);
461 auto&&
yy = Impl::asVector(
y);
470 template<
class X,
class Y>
473 auto&&
xx = Impl::asVector(
x);
474 auto&&
yy = Impl::asVector(
y);
483 template<
class X,
class Y>
485 const X&
x,
Y&
y)
const
487 auto&&
xx = Impl::asVector(
x);
488 auto&&
yy = Impl::asVector(
y);
497 template<
class X,
class Y>
499 const X&
x,
Y&
y)
const
501 auto&&
xx = Impl::asVector(
x);
502 auto&&
yy = Impl::asVector(
y);
511 template<
class X,
class Y>
513 const X&
x,
Y&
y)
const
515 auto&&
xx = Impl::asVector(
x);
516 auto&&
yy = Impl::asVector(
y);
532 return fvmeta::sqrt(sum);
545 typename std::enable_if<!HasNaN<vt>::value,
int>::type = 0>
551 for (
auto const &
x : *
this) {
552 real_type
const a =
x.one_norm();
560 typename std::enable_if<!HasNaN<vt>::value,
int>::type = 0>
566 for (
auto const &
x : *
this) {
567 real_type
const a =
x.one_norm_real();
575 typename std::enable_if<HasNaN<vt>::value,
int>::type = 0>
582 for (
auto const &
x : *
this) {
583 real_type
const a =
x.one_norm();
587 return norm * (isNaN / isNaN);
592 typename std::enable_if<HasNaN<vt>::value,
int>::type = 0>
599 for (
auto const &
x : *
this) {
600 real_type
const a =
x.one_norm_real();
604 return norm * (isNaN / isNaN);
613 template <
class V1,
class V2>
626 template<
typename M2>
644 template<
typename M2>
679 FieldMatrix<K,rows,l> rightmultiplyany (
const FieldMatrix<K,cols,l>&
M)
const
681 FieldMatrix<K,rows,l> C;
687 C[i][j] += (*
this)[i][k]*
M[k][j];
711 return asImp().mat_rows();
717 return asImp().mat_cols();
737 void swap(std::size_t
i, simd_index_type
j);
740 void operator()(
const T&,
int,
int)
743 std::vector<simd_index_type> & pivot_;
751 void swap(std::size_t i, simd_index_type j);
753 void operator()(
const typename V::field_type& factor,
int k,
int i);
760 ElimDet(field_type& sign) : sign_(
sign)
763 void swap(std::size_t i, simd_index_type j)
766 Simd::cond(simd_index_type(i) == j, field_type(1), field_type(-1));
769 void operator()(
const field_type&,
int,
int)
815 template<
class Func,
class Mask>
821 template<
typename MAT>
825 typedef typename std::vector<size_type>::size_type
size_type;
829 template<
typename MAT>
830 void DenseMatrix<MAT>::ElimPivot::swap(std::size_t i, simd_index_type j)
833 Simd::cond(Simd::Scalar<simd_index_type>(i) == j, pivot_[i], j);
836 template<
typename MAT>
838 DenseMatrix<MAT>::Elim<V>::Elim(V& rhs)
842 template<
typename MAT>
844 void DenseMatrix<MAT>::Elim<V>::swap(std::size_t i, simd_index_type j)
854 template<
typename MAT>
856 void DenseMatrix<MAT>::
857 Elim<V>::operator()(
const typename V::field_type& factor,
int k,
int i)
859 (*rhs_)[k] -= factor*(*rhs_)[i];
862 template<
typename MAT>
863 template<
typename Func,
class Mask>
865 luDecomposition(DenseMatrix<MAT>& A, Func func, Mask &nonsingularLanes,
866 bool throwEarly,
bool doPivoting)
876 real_type
pivmax = fvmeta::absreal(
A[
i][
i]);
881 simd_index_type
imax=
i;
884 auto abs = fvmeta::absreal(
A[
k][
i]);
911 DUNE_THROW(FMatrixError,
"matrix is singular");
932 template<
typename MAT>
933 template <
class V1,
class V2>
939 DUNE_THROW(FMatrixError,
"Can't solve for a " << rows() <<
"x" << cols() <<
" matrix!");
943#ifdef DUNE_FMatrix_WITH_CHECKING
946 DUNE_THROW(FMatrixError,
"matrix is singular");
948 x[0] =
b[0]/(*this)[0][0];
951 else if (rows()==2) {
953 field_type
detinv = (*this)[0][0]*(*this)[1][1]-(*this)[0][1]*(*this)[1][0];
954#ifdef DUNE_FMatrix_WITH_CHECKING
957 DUNE_THROW(FMatrixError,
"matrix is singular");
961 x[0] =
detinv*((*this)[1][1]*
b[0]-(*this)[0][1]*
b[1]);
962 x[1] =
detinv*((*this)[0][0]*
b[1]-(*this)[1][0]*
b[0]);
965 else if (rows()==3) {
968#ifdef DUNE_FMatrix_WITH_CHECKING
971 DUNE_THROW(FMatrixError,
"matrix is singular");
974 x[0] = (
b[0]*(*this)[1][1]*(*this)[2][2] -
b[0]*(*this)[2][1]*(*this)[1][2]
975 -
b[1] *(*this)[0][1]*(*this)[2][2] +
b[1]*(*this)[2][1]*(*this)[0][2]
976 +
b[2] *(*this)[0][1]*(*this)[1][2] -
b[2]*(*this)[1][1]*(*this)[0][2]) /
d;
978 x[1] = ((*this)[0][0]*
b[1]*(*this)[2][2] - (*this)[0][0]*
b[2]*(*this)[1][2]
979 - (*this)[1][0] *
b[0]*(*this)[2][2] + (*this)[1][0]*
b[2]*(*this)[0][2]
980 + (*this)[2][0] *
b[0]*(*this)[1][2] - (*this)[2][0]*
b[1]*(*this)[0][2]) /
d;
982 x[2] = ((*this)[0][0]*(*this)[1][1]*
b[2] - (*this)[0][0]*(*this)[2][1]*
b[1]
983 - (*this)[1][0] *(*this)[0][1]*
b[2] + (*this)[1][0]*(*this)[2][1]*
b[0]
984 + (*this)[2][0] *(*this)[0][1]*
b[1] - (*this)[2][0]*(*this)[1][1]*
b[0]) /
d;
993 Simd::Mask<typename FieldTraits<value_type>::real_type>
999 for(
int i=rows()-1;
i>=0;
i--) {
1007 template<
typename MAT>
1015 DUNE_THROW(FMatrixError,
"Can't invert a " << rows() <<
"x" << cols() <<
" matrix!");
1019#ifdef DUNE_FMatrix_WITH_CHECKING
1022 DUNE_THROW(FMatrixError,
"matrix is singular");
1024 (*this)[0][0] = real_type( 1 ) / (*this)[0][0];
1027 else if (rows()==2) {
1029 field_type
detinv = (*this)[0][0]*(*this)[1][1]-(*this)[0][1]*(*this)[1][0];
1030#ifdef DUNE_FMatrix_WITH_CHECKING
1033 DUNE_THROW(FMatrixError,
"matrix is singular");
1037 field_type
temp=(*this)[0][0];
1038 (*this)[0][0] = (*this)[1][1]*
detinv;
1039 (*this)[0][1] = -(*this)[0][1]*
detinv;
1040 (*this)[1][0] = -(*this)[1][0]*
detinv;
1046 using K = field_type;
1048 K
t4 = (*this)[0][0] * (*this)[1][1];
1049 K
t6 = (*this)[0][0] * (*this)[1][2];
1050 K
t8 = (*this)[0][1] * (*this)[1][0];
1051 K
t10 = (*this)[0][2] * (*this)[1][0];
1052 K
t12 = (*this)[0][1] * (*this)[2][0];
1053 K
t14 = (*this)[0][2] * (*this)[2][0];
1055 K
det = (
t4*(*this)[2][2]-
t6*(*this)[2][1]-
t8*(*this)[2][2]+
1056 t10*(*this)[2][1]+
t12*(*this)[1][2]-
t14*(*this)[1][1]);
1064 (*this)[0][0] = ((*this)[1][1] * (*this)[2][2] - (*this)[1][2] * (*this)[2][1])*
t17;
1065 (*this)[0][1] = -((*this)[0][1] * (*this)[2][2] - (*this)[0][2] * (*this)[2][1])*
t17;
1066 (*this)[0][2] = (
matrix01 * (*this)[1][2] - (*this)[0][2] * (*this)[1][1])*
t17;
1067 (*this)[1][0] = -((*this)[1][0] * (*this)[2][2] - (*this)[1][2] * (*this)[2][0])*
t17;
1072 (*this)[2][2] = (
t4-
t8) *
t17;
1078 std::vector<simd_index_type>
pivot(rows());
1079 Simd::Mask<typename FieldTraits<value_type>::real_type>
1095 (*
this)[
i][
k] -=
L[
i][
j]*(*this)[
j][
k];
1102 (*
this)[
i][
k] -=
U[
i][
j]*(*this)[
j][
k];
1103 (*this)[
i][
k] /=
U[
i][
i];
1122 template<
typename MAT>
1128 DUNE_THROW(FMatrixError,
"There is no determinant for a " << rows() <<
"x" << cols() <<
" matrix!");
1131 return (*
this)[0][0];
1134 return (*
this)[0][0]*(*this)[1][1] - (*this)[0][1]*(*this)[1][0];
1138 field_type
t4 = (*this)[0][0] * (*this)[1][1];
1139 field_type
t6 = (*this)[0][0] * (*this)[1][2];
1140 field_type
t8 = (*this)[0][1] * (*this)[1][0];
1141 field_type
t10 = (*this)[0][2] * (*this)[1][0];
1142 field_type
t12 = (*this)[0][1] * (*this)[2][0];
1143 field_type
t14 = (*this)[0][2] * (*this)[2][0];
1145 return (
t4*(*
this)[2][2]-
t6*(*
this)[2][1]-
t8*(*
this)[2][2]+
1146 t10*(*
this)[2][1]+
t12*(*
this)[1][2]-
t14*(*
this)[1][1]);
1152 Simd::Mask<typename FieldTraits<value_type>::real_type>
1165 namespace DenseMatrixHelp {
1168 template <
typename MAT,
typename V1,
typename V2>
1175 for(size_type
i=0;
i<
matrix.rows(); ++
i)
1178 for(size_type
j=0;
j<
matrix.cols(); ++
j)
1187 template <
typename K,
int rows,
int cols>
1192 for(size_type
i=0;
i<cols(); ++
i)
1195 for(size_type
j=0;
j<rows(); ++
j)
1201 template <
typename K,
int rows,
int cols>
1202 static inline FieldVector<K,rows> mult(
const FieldMatrix<K,rows,cols> &matrix,
const FieldVector<K,cols> & x)
1204 FieldVector<K,rows> ret;
1210 template <
typename K,
int rows,
int cols>
1211 static inline FieldVector<K,cols> multTransposed(
const FieldMatrix<K,rows,cols> &matrix,
const FieldVector<K,rows> & x)
1213 FieldVector<K,cols> ret;
1214 multAssignTransposed( matrix, x, ret );
1222 template<
typename MAT>
1226 s <<
a[
i] << std::endl;
A few common exception classes.
Some useful basic math stuff.
Macro for wrapping boundary checks.
Traits for type conversions and type information.
Implements a scalar vector view wrapper around an existing scalar.
A free function to provide the demangled class name of a given object or type as a string.
Implements a vector constructed from a given type representing a field and a compile-time given size.
Various precision settings for calculations with FieldMatrix and FieldVector.
iterator begin()
Get an iterator that is positioned at the first element.
Definition arraylist.hh:517
size_type size() const
Get the number of elements in the list.
Definition arraylist.hh:472
ArrayList()
Constructs an Array list with one chunk.
Definition arraylist.hh:457
#define DUNE_ASSERT_BOUNDS(cond)
If DUNE_CHECK_BOUNDS is defined: check if condition cond holds; otherwise, do nothing.
Definition boundschecking.hh:30
iterator end()
Get a random access iterator positioned after the last element.
Definition arraylist.hh:529
std::ostream & operator<<(std::ostream &s, const bigunsignedint< k > &x)
Definition bigunsignedint.hh:278
#define DUNE_THROW(E, m)
Definition exceptions.hh:218
bool anyTrue(const Mask &mask)
Whether any entry is true
Definition simd/interface.hh:429
V cond(M &&mask, const V &ifTrue, const V &ifFalse)
Like the ?: operator.
Definition simd/interface.hh:386
bool allTrue(const Mask &mask)
Whether all entries are true
Definition simd/interface.hh:439
typename Overloads::RebindType< std::decay_t< S >, std::decay_t< V > >::type Rebind
Construct SIMD type with different scalar type.
Definition simd/interface.hh:252
constexpr std::size_t lanes()
Number of lanes in a SIMD type.
Definition simd/interface.hh:305
decltype(auto) lane(std::size_t l, V &&v)
Extract an element of a SIMD type.
Definition simd/interface.hh:324
Mask< V > mask(ADLTag< 0, std::is_same< V, Mask< V > >::value >, const V &v)
implements Simd::mask()
Definition defaults.hh:153
Dune namespace.
Definition alignedallocator.hh:13
void swap(T &v1, T &v2, bool mask)
Definition simd.hh:472
int sign(const T &val)
Return the sign of the value.
Definition math.hh:180
K conjugateComplex(const K &x)
compute conjugate complex of x
Definition math.hh:164
static void multAssign(const DenseMatrix< MAT > &matrix, const DenseVector< V1 > &x, DenseVector< V2 > &ret)
calculates ret = matrix * x
Definition densematrix.hh:1169
A dynamically growing random access list.
Definition arraylist.hh:62
T value_type
Value type for stl compliance.
Definition arraylist.hh:74
std::size_t size_type
The size type.
Definition arraylist.hh:115
A dense n x m matrix.
Definition densematrix.hh:140
ConstIterator const_iterator
typedef for stl compliant access
Definition densematrix.hh:244
derived_type operator-() const
Matrix negation.
Definition densematrix.hh:298
void solve(V1 &x, const V2 &b, bool doPivoting=true) const
Solve system A x = b.
void mv(const X &x, Y &y) const
y = A x
Definition densematrix.hh:368
Traits::value_type field_type
export the type representing the field
Definition densematrix.hh:160
derived_type & axpy(const field_type &a, const DenseMatrix< Other > &x)
vector space axpy operation (*this += a x)
Definition densematrix.hh:338
ConstIterator beforeEnd() const
Definition densematrix.hh:264
derived_type & operator=(const RHS &rhs)
Definition densematrix.hh:279
void mmtv(const X &x, Y &y) const
y -= A^T x
Definition densematrix.hh:458
FieldTraits< vt >::real_type infinity_norm_real() const
simplified infinity norm (uses Manhattan norm for complex values)
Definition densematrix.hh:561
std::remove_reference< const_row_reference >::type::ConstIterator ConstColIterator
rename the iterators for easier access
Definition densematrix.hh:248
ConstIterator beforeBegin() const
Definition densematrix.hh:271
void invert(bool doPivoting=true)
Compute inverse.
static void luDecomposition(DenseMatrix< MAT > &A, Func func, Mask &nonsingularLanes, bool throwEarly, bool doPivoting)
do an LU-Decomposition on matrix A
Traits::value_type block_type
export the type representing the components
Definition densematrix.hh:163
void mtv(const X &x, Y &y) const
y = A^T x
Definition densematrix.hh:387
constexpr size_type cols() const
number of columns
Definition densematrix.hh:715
size_type size() const
size method (number of rows)
Definition densematrix.hh:200
constexpr size_type M() const
number of columns
Definition densematrix.hh:703
MAT & rightmultiply(const DenseMatrix< M2 > &M)
Multiplies M from the right to this matrix.
Definition densematrix.hh:645
Iterator end()
end iterator
Definition densematrix.hh:222
Iterator beforeBegin()
Definition densematrix.hh:236
derived_type & operator/=(const field_type &k)
vector space division by scalar
Definition densematrix.hh:329
derived_type & operator*=(const field_type &k)
vector space multiplication with scalar
Definition densematrix.hh:321
Iterator beforeEnd()
Definition densematrix.hh:229
Traits::value_type value_type
export the type representing the field
Definition densematrix.hh:157
void usmv(const typename FieldTraits< Y >::field_type &alpha, const X &x, Y &y) const
y += alpha A x
Definition densematrix.hh:484
void usmhv(const typename FieldTraits< Y >::field_type &alpha, const X &x, Y &y) const
y += alpha A^H x
Definition densematrix.hh:512
void mmv(const X &x, Y &y) const
y -= A x
Definition densematrix.hh:445
constexpr size_type rows() const
number of rows
Definition densematrix.hh:709
MAT & leftmultiply(const DenseMatrix< M2 > &M)
Multiplies M from the left to this matrix.
Definition densematrix.hh:627
void usmtv(const typename FieldTraits< Y >::field_type &alpha, const X &x, Y &y) const
y += alpha A^T x
Definition densematrix.hh:498
derived_type & operator-=(const DenseMatrix< Other > &x)
vector space subtraction
Definition densematrix.hh:312
bool operator!=(const DenseMatrix< Other > &x) const
Binary matrix incomparison.
Definition densematrix.hh:358
void mmhv(const X &x, Y &y) const
y -= A^H x
Definition densematrix.hh:471
Traits::derived_type derived_type
type of derived matrix class
Definition densematrix.hh:154
row_reference operator[](size_type i)
random access
Definition densematrix.hh:189
bool exists(size_type i, size_type j) const
return true when (i,j) is in pattern
Definition densematrix.hh:723
Iterator RowIterator
rename the iterators for easier access
Definition densematrix.hh:211
static constexpr int blocklevel
The number of block levels we contain. This is the leaf, that is, 1.
Definition densematrix.hh:178
FieldTraits< value_type >::real_type frobenius_norm() const
frobenius norm: sqrt(sum over squared values of entries)
Definition densematrix.hh:528
void umv(const X &x, Y &y) const
y += A x
Definition densematrix.hh:406
DenseIterator< const DenseMatrix, const row_type, const_row_reference > ConstIterator
Iterator class for sequential access.
Definition densematrix.hh:242
FieldTraits< vt >::real_type infinity_norm() const
infinity norm (row sum norm, how to generalize for blocks?)
Definition densematrix.hh:546
Traits::row_type row_type
The type used to represent a row (must fulfill the Dune::DenseVector interface)
Definition densematrix.hh:169
constexpr size_type N() const
number of rows
Definition densematrix.hh:697
Traits::size_type size_type
The type used for the index access and size operation.
Definition densematrix.hh:166
Traits::const_row_reference const_row_reference
The type used to represent a reference to a constant row (usually const row_type &)
Definition densematrix.hh:175
FieldTraits< value_type >::real_type frobenius_norm2() const
square of frobenius norm, need for block recursion
Definition densematrix.hh:536
std::remove_reference< row_reference >::type::Iterator ColIterator
rename the iterators for easier access
Definition densematrix.hh:213
Traits::row_reference row_reference
The type used to represent a reference to a row (usually row_type &)
Definition densematrix.hh:172
bool operator==(const DenseMatrix< Other > &x) const
Binary matrix comparison.
Definition densematrix.hh:348
Iterator iterator
typedef for stl compliant access
Definition densematrix.hh:209
ConstIterator ConstRowIterator
rename the iterators for easier access
Definition densematrix.hh:246
DenseIterator< DenseMatrix, row_type, row_reference > Iterator
Iterator class for sequential access.
Definition densematrix.hh:207
void umtv(const X &x, Y &y) const
y += A^T x
Definition densematrix.hh:419
ConstIterator begin() const
begin iterator
Definition densematrix.hh:251
field_type determinant(bool doPivoting=true) const
calculates the determinant of this matrix
Iterator begin()
begin iterator
Definition densematrix.hh:216
void umhv(const X &x, Y &y) const
y += A^H x
Definition densematrix.hh:432
derived_type & operator+=(const DenseMatrix< Other > &x)
vector space addition
Definition densematrix.hh:289
ConstIterator end() const
end iterator
Definition densematrix.hh:257
const FieldTraits< typenameDenseMatVecTraits< M >::value_type >::real_type real_type
Definition densematrix.hh:34
const FieldTraits< typenameDenseMatVecTraits< M >::value_type >::field_type field_type
Definition densematrix.hh:33
A dense n x m matrix.
Definition fmatrix.hh:117
Base::size_type size_type
Definition fmatrix.hh:127
vector space out of a tensor product of fields.
Definition fvector.hh:95
you have to specialize this structure for any type that should be assignable to a DenseMatrix
Definition densematrix.hh:59
Error thrown if operations of a FieldMatrix fail.
Definition densematrix.hh:126
Default exception class for mathematical errors.
Definition exceptions.hh:241
T field_type
export the type representing the field
Definition ftraits.hh:28
T real_type
export the type representing the real type of the field
Definition ftraits.hh:30
static ctype absolute_limit()
return threshold to declare matrix singular
Definition precision.hh:28
Include file for users of the SIMD abstraction layer.