Dune Core Modules (2.9.0)

matrix.hh
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file LICENSE.md in module root
2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
4// vi: set et ts=4 sw=2 sts=2:
5#ifndef DUNE_ISTL_MATRIX_HH
6#define DUNE_ISTL_MATRIX_HH
7
12#include <cmath>
13#include <memory>
14
19
20#include <dune/istl/bvector.hh>
21#include <dune/istl/istlexception.hh>
23
24namespace Dune {
25
26namespace MatrixImp
27{
39 template<class B, class A=std::allocator<B> >
40 class DenseMatrixBase : public Imp::block_vector_unmanaged<B,A>
41 // this derivation gives us all the blas level 1 and norms
42 // on the large array. However, access operators have to be
43 // overwritten.
44 {
45 public:
46
47 //===== type definitions and constants
48
50 using field_type = typename Imp::BlockTraits<B>::field_type;
51
53 typedef A allocator_type;
54
56 typedef typename A::size_type size_type;
57
64
68
69 // just a shorthand
70 typedef Imp::BlockVectorWindow<B,A> window_type;
71
72 typedef window_type reference;
73
74 typedef const window_type const_reference;
75
76
77 //===== constructors and such
78
82 DenseMatrixBase () : Imp::block_vector_unmanaged<B,A>()
83 {
84 // nothing is known ...
85 rows_ = 0;
86 columns_ = 0;
87 }
88
95 DenseMatrixBase (size_type rows, size_type columns) : Imp::block_vector_unmanaged<B,A>()
96 {
97 // and we can allocate the big array in the base class
98 this->n = rows*columns;
99 columns_ = columns;
100 if (this->n>0)
101 {
102 this->p = allocator_.allocate(this->n);
103 new (this->p)B[this->n];
104 }
105 else
106 {
107 this->n = 0;
108 this->p = 0;
109 }
110
111 // we can allocate the windows now
112 rows_ = rows;
113 }
114
117 {
118 // allocate the big array in the base class
119 this->n = a.n;
120 columns_ = a.columns_;
121 if (this->n>0)
122 {
123 // allocate and construct objects
124 this->p = allocator_.allocate(this->n);
125 new (this->p)B[this->n];
126
127 // copy data
128 for (size_type i=0; i<this->n; i++)
129 this->p[i]=a.p[i];
130 }
131 else
132 {
133 this->n = 0;
134 this->p = nullptr;
135 }
136
137 // we can allocate the windows now
138 rows_ = a.rows_;
139 }
140
143 {
144 if (this->n>0) {
145 size_type i=this->n;
146 while (i)
147 this->p[--i].~B();
148 allocator_.deallocate(this->p,this->n);
149 }
150 }
151
153 void resize (size_type rows, size_type columns)
154 {
155 // deconstruct objects and deallocate memory if necessary
156 if (this->n>0) {
157 size_type i=this->n;
158 while (i)
159 this->p[--i].~B();
160 allocator_.deallocate(this->p,this->n);
161 }
162
163 // and we can allocate the big array in the base class
164 this->n = rows*columns;
165 if (this->n>0)
166 {
167 this->p = allocator_.allocate(this->n);
168 new (this->p)B[this->n];
169 }
170 else
171 {
172 this->n = 0;
173 this->p = nullptr;
174 }
175
176 // we can allocate the windows now
177 rows_ = rows;
178 columns_ = columns;
179 }
180
183 {
184 if (&a!=this) // check if this and a are different objects
185 {
186 columns_ = a.columns_;
187 // reallocate arrays if necessary
188 // Note: still the block sizes may vary !
189 if (this->n!=a.n || rows_!=a.rows_)
190 {
191 // deconstruct objects and deallocate memory if necessary
192 if (this->n>0) {
193 size_type i=this->n;
194 while (i)
195 this->p[--i].~B();
196 allocator_.deallocate(this->p,this->n);
197 }
198
199 // allocate the big array in the base class
200 this->n = a.n;
201 if (this->n>0)
202 {
203 // allocate and construct objects
204 this->p = allocator_.allocate(this->n);
205 new (this->p)B[this->n];
206 }
207 else
208 {
209 this->n = 0;
210 this->p = nullptr;
211 }
212
213 // Copy number of rows
214 rows_ = a.rows_;
215 }
216
217 // and copy the data
218 for (size_type i=0; i<this->n; i++)
219 this->p[i]=a.p[i];
220 }
221
222 return *this;
223 }
224
225
226 //===== assignment from scalar
227
230 {
231 (static_cast<Imp::block_vector_unmanaged<B,A>&>(*this)) = k;
232 return *this;
233 }
234
235
236 //===== access to components
237 // has to be overwritten from base class because it must
238 // return access to the windows
239
242 {
243#ifdef DUNE_ISTL_WITH_CHECKING
244 if (i>=rows_) DUNE_THROW(ISTLError,"index out of range");
245#endif
246 return window_type(this->p + i*columns_, columns_);
247 }
248
250 const_reference operator[] (size_type i) const
251 {
252#ifdef DUNE_ISTL_WITH_CHECKING
253 if (i<0 || i>=rows_) DUNE_THROW(ISTLError,"index out of range");
254#endif
255 return window_type(this->p + i*columns_, columns_);
256 }
257
258 // forward declaration
259 class ConstIterator;
260
263 {
264 public:
267 : window_(nullptr,0)
268 {
269 i = 0;
270 }
271
272 Iterator (Iterator& other) = default;
273 Iterator (Iterator&& other) = default;
274
276 Iterator (B* data, size_type columns, size_type _i)
277 : i(_i),
278 window_(data + _i*columns, columns)
279 {}
280
283 {
284 i = other.i;
285 // Do NOT use window_.operator=, because that copies the window content, not just the window!
286 window_.set(other.window_.getsize(),other.window_.getptr());
287 return *this;
288 }
289
292 {
293 i = other.i;
294 // Do NOT use window_.operator=, because that copies the window content, not just the window!
295 window_.set(other.window_.getsize(),other.window_.getptr());
296 return *this;
297 }
298
301 {
302 ++i;
303 window_.setptr(window_.getptr()+window_.getsize());
304 return *this;
305 }
306
309 {
310 --i;
311 window_.setptr(window_.getptr()-window_.getsize());
312 return *this;
313 }
314
316 bool operator== (const Iterator& it) const
317 {
318 return window_.getptr() == it.window_.getptr();
319 }
320
322 bool operator!= (const Iterator& it) const
323 {
324 return window_.getptr() != it.window_.getptr();
325 }
326
328 bool operator== (const ConstIterator& it) const
329 {
330 return window_.getptr() == it.window_.getptr();
331 }
332
334 bool operator!= (const ConstIterator& it) const
335 {
336 return window_.getptr() != it.window_.getptr();
337 }
338
340 window_type& operator* () const
341 {
342 return window_;
343 }
344
346 window_type* operator-> () const
347 {
348 return &window_;
349 }
350
351 // return index corresponding to pointer
352 size_type index () const
353 {
354 return i;
355 }
356
357 friend class ConstIterator;
358
359 private:
360 size_type i;
361 mutable window_type window_;
362 };
363
366 {
367 return Iterator(this->p, columns_, 0);
368 }
369
372 {
373 return Iterator(this->p, columns_, rows_);
374 }
375
379 {
380 return Iterator(this->p, columns_, rows_-1);
381 }
382
386 {
387 return Iterator(this->p, columns_, -1);
388 }
389
392 {
393 return Iterator(this->p, columns_, std::min(i,rows_));
394 }
395
398 {
399 return ConstIterator(this->p, columns_, std::min(i,rows_));
400 }
401
404 {
405 public:
408 : window_(nullptr,0)
409 {
410 i = 0;
411 }
412
414 ConstIterator (const B* data, size_type columns, size_type _i)
415 : i(_i),
416 window_(const_cast<B*>(data + _i * columns), columns)
417 {}
418
421 : i(it.i), window_(it.window_.getptr(),it.window_.getsize())
422 {}
423
424 ConstIterator& operator=(Iterator&& other)
425 {
426 i = other.i;
427 // Do NOT use window_.operator=, because that copies the window content, not just the window!
428 window_.set(other.window_.getsize(),other.window_.getptr());
429 return *this;
430 }
431
432 ConstIterator& operator=(Iterator& other)
433 {
434 i = other.i;
435 // Do NOT use window_.operator=, because that copies the window content, not just the window!
436 window_.set(other.window_.getsize(),other.window_.getptr());
437 return *this;
438 }
439
442 {
443 ++i;
444 window_.setptr(window_.getptr()+window_.getsize());
445 return *this;
446 }
447
450 {
451 --i;
452 window_.setptr(window_.getptr()-window_.getsize());
453 return *this;
454 }
455
457 bool operator== (const ConstIterator& it) const
458 {
459 return window_.getptr() == it.window_.getptr();
460 }
461
463 bool operator!= (const ConstIterator& it) const
464 {
465 return window_.getptr() != it.window_.getptr();
466 }
467
469 bool operator== (const Iterator& it) const
470 {
471 return window_.getptr() == it.window_.getptr();
472 }
473
475 bool operator!= (const Iterator& it) const
476 {
477 return window_.getptr() != it.window_.getptr();
478 }
479
481 const window_type& operator* () const
482 {
483 return window_;
484 }
485
487 const window_type* operator-> () const
488 {
489 return &window_;
490 }
491
492 // return index corresponding to pointer
493 size_type index () const
494 {
495 return i;
496 }
497
498 friend class Iterator;
499
500 private:
501 size_type i;
502 mutable window_type window_;
503 };
504
507
510
513 {
514 return ConstIterator(this->p, columns_, 0);
515 }
516
519 {
520 return ConstIterator(this->p, columns_, rows_);
521 }
522
526 {
527 return ConstIterator(this->p, columns_, rows_-1);
528 }
529
532 {
533 return ConstIterator(this->p, columns_, -1);
534 }
535
536 //===== sizes
537
539 size_type N () const
540 {
541 return rows_;
542 }
543
544
545 private:
546 size_type rows_; // number of matrix rows
547 size_type columns_; // number of matrix columns
548
549 A allocator_;
550 };
551
552} // namespace MatrixImp
553
559 template<class T, class A=std::allocator<T> >
560 class Matrix
561 {
562 public:
563
565 using field_type = typename Imp::BlockTraits<T>::field_type;
566
568 typedef T block_type;
569
571 typedef A allocator_type;
572
574 typedef typename MatrixImp::DenseMatrixBase<T,A>::window_type row_type;
575
577 typedef typename A::size_type size_type;
578
581
583 typedef typename row_type::iterator ColIterator;
584
587
589 typedef typename row_type::const_iterator ConstColIterator;
590
592 [[deprecated("Use free function blockLevel(). Will be removed after 2.8.")]]
593 static constexpr auto blocklevel = blockLevel<T>()+1;
594
596 Matrix() : data_(0,0), cols_(0)
597 {}
598
601 Matrix(size_type rows, size_type cols) : data_(rows,cols), cols_(cols)
602 {}
603
608 void setSize(size_type rows, size_type cols) {
609 data_.resize(rows,cols);
610 cols_ = cols;
611 }
612
615 {
616 return data_.begin();
617 }
618
621 {
622 return data_.end();
623 }
624
628 {
629 return data_.beforeEnd();
630 }
631
635 {
636 return data_.beforeBegin();
637 }
638
641 {
642 return data_.begin();
643 }
644
647 {
648 return data_.end();
649 }
650
654 {
655 return data_.beforeEnd();
656 }
657
661 {
662 return data_.beforeBegin();
663 }
664
667 {
668 data_ = t;
669 return *this;
670 }
671
674#ifdef DUNE_ISTL_WITH_CHECKING
675 if (row<0)
676 DUNE_THROW(ISTLError, "Can't access negative rows!");
677 if (row>=N())
678 DUNE_THROW(ISTLError, "Row index out of range!");
679#endif
680 return data_[row];
681 }
682
684 const row_type operator[](size_type row) const {
685#ifdef DUNE_ISTL_WITH_CHECKING
686 if (row<0)
687 DUNE_THROW(ISTLError, "Can't access negative rows!");
688 if (row>=N())
689 DUNE_THROW(ISTLError, "Row index out of range!");
690#endif
691 return data_[row];
692 }
693
695 size_type N() const {
696 return data_.N();
697 }
698
700 size_type M() const {
701 return cols_;
702 }
703
706 data_ *= scalar;
707 return (*this);
708 }
709
712 data_ /= scalar;
713 return (*this);
714 }
715
722#ifdef DUNE_ISTL_WITH_CHECKING
723 if(N()!=b.N() || M() != b.M())
724 DUNE_THROW(RangeError, "Matrix sizes do not match!");
725#endif
726 data_ += b.data_;
727 return (*this);
728 }
729
736#ifdef DUNE_ISTL_WITH_CHECKING
737 if(N()!=b.N() || M() != b.M())
738 DUNE_THROW(RangeError, "Matrix sizes do not match!");
739#endif
740 data_ -= b.data_;
741 return (*this);
742 }
743
746 Matrix out(M(), N());
747 for (size_type i=0; i<N(); i++)
748 for (size_type j=0; j<M(); j++)
749 out[j][i] = (*this)[i][j];
750
751 return out;
752 }
753
755 friend Matrix<T> operator*(const Matrix<T>& m1, const Matrix<T>& m2) {
756 Matrix<T> out(m1.N(), m2.M());
757 out = 0;
758
759 for (size_type i=0; i<out.N(); i++ ) {
760 for ( size_type j=0; j<out.M(); j++ )
761 for (size_type k=0; k<m1.M(); k++)
762 out[i][j] += m1[i][k]*m2[k][j];
763 }
764
765 return out;
766 }
767
769 template <class X, class Y>
770 friend Y operator*(const Matrix<T>& m, const X& vec) {
771#ifdef DUNE_ISTL_WITH_CHECKING
772 if (m.M()!=vec.size())
773 DUNE_THROW(ISTLError, "Vector size doesn't match the number of matrix columns!");
774#endif
775 Y out(m.N());
776 out = 0;
777
778 for (size_type i=0; i<out.size(); i++ ) {
779 for ( size_type j=0; j<vec.size(); j++ )
780 out[i] += m[i][j]*vec[j];
781 }
782
783 return out;
784 }
785
787 template <class X, class Y>
788 void mv(const X& x, Y& y) const
789 {
790#ifdef DUNE_ISTL_WITH_CHECKING
791 if (x.N()!=M()) DUNE_THROW(ISTLError,"vector/matrix size mismatch!");
792 if (y.N()!=N()) DUNE_THROW(ISTLError,"vector/matrix size mismatch!");
793#endif
794 for (size_type i=0; i<data_.N(); i++) {
795 y[i]=0;
796 for (size_type j=0; j<cols_; j++)
797 {
798 auto&& xj = Impl::asVector(x[j]);
799 auto&& yi = Impl::asVector(y[i]);
800 Impl::asMatrix((*this)[i][j]).umv(xj, yi);
801 }
802 }
803 }
804
806 template<class X, class Y>
807 void mtv (const X& x, Y& y) const
808 {
809#ifdef DUNE_ISTL_WITH_CHECKING
810 if (x.N()!=N()) DUNE_THROW(ISTLError,"index out of range");
811 if (y.N()!=M()) DUNE_THROW(ISTLError,"index out of range");
812#endif
813 for(size_type i=0; i<y.N(); ++i)
814 y[i]=0;
815 umtv(x,y);
816 }
817
819 template <class X, class Y>
820 void umv(const X& x, Y& y) const
821 {
822#ifdef DUNE_ISTL_WITH_CHECKING
823 if (x.N()!=M()) DUNE_THROW(ISTLError,"vector/matrix size mismatch!");
824 if (y.N()!=N()) DUNE_THROW(ISTLError,"vector/matrix size mismatch!");
825#endif
826 for (size_type i=0; i<data_.N(); i++)
827 for (size_type j=0; j<cols_; j++)
828 {
829 auto&& xj = Impl::asVector(x[j]);
830 auto&& yi = Impl::asVector(y[i]);
831 Impl::asMatrix((*this)[i][j]).umv(xj, yi);
832 }
833 }
834
836 template<class X, class Y>
837 void mmv (const X& x, Y& y) const
838 {
839#ifdef DUNE_ISTL_WITH_CHECKING
840 if (x.N()!=M()) DUNE_THROW(ISTLError,"vector/matrix size mismatch!");
841 if (y.N()!=N()) DUNE_THROW(ISTLError,"vector/matrix size mismatch!");
842#endif
843 for (size_type i=0; i<data_.N(); i++)
844 for (size_type j=0; j<cols_; j++)
845 {
846 auto&& xj = Impl::asVector(x[j]);
847 auto&& yi = Impl::asVector(y[i]);
848 Impl::asMatrix((*this)[i][j]).mmv(xj, yi);
849 }
850 }
851
853 template <class X, class Y>
854 void usmv(const field_type& alpha, const X& x, Y& y) const
855 {
856#ifdef DUNE_ISTL_WITH_CHECKING
857 if (x.N()!=M()) DUNE_THROW(ISTLError,"vector/matrix size mismatch!");
858 if (y.N()!=N()) DUNE_THROW(ISTLError,"vector/matrix size mismatch!");
859#endif
860 for (size_type i=0; i<data_.N(); i++)
861 for (size_type j=0; j<cols_; j++)
862 {
863 auto&& xj = Impl::asVector(x[j]);
864 auto&& yi = Impl::asVector(y[i]);
865 Impl::asMatrix((*this)[i][j]).usmv(alpha, xj, yi);
866 }
867 }
868
870 template<class X, class Y>
871 void umtv (const X& x, Y& y) const
872 {
873#ifdef DUNE_ISTL_WITH_CHECKING
874 if (x.N()!=N()) DUNE_THROW(ISTLError,"vector/matrix size mismatch!");
875 if (y.N()!=M()) DUNE_THROW(ISTLError,"vector/matrix size mismatch!");
876#endif
877 for (size_type i=0; i<data_.N(); i++)
878 for (size_type j=0; j<cols_; j++)
879 {
880 auto&& xi = Impl::asVector(x[i]);
881 auto&& yj = Impl::asVector(y[j]);
882 Impl::asMatrix((*this)[i][j]).umtv(xi, yj);
883 }
884 }
885
887 template<class X, class Y>
888 void mmtv (const X& x, Y& y) const
889 {
890#ifdef DUNE_ISTL_WITH_CHECKING
891 if (x.N()!=N()) DUNE_THROW(ISTLError,"vector/matrix size mismatch!");
892 if (y.N()!=M()) DUNE_THROW(ISTLError,"vector/matrix size mismatch!");
893#endif
894 for (size_type i=0; i<data_.N(); i++)
895 for (size_type j=0; j<cols_; j++)
896 {
897 auto&& xi = Impl::asVector(x[i]);
898 auto&& yj = Impl::asVector(y[j]);
899 Impl::asMatrix((*this)[i][j]).mmtv(xi, yj);
900 }
901 }
902
904 template<class X, class Y>
905 void usmtv (const field_type& alpha, const X& x, Y& y) const
906 {
907#ifdef DUNE_ISTL_WITH_CHECKING
908 if (x.N()!=N()) DUNE_THROW(ISTLError,"vector/matrix size mismatch!");
909 if (y.N()!=M()) DUNE_THROW(ISTLError,"vector/matrix size mismatch!");
910#endif
911 for (size_type i=0; i<data_.N(); i++)
912 for (size_type j=0; j<cols_; j++)
913 {
914 auto&& xi = Impl::asVector(x[i]);
915 auto&& yj = Impl::asVector(y[j]);
916 Impl::asMatrix((*this)[i][j]).usmtv(alpha, xi, yj);
917 }
918 }
919
921 template<class X, class Y>
922 void umhv (const X& x, Y& y) const
923 {
924#ifdef DUNE_ISTL_WITH_CHECKING
925 if (x.N()!=N()) DUNE_THROW(ISTLError,"vector/matrix size mismatch!");
926 if (y.N()!=M()) DUNE_THROW(ISTLError,"vector/matrix size mismatch!");
927#endif
928 for (size_type i=0; i<data_.N(); i++)
929 for (size_type j=0; j<cols_; j++)
930 {
931 auto&& xi = Impl::asVector(x[i]);
932 auto&& yj = Impl::asVector(y[j]);
933 Impl::asMatrix((*this)[i][j]).umhv(xi,yj);
934 }
935 }
936
938 template<class X, class Y>
939 void mmhv (const X& x, Y& y) const
940 {
941#ifdef DUNE_ISTL_WITH_CHECKING
942 if (x.N()!=N()) DUNE_THROW(ISTLError,"vector/matrix size mismatch!");
943 if (y.N()!=M()) DUNE_THROW(ISTLError,"vector/matrix size mismatch!");
944#endif
945 for (size_type i=0; i<data_.N(); i++)
946 for (size_type j=0; j<cols_; j++)
947 {
948 auto&& xi = Impl::asVector(x[i]);
949 auto&& yj = Impl::asVector(y[j]);
950 Impl::asMatrix((*this)[i][j]).mmhv(xi,yj);
951 }
952 }
953
955 template<class X, class Y>
956 void usmhv (const field_type& alpha, const X& x, Y& y) const
957 {
958#ifdef DUNE_ISTL_WITH_CHECKING
959 if (x.N()!=N()) DUNE_THROW(ISTLError,"vector/matrix size mismatch!");
960 if (y.N()!=M()) DUNE_THROW(ISTLError,"vector/matrix size mismatch!");
961#endif
962 for (size_type i=0; i<data_.N(); i++)
963 for (size_type j=0; j<cols_; j++)
964 {
965 auto&& xi = Impl::asVector(x[i]);
966 auto&& yj = Impl::asVector(y[j]);
967 Impl::asMatrix((*this)[i][j]).usmhv(alpha,xi,yj);
968 }
969 }
970
971 //===== norms
972
974 typename FieldTraits<field_type>::real_type frobenius_norm () const
975 {
976 return std::sqrt(frobenius_norm2());
977 }
978
980 typename FieldTraits<field_type>::real_type frobenius_norm2 () const
981 {
982 typename FieldTraits<field_type>::real_type sum=0;
983 for (size_type i=0; i<this->N(); i++)
984 for (size_type j=0; j<this->M(); j++)
985 sum += Impl::asMatrix(data_[i][j]).frobenius_norm2();
986 return sum;
987 }
988
990 template <typename ft = field_type,
991 typename std::enable_if<!HasNaN<ft>::value, int>::type = 0>
992 typename FieldTraits<ft>::real_type infinity_norm() const {
993 using real_type = typename FieldTraits<ft>::real_type;
994 using std::max;
995
996 real_type norm = 0;
997 for (auto const &x : *this) {
998 real_type sum = 0;
999 for (auto const &y : x)
1000 sum += Impl::asMatrix(y).infinity_norm();
1001 norm = max(sum, norm);
1002 isNaN += sum;
1003 }
1004
1005 return norm;
1006 }
1007
1009 template <typename ft = field_type,
1010 typename std::enable_if<!HasNaN<ft>::value, int>::type = 0>
1011 typename FieldTraits<ft>::real_type infinity_norm_real() const {
1012 using real_type = typename FieldTraits<ft>::real_type;
1013 using std::max;
1014
1015 real_type norm = 0;
1016 for (auto const &x : *this) {
1017 real_type sum = 0;
1018 for (auto const &y : x)
1019 sum += Impl::asMatrix(y).infinity_norm_real();
1020 norm = max(sum, norm);
1021 }
1022 return norm;
1023 }
1024
1026 template <typename ft = field_type,
1027 typename std::enable_if<HasNaN<ft>::value, int>::type = 0>
1028 typename FieldTraits<ft>::real_type infinity_norm() const {
1029 using real_type = typename FieldTraits<ft>::real_type;
1030 using std::max;
1031
1032 real_type norm = 0;
1033 real_type isNaN = 1;
1034 for (auto const &x : *this) {
1035 real_type sum = 0;
1036 for (auto const &y : x)
1037 sum += Impl::asMatrix(y).infinity_norm();
1038 norm = max(sum, norm);
1039 isNaN += sum;
1040 }
1041
1042 return norm * (isNaN / isNaN);
1043 }
1044
1046 template <typename ft = field_type,
1047 typename std::enable_if<HasNaN<ft>::value, int>::type = 0>
1048 typename FieldTraits<ft>::real_type infinity_norm_real() const {
1049 using real_type = typename FieldTraits<ft>::real_type;
1050 using std::max;
1051
1052 real_type norm = 0;
1053 real_type isNaN = 1;
1054 for (auto const &x : *this) {
1055 real_type sum = 0;
1056 for (auto const &y : x)
1057 sum += Impl::asMatrix(y).infinity_norm_real();
1058 norm = max(sum, norm);
1059 isNaN += sum;
1060 }
1061
1062 return norm * (isNaN / isNaN);
1063 }
1064
1065 //===== query
1066
1068 bool exists ([[maybe_unused]] size_type i, [[maybe_unused]] size_type j) const
1069 {
1070#ifdef DUNE_ISTL_WITH_CHECKING
1071 if (i<0 || i>=N()) DUNE_THROW(ISTLError,"row index out of range");
1072 if (j<0 || i>=M()) DUNE_THROW(ISTLError,"column index out of range");
1073#endif
1074 return true;
1075 }
1076
1077 protected:
1078
1082
1089 };
1090
1091 template<class T, class A>
1092 struct FieldTraits< Matrix<T, A> >
1093 {
1094 using field_type = typename Matrix<T, A>::field_type;
1095 using real_type = typename FieldTraits<field_type>::real_type;
1096 };
1097
1099} // end namespace Dune
1100
1101#endif
Helper functions for determining the vector/matrix block level.
This file implements a vector space as a tensor product of a given vector space. The number of compon...
A vector of blocks with memory management.
Definition: bvector.hh:395
derive error class from the base class in common
Definition: istlexception.hh:19
ConstIterator class for sequential access.
Definition: matrix.hh:404
const window_type * operator->() const
arrow
Definition: matrix.hh:487
const window_type & operator*() const
dereferencing
Definition: matrix.hh:481
ConstIterator & operator++()
prefix increment
Definition: matrix.hh:441
ConstIterator(const B *data, size_type columns, size_type _i)
constructor from pointer
Definition: matrix.hh:414
ConstIterator & operator--()
prefix decrement
Definition: matrix.hh:449
ConstIterator(const Iterator &it)
constructor from non_const iterator
Definition: matrix.hh:420
bool operator!=(const ConstIterator &it) const
inequality
Definition: matrix.hh:463
ConstIterator()
constructor
Definition: matrix.hh:407
bool operator==(const ConstIterator &it) const
equality
Definition: matrix.hh:457
Iterator class for sequential access.
Definition: matrix.hh:263
Iterator & operator--()
prefix decrement
Definition: matrix.hh:308
bool operator!=(const Iterator &it) const
inequality
Definition: matrix.hh:322
Iterator & operator=(Iterator &&other)
Move assignment.
Definition: matrix.hh:282
Iterator & operator++()
prefix increment
Definition: matrix.hh:300
Iterator()
constructor, no arguments
Definition: matrix.hh:266
window_type & operator*() const
dereferencing
Definition: matrix.hh:340
bool operator==(const Iterator &it) const
equality
Definition: matrix.hh:316
Iterator & operator=(Iterator &other)
Copy assignment.
Definition: matrix.hh:291
Iterator(B *data, size_type columns, size_type _i)
constructor
Definition: matrix.hh:276
window_type * operator->() const
arrow
Definition: matrix.hh:346
A Vector of blocks with different blocksizes.
Definition: matrix.hh:44
BlockVector< B, A > block_type
Same as value_type, here for historical reasons.
Definition: matrix.hh:67
DenseMatrixBase & operator=(const DenseMatrixBase &a)
assignment
Definition: matrix.hh:182
typename Imp::BlockTraits< B >::field_type field_type
export the type representing the field
Definition: matrix.hh:50
Iterator beforeBegin() const
Definition: matrix.hh:385
void resize(size_type rows, size_type columns)
same effect as constructor with same argument
Definition: matrix.hh:153
DenseMatrixBase(size_type rows, size_type columns)
Definition: matrix.hh:95
Iterator end()
end Iterator
Definition: matrix.hh:371
reference operator[](size_type i)
random access to blocks
Definition: matrix.hh:241
BlockVector< B, A > value_type
Type of the elements of the outer vector, i.e., dynamic vectors of B.
Definition: matrix.hh:63
Iterator find(size_type i)
random access returning iterator (end if not contained)
Definition: matrix.hh:391
size_type N() const
number of blocks in the vector (are of variable size here)
Definition: matrix.hh:539
ConstIterator beforeEnd() const
Definition: matrix.hh:525
ConstIterator end() const
end ConstIterator
Definition: matrix.hh:518
ConstIterator rend() const
end ConstIterator
Definition: matrix.hh:531
Iterator beforeEnd()
Definition: matrix.hh:378
ConstIterator begin() const
begin ConstIterator
Definition: matrix.hh:512
A allocator_type
export the allocator type
Definition: matrix.hh:53
DenseMatrixBase()
Definition: matrix.hh:82
ConstIterator find(size_type i) const
random access returning iterator (end if not contained)
Definition: matrix.hh:397
A::size_type size_type
The size type for the index access.
Definition: matrix.hh:56
~DenseMatrixBase()
free dynamic memory
Definition: matrix.hh:142
Iterator begin()
begin Iterator
Definition: matrix.hh:365
DenseMatrixBase(const DenseMatrixBase &a)
copy constructor, has copy semantics
Definition: matrix.hh:116
A generic dynamic dense matrix.
Definition: matrix.hh:561
size_type cols_
Number of columns of the matrix.
Definition: matrix.hh:1088
FieldTraits< ft >::real_type infinity_norm() const
infinity norm (row sum norm, how to generalize for blocks?)
Definition: matrix.hh:992
A allocator_type
Export the allocator.
Definition: matrix.hh:571
FieldTraits< ft >::real_type infinity_norm_real() const
simplified infinity norm (uses Manhattan norm for complex values)
Definition: matrix.hh:1011
void usmhv(const field_type &alpha, const X &x, Y &y) const
y += alpha A^H x
Definition: matrix.hh:956
void usmv(const field_type &alpha, const X &x, Y &y) const
Definition: matrix.hh:854
A::size_type size_type
Type for indices and sizes.
Definition: matrix.hh:577
MatrixImp::DenseMatrixBase< T, A > data_
Abuse DenseMatrixBase as an engine for a 2d array ISTL-style.
Definition: matrix.hh:1081
Matrix transpose() const
Return the transpose of the matrix.
Definition: matrix.hh:745
void mtv(const X &x, Y &y) const
y = A^T x
Definition: matrix.hh:807
void umv(const X &x, Y &y) const
y += A x
Definition: matrix.hh:820
void mv(const X &x, Y &y) const
y = A x
Definition: matrix.hh:788
MatrixImp::DenseMatrixBase< T, A >::ConstIterator ConstRowIterator
Const iterator over the matrix rows.
Definition: matrix.hh:586
void setSize(size_type rows, size_type cols)
Change the matrix size.
Definition: matrix.hh:608
RowIterator beforeBegin()
Definition: matrix.hh:634
RowIterator beforeEnd()
Definition: matrix.hh:627
Matrix()
Create empty matrix.
Definition: matrix.hh:596
Matrix & operator-=(const Matrix &b)
Subtract the entries of another matrix from this one.
Definition: matrix.hh:735
FieldTraits< field_type >::real_type frobenius_norm2() const
square of frobenius norm, need for block recursion
Definition: matrix.hh:980
row_type::iterator ColIterator
Iterator for the entries of each row.
Definition: matrix.hh:583
ConstRowIterator beforeEnd() const
Definition: matrix.hh:653
Matrix & operator=(const field_type &t)
Assignment from scalar.
Definition: matrix.hh:666
RowIterator end()
Get iterator to one beyond last row.
Definition: matrix.hh:620
const row_type operator[](size_type row) const
The const index operator.
Definition: matrix.hh:684
ConstRowIterator end() const
Get const iterator to one beyond last row.
Definition: matrix.hh:646
friend Y operator*(const Matrix< T > &m, const X &vec)
Generic matrix-vector multiplication.
Definition: matrix.hh:770
Matrix< T > & operator*=(const field_type &scalar)
Multiplication with a scalar.
Definition: matrix.hh:705
row_type operator[](size_type row)
The index operator.
Definition: matrix.hh:673
void mmv(const X &x, Y &y) const
y -= A x
Definition: matrix.hh:837
Matrix & operator+=(const Matrix &b)
Add the entries of another matrix to this one.
Definition: matrix.hh:721
ConstRowIterator begin() const
Get const iterator to first row.
Definition: matrix.hh:640
void mmhv(const X &x, Y &y) const
y -= A^H x
Definition: matrix.hh:939
RowIterator begin()
Get iterator to first row.
Definition: matrix.hh:614
typename Imp::BlockTraits< T >::field_type field_type
Export the type representing the underlying field.
Definition: matrix.hh:565
row_type::const_iterator ConstColIterator
Const iterator for the entries of each row.
Definition: matrix.hh:589
static constexpr auto blocklevel
The number of nesting levels the matrix contains.
Definition: matrix.hh:593
size_type M() const
Return the number of columns.
Definition: matrix.hh:700
T block_type
Export the type representing the components.
Definition: matrix.hh:568
bool exists(size_type i, size_type j) const
return true if (i,j) is in pattern
Definition: matrix.hh:1068
Matrix< T > & operator/=(const field_type &scalar)
Division by a scalar.
Definition: matrix.hh:711
friend Matrix< T > operator*(const Matrix< T > &m1, const Matrix< T > &m2)
Generic matrix multiplication.
Definition: matrix.hh:755
void umtv(const X &x, Y &y) const
y += A^T x
Definition: matrix.hh:871
void mmtv(const X &x, Y &y) const
y -= A^T x
Definition: matrix.hh:888
MatrixImp::DenseMatrixBase< T, A >::window_type row_type
The type implementing a matrix row.
Definition: matrix.hh:574
FieldTraits< field_type >::real_type frobenius_norm() const
frobenius norm: sqrt(sum over squared values of entries)
Definition: matrix.hh:974
void usmtv(const field_type &alpha, const X &x, Y &y) const
y += alpha A^T x
Definition: matrix.hh:905
void umhv(const X &x, Y &y) const
y += A^H x
Definition: matrix.hh:922
size_type N() const
Return the number of rows.
Definition: matrix.hh:695
ConstRowIterator beforeBegin() const
Definition: matrix.hh:660
Matrix(size_type rows, size_type cols)
Create uninitialized matrix of size rows x cols.
Definition: matrix.hh:601
MatrixImp::DenseMatrixBase< T, A >::Iterator RowIterator
Iterator over the matrix rows.
Definition: matrix.hh:580
Default exception class for range errors.
Definition: exceptions.hh:254
Traits for type conversions and type information.
Type traits to determine the type of reals (when working with complex numbers)
#define DUNE_THROW(E, m)
Definition: exceptions.hh:218
auto max(ADLTag< 0 >, const V &v1, const V &v2)
implements binary Simd::max()
Definition: defaults.hh:81
Dune namespace.
Definition: alignedallocator.hh:13
Implements a scalar matrix view wrapper around an existing scalar.
Implements a scalar vector view wrapper around an existing scalar.
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Dec 21, 23:30, 2024)