5 #ifndef DUNE_FMATRIX_HH 6 #define DUNE_FMATRIX_HH 12 #include <initializer_list> 30 class ColumnVectorView
34 using value_type =
typename M::value_type;
35 using size_type =
typename M::size_type;
37 constexpr ColumnVectorView(M& matrix, size_type col) :
42 constexpr size_type N ()
const {
46 template<
class M_ = M,
47 std::enable_if_t<std::is_same_v<M_,M> and not std::is_const_v<M_>,
int> = 0>
48 constexpr value_type& operator[] (size_type row) {
49 return matrix_[row][col_];
52 constexpr
const value_type& operator[] (size_type row)
const {
53 return matrix_[row][col_];
64 struct FieldTraits< Impl::ColumnVectorView<M> >
81 template<
class K,
int ROWS,
int COLS = ROWS >
class FieldMatrix;
84 template<
class K,
int ROWS,
int COLS >
97 typedef typename container_type::size_type
size_type;
100 template<
class K,
int ROWS,
int COLS >
115 template<
class K,
int ROWS,
int COLS>
119 std::array< FieldVector<K,COLS>, ROWS > _data;
124 constexpr
static int rows = ROWS;
126 constexpr
static int cols = COLS;
142 assert(l.size() ==
rows);
143 for(std::size_t
i=0; i<std::min<std::size_t>(ROWS, l.size()); ++
i)
144 _data[
i] = std::data(l)[
i];
152 typename = std::enable_if_t<HasDenseMatrixAssigner<FieldMatrix, T>::value>>
159 using Base::operator=;
170 for (std::size_t
i = 0;
i < _data.size(); ++
i)
171 _data[
i] = x._data[
i];
176 template <
typename T,
int rows,
int cols>
183 for(
int i = 0;
i < ROWS; ++
i )
184 for(
int j = 0; j < COLS; ++j )
185 AT[j][
i] = (*
this)[
i][j];
190 template <
class OtherScalar>
198 result[
i][j] = matrixA[
i][j] + matrixB[
i][j];
204 template <
class OtherScalar>
212 result[
i][j] = matrixA[
i][j] - matrixB[
i][j];
219 std::enable_if_t<IsNumber<Scalar>::value,
int> = 0>
226 result[
i][j] = matrix[
i][j] * scalar;
233 std::enable_if_t<IsNumber<Scalar>::value,
int> = 0>
240 result[
i][j] = scalar * matrix[
i][j];
247 std::enable_if_t<IsNumber<Scalar>::value,
int> = 0>
254 result[
i][j] = matrix[
i][j] / scalar;
261 template <
class OtherScalar,
int otherCols>
272 result[
i][j] += matrixA[
i][k] * matrixB[k][j];
284 template <
class OtherMatrix, std::enable_if_t<
285 Impl::IsStaticSizeMatrix_v<OtherMatrix>
286 and not Impl::IsFieldMatrix_v<OtherMatrix>
289 const OtherMatrix& matrixB)
293 for (std::size_t j=0; j<
rows; ++j)
294 matrixB.
mtv(matrixA[j], result[j]);
304 template <
class OtherMatrix, std::enable_if_t<
305 Impl::IsStaticSizeMatrix_v<OtherMatrix>
306 and not Impl::IsFieldMatrix_v<OtherMatrix>
308 friend constexpr
auto operator* (
const OtherMatrix& matrixA,
313 for (std::size_t j=0; j<
cols; ++j)
315 auto B_j = Impl::ColumnVectorView(matrixB, j);
316 auto result_j = Impl::ColumnVectorView(result, j);
317 matrixA.mv(B_j, result_j);
332 C[
i][j] +=
M[
i][k]*(*
this)[k][j];
341 template <
int r,
int c>
344 static_assert(r == c,
"Cannot rightmultiply with non-square matrix");
345 static_assert(r ==
cols,
"Size mismatch");
352 (*
this)[
i][j] += C[
i][k]*
M[k][j];
367 C[
i][j] += (*
this)[
i][k]*
M[k][j];
390 #ifndef DOXYGEN // hide specialization 394 class FieldMatrix<K,1,1> :
public DenseMatrix< FieldMatrix<K,1,1> >
396 FieldVector<K,1> _data;
397 typedef DenseMatrix< FieldMatrix<K,1,1> > Base;
417 constexpr
static int rows = 1;
420 constexpr
static int cols = 1;
431 std::copy_n(l.begin(), std::min<std::size_t>(1, l.size()), &_data);
435 typename = std::enable_if_t<HasDenseMatrixAssigner<FieldMatrix, T>::value>>
441 using Base::operator=;
444 constexpr FieldMatrix<K, 1, 1>
transposed()
const 450 template <
class OtherScalar>
452 const FieldMatrix<OtherScalar,1,1>& matrixB)
454 return FieldMatrix<typename PromotionTraits<K,OtherScalar>::PromotedType,1,1>{matrixA[0][0] + matrixB[0][0]};
459 std::enable_if_t<IsNumber<Scalar>::value,
int> = 0>
463 return FieldMatrix<typename PromotionTraits<K,Scalar>::PromotedType,1,1>{matrix[0][0] + scalar};
468 std::enable_if_t<IsNumber<Scalar>::value,
int> = 0>
472 return FieldMatrix<typename PromotionTraits<Scalar,K>::PromotedType,1,1>{scalar + matrix[0][0]};
476 template <
class OtherScalar>
478 const FieldMatrix<OtherScalar,1,1>& matrixB)
480 return FieldMatrix<typename PromotionTraits<K,OtherScalar>::PromotedType,1,1>{matrixA[0][0] - matrixB[0][0]};
485 std::enable_if_t<IsNumber<Scalar>::value,
int> = 0>
489 return FieldMatrix<typename PromotionTraits<K,Scalar>::PromotedType,1,1>{matrix[0][0] - scalar};
494 std::enable_if_t<IsNumber<Scalar>::value,
int> = 0>
498 return FieldMatrix<typename PromotionTraits<Scalar,K>::PromotedType,1,1>{scalar - matrix[0][0]};
503 std::enable_if_t<IsNumber<Scalar>::value,
int> = 0>
506 return FieldMatrix<typename PromotionTraits<K,Scalar>::PromotedType,1,1> {matrix[0][0] * scalar};
511 std::enable_if_t<IsNumber<Scalar>::value,
int> = 0>
514 return FieldMatrix<typename PromotionTraits<K,Scalar>::PromotedType,1,1> {scalar * matrix[0][0]};
519 std::enable_if_t<IsNumber<Scalar>::value,
int> = 0>
522 return FieldMatrix<typename PromotionTraits<K,Scalar>::PromotedType,1,1> {matrix[0][0] / scalar};
529 template <
class OtherScalar,
int otherCols>
531 const FieldMatrix<OtherScalar, 1, otherCols>& matrixB)
533 FieldMatrix<typename PromotionTraits<K,OtherScalar>::PromotedType,1,otherCols> result;
535 for (
size_type j = 0; j < matrixB.mat_cols(); ++j)
536 result[0][j] = matrixA[0][0] * matrixB[0][j];
547 template <
class OtherMatrix, std::enable_if_t<
548 Impl::IsStaticSizeMatrix_v<OtherMatrix>
549 and not Impl::IsFieldMatrix_v<OtherMatrix>
550 and (OtherMatrix::rows==1)
553 const OtherMatrix& matrixB)
557 for (std::size_t j=0; j<
rows; ++j)
558 matrixB.mtv(matrixA[j], result[j]);
568 template <
class OtherMatrix, std::enable_if_t<
569 Impl::IsStaticSizeMatrix_v<OtherMatrix>
570 and not Impl::IsFieldMatrix_v<OtherMatrix>
571 and (OtherMatrix::cols==1)
573 friend constexpr
auto operator* (
const OtherMatrix& matrixA,
578 for (std::size_t j=0; j<
cols; ++j)
580 auto B_j = Impl::ColumnVectorView(matrixB, j);
581 auto result_j = Impl::ColumnVectorView(result, j);
582 matrixA.mv(B_j, result_j);
589 constexpr FieldMatrix<K,l,1>
leftmultiplyany (
const FieldMatrix<K,l,1>&
M)
const 591 FieldMatrix<K,l,1> C;
593 C[j][0] =
M[j][0]*(*
this)[0][0];
606 constexpr FieldMatrix<K,1,l>
rightmultiplyany (
const FieldMatrix<K,1,l>&
M)
const 608 FieldMatrix<K,1,l> C;
611 C[0][j] =
M[0][j]*_data[0];
661 constexpr
operator const K& ()
const {
return _data[0]; }
667 std::ostream& operator<< (std::ostream& s, const FieldMatrix<K,1,1>& a)
675 namespace FMatrixHelp {
678 template <
typename K>
682 inverse[0][0] = real_type(1.0)/matrix[0][0];
687 template <
typename K>
695 template <
typename K>
700 K det = (matrix[0][0]*matrix[1][1] - matrix[0][1]*matrix[1][0]);
701 K det_1 = real_type(1.0)/det;
702 inverse[0][0] = matrix[1][1] * det_1;
703 inverse[0][1] = - matrix[0][1] * det_1;
704 inverse[1][0] = - matrix[1][0] * det_1;
705 inverse[1][1] = matrix[0][0] * det_1;
711 template <
typename K>
716 K det = (matrix[0][0]*matrix[1][1] - matrix[0][1]*matrix[1][0]);
717 K det_1 = real_type(1.0)/det;
718 inverse[0][0] = matrix[1][1] * det_1;
719 inverse[1][0] = - matrix[0][1] * det_1;
720 inverse[0][1] = - matrix[1][0] * det_1;
721 inverse[1][1] = matrix[0][0] * det_1;
726 template <
typename K>
731 K t4 = matrix[0][0] * matrix[1][1];
732 K t6 = matrix[0][0] * matrix[1][2];
733 K t8 = matrix[0][1] * matrix[1][0];
734 K t10 = matrix[0][2] * matrix[1][0];
735 K t12 = matrix[0][1] * matrix[2][0];
736 K t14 = matrix[0][2] * matrix[2][0];
738 K det = (t4*matrix[2][2]-t6*matrix[2][1]-t8*matrix[2][2]+
739 t10*matrix[2][1]+t12*matrix[1][2]-t14*matrix[1][1]);
740 K t17 = real_type(1.0)/det;
742 inverse[0][0] = (matrix[1][1] * matrix[2][2] - matrix[1][2] * matrix[2][1])*t17;
743 inverse[0][1] = -(matrix[0][1] * matrix[2][2] - matrix[0][2] * matrix[2][1])*t17;
744 inverse[0][2] = (matrix[0][1] * matrix[1][2] - matrix[0][2] * matrix[1][1])*t17;
745 inverse[1][0] = -(matrix[1][0] * matrix[2][2] - matrix[1][2] * matrix[2][0])*t17;
746 inverse[1][1] = (matrix[0][0] * matrix[2][2] - t14) * t17;
747 inverse[1][2] = -(t6-t10) * t17;
748 inverse[2][0] = (matrix[1][0] * matrix[2][1] - matrix[1][1] * matrix[2][0]) * t17;
749 inverse[2][1] = -(matrix[0][0] * matrix[2][1] - t12) * t17;
750 inverse[2][2] = (t4-t8) * t17;
756 template <
typename K>
761 K t4 = matrix[0][0] * matrix[1][1];
762 K t6 = matrix[0][0] * matrix[1][2];
763 K t8 = matrix[0][1] * matrix[1][0];
764 K t10 = matrix[0][2] * matrix[1][0];
765 K t12 = matrix[0][1] * matrix[2][0];
766 K t14 = matrix[0][2] * matrix[2][0];
768 K det = (t4*matrix[2][2]-t6*matrix[2][1]-t8*matrix[2][2]+
769 t10*matrix[2][1]+t12*matrix[1][2]-t14*matrix[1][1]);
770 K t17 = real_type(1.0)/det;
772 inverse[0][0] = (matrix[1][1] * matrix[2][2] - matrix[1][2] * matrix[2][1])*t17;
773 inverse[1][0] = -(matrix[0][1] * matrix[2][2] - matrix[0][2] * matrix[2][1])*t17;
774 inverse[2][0] = (matrix[0][1] * matrix[1][2] - matrix[0][2] * matrix[1][1])*t17;
775 inverse[0][1] = -(matrix[1][0] * matrix[2][2] - matrix[1][2] * matrix[2][0])*t17;
776 inverse[1][1] = (matrix[0][0] * matrix[2][2] - t14) * t17;
777 inverse[2][1] = -(t6-t10) * t17;
778 inverse[0][2] = (matrix[1][0] * matrix[2][1] - matrix[1][1] * matrix[2][0]) * t17;
779 inverse[1][2] = -(matrix[0][0] * matrix[2][1] - t12) * t17;
780 inverse[2][2] = (t4-t8) * t17;
786 template<
class K,
int m,
int n,
int p >
793 for( size_type
i = 0;
i < m; ++
i )
795 for( size_type j = 0; j < p; ++j )
797 ret[
i ][ j ] = K( 0 );
798 for( size_type k = 0; k < n; ++k )
799 ret[
i ][ j ] += A[
i ][ k ] * B[ k ][ j ];
805 template <
typename K,
int rows,
int cols>
810 for(size_type
i=0;
i<cols;
i++)
811 for(size_type j=0; j<cols; j++)
814 for(size_type k=0; k<rows; k++)
815 ret[
i][j]+=matrix[k][
i]*matrix[k][j];
822 template <
typename K,
int rows,
int cols>
827 for(size_type
i=0;
i<cols; ++
i)
830 for(size_type j=0; j<rows; ++j)
831 ret[
i] += matrix[j][
i]*x[j];
836 template <
typename K,
int rows,
int cols>
845 template <
typename K,
int rows,
int cols>
constexpr const_row_reference mat_access(size_type i) const
Definition: fmatrix.hh:383
static constexpr void multTransposedMatrix(const FieldMatrix< K, rows, cols > &matrix, FieldMatrix< K, cols, cols > &ret)
calculates ret= A_t*A
Definition: fmatrix.hh:806
friend constexpr auto operator+(const FieldMatrix &matrixA, const FieldMatrix< OtherScalar, ROWS, COLS > &matrixB)
vector space addition – two-argument version
Definition: fmatrix.hh:191
decltype(std::declval< T1 >()+std::declval< T2 >()) typedef PromotedType
Definition: promotiontraits.hh:28
constexpr derived_type & operator/=(const field_type &k)
vector space division by scalar
Definition: densematrix.hh:334
static constexpr size_type mat_rows()
Definition: fmatrix.hh:374
constexpr derived_type & operator+=(const DenseMatrix< Other > &x)
vector space addition
Definition: densematrix.hh:294
constexpr FieldMatrix< K, COLS, ROWS > transposed() const
Return transposed of the matrix as FieldMatrix.
Definition: fmatrix.hh:180
container_type::size_type size_type
Definition: fmatrix.hh:97
A dense n x m matrix.
Definition: densematrix.hh:39
row_type & row_reference
Definition: fmatrix.hh:92
Compute type of the result of an arithmetic operation involving two different number types...
Definition: promotiontraits.hh:26
FieldVector< K, COLS > row_type
Definition: fmatrix.hh:90
K value_type
Definition: fmatrix.hh:96
constexpr FieldMatrix(std::initializer_list< Dune::FieldVector< K, cols > > const &l)
Constructor initializing the matrix from a list of vector.
Definition: fmatrix.hh:141
FieldMatrix< K, ROWS, COLS > derived_type
Definition: fmatrix.hh:87
FieldMatrix< K, ROWS, COLS > & rightmultiply(const DenseMatrix< M2 > &M)
Multiplies M from the right to this matrix.
Definition: densematrix.hh:650
constexpr FieldMatrix()=default
Default constructor.
constexpr FieldMatrix(T const &rhs)
copy constructor from assignable type T
Definition: fmatrix.hh:153
constexpr FieldMatrix & operator=(const FieldMatrix &)=default
copy assignment operator
static constexpr size_type mat_cols()
Definition: fmatrix.hh:375
#define DUNE_ASSERT_BOUNDS(cond)
If DUNE_CHECK_BOUNDS is defined: check if condition cond holds; otherwise, do nothing.
Definition: boundschecking.hh:30
Definition: matvectraits.hh:31
Base::const_row_reference const_row_reference
Definition: fmatrix.hh:132
Various precision settings for calculations with FieldMatrix and FieldVector.
I i
Definition: hybridmultiindex.hh:328
T real_type
export the type representing the real type of the field
Definition: ftraits.hh:30
constexpr void mtv(const X &x, Y &y) const
y = A^T x
Definition: densematrix.hh:392
Macro for wrapping boundary checks.
static constexpr FieldVector< K, rows > mult(const FieldMatrix< K, rows, cols > &matrix, const FieldVector< K, cols > &x)
calculates ret = matrix * x
Definition: fmatrix.hh:837
static constexpr int blocklevel
The number of block levels we contain. This is the leaf, that is, 1.
Definition: densematrix.hh:183
Base::row_reference row_reference
Definition: fmatrix.hh:131
constexpr derived_type & operator*=(const field_type &k)
vector space multiplication with scalar
Definition: densematrix.hh:326
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:180
static constexpr FieldVector< K, cols > multTransposed(const FieldMatrix< K, rows, cols > &matrix, const FieldVector< K, rows > &x)
calculates ret = matrix^T * x
Definition: fmatrix.hh:846
typename Overloads::ScalarType< std::decay_t< V > >::type Scalar
Element type of some SIMD type.
Definition: simd/interface.hh:235
Base::size_type size_type
Definition: fmatrix.hh:128
constexpr derived_type & operator-=(const DenseMatrix< Other > &x)
vector space subtraction
Definition: densematrix.hh:317
Traits::size_type size_type
The type used for the index access and size operation.
Definition: densematrix.hh:171
constexpr size_type cols() const
number of columns
Definition: densematrix.hh:720
Dune namespace
Definition: alignedallocator.hh:12
static constexpr void multAssignTransposed(const FieldMatrix< K, rows, cols > &matrix, const FieldVector< K, rows > &x, FieldVector< K, cols > &ret)
calculates ret = matrix^T * x
Definition: fmatrix.hh:823
std::array< row_type, ROWS > container_type
Definition: fmatrix.hh:95
static void multAssign(const DenseMatrix< MAT > &matrix, const DenseVector< V1 > &x, DenseVector< V2 > &ret)
calculates ret = matrix * x
Definition: densematrix.hh:1174
Traits::row_type row_type
The type used to represent a row (must fulfill the Dune::DenseVector interface)
Definition: densematrix.hh:174
friend constexpr auto operator*(const FieldMatrix &matrix, Scalar scalar)
vector space multiplication with scalar
Definition: fmatrix.hh:220
A dense n x m matrix.
Definition: densematrix.hh:30
FieldTraits< K >::real_type real_type
Definition: fmatrix.hh:104
Compute type of the result of an arithmetic operation involving two different number types...
static constexpr K invertMatrix(const FieldMatrix< K, 1, 1 > &matrix, FieldMatrix< K, 1, 1 > &inverse)
invert scalar without changing the original matrix
Definition: fmatrix.hh:679
Definition: ftraits.hh:25
Implements a vector constructed from a given type representing a field and a compile-time given size...
constexpr FieldMatrix< K, l, cols > leftmultiplyany(const FieldMatrix< K, l, rows > &M) const
Multiplies M from the left to this matrix, this matrix is not modified.
Definition: fmatrix.hh:324
constexpr size_type M() const
number of columns
Definition: densematrix.hh:708
constexpr row_reference mat_access(size_type i)
Definition: fmatrix.hh:377
A few common exception classes.
constexpr size_type rows() const
number of rows
Definition: densematrix.hh:714
T field_type
export the type representing the field
Definition: ftraits.hh:28
friend constexpr auto operator/(const FieldMatrix &matrix, Scalar scalar)
vector space division by scalar
Definition: fmatrix.hh:248
Traits::row_reference row_reference
The type used to represent a reference to a row (usually row_type &)
Definition: densematrix.hh:177
constexpr FieldMatrix & operator=(const FieldMatrix< T, ROWS, COLS > &x)
copy assignment from FieldMatrix over a different field
Definition: fmatrix.hh:166
static constexpr K invertMatrix_retTransposed(const FieldMatrix< K, 1, 1 > &matrix, FieldMatrix< K, 1, 1 > &inverse)
invert scalar without changing the original matrix
Definition: fmatrix.hh:688
constexpr derived_type operator-() const
Matrix negation.
Definition: densematrix.hh:303
Implements a matrix constructed from a given type representing a field and a compile-time given numbe...
Traits for type conversions and type information.
Eigenvalue computations for the FieldMatrix class.
constexpr FieldMatrix & rightmultiply(const FieldMatrix< K, r, c > &M)
Multiplies M from the right to this matrix.
Definition: fmatrix.hh:342
const row_type & const_row_reference
Definition: fmatrix.hh:93
Base::row_type row_type
Definition: fmatrix.hh:129
constexpr FieldMatrix< K, rows, l > rightmultiplyany(const FieldMatrix< K, cols, l > &M) const
Multiplies M from the right to this matrix, this matrix is not modified.
Definition: fmatrix.hh:359
FieldTraits< K >::field_type field_type
Definition: fmatrix.hh:103
static constexpr void multMatrix(const FieldMatrix< K, m, n > &A, const FieldMatrix< K, n, p > &B, FieldMatrix< K, m, p > &ret)
calculates ret = A * B
Definition: fmatrix.hh:787