scaledidmatrix.hh

Go to the documentation of this file.
00001 #ifndef DUNE_SCALED_IDENTITY_MATRIX_HH
00002 #define DUNE_SCALED_IDENTITY_MATRIX_HH
00003 
00010 #include<cmath>
00011 #include<cstddef>
00012 #include<complex>
00013 #include<iostream>
00014 #include <dune/common/exceptions.hh>
00015 #include <dune/common/fmatrix.hh>
00016 #include <dune/istl/diagonalmatrix.hh>
00017 
00018 namespace Dune {
00019    
00023     template<class K, int n>
00024     class ScaledIdentityMatrix
00025     {
00026 
00027     public:
00028         //===== type definitions and constants
00029 
00031         typedef K field_type;
00032 
00034         typedef K block_type;
00035     
00037         typedef std::size_t size_type;
00038     
00040         enum {
00042             blocklevel = 1
00043         };
00044 
00046     typedef DiagonalRowVector<K,n> row_type;
00047     typedef row_type reference;
00048     typedef DiagonalRowVectorConst<K,n> const_row_type;
00049     typedef const_row_type const_reference;
00050 
00052         enum {
00054           rows = n, 
00056           cols = n
00057         };
00058 
00059         //===== constructors
00062         ScaledIdentityMatrix () {}
00063 
00066         ScaledIdentityMatrix (const K& k) 
00067             : p_(k)
00068         {}
00069 
00070         //===== assignment from scalar
00071         ScaledIdentityMatrix& operator= (const K& k)
00072         {
00073             p_ = k;
00074             return *this;         
00075         }
00076 
00077     // check if matrix is identical to other matrix (not only identical values)
00078     bool identical(const ScaledIdentityMatrix<K,n>& other) const
00079     {
00080         return (this==&other);
00081     }
00082 
00083     //===== iterator interface to rows of the matrix
00085     typedef ReferenceStorageIterator<ScaledIdentityMatrix<K,n>,reference,reference,ScaledIdentityMatrix<K,n>&> Iterator;
00087     typedef Iterator iterator;
00089     typedef Iterator RowIterator;
00091     typedef typename row_type::Iterator ColIterator;
00092 
00094     Iterator begin ()
00095     {
00096         return Iterator(*this,0);
00097     }
00098 
00100     Iterator end ()
00101     {
00102         return Iterator(*this,n);
00103     }
00104 
00106     Iterator rbegin ()
00107     {
00108         return Iterator(*this,n-1);
00109     }
00110 
00112     Iterator rend ()
00113     {
00114         return Iterator(*this,-1);
00115     }
00116 
00117 
00119     typedef ReferenceStorageIterator<const ScaledIdentityMatrix<K,n>,const_reference,const_reference,const ScaledIdentityMatrix<K,n>&> ConstIterator;
00121     typedef ConstIterator const_iterator;
00123     typedef ConstIterator ConstRowIterator;
00125     typedef typename const_row_type::ConstIterator ConstColIterator;
00126 
00128     ConstIterator begin () const
00129     {
00130         return ConstIterator(*this,0);
00131     }
00132 
00134     ConstIterator end () const
00135     {
00136         return ConstIterator(*this,n);
00137     }
00138 
00140     ConstIterator rbegin () const
00141     {
00142         return ConstIterator(*this,n-1);
00143     }
00144 
00146     ConstIterator rend () const
00147     {
00148         return ConstIterator(*this,-1);
00149     }
00150 
00151         //===== vector space arithmetic
00152 
00154         ScaledIdentityMatrix& operator+= (const ScaledIdentityMatrix& y)
00155         {
00156             p_ += y.p_;
00157             return *this;
00158         }
00159 
00161         ScaledIdentityMatrix& operator-= (const ScaledIdentityMatrix& y)
00162         {
00163             p_ -= y.p_;
00164             return *this;
00165         }
00166 
00168         ScaledIdentityMatrix& operator+= (const K& k)
00169         {
00170             p_ += k;
00171             return *this;
00172         }
00173 
00175         ScaledIdentityMatrix& operator-= (const K& k)
00176         {
00177             p_ -= k;
00178             return *this;
00179         }
00181         ScaledIdentityMatrix& operator*= (const K& k)
00182         {
00183             p_ *= k;
00184             return *this;
00185         }
00186 
00188         ScaledIdentityMatrix& operator/= (const K& k)
00189         {
00190             p_ /= k;
00191             return *this;
00192         }
00193 
00194         //===== linear maps
00195    
00197         template<class X, class Y>
00198         void mv (const X& x, Y& y) const
00199         {
00200 #ifdef DUNE_FMatrix_WITH_CHECKING
00201             if (x.N()!=M()) DUNE_THROW(FMatrixError,"index out of range");
00202             if (y.N()!=N()) DUNE_THROW(FMatrixError,"index out of range");
00203 #endif
00204             for (size_type i=0; i<n; ++i)
00205                 y[i] = p_ * x[i];
00206         }
00207 
00209         template<class X, class Y>
00210         void umv (const X& x, Y& y) const
00211         {
00212 #ifdef DUNE_FMatrix_WITH_CHECKING
00213           if (x.N()!=M()) DUNE_THROW(FMatrixError,"index out of range");
00214           if (y.N()!=N()) DUNE_THROW(FMatrixError,"index out of range");
00215 #endif
00216           for (size_type i=0; i<n; ++i)
00217                 y[i] += p_ * x[i];
00218         }
00219 
00221         template<class X, class Y>
00222         void umtv (const X& x, Y& y) const
00223         {
00224 #ifdef DUNE_FMatrix_WITH_CHECKING
00225           if (x.N()!=N()) DUNE_THROW(FMatrixError,"index out of range");
00226           if (y.N()!=M()) DUNE_THROW(FMatrixError,"index out of range");
00227 #endif
00228           for (size_type i=0; i<n; ++i)
00229                 y[i] += p_ * x[i];
00230         }
00231 
00233         template<class X, class Y>
00234         void umhv (const X& x, Y& y) const
00235         {
00236 #ifdef DUNE_FMatrix_WITH_CHECKING
00237           if (x.N()!=N()) DUNE_THROW(FMatrixError,"index out of range");
00238           if (y.N()!=M()) DUNE_THROW(FMatrixError,"index out of range");
00239 #endif
00240           for (size_type i=0; i<n; i++)
00241               y[i] += fm_ck(p_)*x[i];
00242         }
00243 
00245         template<class X, class Y>
00246         void mmv (const X& x, Y& y) const
00247         {
00248 #ifdef DUNE_FMatrix_WITH_CHECKING
00249           if (x.N()!=M()) DUNE_THROW(FMatrixError,"index out of range");
00250           if (y.N()!=N()) DUNE_THROW(FMatrixError,"index out of range");
00251 #endif
00252           for (size_type i=0; i<n; ++i)
00253                 y[i] -= p_ * x[i];
00254         }
00255 
00257         template<class X, class Y>
00258         void mmtv (const X& x, Y& y) const
00259         {
00260 #ifdef DUNE_FMatrix_WITH_CHECKING
00261           if (x.N()!=N()) DUNE_THROW(FMatrixError,"index out of range");
00262           if (y.N()!=M()) DUNE_THROW(FMatrixError,"index out of range");
00263 #endif
00264           for (size_type i=0; i<n; ++i)
00265               y[i] -= p_ * x[i];
00266         }
00267 
00269         template<class X, class Y>
00270         void mmhv (const X& x, Y& y) const
00271         {
00272 #ifdef DUNE_FMatrix_WITH_CHECKING
00273           if (x.N()!=N()) DUNE_THROW(FMatrixError,"index out of range");
00274           if (y.N()!=M()) DUNE_THROW(FMatrixError,"index out of range");
00275 #endif
00276           
00277           for (size_type i=0; i<n; i++)
00278               y[i] -= fm_ck(p_)*x[i];
00279         }
00280 
00282         template<class X, class Y>
00283         void usmv (const K& alpha, const X& x, Y& y) const
00284         {
00285 #ifdef DUNE_FMatrix_WITH_CHECKING
00286           if (x.N()!=M()) DUNE_THROW(FMatrixError,"index out of range");
00287           if (y.N()!=N()) DUNE_THROW(FMatrixError,"index out of range");
00288 #endif
00289           for (size_type i=0; i<n; i++)
00290               y[i] += alpha * p_ * x[i];
00291         }
00292 
00294         template<class X, class Y>
00295         void usmtv (const K& alpha, const X& x, Y& y) const
00296         {
00297 #ifdef DUNE_FMatrix_WITH_CHECKING
00298           if (x.N()!=N()) DUNE_THROW(FMatrixError,"index out of range");
00299           if (y.N()!=M()) DUNE_THROW(FMatrixError,"index out of range");
00300 #endif
00301           for (size_type i=0; i<n; i++)
00302               y[i] += alpha * p_ * x[i];
00303         }
00304 
00306         template<class X, class Y>
00307         void usmhv (const K& alpha, const X& x, Y& y) const
00308         {
00309 #ifdef DUNE_FMatrix_WITH_CHECKING
00310           if (x.N()!=N()) DUNE_THROW(FMatrixError,"index out of range");
00311           if (y.N()!=M()) DUNE_THROW(FMatrixError,"index out of range");
00312 #endif
00313           for (size_type i=0; i<n; i++)
00314               y[i] += alpha * fm_ck(p_) * x[i];
00315         }
00316 
00317         //===== norms
00318 
00320     double frobenius_norm () const
00321         {
00322             return std::sqrt(n*p_*p_);
00323         }
00324 
00326     double frobenius_norm2 () const
00327         {
00328             return n*p_*p_;
00329         }
00330 
00332     double infinity_norm () const
00333         {
00334           return std::fabs(p_);
00335         }
00336 
00338         double infinity_norm_real () const
00339         {
00340           return fvmeta_absreal(p_);
00341         }
00342 
00343         //===== solve
00344 
00347         template<class V>
00348         void solve (V& x, const V& b) const {
00349             for (int i=0; i<n; i++)
00350                 x[i] = b[i]/p_;
00351         }
00352 
00355         void invert() {
00356             p_ = 1/p_;
00357         }
00358 
00360         K determinant () const {
00361             return std::pow(p_,n);
00362         }
00363 
00364         //===== sizes
00365 
00367         size_type N () const
00368         {
00369           return n;
00370         }
00371 
00373         size_type M () const
00374         {
00375           return n;
00376         }
00377 
00378         //===== query
00379         
00381         bool exists (size_type i, size_type j) const
00382         {
00383 #ifdef DUNE_FMatrix_WITH_CHECKING
00384           if (i<0 || i>=n) DUNE_THROW(FMatrixError,"row index out of range");
00385           if (j<0 || j>=m) DUNE_THROW(FMatrixError,"column index out of range");
00386 #endif
00387           return i==j;
00388         }
00389 
00390         //===== conversion operator
00391 
00393 //        operator K () const {return p_;}
00394 
00398       /*   operator FieldMatrix<K,n,n>() const
00399     {
00400         FieldMatrix<K, n, n> fm = 0.0;
00401         for(int i=0; i<n; ++i)
00402             fm[i][i] = p_;
00403         return fm;
00404         }*/
00405 
00406 
00407 
00409       friend std::ostream& operator<< (std::ostream& s, const ScaledIdentityMatrix<K,n>& a)
00410       {
00411           for (size_type i=0; i<n; i++) {
00412               for (size_type j=0; j<n; j++)
00413                   s << ((i==j) ? a.p_ : 0) << " ";
00414               s << std::endl;
00415           }
00416           return s;
00417       }
00418 
00420     reference operator[](size_type i)
00421     {
00422         return reference(const_cast<K*>(&p_), i);
00423     }
00424 
00426     const_reference operator[](size_type i) const
00427     {
00428         return const_reference(const_cast<K*>(&p_), i);
00429     }
00430 
00432     const K& diagonal(size_type i) const
00433     {
00434         return p_;
00435     }
00436 
00438     K& diagonal(size_type i)
00439     {
00440         return p_;
00441     }
00442 
00445     const K& scalar() const
00446     {
00447         return p_;
00448     }
00449 
00452     K& scalar()
00453     {
00454         return p_;
00455     }
00456 
00457   private:
00458         // the data, very simply a single number
00459         K p_; 
00460 
00461     };
00462 
00463   template<class K, int n>
00464   void istl_assign_to_fmatrix(FieldMatrix<K,n,n>& fm, const ScaledIdentityMatrix<K,n>& s)
00465   {
00466     fm = K();
00467     for(int i=0; i<n; ++i)
00468       fm[i][i] = s.scalar();
00469   }
00470   
00471 } // end namespace
00472 
00473 #endif

Generated on Sun Nov 15 22:29:37 2009 for dune-istl by  doxygen 1.5.6