Discontinuous Galerkin Library
#include "dg/algorithm.h"
Loading...
Searching...
No Matches
operator.h
Go to the documentation of this file.
1#ifndef _DG_OPERATORS_DYN_
2#define _DG_OPERATORS_DYN_
3
4#include <vector>
5#include <algorithm>
6#include <cmath>
7#include <iterator>
8#include <stdexcept>
9#include <cassert>
10#include "dlt.h"
11#include "../blas1.h" // reproducible DOT products
12#include "../blas2.h" // Matrix tensor traits
13
14namespace dg{
15
16
29template< class T>
31{
32 public:
33 typedef T value_type;
37 SquareMatrix() = default;
43 explicit SquareMatrix( const unsigned n): n_(n), data_(n_*n_){}
50 SquareMatrix( const unsigned n, const T& value): n_(n), data_(n_*n_, value) {}
58 template< class InputIterator>
59 SquareMatrix( InputIterator first, InputIterator last, std::enable_if_t<!std::is_integral<InputIterator>::value>* = 0): data_(first, last)
60 {
61 unsigned n = std::distance( first, last);
62 n_ = (unsigned)sqrt( (double)n);
63 if( n_*n_!=n) throw Error( Message(_ping_)<<"Too few elements "<<n<<" need "<<n_*n_<<"\n");
64 }
70 SquareMatrix( const std::vector<T>& src): data_(src)
71 {
72 unsigned n = src.size();
73 n_ = (unsigned)sqrt( (double)n);
74 if( n_*n_!=n) throw Error( Message(_ping_)<<"Wrong number of elements "<<n<<" need "<<n_*n_<<"\n");
75 }
76
80 void zero() {
81 for( unsigned i=0; i<n_*n_; i++)
82 data_[i] = 0;
83 }
84
91 T& operator()(const size_t i, const size_t j)
92 {
93 return data_[ i*n_+j];
94 }
101 const T& operator()(const size_t i, const size_t j) const {
102 return data_[ i*n_+j];
103 }
104
110 unsigned size() const { return n_;}
117 void resize( unsigned m, T val = T()) {
118 n_ = m;
119 data_.resize( m*m, val);
120 }
121
127 const std::vector<value_type>& data() const {return data_;}
134 std::vector<value_type>& data() {return data_;}
135
142 void swap_lines( const size_t i, const size_t k)
143 {
144 if(!( i< n_ && k<n_)) throw Error( Message(_ping_) << "Out of range "<<i<<" "<<k<<" range is "<<n_<<"\n");
145 for( size_t j = 0; j<n_; j++)
146 {
147 std::swap( data_[i*n_+j], data_[k*n_+j]);
148 }
149 }
150
157 {
158 SquareMatrix o(*this);
159 for( unsigned i=0; i<n_; i++)
160 for( unsigned j=0; j<i; j++)
161 {
162 std::swap( o.data_[i*n_+j], o.data_[j*n_+i]);
163 }
164 return o;
165 }
166
174 template<class ContainerType1, class ContainerType2>
175 void symv( const ContainerType1& x, ContainerType2& y) const
176 {
177 for( unsigned j=0; j<n_; j++)
178 {
179 y[j] = 0;
180 for( unsigned k=0; k<n_; k++)
181 y[j] += data_[j*n_+k]*x[k];
182 }
183 }
193 template<class value_type1, class ContainerType1, class value_type2, class ContainerType2>
194 void symv( value_type1 alpha, const ContainerType1& x, value_type2 beta, ContainerType2& y) const
195 {
196 for( unsigned j=0; j<n_; j++)
197 {
198 y[j] *= beta;
199 for( unsigned k=0; k<n_; k++)
200 y[j] += alpha*data_[j*n_+k]*x[k];
201 }
202 }
203
209 bool operator!=( const SquareMatrix& rhs) const{
210 for( size_t i = 0; i < n_*n_; i++)
211 if( data_[i] != rhs.data_[i])
212 return true;
213 return false;
214 }
215
221 bool operator==( const SquareMatrix& rhs) const {return !((*this != rhs));}
222
229 {
230 SquareMatrix temp(n_, 0.);
231 for( unsigned i=0; i<n_*n_; i++)
232 temp.data_[i] = -data_[i];
233 return temp;
234 }
243 {
244 for( unsigned i=0; i<n_*n_; i++)
245 data_[i] += op.data_[i];
246 return *this;
247 }
256 {
257 for( unsigned i=0; i<n_*n_; i++)
258 data_[i] -= op.data_[i];
259 return *this;
260 }
268 SquareMatrix& operator*=( const T& value )
269 {
270 for( unsigned i=0; i<n_*n_; i++)
271 data_[i] *= value;
272 return *this;
273 }
282 friend SquareMatrix operator+( const SquareMatrix& lhs, const SquareMatrix& rhs)
283 {
284 SquareMatrix temp(lhs);
285 temp+=rhs;
286 return temp;
287 }
296 friend SquareMatrix operator-( const SquareMatrix& lhs, const SquareMatrix& rhs)
297 {
298 SquareMatrix temp(lhs);
299 temp-=rhs;
300 return temp;
301 }
310 friend SquareMatrix operator*( const T& value, const SquareMatrix& rhs )
311 {
312 SquareMatrix temp(rhs);
313 temp*=value;
314 return temp;
315 }
316
325 friend SquareMatrix operator*( const SquareMatrix& lhs, const T& value)
326 {
327 return value*lhs;
328 }
329
338 friend SquareMatrix operator*( const SquareMatrix& lhs, const SquareMatrix& rhs)
339 {
340 unsigned n_ = lhs.n_;
341 SquareMatrix temp(n_, 0.);
342 for( unsigned i=0; i< n_; i++)
343 for( unsigned j=0; j<n_; j++)
344 {
345 temp.data_[i*n_+j] = (T)0;
346 for( unsigned k=0; k<n_; k++)
347 temp.data_[i*n_+j] += lhs.data_[i*n_+k]*rhs.data_[k*n_+j];
348 }
349 return temp;
350 }
351
361 template<class ContainerType>
362 friend ContainerType operator*( const SquareMatrix& S, const ContainerType& x)
363 {
364 ContainerType out(x);
365 S.symv( x, out);
366 return out;
367 }
368
376 friend std::ostream& operator<<(std::ostream& os, const SquareMatrix& mat)
377 {
378 unsigned n_ = mat.n_;
379 for( size_t i=0; i < n_ ; i++)
380 {
381 for( size_t j = 0;j < n_; j++)
382 os << mat(i,j) << " ";
383 os << "\n";
384 }
385 return os;
386 }
387
397 template< class Istream>
398 friend Istream& operator>> ( Istream& is, SquareMatrix<T>& mat){
399 unsigned n_ = mat.n_;
400 for( size_t i=0; i<n_; i++)
401 for( size_t j=0; j<n_; j++)
402 is >> mat(i, j);
403 return is;
404 }
405
406 private:
407 unsigned n_;
408 std::vector<T> data_;
409};
410
412template<class T>
419
420
421namespace create
422{
425
439template< class T>
440T lu_pivot( dg::SquareMatrix<T>& m, std::vector<unsigned>& p)
441{
442 //from numerical recipes
443 T pivot, determinant=(T)1;
444 unsigned pivotzeile, numberOfSwaps=0;
445 const size_t n = m.size();
446 p.resize( n);
447 for( size_t j = 0; j < n; j++) //gehe Spalten /Diagonale durch
448 {
449 //compute upper matrix except for the diagonal element (the pivot)
450 for( size_t i = 0; i< j; i++)
451 {
452 thrust::host_vector<T> mik(i), mkj(i);
453 for( size_t k=0; k<i; k++)
454 mik[k] = m(i,k), mkj[k] = m(k,j);
455 m(i,j) -= dg::blas1::dot( mik, mkj);
456 }
457 //compute canditates for pivot elements
458 for( size_t i = j; i< n; i++)
459 {
460 thrust::host_vector<T> mik(j), mkj(j);
461 for( size_t k=0; k<j; k++)
462 mik[k] = m(i,k), mkj[k] = m(k,j);
463 m(i,j) -= dg::blas1::dot( mik, mkj);
464 }
465 //search for absolute maximum of pivot candidates
466 pivot = m(j,j);
467 pivotzeile = j;
468 for( size_t i = j+1; i < n; i++)
469 if( fabs( m(i,j)) > fabs(pivot))
470 {
471 pivot = m(i,j), pivotzeile = i;
472 }
473
474 if( fabs(pivot) > 1e-15 )
475 {
476 if( pivotzeile != j)
477 {
478 m.swap_lines( pivotzeile, j);
479 numberOfSwaps++;
480 }
481 p[j] = pivotzeile;
482 //divide all elements below the diagonal by the pivot to get the lower matrix
483 for( size_t i=j+1; i<n; i++)
484 m(i,j) /= pivot;
485 determinant*=m(j,j);
486
487 }
488 else
489 throw std::runtime_error( "Matrix is singular!!");
490 }
491 if( numberOfSwaps % 2 != 0)
492 determinant*=-1.;
493 return determinant;
494
495}
496
512template<class T>
514{
515 dg::SquareMatrix<T> out(in);
516 const unsigned n = in.size();
517 std::vector<unsigned> pivot( n);
518 dg::SquareMatrix<T> lu(in);
519 T determinant = lu_pivot( lu, pivot);
520 if( fabs(determinant ) == 0)
521 throw std::runtime_error( "Determinant zero!");
522 for( unsigned i=0; i<n; i++)
523 {
524 std::vector<T> unit(n, 0);
525 unit[i] = 1;
526 lu_solve( lu, pivot, unit);
527 for( unsigned j=0; j<n; j++)
528 out(j,i) = unit[j];
529 }
530 return out;
531}
532
534
542template<class real_type>
543SquareMatrix<real_type> delta( unsigned n)
544{
546 for( unsigned i=0; i<n; i++)
547 op( i,i) = 1.;
548 return op;
549}
550
551
552// Not sure why we called this dg::create::lu_solve instead of dg::lu_solve
553template<class T>
554void lu_solve( const dg::SquareMatrix<T>& lu, const std::vector<unsigned>& p, std::vector<T>& b)
555{
556 assert(p.size() == lu.size() && p.size() == b.size());
557 const size_t n = p.size();
558 // Vorwärtseinsetzen
559 for( size_t i = 0; i<n; i++)
560 {
561 //mache Zeilentausch
562 std::swap( b[ p[i] ], b[i]);
563 thrust::host_vector<T> lui(i), bi(i);
564 for( size_t j = 0; j < i; j++)
565 lui[j] = lu(i,j), bi[j] = b[j];
566 b[i] -= dg::blas1::dot( lui, bi);
567 }
568 // Rückwärtseinsetzen
569 for( int i = n-1; i>=0; i--)
570 {
571 thrust::host_vector<T> lui(n-(i+1)), bi(n-(i+1));
572 for( size_t j = i+1; j < n; j++)
573 lui[j-(i+1)] = lu(i,j), bi[j-(i+1)] = b[j];
574 b[i] -= dg::blas1::dot( lui, bi);
575 b[i] /= lu(i,i);
576 }
577}
578
579
580// S-matrix
581template<class real_type>
582SquareMatrix<real_type> pipj( unsigned n)
583{
584 SquareMatrix<real_type> op(n, 0);
585 for( unsigned i=0; i<n; i++)
586 op( i,i) = 2./(real_type)(2*i+1);
587 return op;
588}
589// T-matrix
590template<class real_type>
591SquareMatrix<real_type> pipj_inv( unsigned n)
592{
593 SquareMatrix<real_type> op(n, 0);
594 for( unsigned i=0; i<n; i++)
595 op( i,i) = (real_type)(2*i+1)/2.;
596 return op;
597}
598// D-matrix
599template<class real_type>
600SquareMatrix<real_type> pidxpj( unsigned n)
601{
602 SquareMatrix<real_type> op(n, 0);
603 for( unsigned i=0; i<n; i++)
604 for( unsigned j=0; j<n; j++)
605 {
606 if( i < j)
607 {
608 if( (i+j)%2 != 0)
609 op( i, j) = 2;
610 }
611 }
612 return op;
613}
614// R-matrix
615template<class real_type>
616SquareMatrix<real_type> rirj( unsigned n)
617{
618 return SquareMatrix<real_type>( n, 1.);
619}
620// RL-matrix
621template<class real_type>
622SquareMatrix<real_type> rilj( unsigned n)
623{
624 SquareMatrix<real_type> op( n, -1.);
625 for( unsigned i=0; i<n; i++)
626 for( unsigned j=0; j<n; j++)
627 if( j%2 == 0)
628 op( i,j) = 1.;
629 return op;
630}
631// LR-matrix
632template<class real_type>
633SquareMatrix<real_type> lirj( unsigned n) {
634 return rilj<real_type>( n).transpose();
635}
636// L-matrix
637template<class real_type>
638SquareMatrix<real_type> lilj( unsigned n)
639{
640 SquareMatrix<real_type> op( n, -1.);
641 for( unsigned i=0; i<n; i++)
642 for( unsigned j=0; j<n; j++)
643 if( ((i+j)%2) == 0)
644 op( i,j) = 1.;
645 return op;
646}
647
648// N-matrix
649template<class real_type>
650SquareMatrix<real_type> ninj( unsigned n)
651{
652 SquareMatrix<real_type> op( n, 0.);
653 for( int i=0; i<(int)n; i++)
654 for( int j=0; j<(int)n; j++)
655 {
656 if( i == j+1)
657 op( i,j) = 2./(2*i+1)/(2*j+1);
658 if( i == j-1)
659 op( i,j) = -2./(2*i+1)/(2*j+1);
660 }
661 op(0,0) = 2;
662 return op;
663}
665
666
668}//namespace create
669
680template<class T>
681void lu_solve( const dg::SquareMatrix<T>& lu, const std::vector<unsigned>& p, std::vector<T>& b)
682{
683 dg::create::lu_solve( lu, p, b);
684}
685
689template<class T>
697template<class T>
699
700} //namespace dg
701
702#endif //_DG_OPERATORS_DYN_
class intended for the use in throw statements
Definition exceptions.h:83
small class holding a stringstream
Definition exceptions.h:29
A square nxn matrix.
Definition operator.h:31
SquareMatrix & operator-=(const SquareMatrix &op)
subtract
Definition operator.h:255
unsigned size() const
Size n of the SquareMatrix.
Definition operator.h:110
SquareMatrix & operator*=(const T &value)
scalar multiply
Definition operator.h:268
const std::vector< value_type > & data() const
access underlying data
Definition operator.h:127
SquareMatrix(const unsigned n)
allocate storage for nxn matrix
Definition operator.h:43
SquareMatrix(const unsigned n, const T &value)
Initialize elements.
Definition operator.h:50
void symv(value_type1 alpha, const ContainerType1 &x, value_type2 beta, ContainerType2 &y) const
Matrix vector multiplication .
Definition operator.h:194
const T & operator()(const size_t i, const size_t j) const
const access operator
Definition operator.h:101
void resize(unsigned m, T val=T())
Resize.
Definition operator.h:117
friend SquareMatrix operator*(const SquareMatrix &lhs, const T &value)
scalar multiplication
Definition operator.h:325
friend SquareMatrix operator*(const SquareMatrix &lhs, const SquareMatrix &rhs)
matrix multiplication
Definition operator.h:338
friend std::ostream & operator<<(std::ostream &os, const SquareMatrix &mat)
puts a matrix linewise in output stream
Definition operator.h:376
bool operator==(const SquareMatrix &rhs) const
two Matrices are considered equal if elements are equal
Definition operator.h:221
SquareMatrix & operator+=(const SquareMatrix &op)
add
Definition operator.h:242
void swap_lines(const size_t i, const size_t k)
Swap two lines in the square matrix.
Definition operator.h:142
void zero()
Assign zero to all elements.
Definition operator.h:80
T value_type
typically double or float
Definition operator.h:33
void symv(const ContainerType1 &x, ContainerType2 &y) const
Matrix vector multiplication .
Definition operator.h:175
friend ContainerType operator*(const SquareMatrix &S, const ContainerType &x)
matrix-vector multiplication
Definition operator.h:362
friend SquareMatrix operator*(const T &value, const SquareMatrix &rhs)
scalar multiplication
Definition operator.h:310
SquareMatrix(const std::vector< T > &src)
Copy from existing data.
Definition operator.h:70
SquareMatrix operator-() const
subtract
Definition operator.h:228
friend SquareMatrix operator+(const SquareMatrix &lhs, const SquareMatrix &rhs)
add
Definition operator.h:282
friend SquareMatrix operator-(const SquareMatrix &lhs, const SquareMatrix &rhs)
subtract
Definition operator.h:296
bool operator!=(const SquareMatrix &rhs) const
two Matrices are considered equal if elements are equal
Definition operator.h:209
friend Istream & operator>>(Istream &is, SquareMatrix< T > &mat)
Read values into a Matrix from given istream.
Definition operator.h:398
T & operator()(const size_t i, const size_t j)
access operator
Definition operator.h:91
SquareMatrix()=default
Construct empty SquareMatrix.
std::vector< value_type > & data()
Write access to underlying data.
Definition operator.h:134
SquareMatrix(InputIterator first, InputIterator last, std::enable_if_t<!std::is_integral< InputIterator >::value > *=0)
Construct from iterators.
Definition operator.h:59
SquareMatrix transpose() const
Transposition.
Definition operator.h:156
The discrete legendre trafo class.
#define _ping_
Definition exceptions.h:12
void rhs(double t, double, double &yp)
auto dot(const ContainerType1 &x, const ContainerType2 &y)
Binary reproducible Euclidean dot product between two vectors
Definition blas1.h:153
@ y
y direction
@ x
x direction
dg::SquareMatrix< T > inverse(const dg::SquareMatrix< T > &in)
Invert a square matrix.
Definition operator.h:513
void lu_solve(const dg::SquareMatrix< T > &lu, const std::vector< unsigned > &p, std::vector< T > &b)
Solve the linear system with the LU decomposition.
Definition operator.h:681
T lu_pivot(dg::SquareMatrix< T > &m, std::vector< unsigned > &p)
LU Decomposition with partial pivoting.
Definition operator.h:440
dg::SquareMatrix< T > invert(const dg::SquareMatrix< T > &in)
Compute inverse of square matrix (alias for dg::create::inverse)
Definition operator.h:690
double lhs(double x, double y)
const double m
const double alpha
const double n
This is the namespace for all functions and classes defined and used by the discontinuous Galerkin li...
const double beta
Indicates that the type has a member function with the same name and interface (up to the matrix itse...
Definition matrix_categories.h:26
Indicate sequential execution.
Definition execution_policy.h:26
T value_type
Definition operator.h:415
The vector traits.
Definition tensor_traits.h:38