scaledidmatrix.hh

Go to the documentation of this file.
00001 // -*- tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
00002 // vi: set et ts=8 sw=4 sts=4:
00003 #ifndef DUNE_SCALED_IDENTITY_MATRIX_HH
00004 #define DUNE_SCALED_IDENTITY_MATRIX_HH
00005 
00012 #include<cmath>
00013 #include<cstddef>
00014 #include<complex>
00015 #include<iostream>
00016 #include <dune/common/exceptions.hh>
00017 #include <dune/common/fmatrix.hh>
00018 #include <dune/istl/diagonalmatrix.hh>
00019 
00020 namespace Dune {
00021 
00025 template<class K, int n>
00026 class ScaledIdentityMatrix
00027 {
00028     typedef DiagonalMatrixWrapper< ScaledIdentityMatrix<K,n> > WrapperType;
00029 
00030 public:
00031     //===== type definitions and constants
00032 
00034     typedef K field_type;
00035 
00037     typedef K block_type;
00038 
00040         typedef std::size_t size_type;
00041 
00043     enum {
00045             blocklevel = 1
00046     };
00047 
00049     typedef DiagonalRowVector<K,n> row_type;
00050     typedef row_type reference;
00051     typedef DiagonalRowVectorConst<K,n> const_row_type;
00052     typedef const_row_type const_reference;
00053 
00055     enum {
00057         rows = n,
00059         cols = n
00060     };
00061 
00062     //===== constructors
00065     ScaledIdentityMatrix () {}
00066 
00069     ScaledIdentityMatrix (const K& k)
00070         : p_(k)
00071     {}
00072 
00073     //===== assignment from scalar
00074     ScaledIdentityMatrix& operator= (const K& k)
00075     {
00076         p_ = k;
00077         return *this;
00078     }
00079 
00080     // check if matrix is identical to other matrix (not only identical values)
00081     bool identical(const ScaledIdentityMatrix<K,n>& other) const
00082     {
00083         return (this==&other);
00084     }
00085 
00086     //===== iterator interface to rows of the matrix
00088     typedef ContainerWrapperIterator<const WrapperType, reference, reference> Iterator;
00090     typedef Iterator iterator;
00092     typedef Iterator RowIterator;
00094     typedef typename row_type::Iterator ColIterator;
00095 
00097     Iterator begin ()
00098     {
00099         return Iterator(WrapperType(this),0);
00100     }
00101 
00103     Iterator end ()
00104     {
00105         return Iterator(WrapperType(this),n);
00106     }
00107 
00109     Iterator rbegin ()
00110     {
00111         return Iterator(WrapperType(this),n-1);
00112     }
00113 
00115     Iterator rend ()
00116     {
00117         return Iterator(WrapperType(this),-1);
00118     }
00119 
00120 
00122     typedef ContainerWrapperIterator<const WrapperType, const_reference, const_reference> ConstIterator;
00124     typedef ConstIterator const_iterator;
00126     typedef ConstIterator ConstRowIterator;
00128     typedef typename const_row_type::ConstIterator ConstColIterator;
00129 
00131     ConstIterator begin () const
00132     {
00133         return ConstIterator(WrapperType(this),0);
00134     }
00135 
00137     ConstIterator end () const
00138     {
00139         return ConstIterator(WrapperType(this),n);
00140     }
00141 
00143     ConstIterator rbegin () const
00144     {
00145         return ConstIterator(WrapperType(this),n-1);
00146     }
00147 
00149     ConstIterator rend () const
00150     {
00151         return ConstIterator(WrapperType(this),-1);
00152     }
00153 
00154     //===== vector space arithmetic
00155 
00157     ScaledIdentityMatrix& operator+= (const ScaledIdentityMatrix& y)
00158     {
00159         p_ += y.p_;
00160         return *this;
00161     }
00162 
00164     ScaledIdentityMatrix& operator-= (const ScaledIdentityMatrix& y)
00165     {
00166         p_ -= y.p_;
00167         return *this;
00168     }
00169 
00171     ScaledIdentityMatrix& operator+= (const K& k)
00172     {
00173         p_ += k;
00174         return *this;
00175     }
00176 
00178     ScaledIdentityMatrix& operator-= (const K& k)
00179     {
00180         p_ -= k;
00181         return *this;
00182     }
00184     ScaledIdentityMatrix& operator*= (const K& k)
00185     {
00186         p_ *= k;
00187         return *this;
00188     }
00189 
00191     ScaledIdentityMatrix& operator/= (const K& k)
00192     {
00193         p_ /= k;
00194         return *this;
00195     }
00196 
00197     //===== linear maps
00198 
00200     template<class X, class Y>
00201     void mv (const X& x, Y& y) const
00202     {
00203 #ifdef DUNE_FMatrix_WITH_CHECKING
00204         if (x.N()!=M()) DUNE_THROW(FMatrixError,"index out of range");
00205         if (y.N()!=N()) DUNE_THROW(FMatrixError,"index out of range");
00206 #endif
00207         for (size_type i=0; i<n; ++i)
00208             y[i] = p_ * x[i];
00209     }
00210 
00212     template<class X, class Y>
00213     void mtv (const X& x, Y& y) const
00214     {
00215         mv(x, y);
00216     }
00217 
00219     template<class X, class Y>
00220     void umv (const X& x, Y& y) const
00221     {
00222 #ifdef DUNE_FMatrix_WITH_CHECKING
00223         if (x.N()!=M()) DUNE_THROW(FMatrixError,"index out of range");
00224         if (y.N()!=N()) DUNE_THROW(FMatrixError,"index out of range");
00225 #endif
00226         for (size_type i=0; i<n; ++i)
00227             y[i] += p_ * x[i];
00228     }
00229 
00231     template<class X, class Y>
00232     void umtv (const X& x, Y& y) const
00233     {
00234 #ifdef DUNE_FMatrix_WITH_CHECKING
00235         if (x.N()!=N()) DUNE_THROW(FMatrixError,"index out of range");
00236         if (y.N()!=M()) DUNE_THROW(FMatrixError,"index out of range");
00237 #endif
00238         for (size_type i=0; i<n; ++i)
00239             y[i] += p_ * x[i];
00240     }
00241 
00243     template<class X, class Y>
00244     void umhv (const X& x, Y& y) const
00245     {
00246 #ifdef DUNE_FMatrix_WITH_CHECKING
00247         if (x.N()!=N()) DUNE_THROW(FMatrixError,"index out of range");
00248         if (y.N()!=M()) DUNE_THROW(FMatrixError,"index out of range");
00249 #endif
00250         for (size_type i=0; i<n; i++)
00251             y[i] += conjugateComplex(p_)*x[i];
00252     }
00253 
00255     template<class X, class Y>
00256     void mmv (const X& x, Y& y) const
00257     {
00258 #ifdef DUNE_FMatrix_WITH_CHECKING
00259         if (x.N()!=M()) DUNE_THROW(FMatrixError,"index out of range");
00260         if (y.N()!=N()) DUNE_THROW(FMatrixError,"index out of range");
00261 #endif
00262         for (size_type i=0; i<n; ++i)
00263             y[i] -= p_ * x[i];
00264     }
00265 
00267     template<class X, class Y>
00268     void mmtv (const X& x, Y& y) const
00269     {
00270 #ifdef DUNE_FMatrix_WITH_CHECKING
00271         if (x.N()!=N()) DUNE_THROW(FMatrixError,"index out of range");
00272         if (y.N()!=M()) DUNE_THROW(FMatrixError,"index out of range");
00273 #endif
00274         for (size_type i=0; i<n; ++i)
00275             y[i] -= p_ * x[i];
00276     }
00277 
00279     template<class X, class Y>
00280     void mmhv (const X& x, Y& y) const
00281     {
00282 #ifdef DUNE_FMatrix_WITH_CHECKING
00283         if (x.N()!=N()) DUNE_THROW(FMatrixError,"index out of range");
00284         if (y.N()!=M()) DUNE_THROW(FMatrixError,"index out of range");
00285 #endif
00286         for (size_type i=0; i<n; i++)
00287             y[i] -= conjugateComplex(p_)*x[i];
00288     }
00289 
00291     template<class X, class Y>
00292     void usmv (const K& alpha, const X& x, Y& y) const
00293     {
00294 #ifdef DUNE_FMatrix_WITH_CHECKING
00295         if (x.N()!=M()) DUNE_THROW(FMatrixError,"index out of range");
00296         if (y.N()!=N()) DUNE_THROW(FMatrixError,"index out of range");
00297 #endif
00298         for (size_type i=0; i<n; i++)
00299             y[i] += alpha * p_ * x[i];
00300     }
00301 
00303     template<class X, class Y>
00304     void usmtv (const K& alpha, const X& x, Y& y) const
00305     {
00306 #ifdef DUNE_FMatrix_WITH_CHECKING
00307         if (x.N()!=N()) DUNE_THROW(FMatrixError,"index out of range");
00308         if (y.N()!=M()) DUNE_THROW(FMatrixError,"index out of range");
00309 #endif
00310         for (size_type i=0; i<n; i++)
00311             y[i] += alpha * p_ * x[i];
00312     }
00313 
00315     template<class X, class Y>
00316     void usmhv (const K& alpha, const X& x, Y& y) const
00317     {
00318 #ifdef DUNE_FMatrix_WITH_CHECKING
00319         if (x.N()!=N()) DUNE_THROW(FMatrixError,"index out of range");
00320         if (y.N()!=M()) DUNE_THROW(FMatrixError,"index out of range");
00321 #endif
00322         for (size_type i=0; i<n; i++)
00323             y[i] += alpha * conjugateComplex(p_) * x[i];
00324     }
00325 
00326     //===== norms
00327 
00329     double frobenius_norm () const
00330     {
00331         return fvmeta::sqrt(n*p_*p_);
00332     }
00333 
00335     double frobenius_norm2 () const
00336     {
00337         return n*p_*p_;
00338     }
00339 
00341     double infinity_norm () const
00342     {
00343         return std::abs(p_);
00344     }
00345 
00347     double infinity_norm_real () const
00348     {
00349         return fvmeta::absreal(p_);
00350     }
00351 
00352     //===== solve
00353 
00356     template<class V>
00357     void solve (V& x, const V& b) const
00358     {
00359         for (int i=0; i<n; i++)
00360             x[i] = b[i]/p_;
00361     }
00362 
00365     void invert()
00366     {
00367         p_ = 1/p_;
00368     }
00369 
00371     K determinant () const {
00372         return std::pow(p_,n);
00373     }
00374 
00375     //===== sizes
00376 
00378     size_type N () const
00379     {
00380         return n;
00381     }
00382 
00384     size_type M () const
00385     {
00386         return n;
00387     }
00388 
00389     //===== query
00390 
00392     bool exists (size_type i, size_type j) const
00393     {
00394 #ifdef DUNE_FMatrix_WITH_CHECKING
00395         if (i<0 || i>=n) DUNE_THROW(FMatrixError,"row index out of range");
00396         if (j<0 || j>=m) DUNE_THROW(FMatrixError,"column index out of range");
00397 #endif
00398         return i==j;
00399     }
00400 
00401     //===== conversion operator
00402 
00404     friend std::ostream& operator<< (std::ostream& s, const ScaledIdentityMatrix<K,n>& a)
00405     {
00406         for (size_type i=0; i<n; i++) {
00407             for (size_type j=0; j<n; j++)
00408                 s << ((i==j) ? a.p_ : 0) << " ";
00409             s << std::endl;
00410         }
00411         return s;
00412     }
00413 
00415     reference operator[](size_type i)
00416     {
00417         return reference(const_cast<K*>(&p_), i);
00418     }
00419 
00421     const_reference operator[](size_type i) const
00422     {
00423         return const_reference(const_cast<K*>(&p_), i);
00424     }
00425 
00427     const K& diagonal(size_type i) const
00428     {
00429         return p_;
00430     }
00431 
00433     K& diagonal(size_type i)
00434     {
00435         return p_;
00436     }
00437 
00440     const K& scalar() const
00441     {
00442         return p_;
00443     }
00444 
00447     K& scalar()
00448     {
00449         return p_;
00450     }
00451 
00452 private:
00453     // the data, very simply a single number
00454     K p_;
00455 
00456 };
00457 
00458 template<class K, int n>
00459 void istl_assign_to_fmatrix(FieldMatrix<K,n,n>& fm, const ScaledIdentityMatrix<K,n>& s)
00460 {
00461     fm = K();
00462     for(int i=0; i<n; ++i)
00463         fm[i][i] = s.scalar();
00464 }
00465 
00466 } // end namespace
00467 
00468 #endif
Generated on Sat Apr 24 11:13:47 2010 for dune-istl by  doxygen 1.6.3