Dune Core Modules (unstable)

scaledidmatrix.hh
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: Copyright © 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_SCALEDIDMATRIX_HH
6 #define DUNE_ISTL_SCALEDIDMATRIX_HH
7 
14 #include <cmath>
15 #include <cstddef>
16 #include <complex>
17 #include <iostream>
19 #include <dune/common/fmatrix.hh>
21 #include <dune/common/ftraits.hh>
22 
23 namespace Dune {
24 
28  template<class K, int n>
30  {
31  typedef DiagonalMatrixWrapper< ScaledIdentityMatrix<K,n> > WrapperType;
32 
33  public:
34  //===== type definitions and constants
35 
37  typedef K field_type;
38 
40  typedef K block_type;
41 
43  typedef std::size_t size_type;
44 
46  typedef DiagonalRowVector<K,n> row_type;
47  typedef row_type reference;
48  typedef DiagonalRowVectorConst<K,n> const_row_type;
49  typedef const_row_type const_reference;
50 
52  enum {
54  rows = n,
56  cols = n
57  };
58 
59  //===== constructors
63 
66  ScaledIdentityMatrix (const K& k)
67  : p_(k)
68  {}
69 
70  //===== assignment from scalar
71  ScaledIdentityMatrix& operator= (const K& k)
72  {
73  p_ = k;
74  return *this;
75  }
76 
77  // check if matrix is identical to other matrix (not only identical values)
78  bool identical(const ScaledIdentityMatrix<K,n>& other) const
79  {
80  return (this==&other);
81  }
82 
83  //===== iterator interface to rows of the matrix
87  typedef Iterator iterator;
91  typedef typename row_type::Iterator ColIterator;
92 
95  {
96  return Iterator(WrapperType(this),0);
97  }
98 
101  {
102  return Iterator(WrapperType(this),n);
103  }
104 
108  {
109  return Iterator(WrapperType(this),n-1);
110  }
111 
115  {
116  return Iterator(WrapperType(this),-1);
117  }
118 
119 
128 
131  {
132  return ConstIterator(WrapperType(this),0);
133  }
134 
137  {
138  return ConstIterator(WrapperType(this),n);
139  }
140 
144  {
145  return ConstIterator(WrapperType(this),n-1);
146  }
147 
151  {
152  return ConstIterator(WrapperType(this),-1);
153  }
154 
155  //===== vector space arithmetic
156 
159  {
160  p_ += y.p_;
161  return *this;
162  }
163 
166  {
167  p_ -= y.p_;
168  return *this;
169  }
170 
173  {
174  p_ += k;
175  return *this;
176  }
177 
180  {
181  p_ -= k;
182  return *this;
183  }
186  {
187  p_ *= k;
188  return *this;
189  }
190 
193  {
194  p_ /= k;
195  return *this;
196  }
197 
198  //===== binary operators
199 
201  template <class Scalar,
202  std::enable_if_t<IsNumber<Scalar>::value, int> = 0>
203  friend auto operator* ( const ScaledIdentityMatrix& matrix, Scalar scalar)
204  {
206  }
207 
209  template <class Scalar,
210  std::enable_if_t<IsNumber<Scalar>::value, int> = 0>
211  friend auto operator* (Scalar scalar, const ScaledIdentityMatrix& matrix)
212  {
214  }
215 
216  //===== comparison ops
217 
219  bool operator==(const ScaledIdentityMatrix& other) const
220  {
221  return p_==other.scalar();
222  }
223 
225  bool operator!=(const ScaledIdentityMatrix& other) const
226  {
227  return p_!=other.scalar();
228  }
229 
230  //===== linear maps
231 
233  template<class X, class Y>
234  void mv (const X& x, Y& y) const
235  {
236 #ifdef DUNE_FMatrix_WITH_CHECKING
237  if (x.N()!=M()) DUNE_THROW(FMatrixError,"index out of range");
238  if (y.N()!=N()) DUNE_THROW(FMatrixError,"index out of range");
239 #endif
240  for (size_type i=0; i<n; ++i)
241  y[i] = p_ * x[i];
242  }
243 
245  template<class X, class Y>
246  void mtv (const X& x, Y& y) const
247  {
248  mv(x, y);
249  }
250 
252  template<class X, class Y>
253  void umv (const X& x, Y& y) const
254  {
255 #ifdef DUNE_FMatrix_WITH_CHECKING
256  if (x.N()!=M()) DUNE_THROW(FMatrixError,"index out of range");
257  if (y.N()!=N()) DUNE_THROW(FMatrixError,"index out of range");
258 #endif
259  for (size_type i=0; i<n; ++i)
260  y[i] += p_ * x[i];
261  }
262 
264  template<class X, class Y>
265  void umtv (const X& x, Y& y) const
266  {
267 #ifdef DUNE_FMatrix_WITH_CHECKING
268  if (x.N()!=N()) DUNE_THROW(FMatrixError,"index out of range");
269  if (y.N()!=M()) DUNE_THROW(FMatrixError,"index out of range");
270 #endif
271  for (size_type i=0; i<n; ++i)
272  y[i] += p_ * x[i];
273  }
274 
276  template<class X, class Y>
277  void umhv (const X& x, Y& y) const
278  {
279 #ifdef DUNE_FMatrix_WITH_CHECKING
280  if (x.N()!=N()) DUNE_THROW(FMatrixError,"index out of range");
281  if (y.N()!=M()) DUNE_THROW(FMatrixError,"index out of range");
282 #endif
283  for (size_type i=0; i<n; i++)
284  y[i] += conjugateComplex(p_)*x[i];
285  }
286 
288  template<class X, class Y>
289  void mmv (const X& x, Y& y) const
290  {
291 #ifdef DUNE_FMatrix_WITH_CHECKING
292  if (x.N()!=M()) DUNE_THROW(FMatrixError,"index out of range");
293  if (y.N()!=N()) DUNE_THROW(FMatrixError,"index out of range");
294 #endif
295  for (size_type i=0; i<n; ++i)
296  y[i] -= p_ * x[i];
297  }
298 
300  template<class X, class Y>
301  void mmtv (const X& x, Y& y) const
302  {
303 #ifdef DUNE_FMatrix_WITH_CHECKING
304  if (x.N()!=N()) DUNE_THROW(FMatrixError,"index out of range");
305  if (y.N()!=M()) DUNE_THROW(FMatrixError,"index out of range");
306 #endif
307  for (size_type i=0; i<n; ++i)
308  y[i] -= p_ * x[i];
309  }
310 
312  template<class X, class Y>
313  void mmhv (const X& x, Y& y) const
314  {
315 #ifdef DUNE_FMatrix_WITH_CHECKING
316  if (x.N()!=N()) DUNE_THROW(FMatrixError,"index out of range");
317  if (y.N()!=M()) DUNE_THROW(FMatrixError,"index out of range");
318 #endif
319  for (size_type i=0; i<n; i++)
320  y[i] -= conjugateComplex(p_)*x[i];
321  }
322 
324  template<class X, class Y>
325  void usmv (const K& alpha, const X& x, Y& y) const
326  {
327 #ifdef DUNE_FMatrix_WITH_CHECKING
328  if (x.N()!=M()) DUNE_THROW(FMatrixError,"index out of range");
329  if (y.N()!=N()) DUNE_THROW(FMatrixError,"index out of range");
330 #endif
331  for (size_type i=0; i<n; i++)
332  y[i] += alpha * p_ * x[i];
333  }
334 
336  template<class X, class Y>
337  void usmtv (const K& alpha, const X& x, Y& y) const
338  {
339 #ifdef DUNE_FMatrix_WITH_CHECKING
340  if (x.N()!=N()) DUNE_THROW(FMatrixError,"index out of range");
341  if (y.N()!=M()) DUNE_THROW(FMatrixError,"index out of range");
342 #endif
343  for (size_type i=0; i<n; i++)
344  y[i] += alpha * p_ * x[i];
345  }
346 
348  template<class X, class Y>
349  void usmhv (const K& alpha, const X& x, Y& y) const
350  {
351 #ifdef DUNE_FMatrix_WITH_CHECKING
352  if (x.N()!=N()) DUNE_THROW(FMatrixError,"index out of range");
353  if (y.N()!=M()) DUNE_THROW(FMatrixError,"index out of range");
354 #endif
355  for (size_type i=0; i<n; i++)
356  y[i] += alpha * conjugateComplex(p_) * x[i];
357  }
358 
359  //===== norms
360 
362  typename FieldTraits<field_type>::real_type frobenius_norm () const
363  {
364  return fvmeta::sqrt(n*p_*p_);
365  }
366 
368  typename FieldTraits<field_type>::real_type frobenius_norm2 () const
369  {
370  return n*p_*p_;
371  }
372 
374  typename FieldTraits<field_type>::real_type infinity_norm () const
375  {
376  return std::abs(p_);
377  }
378 
380  typename FieldTraits<field_type>::real_type infinity_norm_real () const
381  {
382  return fvmeta::absreal(p_);
383  }
384 
385  //===== solve
386 
389  template<class V>
390  void solve (V& x, const V& b) const
391  {
392  for (int i=0; i<n; i++)
393  x[i] = b[i]/p_;
394  }
395 
398  void invert()
399  {
400  p_ = 1/p_;
401  }
402 
404  K determinant () const {
405  return std::pow(p_,n);
406  }
407 
408  //===== sizes
409 
411  size_type N () const
412  {
413  return n;
414  }
415 
417  size_type M () const
418  {
419  return n;
420  }
421 
422  //===== query
423 
425  bool exists (size_type i, size_type j) const
426  {
427 #ifdef DUNE_FMatrix_WITH_CHECKING
428  if (i<0 || i>=n) DUNE_THROW(FMatrixError,"row index out of range");
429  if (j<0 || j>=n) DUNE_THROW(FMatrixError,"column index out of range");
430 #endif
431  return i==j;
432  }
433 
434  //===== conversion operator
435 
437  friend std::ostream& operator<< (std::ostream& s, const ScaledIdentityMatrix<K,n>& a)
438  {
439  for (size_type i=0; i<n; i++) {
440  for (size_type j=0; j<n; j++)
441  s << ((i==j) ? a.p_ : 0) << " ";
442  s << std::endl;
443  }
444  return s;
445  }
446 
448  reference operator[](size_type i)
449  {
450  return reference(const_cast<K*>(&p_), i);
451  }
452 
454  const_reference operator[](size_type i) const
455  {
456  return const_reference(const_cast<K*>(&p_), i);
457  }
458 
460  const K& diagonal(size_type /*i*/) const
461  {
462  return p_;
463  }
464 
466  K& diagonal(size_type /*i*/)
467  {
468  return p_;
469  }
470 
473  const K& scalar() const
474  {
475  return p_;
476  }
477 
480  K& scalar()
481  {
482  return p_;
483  }
484 
485  private:
486  // the data, very simply a single number
487  K p_;
488 
489  };
490 
491  template <class DenseMatrix, class field, int N>
492  struct DenseMatrixAssigner<DenseMatrix, ScaledIdentityMatrix<field, N>> {
493  static void apply(DenseMatrix& denseMatrix,
494  ScaledIdentityMatrix<field, N> const& rhs) {
495  assert(denseMatrix.M() == N);
496  assert(denseMatrix.N() == N);
497  denseMatrix = field(0);
498  for (int i = 0; i < N; ++i)
499  denseMatrix[i][i] = rhs.scalar();
500  }
501  };
502 
503  template<class K, int n>
504  struct FieldTraits< ScaledIdentityMatrix<K, n> >
505  {
506  using field_type = typename ScaledIdentityMatrix<K, n>::field_type;
507  using real_type = typename FieldTraits<field_type>::real_type;
508  };
509 
510 } // end namespace
511 
512 #endif
Iterator class for sparse vector-like containers.
Definition: diagonalmatrix.hh:998
Error thrown if operations of a FieldMatrix fail.
Definition: densematrix.hh:126
A multiple of the identity matrix of static size.
Definition: scaledidmatrix.hh:30
void usmhv(const K &alpha, const X &x, Y &y) const
y += alpha A^H x
Definition: scaledidmatrix.hh:349
void mmtv(const X &x, Y &y) const
y -= A^T x
Definition: scaledidmatrix.hh:301
const_row_type::ConstIterator ConstColIterator
rename the iterators for easier access
Definition: scaledidmatrix.hh:127
ConstIterator end() const
end iterator
Definition: scaledidmatrix.hh:136
Iterator beforeBegin()
Definition: scaledidmatrix.hh:114
bool operator!=(const ScaledIdentityMatrix &other) const
incomparison operator
Definition: scaledidmatrix.hh:225
void mmv(const X &x, Y &y) const
y -= A x
Definition: scaledidmatrix.hh:289
K & diagonal(size_type)
Get reference to diagonal entry.
Definition: scaledidmatrix.hh:466
std::size_t size_type
The type used for the index access and size operations.
Definition: scaledidmatrix.hh:43
void usmv(const K &alpha, const X &x, Y &y) const
y += alpha A x
Definition: scaledidmatrix.hh:325
row_type::Iterator ColIterator
rename the iterators for easier access
Definition: scaledidmatrix.hh:91
void mv(const X &x, Y &y) const
y = A x
Definition: scaledidmatrix.hh:234
void umtv(const X &x, Y &y) const
y += A^T x
Definition: scaledidmatrix.hh:265
void umhv(const X &x, Y &y) const
y += A^H x
Definition: scaledidmatrix.hh:277
DiagonalRowVector< K, n > row_type
Each row is implemented by a field vector.
Definition: scaledidmatrix.hh:46
ContainerWrapperIterator< const WrapperType, reference, reference > Iterator
Iterator class for sequential access.
Definition: scaledidmatrix.hh:85
ScaledIdentityMatrix & operator+=(const ScaledIdentityMatrix &y)
vector space addition
Definition: scaledidmatrix.hh:158
Iterator beforeEnd()
Definition: scaledidmatrix.hh:107
K determinant() const
calculates the determinant of this matrix
Definition: scaledidmatrix.hh:404
K field_type
export the type representing the field
Definition: scaledidmatrix.hh:37
void usmtv(const K &alpha, const X &x, Y &y) const
y += alpha A^T x
Definition: scaledidmatrix.hh:337
Iterator end()
end iterator
Definition: scaledidmatrix.hh:100
Iterator iterator
typedef for stl compliant access
Definition: scaledidmatrix.hh:87
const K & scalar() const
Get const reference to the scalar diagonal value.
Definition: scaledidmatrix.hh:473
void umv(const X &x, Y &y) const
y += A x
Definition: scaledidmatrix.hh:253
@ rows
The number of rows.
Definition: scaledidmatrix.hh:54
@ cols
The number of columns.
Definition: scaledidmatrix.hh:56
ContainerWrapperIterator< const WrapperType, const_reference, const_reference > ConstIterator
Iterator class for sequential access.
Definition: scaledidmatrix.hh:121
ScaledIdentityMatrix & operator/=(const K &k)
vector space division by scalar
Definition: scaledidmatrix.hh:192
void solve(V &x, const V &b) const
Solve system A x = b.
Definition: scaledidmatrix.hh:390
bool exists(size_type i, size_type j) const
return true when (i,j) is in pattern
Definition: scaledidmatrix.hh:425
Iterator RowIterator
rename the iterators for easier access
Definition: scaledidmatrix.hh:89
ConstIterator const_iterator
typedef for stl compliant access
Definition: scaledidmatrix.hh:123
ScaledIdentityMatrix()
Default constructor.
Definition: scaledidmatrix.hh:62
bool operator==(const ScaledIdentityMatrix &other) const
comparison operator
Definition: scaledidmatrix.hh:219
FieldTraits< field_type >::real_type infinity_norm() const
infinity norm (row sum norm, how to generalize for blocks?)
Definition: scaledidmatrix.hh:374
ConstIterator beforeBegin() const
Definition: scaledidmatrix.hh:150
FieldTraits< field_type >::real_type infinity_norm_real() const
simplified infinity norm (uses Manhattan norm for complex values)
Definition: scaledidmatrix.hh:380
ConstIterator ConstRowIterator
rename the iterators for easier access
Definition: scaledidmatrix.hh:125
ConstIterator beforeEnd() const
Definition: scaledidmatrix.hh:143
size_type M() const
number of blocks in column direction
Definition: scaledidmatrix.hh:417
const_reference operator[](size_type i) const
Return const_reference object as row replacement.
Definition: scaledidmatrix.hh:454
ScaledIdentityMatrix(const K &k)
Constructor initializing the whole matrix with a scalar.
Definition: scaledidmatrix.hh:66
friend auto operator*(const ScaledIdentityMatrix &matrix, Scalar scalar)
vector space multiplication with scalar
Definition: scaledidmatrix.hh:203
void invert()
Compute inverse.
Definition: scaledidmatrix.hh:398
Iterator begin()
begin iterator
Definition: scaledidmatrix.hh:94
K & scalar()
Get reference to the scalar diagonal value.
Definition: scaledidmatrix.hh:480
ScaledIdentityMatrix & operator-=(const ScaledIdentityMatrix &y)
vector space subtraction
Definition: scaledidmatrix.hh:165
K block_type
export the type representing the components
Definition: scaledidmatrix.hh:40
FieldTraits< field_type >::real_type frobenius_norm() const
frobenius norm: sqrt(sum over squared values of entries)
Definition: scaledidmatrix.hh:362
void mmhv(const X &x, Y &y) const
y -= A^H x
Definition: scaledidmatrix.hh:313
friend std::ostream & operator<<(std::ostream &s, const ScaledIdentityMatrix< K, n > &a)
Sends the matrix to an output stream.
Definition: scaledidmatrix.hh:437
void mtv(const X &x, Y &y) const
y = A^T x
Definition: scaledidmatrix.hh:246
ScaledIdentityMatrix & operator*=(const K &k)
vector space multiplication with scalar
Definition: scaledidmatrix.hh:185
reference operator[](size_type i)
Return reference object as row replacement.
Definition: scaledidmatrix.hh:448
const K & diagonal(size_type) const
Get const reference to diagonal entry.
Definition: scaledidmatrix.hh:460
ConstIterator begin() const
begin iterator
Definition: scaledidmatrix.hh:130
FieldTraits< field_type >::real_type frobenius_norm2() const
square of frobenius norm, need for block recursion
Definition: scaledidmatrix.hh:368
size_type N() const
number of blocks in row direction
Definition: scaledidmatrix.hh:411
This file implements a quadratic diagonal matrix of fixed size.
A few common exception classes.
Implements a matrix constructed from a given type representing a field and compile-time given number ...
Type traits to determine the type of reals (when working with complex numbers)
#define DUNE_THROW(E, m)
Definition: exceptions.hh:218
typename Overloads::ScalarType< std::decay_t< V > >::type Scalar
Element type of some SIMD type.
Definition: interface.hh:235
Dune namespace.
Definition: alignedallocator.hh:13
K conjugateComplex(const K &x)
compute conjugate complex of x
Definition: math.hh:164
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.80.0 (May 3, 22:32, 2024)