KASKADE 7 development version
dynamicMatrix.hh
Go to the documentation of this file.
1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2/* */
3/* This file is part of the library KASKADE 7 */
4/* https://www.zib.de/research/projects/kaskade7-finite-element-toolbox */
5/* */
6/* Copyright (C) 2013-2023 Zuse Institute Berlin */
7/* */
8/* KASKADE 7 is distributed under the terms of the ZIB Academic License. */
9/* see $KASKADE/academic.txt */
10/* */
11/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
12
13#ifndef DYNAMICMATRIX_HH
14#define DYNAMICMATRIX_HH
15
16#include "dune/common/config.h"
17
18#include "fem/fixdune.hh"
19#include "utilities/scalar.hh"
20
21
22#include "dune/common/dynvector.hh"
23#include "dune/common/densematrix.hh"
24#include "dune/common/fmatrix.hh"
25
26#include <tuple>
27#include <type_traits>
28#include <vector>
29
30namespace Dune
31{
32 // Forward declaration
33 template <class B, class A>
35}
36
37
39namespace Kaskade {
40 template<class K> class DynamicMatrix;
41
42 namespace DynamicMatrixDetail {
43
44 // We support DynamicMatrix<Dune::FieldMatrix<double,n,m>> as well as DynamicMatrix<double>.
45 // Occasionally we need the dimensions of the entry types. For FieldMatrix entries, these
46 // are member enums, while for doubles this is implicitly 1x1. For a uniform access, we define
47 // some traits class here.
48
49 // --------------------------------------------------------------------------------------------
50
51 template <class EntryA, class EntryB, class Enable=void> struct ProductTraits;
52
53 template <class Scalar>
54 struct ProductTraits<Scalar,Scalar,std::enable_if_t<std::is_arithmetic_v<Scalar>>>
55 {
56 using type = Scalar;
57 };
58
59 template <class EntryA, class EntryB, int n, int m, int k>
60 struct ProductTraits<Dune::FieldMatrix<EntryA,n,m>,Dune::FieldMatrix<EntryB,m,k>,void>
61 {
63 };
64
65 // --------------------------------------------------------------------------------------------
66
67
68 // The row vector class accessing DynamicMatrix rows. It simply stores a pointer to the
69 // first element, the number (of columns in the matrix) and the stride (number of rows,
70 // as the matrix stores elements column-major as in BLAS/LAPACK). It does not own or manage
71 // the memory.
72 // The interface adheres to the Dune::DenseVector requirements.
73 template <class K>
74 class StridedVector: public Dune::DenseVector<StridedVector<K>>
75 {
76 using Self = StridedVector<K>;
77 typedef Dune::DenseVector<Self> Base;
78 using Entry = std::remove_const_t<K>;
79
80 public:
81 using size_type = typename Base::size_type;
82 using value_type = K;
84
85 StridedVector(StridedVector const& x): Dune::DenseVector<StridedVector<K>>(), p(x.p), n(x.n), stride(x.stride) {}
86
93 StridedVector(K* p_, size_type n_, size_type stride_): p(p_), n(n_), stride(stride_) { }
94
96 StridedVector& operator=(K const& x) { for (size_type i=0; i<n; ++i) vec_access(i) = x; return *this; }
97
98 // for DUNE 2.4.x
99 value_type& vec_access(size_type i) { return *(p+i*stride); }
100 value_type const& vec_access(size_type i) const { return *(p+i*stride); }
101 size_type vec_size() const { return n; }
102 // for DUNE 2.5
103 value_type& _access(size_type i) { return *(p+i*stride); }
104 value_type const& _access(size_type i) const { return *(p+i*stride); }
105 size_type _size() const { return n; }
106 size_type size() const { return n; } // bug in Dune 2.5 DenseVector<>::size() calling Implementation's size()
107
109 value_type const& operator[] (size_type i) const { return vec_access(i); }
110
111 // With Dune 2.4.1 and GCC 5.3 there is some weird thing going on that leads to an infinite loop.
112 // Maybe due to wrong detection of enable_if in DenseVector::operator+=()? We provide a fix here.
113 template <class X>
115 {
116 for (size_type i=0; i<n; ++i)
117 (*this)[i] += x[i];
118 return *this;
119 }
120 template <class X>
122 {
123 for (size_type i=0; i<n; ++i)
124 (*this)[i] -= x[i];
125 return *this;
126 }
127
128 // Dune::DenseVector cannot treat FieldMatrices as entries as of Dune 2.4.1
130 {
131 real_type r = 0;
132 for (size_type i=0; i<n; ++i)
134 return r;
135 }
136
138 {
139 return std::sqrt(two_norm2());
140 }
141
142 private:
143 K* p;
144 size_type n;
145 size_type stride;
146 };
147
148 // Helper class for extracting a pointer to the first entry (or the entry itself in case of elementary types
149 template <class K>
151 {
152 static K * from(K & k) { return &k; }
153 static K const* from(K const& k) { return &k; }
154 };
155
156 template <class K, int n, int m>
157 struct GetAddress<Dune::FieldMatrix<K,n,m>>
158 {
160
162 static field_type const* from(Dune::FieldMatrix<K,n,m> const& k) { return GetAddress<K>::from(k[0][0]); }
163 };
164
165 template <class K, int n>
166 struct GetAddress<Dune::FieldVector<K,n>>
167 {
169
171 static field_type const* from(Dune::FieldVector<K,n> const& k) { return GetAddress<K>::from(k[0]); }
172 };
173
174 template <class K, class A>
176 {
178
180 static field_type const* from(Dune::BlockVector<K,A> const& k) { return GetAddress<K>::from(k[0]); }
181 };
182
183 template <class K>
184 auto getAddress(K& a)
185 {
186 return GetAddress<std::remove_const_t<K>>::from(a);
187 }
188
189 // Helper class for assigning Dune::FieldMatrix of different scalar type (which leads to segmentation faults as of Dune 2.4)
190 template <class A, class B>
191 struct Copy
192 {
193 static void apply(A const& a, B& b)
194 {
195 b = a;
196 assert(!std::isnan(b));
197 }
198 };
199
200 template <class A, class B, int n, int m>
201 struct Copy<Dune::FieldMatrix<A,n,m>, Dune::FieldMatrix<B,n,m>>
202 {
204 {
205 for (int i=0; i<n; ++i)
206 for (int j=0; j<n; ++j)
207 Copy<A,B>::apply(a[i][j],b[i][j]);
208 }
209 };
210
211
212 // matrix-vector multiplication calling BLAS
213 // y <- alpha*A*x + beta*y
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);
216
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);
227
228 inline double transpose(double x) { return x; }
229 inline float transpose(float x) { return x; }
230
231 // For accessing flat matrices
232 template <class Scalar>
233 Scalar& scalarEntry(Scalar& x, int row, int col)
234 {
235 return x;
236 }
237
238 template <class Entry, int n, int m>
240 {
241 using L = EntryTraits<Entry>;
242 return scalarEntry(A[row/L::rows][col/L::cols],row%L::rows,col%L::cols);
243 }
244
245 template <class Entry, int n, int m>
247 {
248 using L = EntryTraits<Entry>;
249 return scalarEntry(A[row/L::rows][col/L::cols],row%L::rows,col%L::cols);
250 }
251
252 template <class Entry>
254 {
255 using L = EntryTraits<Entry>;
256 return scalarEntry(A[row/L::rows][col/L::cols],row%L::rows,col%L::cols);
257 }
258
259 template <class Entry>
261 {
262 using L = EntryTraits<Entry>;
263 return scalarEntry(A[row/L::rows][col/L::cols],row%L::rows,col%L::cols);
264 }
265
266
267
268
269
270 template <class Scalar, class enable = typename std::enable_if_t<std::is_floating_point_v<Scalar>,int>>
272 {
273 static_assert(EntryTraits<Scalar>::rows == 1 && EntryTraits<Scalar>::cols==1,"Default specialization only for scalars!");
274 return A;
275 }
276
277 template <class Entry, int n, int m>
279 {
281
282 DynamicMatrix<typename EntryTraits<Entry>::field_type> B(L::rows*A.N(),L::cols*A.M());
283 for (int j=0; j<B.M(); ++j)
284 for (int i=0; i<B.N(); ++i)
285 B[i][j] = scalarEntry(A,i,j);
286 return B;
287 }
288
289 template <class Entry>
291 {
292 using L = EntryTraits<Entry>;
293
294 A.resize(B.N()/L::rows,B.M()/L::cols);
295
296 for (int j=0; j<B.M(); ++j)
297 for (int i=0; i<B.N(); ++i)
298 scalarEntry(A,i,j) = B[i][j];
299 }
300
301 }
302}
303
304namespace Dune
305{
306
307 namespace Impl
308 {
309 // For some unknown reason, Dune does not provide the assignment from the matrix entry
310 // type to the matrix as of Dune 2.9. The overload is provided only for not-number entry
311 // types, as assignment from number types *is* provided by Dune.
312 template <class DenseMatrix>
313 class DenseMatrixAssigner<DenseMatrix, typename DenseMatrix::value_type,
314 std::enable_if_t<!Dune::IsNumber<typename DenseMatrix::value_type>::value>>
315 {
316 public:
317 static void apply(DenseMatrix& denseMatrix, typename DenseMatrix::value_type const& a)
318 {
319 std::fill(denseMatrix.begin(),denseMatrix.end(),a);
320 }
321 };
322 }
323
324 // type traits accessed by Dune::Dense matrix base class
325 template <class K>
326 struct DenseMatVecTraits<Kaskade::DynamicMatrix<K>>
327 {
331
334
335 typedef std::vector<K> container_type;
336 typedef K value_type;
337 typedef typename container_type::size_type size_type;
338 };
339
340 template <class K>
341 struct DenseMatVecTraits<Kaskade::DynamicMatrixDetail::StridedVector<K>>
342 {
345
346 typedef K value_type;
347 typedef typename std::vector<typename std::remove_const<K>::type>::size_type size_type;
348 };
349
350 template <class K>
351 struct FieldTraits<Kaskade::DynamicMatrix<K>>
352 {
353 typedef typename FieldTraits<K>::field_type field_type;
354 typedef typename FieldTraits<K>::real_type real_type;
355 };
356}
358
359namespace Kaskade {
376 template<class K>
377 class DynamicMatrix: public Dune::DenseMatrix<DynamicMatrix<K>>
378 {
379 typedef Dune::DenseMatrix<DynamicMatrix<K>> Base;
380 using Self = DynamicMatrix<K>;
381 typedef typename Base::row_reference row_reference;
382 typedef typename Base::const_row_reference const_row_reference;
385 using ET = EntryTraits<K>;
386
387 public:
388 using size_type = typename Base::size_type;
389 using value_type = typename Base::value_type;
390 using field_type = typename Dune::FieldTraits<K>::field_type; // buggy in base class (defined as value_type there)
391 typedef typename Base::row_type row_type;
392
401 DynamicMatrix (): rs(0), cs(0), dat(1) {} // allocate at least one entry to prevent segmentation faults
402
406 DynamicMatrix(Self const& a) = default;
407
408 template <class OtherK>
409 friend class DynamicMatrix;
410
416 template <class OtherK>
418 : DynamicMatrix(A.N()*EntryTraits<OtherK>::rows/ET::rows,
419 A.M()*EntryTraits<OtherK>::cols/ET::cols)
420 {
421 constexpr int otherRows = EntryTraits<OtherK>::rows;
422 constexpr int otherCols = EntryTraits<OtherK>::cols;
423
424 int n = A.N()*otherRows; // number of scalar rows
425 int m = A.M()*otherCols; // and cols
426
427 assert(n % ET::rows == 0); // make sure the matrices can have the same scalar size
428 assert(m % ET::cols == 0);
429
430 // Copy scalar by scalar. Even if the entries have compatible row and column sizes,
431 // there need not be an assignment operator (e.g., one is a block matrix and the other one not).
432 for (int j=0; j<m; ++j)
433 for (int i=0; i<n; ++i)
435 }
436
440 DynamicMatrix (Self&& a) = default;
441
446 rs(r), cs(c), dat(r*c,v)
447 {}
448
456 using Base::operator=;
457
458
465
470
474 template <class OtherK>
476 {
478 "assignment only from compatible entries");
479 resize(A.N(),A.M());
480 copy(A.dat,dat);
481 return *this;
482 }
483
490 {
491 rs = r;
492 cs = c;
493 dat.resize(r*c);
494 }
495
502 {
503 resize(r,c);
504 }
505
506 void fill (K val)
507 {
508 for (int i=0; i<rs*cs; ++i)
509 dat[i]=val;
510 }
511
521 template <class RRange, class CRange>
522 DynamicMatrix operator()(RRange const& ridx, CRange const& cidx) const
523 {
524 DynamicMatrix B(ridx.size(),cidx.size());
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]];
528 return B;
529 }
530
548 template<class X, class Y>
549 void mv (const X& x, Y& y) const
550 {
551 using namespace DynamicMatrixDetail;
552
553 if (ET::lapackLayout && rs>0)
554 // If the scalar entries are arranged in LAPACK memory layout (and there is anything to do),
555 // we just call BLAS.
556 gemv(false,rs*ET::rows,cs*ET::cols,1.0,data(),lda(),
557 GetAddress<typename X::value_type>::from(x[0]),
558 0.0,GetAddress<typename Y::value_type>::from(y[0]));
559 else
560 // As of Dune 2.4, the DenseMatrix::mv implementation is buggy and prevents the use of
561 // non-scalar entry types. We provide a fixed version here. (2016-02) Apparently corrected
562 // in later Dune version.
563 for (size_type i=0; i<rs; ++i)
564 {
565 y[i] = 0; // this was initialized by value_type(0), which can be a matrix...
566 for (size_type j=0; j<cs; ++j)
567 y[i] += (*this)[i][j] * x[j];
568 }
569 }
570
577 template <class X, class Y>
578 void mtv(const X& x, Y& y) const
579 {
580 for (int i=0; i<this->M(); ++i) // we could use y = 0, but the loop works for std::vector as well
581 y[i] = 0;
582 umtv(x,y);
583 }
584
591 template <class X, class Y>
592 void umtv(const X& x, Y& y) const
593 {
594 usmtv(1.0,x,y);
595 }
596
608 template <class X, class Y>
609 void usmv(typename Dune::FieldTraits<Y>::field_type alpha, X const& x, Y& y) const
610 {
611 using namespace DynamicMatrixDetail;
612
613 if (ET::lapackLayout && rs>0)
614 gemv(false,rs*ET::rows,cs*ET::cols,alpha,data(),lda(),
615 GetAddress<typename X::value_type>::from(x[0]),
616 1.0,GetAddress<typename Y::value_type>::from(y[0]));
617 else
618 for (size_type i=0; i<rs; ++i)
619 {
620 typename Y::value_type tmp(0.0);
621 for (size_type j=0; j<cs; ++j)
622 tmp += (*this)[i][j] * x[j];
623 y[i] += alpha*tmp;
624 }
625 }
626
638 template <class X, class Y>
639 void usmtv(typename Dune::FieldTraits<Y>::field_type alpha, X const& x, Y& y) const
640 {
641 using namespace DynamicMatrixDetail;
642
643 if (ET::lapackLayout && rs>0)
644 gemv(true,rs*ET::rows,cs*ET::cols,alpha,data(),lda(),
645 GetAddress<typename X::value_type>::from(x[0]),
646 1.0,GetAddress<typename Y::value_type>::from(y[0]));
647 else
648 for(size_type i = 0; i<cs; ++i)
649 for(size_type j=0; j<rs; ++j)
650 y[i] += alpha * (transpose((*this)[j][i]) * x[j]);
651 }
652
661 {
662 for (K& a: dat)
663 a *= s;
664 return *this;
665 }
666
682 size_type lda() const
683 {
684 return rs*EntryTraits<K>::rows;
685 }
686
692
698
699 // make this thing a matrix in the sense of the Dune interface
700 size_type mat_rows() const { return rs; }
701 size_type mat_cols() const { return cs; }
702 row_reference mat_access(size_type i) { return row_reference(&dat[i],cs,rs); }
703 const_row_reference mat_access(size_type i) const { return const_row_reference(&dat[i],cs,rs); }
704
709 private:
710 size_type rs, cs;
711 std::vector<K> dat;
712
713 // The assignment Dune::FieldMatrix<float,3,3> = Dune::FieldMatrix<double,3,3> leads to a segmentation fault
714 // possibly after interminate recursion as of Dune 2.4. Thus we provide a fix. (2016-02)
715 template <class OtherK>
716 void copy(std::vector<OtherK> const& a, std::vector<K>& b)
717 {
718 for (size_t i=0; i<a.size(); ++i)
720 }
721 };
722
723 // --------------------------------------------------------------------------------------------------------
724 // --------------------------------------------------------------------------------------------------------
725
731 template <class Entry>
732 std::ostream& operator<<(std::ostream& out, DynamicMatrix<Entry> const& A)
733 {
734 using namespace DynamicMatrixDetail;
735 using L = EntryTraits<Entry>;
736
737 int n = A.N()*L::rows;
738 int m = A.M()*L::cols;
739
740 for (int i=0; i<n; ++i)
741 {
742 for (int j=0; j<m; ++j)
743 out << scalarEntry(A,i,j) << " ";
744 out << '\n';
745 }
746 return out;
747 }
748
749 template <class T, typename = std::enable_if_t<std::is_arithmetic<T>::value>>
751 {
752 return x;
753 }
754
763 template <class Entry>
764 DynamicMatrix<typename EntryTraits<Entry>::transpose_type>
766 {
768 for (int j=0; j<C.M(); ++j)
769 for (int i=0; i<C.N(); ++i)
770 C[i][j] = transpose(A[j][i]);
771 return C;
772 }
773
774 // ----------------------------------------------------------------------------------------------
775
779 namespace DynamicMatrixDetail
780 {
781 template <class Scalar>
782 std::tuple<DynamicMatrix<Dune::FieldMatrix<Scalar,1,1>>,
783 std::vector<typename ScalarTraits<Scalar>::Real>,
785 svd(DynamicMatrix<Scalar>& A);
786 }
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>,
808 {
810 return DynamicMatrixDetail::svd(Acopy);
811 }
812
823 template <class Entry>
825 {
826 // Condition number is largest singular value.
827 // TODO: there are faster ways of computing the spectral norm (at least approximately and for square matrices).
828 auto sigma = std::get<1>(svd(A));
829 return *std::max_element(begin(sigma),end(sigma));
830 }
831
832
843 template <class Entry>
845 {
846 assert(A.N() == A.M());
847
848 // Condition number is ratio of largest and smallest singular value. Take care if a singular value is zero.
849 // TODO: there are faster ways of computing the condition number (at least in special cases).
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();
854 else
855 return *minmax.second / *minmax.first;
856 }
857
867 template <class MEntry, class Vector>
869
881 template <class MEntry, class Vector>
883
890 template <class Scalar>
892
904 template <class Entry>
906
917 template <class Entry>
920
921
928 template <class Entry>
929 std::vector<typename EntryTraits<Entry>::real_type> eigenvalues(DynamicMatrix<Entry> A);
930
931
941 template <class Entry>
942 std::vector<typename EntryTraits<Entry>::real_type> eig(DynamicMatrix<Entry>& A,
943 bool computeEigenvectors=true);
944
945
951 template <class Scalar, int d>
953
954
967 template <class Scalar, int d>
969
970
978 template <class Scalar, int d>
980
981
989 template <class Entry>
991 typename ScalarTraits<typename EntryTraits<Entry>::field_type>::Real threshold = 0);
992
1013 template <class Entry>
1014 std::tuple<std::vector<typename EntryTraits<Entry>::field_type>,
1016 std::vector<int>>
1018
1019 // ----------------------------------------------------------------------------------------------
1020 // ----------------------------------------------------------------------------------------------
1021
1022
1036 template<int dimIn, int dimOut>
1038 {
1039 assert( (dimIn == 1 && b.N()%dimOut == 0) || (dimIn > 1 && dimOut == 1) );
1040
1042
1043 if(dimIn == 1) // --> dimOut > 1
1044 {
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];
1049 } else // --> dimIn > 1 and dimOut == 1
1050 {
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];
1055 }
1056 return c;
1057 }
1058
1059}
1060
1061#endif
value_type const & _access(size_type i) const
Self & operator-=(StridedVector< X > const &x)
StridedVector & operator=(K const &x)
value_type const & vec_access(size_type i) const
StridedVector & operator=(StridedVector const &v)=default
typename EntryTraits< Entry >::real_type real_type
StridedVector(K *p_, size_type n_, size_type stride_)
Constructor.
Self & operator+=(StridedVector< X > const &x)
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.
Base::row_type row_type
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.
Definition: scalar.hh:36
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)
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
T transpose(T x)
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
Kaskade::DynamicMatrixDetail::StridedVector< K > row_type
std::vector< typenamestd::remove_const< K >::type >::size_type size_type
Kaskade::DynamicMatrixDetail::StridedVector< K > derived_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)
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)
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)
Definition: scalar.hh:73
Entry field_type
Definition: scalar.hh:77
typename ScalarTraits< field_type >::Real real_type
Definition: scalar.hh:78
static int const rows
Definition: scalar.hh:74
static int const lapackLayout
Definition: scalar.hh:79
static int const cols
Definition: scalar.hh:75