5#ifndef DUNE_ISTL_MATRIXMATRIX_HH
6#define DUNE_ISTL_MATRIXMATRIX_HH
38 struct NonzeroPatternTraverser
43 struct NonzeroPatternTraverser<0>
45 template<
class T,
class A1,
class A2,
class F,
int n,
int m,
int k>
51 DUNE_THROW(ISTLError,
"The sizes of the matrices do not match: "<<A.M()<<
"!="<<B.N());
56 for(Row row= A.begin(); row != A.end(); ++row) {
58 for(Col col = row->begin(); col != row->end(); ++col) {
61 for(BCol bcol = B[col.index()].begin(); bcol != B[col.index()].end(); ++bcol) {
62 func(*col, *bcol, row.index(), bcol.index());
71 struct NonzeroPatternTraverser<1>
73 template<
class T,
class A1,
class A2,
class F,
int n,
int m,
int k>
80 DUNE_THROW(ISTLError,
"The sizes of the matrices do not match: "<<A.N()<<
"!="<<B.N());
86 for(Row row=A.begin(); row!=A.end(); ++row) {
87 for(Col col=row->begin(); col!=row->end(); ++col) {
88 for(BCol bcol = B[row.index()].begin(); bcol != B[row.index()].end(); ++bcol) {
89 func(*col, *bcol, col.index(), bcol.index());
97 struct NonzeroPatternTraverser<2>
99 template<
class T,
class A1,
class A2,
class F,
int n,
int m,
int k>
100 static void traverse(
const BCRSMatrix<FieldMatrix<T,n,m>,A1>& mat,
101 const BCRSMatrix<FieldMatrix<T,k,m>,A2>& matt,
104 if(mat.M()!=matt.M())
105 DUNE_THROW(ISTLError,
"The sizes of the matrices do not match: "<<mat.M()<<
"!="<<matt.M());
107 typedef typename BCRSMatrix<FieldMatrix<T,n,m>,A1>::ConstRowIterator row_iterator;
108 typedef typename BCRSMatrix<FieldMatrix<T,n,m>,A1>::ConstColIterator col_iterator;
109 typedef typename BCRSMatrix<FieldMatrix<T,k,m>,A2>::ConstRowIterator row_iterator_t;
110 typedef typename BCRSMatrix<FieldMatrix<T,k,m>,A2>::ConstColIterator col_iterator_t;
112 for(row_iterator mrow=mat.begin(); mrow != mat.end(); ++mrow) {
119 for(row_iterator_t mtcol=matt.begin(); mtcol != matt.end(); ++mtcol) {
122 col_iterator_t mtrow=mtcol->begin();
123 bool funcCalled =
false;
124 for(col_iterator mcol=mrow->begin(); mcol != mrow->end(); ++mcol) {
127 for( ; mtrow != mtcol->end(); ++mtrow)
128 if(mtrow.index()>=mcol.index())
130 if(mtrow != mtcol->end() && mtrow.index()==mcol.index()) {
131 func(*mcol, *mtrow, mtcol.index());
151 template<
class T,
class A,
int n,
int m>
152 class SparsityPatternInitializer
155 enum {do_break=
true};
156 typedef typename BCRSMatrix<FieldMatrix<T,n,m>,A>::CreateIterator CreateIterator;
157 typedef typename BCRSMatrix<FieldMatrix<T,n,m>,A>::size_type size_type;
159 SparsityPatternInitializer(CreateIterator iter)
163 template<
class T1,
class T2>
164 void operator()(
const T1&,
const T2&, size_type j)
177 CreateIterator rowiter;
181 template<
int transpose,
class T,
class TA,
int n,
int m>
182 class MatrixInitializer
185 enum {do_break=
true};
190 MatrixInitializer(Matrix& A_, size_type)
193 template<
class T1,
class T2>
194 void operator()(
const T1&,
const T2&,
int)
205 std::size_t nonzeros()
210 template<
class A1,
class A2,
int n2,
int m2,
int n3,
int m3>
211 void initPattern(
const BCRSMatrix<FieldMatrix<T,n2,m2>,A1>& mat1,
212 const BCRSMatrix<FieldMatrix<T,n3,m3>,A2>& mat2)
214 SparsityPatternInitializer<T, TA, n, m> sparsity(A.
createbegin());
215 NonzeroPatternTraverser<transpose>::traverse(mat1,mat2,sparsity);
223 template<
class T,
class TA,
int n,
int m>
224 class MatrixInitializer<1,T,TA,n,m>
227 enum {do_break=
false};
232 MatrixInitializer(Matrix& A_, size_type rows)
233 : A(A_), entries(rows)
236 template<
class T1,
class T2>
237 void operator()(
const T1&,
const T2&, size_type i, size_type j)
239 entries[i].insert(j);
248 typedef typename std::vector<std::set<size_t> >::const_iterator Iter;
249 for(Iter iter = entries.begin(); iter != entries.end(); ++iter)
253 template<
class A1,
class A2,
int n2,
int m2,
int n3,
int m3>
254 void initPattern(
const BCRSMatrix<FieldMatrix<T,n2,m2>,A1>&,
255 const BCRSMatrix<FieldMatrix<T,n3,m3>,A2>&)
257 typedef typename std::vector<std::set<size_t> >::const_iterator Iter;
259 for(Iter iter = entries.begin(); iter != entries.end(); ++iter, ++citer) {
260 typedef std::set<size_t>::const_iterator SetIter;
261 for(SetIter index=iter->begin(); index != iter->end(); ++index)
268 std::vector<std::set<size_t> > entries;
271 template<
class T,
class TA,
int n,
int m>
272 struct MatrixInitializer<0,T,TA,n,m>
273 :
public MatrixInitializer<1,T,TA,n,m>
277 : MatrixInitializer<1,T,TA,n,m>(A_,rows)
282 template<
class T,
class T1,
class T2,
int n,
int m,
int k>
283 void addMatMultTransposeMat(FieldMatrix<T,n,k>& res,
const FieldMatrix<T1,n,m>& mat,
284 const FieldMatrix<T2,k,m>& matt)
286 typedef typename FieldMatrix<T,n,k>::size_type size_type;
288 for(size_type row=0; row<n; ++row)
289 for(size_type col=0; col<k; ++col) {
290 for(size_type i=0; i < m; ++i)
291 res[row][col]+=mat[row][i]*matt[col][i];
295 template<
class T,
class T1,
class T2,
int n,
int m,
int k>
296 void addTransposeMatMultMat(FieldMatrix<T,n,k>& res,
const FieldMatrix<T1,m,n>& mat,
297 const FieldMatrix<T2,m,k>& matt)
299 typedef typename FieldMatrix<T,n,k>::size_type size_type;
300 for(size_type i=0; i<m; ++i)
301 for(size_type row=0; row<n; ++row) {
302 for(size_type col=0; col < k; ++col)
303 res[row][col]+=mat[i][row]*matt[i][col];
307 template<
class T,
class T1,
class T2,
int n,
int m,
int k>
308 void addMatMultMat(FieldMatrix<T,n,m>& res,
const FieldMatrix<T1,n,k>& mat,
309 const FieldMatrix<T2,k,m>& matt)
311 typedef typename FieldMatrix<T,n,k>::size_type size_type;
312 for(size_type row=0; row<n; ++row)
313 for(size_type col=0; col<m; ++col) {
314 for(size_type i=0; i < k; ++i)
315 res[row][col]+=mat[row][i]*matt[i][col];
320 template<
class T,
class A,
int n,
int m>
321 class EntryAccumulatorFather
324 enum {do_break=
false};
325 typedef BCRSMatrix<FieldMatrix<T,n,m>,A> Matrix;
329 EntryAccumulatorFather(Matrix& mat_)
330 : mat(mat_), row(mat.begin())
354 template<
class T,
class A,
int n,
int m,
int transpose>
355 class EntryAccumulator
356 :
public EntryAccumulatorFather<T,A,n,m>
359 typedef BCRSMatrix<FieldMatrix<T,n,m>,A> Matrix;
362 EntryAccumulator(Matrix& mat_)
363 : EntryAccumulatorFather<T,A,n,m>(mat_)
366 template<
class T1,
class T2>
367 void operator()(
const T1& t1,
const T2& t2, size_type i)
369 assert(this->col.index()==i);
370 addMatMultMat(*(this->col),t1,t2);
374 template<
class T,
class A,
int n,
int m>
375 class EntryAccumulator<T,A,n,m,0>
376 :
public EntryAccumulatorFather<T,A,n,m>
379 typedef BCRSMatrix<FieldMatrix<T,n,m>,A> Matrix;
382 EntryAccumulator(Matrix& mat_)
383 : EntryAccumulatorFather<T,A,n,m>(mat_)
386 template<
class T1,
class T2>
387 void operator()(
const T1& t1,
const T2& t2, size_type i, size_type j)
389 addMatMultMat(this->mat[i][j], t1, t2);
393 template<
class T,
class A,
int n,
int m>
394 class EntryAccumulator<T,A,n,m,1>
395 :
public EntryAccumulatorFather<T,A,n,m>
398 typedef BCRSMatrix<FieldMatrix<T,n,m>,A> Matrix;
401 EntryAccumulator(Matrix& mat_)
402 : EntryAccumulatorFather<T,A,n,m>(mat_)
405 template<
class T1,
class T2>
406 void operator()(
const T1& t1,
const T2& t2, size_type i, size_type j)
408 addTransposeMatMultMat(this->mat[i][j], t1, t2);
412 template<
class T,
class A,
int n,
int m>
413 class EntryAccumulator<T,A,n,m,2>
414 :
public EntryAccumulatorFather<T,A,n,m>
417 typedef BCRSMatrix<FieldMatrix<T,n,m>,A> Matrix;
420 EntryAccumulator(Matrix& mat_)
421 : EntryAccumulatorFather<T,A,n,m>(mat_)
424 template<
class T1,
class T2>
425 void operator()(
const T1& t1,
const T2& t2, [[maybe_unused]] size_type i)
427 assert(this->col.index()==i);
428 addMatMultTransposeMat(*this->col,t1,t2);
433 template<
int transpose>
438 struct SizeSelector<0>
440 template<
class M1,
class M2>
441 static std::tuple<typename M1::size_type, typename M2::size_type>
442 size(
const M1& m1,
const M2& m2)
444 return std::make_tuple(m1.N(), m2.M());
449 struct SizeSelector<1>
451 template<
class M1,
class M2>
452 static std::tuple<typename M1::size_type, typename M2::size_type>
453 size(
const M1& m1,
const M2& m2)
455 return std::make_tuple(m1.M(), m2.M());
461 struct SizeSelector<2>
463 template<
class M1,
class M2>
464 static std::tuple<typename M1::size_type, typename M2::size_type>
465 size(
const M1& m1,
const M2& m2)
467 return std::make_tuple(m1.N(), m2.N());
471 template<
int transpose,
class T,
class A,
class A1,
class A2,
int n1,
int m1,
int n2,
int m2,
int n3,
int m3>
472 void matMultMat(BCRSMatrix<FieldMatrix<T,n1,m1>,A>& res,
const BCRSMatrix<FieldMatrix<T,n2,m2>,A1>& mat1,
473 const BCRSMatrix<FieldMatrix<T,n3,m3>,A2>& mat2)
476 typename BCRSMatrix<FieldMatrix<T,n1,m1>,A>::size_type rows, cols;
477 std::tie(rows,cols)=SizeSelector<transpose>::size(mat1, mat2);
478 MatrixInitializer<transpose,T,A,n1,m1> patternInit(res, rows);
480 NonzeroPatternTraverser<transpose>::traverse(mat1,mat2,patternInit);
481 res.setSize(rows, cols, patternInit.nonzeros());
482 res.setBuildMode(BCRSMatrix<FieldMatrix<T,n1,m1>,A>::row_wise);
488 patternInit.initPattern(mat1, mat2);
494 EntryAccumulator<T,A,n1,m1, transpose> entriesAccu(res);
495 NonzeroPatternTraverser<transpose>::traverse(mat1,mat2,entriesAccu);
508 template<
typename M1,
typename M2>
512 template<
typename T,
int n,
int k,
int m>
518 template<
typename T,
typename A,
typename A1,
int n,
int k,
int m>
519 struct MatMultMatResult<BCRSMatrix<FieldMatrix<T,n,k>,A >,BCRSMatrix<FieldMatrix<T,k,m>,A1 > >
521 typedef BCRSMatrix<typename MatMultMatResult<FieldMatrix<T,n,k>,FieldMatrix<T,k,m> >::type,
522 std::allocator<typename MatMultMatResult<FieldMatrix<T,n,k>,FieldMatrix<T,k,m> >::type> > type;
533 template<
typename M1,
typename M2>
537 template<
typename T,
int n,
int k,
int m>
543 template<
typename T,
typename A,
typename A1,
int n,
int k,
int m>
544 struct TransposedMatMultMatResult<BCRSMatrix<FieldMatrix<T,k,n>,A >,BCRSMatrix<FieldMatrix<T,k,m>,A1 > >
546 typedef BCRSMatrix<typename MatMultMatResult<FieldMatrix<T,n,k>,FieldMatrix<T,k,m> >::type,
547 std::allocator<typename MatMultMatResult<FieldMatrix<T,n,k>,FieldMatrix<T,k,m> >::type> > type;
559 template<
class T,
class A,
class A1,
class A2,
int n,
int m,
int k>
563 matMultMat<2>(res,mat, matt);
574 template<
class T,
class A,
class A1,
class A2,
int n,
int m,
int k>
578 matMultMat<0>(res,mat, matt);
589 template<
class T,
class A,
class A1,
class A2,
int n,
int m,
int k>
593 matMultMat<1>(res,mat, matt);
Implementation of the BCRSMatrix class.
void insert(size_type j)
put column index in row
Definition: bcrsmatrix.hh:1064
A sparse block matrix with compressed row storage.
Definition: bcrsmatrix.hh:466
friend class CreateIterator
allow CreateIterator to access internal data
Definition: bcrsmatrix.hh:1094
Iterator RowIterator
rename the iterators for easier access
Definition: bcrsmatrix.hh:701
Iterator end()
Get iterator to one beyond last row.
Definition: bcrsmatrix.hh:681
row_type::Iterator ColIterator
Iterator for the entries of each row.
Definition: bcrsmatrix.hh:704
A::size_type size_type
The type for the index access and the size.
Definition: bcrsmatrix.hh:500
CreateIterator createbegin()
get initial create iterator
Definition: bcrsmatrix.hh:1097
A dense n x m matrix.
Definition: fmatrix.hh:117
Implements a matrix constructed from a given type representing a field and compile-time given number ...
#define DUNE_THROW(E, m)
Definition: exceptions.hh:218
void transposeMatMultMat(BCRSMatrix< FieldMatrix< T, n, m >, A > &res, const BCRSMatrix< FieldMatrix< T, k, n >, A1 > &mat, const BCRSMatrix< FieldMatrix< T, k, m >, A2 > &matt, bool tryHard=false)
Calculate product of a transposed sparse matrix with another sparse matrices ( ).
Definition: matrixmatrix.hh:590
void matMultMat(BCRSMatrix< FieldMatrix< T, n, m >, A > &res, const BCRSMatrix< FieldMatrix< T, n, k >, A1 > &mat, const BCRSMatrix< FieldMatrix< T, k, m >, A2 > &matt, bool tryHard=false)
Calculate product of two sparse matrices ( ).
Definition: matrixmatrix.hh:575
void matMultTransposeMat(BCRSMatrix< FieldMatrix< T, n, k >, A > &res, const BCRSMatrix< FieldMatrix< T, n, m >, A1 > &mat, const BCRSMatrix< FieldMatrix< T, k, m >, A2 > &matt, bool tryHard=false)
Calculate product of a sparse matrix with a transposed sparse matrices ( ).
Definition: matrixmatrix.hh:560
Dune namespace.
Definition: alignedallocator.hh:13
Helper TMP to get the result type of a sparse matrix matrix multiplication ( )
Definition: matrixmatrix.hh:510
Helper TMP to get the result type of a sparse matrix matrix multiplication ( )
Definition: matrixmatrix.hh:535