13#ifndef DYNAMICMATRIX_HH
14#define DYNAMICMATRIX_HH
16#include "dune/common/config.h"
22#include "dune/common/dynvector.hh"
23#include "dune/common/densematrix.hh"
24#include "dune/common/fmatrix.hh"
33 template <
class B,
class A>
40 template<
class K>
class DynamicMatrix;
42 namespace DynamicMatrixDetail {
51 template <
class EntryA,
class EntryB,
class Enable=
void>
struct ProductTraits;
53 template <
class Scalar>
54 struct ProductTraits<Scalar,Scalar,std::enable_if_t<std::is_arithmetic_v<Scalar>>>
59 template <
class EntryA,
class EntryB,
int n,
int m,
int k>
77 typedef Dune::DenseVector<Self> Base;
78 using Entry = std::remove_const_t<K>;
152 static K *
from(K & k) {
return &k; }
153 static K
const*
from(K
const& k) {
return &k; }
156 template <
class K,
int n,
int m>
165 template <
class K,
int n>
174 template <
class K,
class A>
190 template <
class A,
class B>
196 assert(!std::isnan(b));
200 template <
class A,
class B,
int n,
int m>
205 for (
int i=0; i<n; ++i)
206 for (
int j=0; j<n; ++j)
214 void gemv(
bool transpose,
int n,
int m,
double alpha,
double const* A,
int lda,
double const* x,
double beta,
double* y);
215 void gemv(
bool transpose,
int n,
int m,
float alpha,
float const* A,
int lda,
float const* x,
float beta,
float * y);
223 void gemm(
bool transposeA,
bool transposeB,
int m,
int n,
int k,
double alpha,
double const* A,
int lda,
double const* B,
int ldb,
224 double beta,
double* C,
int ldc);
225 void gemm(
bool transposeA,
bool transposeB,
int m,
int n,
int k,
float alpha,
float const* A,
int lda,
float const* B,
int ldb,
226 float beta,
float* C,
int ldc);
232 template <
class Scalar>
238 template <
class Entry,
int n,
int m>
242 return scalarEntry(A[row/L::rows][col/L::cols],row%L::rows,col%L::cols);
245 template <
class Entry,
int n,
int m>
249 return scalarEntry(A[row/L::rows][col/L::cols],row%L::rows,col%L::cols);
252 template <
class Entry>
256 return scalarEntry(A[row/L::rows][col/L::cols],row%L::rows,col%L::cols);
259 template <
class Entry>
263 return scalarEntry(A[row/L::rows][col/L::cols],row%L::rows,col%L::cols);
270 template <
class Scalar,
class enable =
typename std::enable_if_t<std::is_
floating_po
int_v<Scalar>,
int>>
277 template <
class Entry,
int n,
int m>
283 for (
int j=0; j<B.M(); ++j)
284 for (
int i=0; i<B.N(); ++i)
289 template <
class Entry>
294 A.
resize(B.N()/L::rows,B.M()/L::cols);
296 for (
int j=0; j<B.M(); ++j)
297 for (
int i=0; i<B.N(); ++i)
312 template <
class DenseMatrix>
313 class DenseMatrixAssigner<DenseMatrix, typename DenseMatrix::value_type,
314 std::enable_if_t<!Dune::IsNumber<typename DenseMatrix::value_type>::value>>
317 static void apply(DenseMatrix& denseMatrix,
typename DenseMatrix::value_type
const& a)
319 std::fill(denseMatrix.begin(),denseMatrix.end(),a);
326 struct DenseMatVecTraits<
Kaskade::DynamicMatrix<K>>
341 struct DenseMatVecTraits<
Kaskade::DynamicMatrixDetail::StridedVector<K>>
347 typedef typename std::vector<typename std::remove_const<K>::type>::size_type
size_type;
379 typedef Dune::DenseMatrix<DynamicMatrix<K>> Base;
381 typedef typename Base::row_reference row_reference;
382 typedef typename Base::const_row_reference const_row_reference;
390 using field_type =
typename Dune::FieldTraits<K>::field_type;
408 template <
class OtherK>
416 template <
class OtherK>
424 int n = A.N()*otherRows;
425 int m = A.M()*otherCols;
432 for (
int j=0; j<m; ++j)
433 for (
int i=0; i<n; ++i)
446 rs(r), cs(c), dat(r*c,v)
456 using Base::operator=;
474 template <
class OtherK>
478 "assignment only from compatible entries");
508 for (
int i=0; i<rs*cs; ++i)
521 template <
class RRange,
class CRange>
525 for (
int c=0; c<cidx.size(); ++c)
526 for (
int r=0; r<ridx.size(); ++r)
527 B[r][c] = (*
this)[ridx[r]][cidx[c]];
548 template<
class X,
class Y>
549 void mv (
const X& x,
Y& y)
const
551 using namespace DynamicMatrixDetail;
557 GetAddress<typename X::value_type>::from(x[0]),
558 0.0,GetAddress<typename Y::value_type>::from(y[0]));
567 y[i] += (*
this)[i][j] * x[j];
577 template <
class X,
class Y>
580 for (
int i=0; i<this->M(); ++i)
591 template <
class X,
class Y>
608 template <
class X,
class Y>
609 void usmv(
typename Dune::FieldTraits<Y>::field_type alpha,
X const& x,
Y& y)
const
611 using namespace DynamicMatrixDetail;
615 GetAddress<typename X::value_type>::from(x[0]),
616 1.0,GetAddress<typename Y::value_type>::from(y[0]));
620 typename Y::value_type tmp(0.0);
622 tmp += (*
this)[i][j] * x[j];
638 template <
class X,
class Y>
639 void usmtv(
typename Dune::FieldTraits<Y>::field_type alpha,
X const& x,
Y& y)
const
641 using namespace DynamicMatrixDetail;
645 GetAddress<typename X::value_type>::from(x[0]),
646 1.0,GetAddress<typename Y::value_type>::from(y[0]));
650 y[i] += alpha * (
transpose((*
this)[j][i]) * x[j]);
715 template <
class OtherK>
716 void copy(std::vector<OtherK>
const& a, std::vector<K>& b)
718 for (
size_t i=0; i<a.size(); ++i)
731 template <
class Entry>
734 using namespace DynamicMatrixDetail;
737 int n = A.N()*L::rows;
738 int m = A.M()*L::cols;
740 for (
int i=0; i<n; ++i)
742 for (
int j=0; j<m; ++j)
749 template <class T, typename = std::enable_if_t<std::is_arithmetic<T>::value>>
763 template <
class Entry>
764 DynamicMatrix<typename EntryTraits<Entry>::transpose_type>
768 for (
int j=0; j<C.M(); ++j)
769 for (
int i=0; i<C.N(); ++i)
779 namespace DynamicMatrixDetail
781 template <
class Scalar>
782 std::tuple<DynamicMatrix<Dune::FieldMatrix<Scalar,1,1>>,
783 std::vector<typename ScalarTraits<Scalar>::Real>,
803 template <
class Entry>
804 std::tuple<DynamicMatrix<Dune::FieldMatrix<typename EntryTraits<Entry>::field_type,1,1>>,
805 std::vector<typename EntryTraits<Entry>::real_type>,
810 return DynamicMatrixDetail::svd(Acopy);
823 template <
class Entry>
828 auto sigma = std::get<1>(svd(A));
829 return *std::max_element(begin(sigma),end(sigma));
843 template <
class Entry>
846 assert(A.N() == A.M());
850 auto sigma = std::get<1>(svd(A));
851 auto minmax = std::minmax_element(begin(sigma),end(sigma));
852 if (*minmax.first <= 0)
853 return std::numeric_limits<typename EntryTraits<Entry>::real_type>::infinity();
855 return *minmax.second / *minmax.first;
867 template <
class MEntry,
class Vector>
881 template <
class MEntry,
class Vector>
890 template <
class Scalar>
904 template <
class Entry>
917 template <
class Entry>
928 template <
class Entry>
941 template <
class Entry>
943 bool computeEigenvectors=
true);
951 template <
class Scalar,
int d>
967 template <
class Scalar,
int d>
978 template <
class Scalar,
int d>
989 template <
class Entry>
1013 template <
class Entry>
1014 std::tuple<std::vector<typename EntryTraits<Entry>::field_type>,
1036 template<
int dimIn,
int dimOut>
1039 assert( (dimIn == 1 && b.N()%dimOut == 0) || (dimIn > 1 && dimOut == 1) );
1045 c.resize(b.N()/dimOut);
1046 for(
auto i=c.begin(); i!=c.end(); ++i)
1047 for(
int k=0; k<dimOut; ++k)
1048 c[i.index()][k] = b[i.index()*dimOut+k][0];
1051 c.resize(b.N()*dimIn);
1052 for(
auto i=b.begin(); i!=b.end(); ++i)
1053 for(
int k=0; k<dimIn; ++k)
1054 c[i.index()*dimIn+k][0] = b[i.index()][k];
static void apply(DenseMatrix &denseMatrix, typename DenseMatrix::value_type const &a)
real_type two_norm() const
typename Base::size_type size_type
value_type const & _access(size_type i) const
StridedVector(StridedVector const &x)
Self & operator-=(StridedVector< X > const &x)
StridedVector & operator=(K const &x)
value_type const & vec_access(size_type i) const
value_type & operator[](size_type i)
StridedVector & operator=(StridedVector const &v)=default
typename EntryTraits< Entry >::real_type real_type
size_type vec_size() const
StridedVector(K *p_, size_type n_, size_type stride_)
Constructor.
real_type two_norm2() const
value_type & vec_access(size_type i)
Self & operator+=(StridedVector< X > const &x)
value_type & _access(size_type i)
typename Base::size_type size_type
field_type * data()
Raw access to data (for calling BLAS/LAPACK).
void setSize(size_type r, size_type c)
Resizes the matrix to r x c, leaving the entries in an undefined state.
void resize(size_type r, size_type c)
Resizes the matrix to r x c, leaving the entries in an undefined state.
void mv(const X &x, Y &y) const
matrix-vector product
row_reference mat_access(size_type i)
field_type const * data() const
Raw access to data (for calling BLAS/LAPACK).
DynamicMatrix & operator=(DynamicMatrix const &a)=default
Copy assignment.
size_type lda() const
The leading dimension (for calling BLAS/LAPACK).
size_type mat_rows() const
typename Base::value_type value_type
const_row_reference mat_access(size_type i) const
DynamicMatrix()
Creates a 0 x 0 matrix.
void umtv(const X &x, Y &y) const
update transpose matrix vector product .
size_type mat_cols() const
DynamicMatrix & operator=(DynamicMatrix &&a)=default
Move assignment.
DynamicMatrix & operator=(DynamicMatrix< OtherK > const &A)
Assignment from matrix with other scalar type.
DynamicMatrix(size_type r, size_type c, value_type v=value_type())
Creates a r x c matrix, initialized with given value.
typename Dune::FieldTraits< K >::field_type field_type
DynamicMatrix & operator*=(field_type s)
Scales the matrix by a scalar: .
void usmv(typename Dune::FieldTraits< Y >::field_type alpha, X const &x, Y &y) const
update and scale matrix vector product .
DynamicMatrix operator()(RRange const &ridx, CRange const &cidx) const
Submatrix extraction.
std::ostream & operator<<(std::ostream &out, DynamicMatrix< Entry > const &A)
pretty output of dense matrices
DynamicMatrix(Self &&a)=default
Move constructor.
void usmtv(typename Dune::FieldTraits< Y >::field_type alpha, X const &x, Y &y) const
update and scale transposed matrix vector product .
DynamicMatrix(Self const &a)=default
Copy constructor.
void mtv(const X &x, Y &y) const
transpose matrix vector product
DynamicMatrix(DynamicMatrix< OtherK > const &A)
Copies from a matrix with different entry type.
Helper class for working with (real or complex) scalar field types.
This file contains various utility functions that augment the basic functionality of Dune.
void gemm(bool transposeA, bool transposeB, int m, int n, int k, double alpha, double const *A, int lda, double const *B, int ldb, double beta, double *C, int ldc)
computes
Vector gesv(DynamicMatrix< MEntry > const &A, Vector const &b)
Computes the solution of for general invertible matrices.
bool makePositiveSemiDefinite(DynamicMatrix< Entry > &A, typename ScalarTraits< typename EntryTraits< Entry >::field_type >::Real threshold=0)
Computes a positive semi-definite approximation to by cutting off negative eigenvalues.
bool makePositiveSemiDefinite(Dune::FieldMatrix< Scalar, d, d > &A)
Computes a positive semi-definite approximation to by cutting off negative eigenvalues.
std::vector< typename EntryTraits< Entry >::real_type > eig(DynamicMatrix< Entry > &A, bool computeEigenvectors=true)
Computes the eigenvalues and eigenvectors of a symmetric matrix .
EntryTraits< Entry >::real_type two_norm(DynamicMatrix< Entry > const &A)
Computes the spectral norm of the given matrix.
DynamicMatrix< Entry > & invertSpd(DynamicMatrix< Entry > &A, bool symmetrize=true)
In place computation of the inverse .
std::tuple< DynamicMatrix< Dune::FieldMatrix< typename EntryTraits< Entry >::field_type, 1, 1 > >, std::vector< typename EntryTraits< Entry >::real_type >, DynamicMatrix< Dune::FieldMatrix< typename EntryTraits< Entry >::field_type, 1, 1 > > > svd(DynamicMatrix< Entry > const &A)
Computes the singular value decomposition .
void invert(DynamicMatrix< Scalar > &A)
Computes the inverse .
Dune::FieldVector< Scalar, d > eigenvalues(Dune::FieldMatrix< Scalar, d, d > A)
Computes the eigenvalues of a symmetric matrix .
std::vector< typename EntryTraits< Entry >::real_type > eigenvalues(DynamicMatrix< Entry > A)
Computes the eigenvalues of a symmetric matrix .
EntryTraits< Entry >::real_type condition(DynamicMatrix< Entry > const &A)
Computes the condition number of the given square matrix.
Dune::FieldVector< Scalar, d > eig(Dune::FieldMatrix< Scalar, d, d > &A, bool computeEigenvectors=true)
Computes the eigenvalues and eigenvectors of a symmetric matrix .
DynamicMatrix< typename EntryTraits< Entry >::transpose_type > pseudoinverse(DynamicMatrix< Entry > A)
Computes the right pseudoinverse of a wide matrix such that .
std::tuple< std::vector< typename EntryTraits< Entry >::field_type >, DynamicMatrix< typename EntryTraits< Entry >::field_type >, std::vector< int > > qr(DynamicMatrix< Entry > const &A)
Computes a rank-revealing QR decomposition of using column pivoting.
Vector posv(DynamicMatrix< MEntry > const &A, Vector const &b)
Computes the solution of if is symmetric positive definite.
DynamicMatrix< typename EntryTraits< Entry >::transpose_type > transpose(DynamicMatrix< Entry > const &A)
Computes the transpose of a matrix.
void gemv(bool transpose, int n, int m, double alpha, double const *A, int lda, double const *x, double beta, double *y)
double transpose(double x)
void gemv(bool transpose, int n, int m, float alpha, float const *A, int lda, float const *x, float beta, float *y)
EntryTraits< Entry >::field_type & scalarEntry(DynamicMatrix< Entry > &A, int row, int col)
void unflatten(DynamicMatrix< Entry > &A, DynamicMatrix< typename EntryTraits< Entry >::field_type > const &B)
Scalar & scalarEntry(Scalar &x, int row, int col)
DynamicMatrix< Scalar > flatMatrix(DynamicMatrix< Scalar > const &A)
Dune::BlockVector< Dune::FieldVector< Scalar, n >, Allocator > BlockVector
Dune::FieldVector< Scalar, dim > Vector
Dune::BlockVector< Dune::FieldVector< double, dimOut > > reshapeBlocks(Dune::BlockVector< Dune::FieldVector< double, dimIn > > const &b)
reshapes a Dune::BlockVector block structure
Kaskade::DynamicMatrixDetail::StridedVector< K const > const_row_type
std::vector< K > container_type
Kaskade::DynamicMatrix< K > derived_type
Kaskade::DynamicMatrixDetail::StridedVector< K > row_type
container_type::size_type size_type
const_row_type const_row_reference
std::vector< typenamestd::remove_const< K >::type >::size_type size_type
Kaskade::DynamicMatrixDetail::StridedVector< K > derived_type
FieldTraits< K >::field_type field_type
FieldTraits< K >::real_type real_type
static void apply(Dune::FieldMatrix< A, n, m > const &a, Dune::FieldMatrix< B, n, m > &b)
static void apply(A const &a, B &b)
static field_type const * from(Dune::BlockVector< K, A > const &k)
typename EntryTraits< K >::field_type field_type
static field_type * from(Dune::BlockVector< K, A > &k)
static field_type const * from(Dune::FieldMatrix< K, n, m > const &k)
static field_type * from(Dune::FieldMatrix< K, n, m > &k)
typename EntryTraits< K >::field_type field_type
typename EntryTraits< K >::field_type field_type
static field_type const * from(Dune::FieldVector< K, n > const &k)
static field_type * from(Dune::FieldVector< K, n > &k)
static K const * from(K const &k)
typename ScalarTraits< field_type >::Real real_type
static int const lapackLayout