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 
15 #include <dune/common/ftraits.hh>
19 
20 #include <dune/istl/bvector.hh>
21 #include <dune/istl/istlexception.hh>
22 #include <dune/istl/blocklevel.hh>
23 
24 namespace Dune {
25 
26 namespace 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 
241  reference operator[] (size_type i)
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 
262  class Iterator
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 
705  Matrix<T>& operator*=(const field_type& scalar) {
706  data_ *= scalar;
707  return (*this);
708  }
709 
711  Matrix<T>& operator/=(const field_type& scalar) {
712  data_ /= scalar;
713  return (*this);
714  }
715 
721  Matrix& operator+= (const Matrix& b) {
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 
735  Matrix& operator-= (const Matrix& b) {
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 
745  Matrix transpose() const {
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
dereferencing
Definition: matrix.hh:481
ConstIterator & operator++()
prefix increment
Definition: matrix.hh:441
ConstIterator & operator--()
prefix decrement
Definition: matrix.hh:449
ConstIterator(const B *data, size_type columns, size_type _i)
constructor from pointer
Definition: matrix.hh:414
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
const window_type * operator->() const
arrow
Definition: matrix.hh:487
Iterator class for sequential access.
Definition: matrix.hh:263
Iterator & operator++()
prefix increment
Definition: matrix.hh:300
bool operator!=(const Iterator &it) const
inequality
Definition: matrix.hh:322
Iterator & operator--()
prefix decrement
Definition: matrix.hh:308
window_type & operator*() const
dereferencing
Definition: matrix.hh:340
Iterator & operator=(Iterator &&other)
Move assignment.
Definition: matrix.hh:282
Iterator()
constructor, no arguments
Definition: matrix.hh:266
window_type * operator->() const
arrow
Definition: matrix.hh:346
bool operator==(const Iterator &it) const
equality
Definition: matrix.hh:316
Iterator(B *data, size_type columns, size_type _i)
constructor
Definition: matrix.hh:276
Iterator & operator=(Iterator &other)
Copy assignment.
Definition: matrix.hh:291
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
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
DenseMatrixBase & operator=(const DenseMatrixBase &a)
assignment
Definition: matrix.hh:182
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
A allocator_type
Export the allocator.
Definition: matrix.hh:571
FieldTraits< field_type >::real_type frobenius_norm() const
frobenius norm: sqrt(sum over squared values of entries)
Definition: matrix.hh:974
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
Matrix & operator=(const field_type &t)
Assignment from scalar.
Definition: matrix.hh:666
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
Matrix< T > & operator/=(const field_type &scalar)
Division by a scalar.
Definition: matrix.hh:711
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
bool exists([[maybe_unused]] size_type i, [[maybe_unused]] size_type j) const
return true if (i,j) is in pattern
Definition: matrix.hh:1068
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
FieldTraits< ft >::real_type infinity_norm() const
infinity norm (row sum norm, how to generalize for blocks?)
Definition: matrix.hh:992
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 Matrix &b)
Subtract the entries of another matrix from this one.
Definition: matrix.hh:735
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
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
FieldTraits< ft >::real_type infinity_norm_real() const
simplified infinity norm (uses Manhattan norm for complex values)
Definition: matrix.hh:1011
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
friend Matrix< T > operator*(const Matrix< T > &m1, const Matrix< T > &m2)
Generic matrix multiplication.
Definition: matrix.hh:755
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
void umtv(const X &x, Y &y) const
y += A^T x
Definition: matrix.hh:871
FieldTraits< field_type >::real_type frobenius_norm2() const
square of frobenius norm, need for block recursion
Definition: matrix.hh:980
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
Matrix & operator+=(const Matrix &b)
Add the entries of another matrix to this one.
Definition: matrix.hh:721
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< T > & operator*=(const field_type &scalar)
Multiplication with a scalar.
Definition: matrix.hh:705
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 min(ADLTag< 0 >, const V &v1, const V &v2)
implements binary Simd::min()
Definition: defaults.hh:89
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.80.0 (May 5, 22:29, 2024)