dune-istl  2.1.1
diagonalmatrix.hh
Go to the documentation of this file.
00001 // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
00002 // vi: set et ts=4 sw=4 sts=4:
00003 #ifndef DUNE_DIAGONAL_MATRIX_NEW_HH
00004 #define DUNE_DIAGONAL_MATRIX_NEW_HH
00005 
00010 #include<cmath>
00011 #include<cstddef>
00012 #include<complex>
00013 #include<iostream>
00014 #include<memory>
00015 #include <dune/common/exceptions.hh>
00016 #include <dune/common/fmatrix.hh>
00017 #include <dune/common/fvector.hh>
00018 #include <dune/common/genericiterator.hh>
00019 
00020 
00021 
00022 namespace Dune {
00023 
00024 template< class K, int n > class DiagonalRowVectorConst;
00025 template< class K, int n > class DiagonalRowVector;
00026 template< class DiagonalMatrixType > class DiagonalMatrixWrapper;
00027 template< class C, class T, class R> class ContainerWrapperIterator;
00028 
00039 template<class K, int n>
00040 class DiagonalMatrix
00041 {
00042     typedef DiagonalMatrixWrapper< DiagonalMatrix<K,n> > WrapperType;
00043 
00044     public:
00045     //===== type definitions and constants
00046 
00048     typedef K field_type;
00049 
00051     typedef K block_type;
00052 
00054     typedef std::size_t size_type;
00055 
00057     enum {
00059         blocklevel = 1
00060     };
00061 
00063     typedef DiagonalRowVector<K,n> row_type;
00064     typedef row_type reference;
00065     typedef DiagonalRowVectorConst<K,n> const_row_type;
00066     typedef const_row_type const_reference;
00067 
00069     enum {
00071         rows = n,
00073         cols = n
00074     };
00075 
00076 
00077 
00078     //===== constructors
00079 
00081     DiagonalMatrix () {}
00082 
00084     DiagonalMatrix (const K& k)
00085         : diag_(k)
00086     {}
00087 
00089     DiagonalMatrix (const FieldVector<K,n>& diag)
00090         : diag_(diag)
00091     {}
00092 
00093 
00094     //===== assignment from scalar
00095     DiagonalMatrix& operator= (const K& k)
00096     {
00097         diag_ = k;
00098         return *this;
00099     }
00100 
00101     // check if matrix is identical to other matrix (not only identical values)
00102     bool identical(const DiagonalMatrix<K,n>& other) const
00103     {
00104         return (this==&other);
00105     }
00106 
00107     //===== iterator interface to rows of the matrix
00109     typedef ContainerWrapperIterator<const WrapperType, reference, reference> Iterator;
00111     typedef Iterator iterator;
00113     typedef Iterator RowIterator;
00115     typedef typename row_type::Iterator ColIterator;
00116 
00118     Iterator begin ()
00119     {
00120         return Iterator(WrapperType(this),0);
00121     }
00122 
00124     Iterator end ()
00125     {
00126         return Iterator(WrapperType(this),n);
00127     }
00128 
00133     Iterator rbegin() DUNE_DEPRECATED
00134     {
00135         return beforeEnd();
00136     }
00137 
00140         Iterator beforeEnd ()
00141     {
00142         return Iterator(WrapperType(this),n-1);
00143     }
00144 
00149     Iterator rend ()  DUNE_DEPRECATED
00150     {
00151         return beforeBegin();
00152     }
00153 
00156         Iterator beforeBegin ()
00157     {
00158         return Iterator(WrapperType(this),-1);
00159     }
00160 
00161 
00163     typedef ContainerWrapperIterator<const WrapperType, const_reference, const_reference> ConstIterator;
00165     typedef ConstIterator const_iterator;
00167     typedef ConstIterator ConstRowIterator;
00169     typedef typename const_row_type::ConstIterator ConstColIterator;
00170 
00172     ConstIterator begin () const
00173     {
00174         return ConstIterator(WrapperType(this),0);
00175     }
00176 
00178     ConstIterator end () const
00179     {
00180         return ConstIterator(WrapperType(this),n);
00181     }
00182 
00187     ConstIterator rbegin() const DUNE_DEPRECATED
00188     {
00189         return beforeEnd();
00190     }
00191 
00194         ConstIterator beforeEnd() const
00195     {
00196         return ConstIterator(WrapperType(this),n-1);
00197     }
00198 
00203     ConstIterator rend () const DUNE_DEPRECATED
00204     {
00205         return beforeBegin();
00206     }
00207     
00210         ConstIterator beforeBegin () const
00211     {
00212         return ConstIterator(WrapperType(this),-1);
00213     }
00214 
00215 
00216 
00217     //===== vector space arithmetic
00218 
00220     DiagonalMatrix& operator+= (const DiagonalMatrix& y)
00221     {
00222         diag_ += y.diag_;
00223         return *this;
00224     }
00225 
00227     DiagonalMatrix& operator-= (const DiagonalMatrix& y)
00228     {
00229         diag_ -= y.diag_;
00230         return *this;
00231     }
00232 
00234     DiagonalMatrix& operator+= (const K& k)
00235     {
00236         diag_ += k;
00237         return *this;
00238     }
00239 
00241     DiagonalMatrix& operator-= (const K& k)
00242     {
00243         diag_ -= k;
00244         return *this;
00245     }
00246 
00248     DiagonalMatrix& operator*= (const K& k)
00249     {
00250         diag_ *= k;
00251         return *this;
00252     }
00253 
00255     DiagonalMatrix& operator/= (const K& k)
00256     {
00257         diag_ /= k;
00258         return *this;
00259     }
00260 
00261 
00262 
00263     //===== linear maps
00264 
00266     template<class X, class Y>
00267     void mv (const X& x, Y& y) const
00268     {
00269 #ifdef DUNE_FMatrix_WITH_CHECKING
00270         if (x.N()!=M()) DUNE_THROW(FMatrixError,"index out of range");
00271         if (y.N()!=N()) DUNE_THROW(FMatrixError,"index out of range");
00272 #endif
00273         for (size_type i=0; i<n; ++i)
00274             y[i] = diag_[i] * x[i];
00275     }
00276 
00278     template<class X, class Y>
00279     void mtv (const X& x, Y& y) const
00280     {
00281         mv(x, y);
00282     }
00283 
00285     template<class X, class Y>
00286     void umv (const X& x, Y& y) const
00287     {
00288 #ifdef DUNE_FMatrix_WITH_CHECKING
00289         if (x.N()!=M()) DUNE_THROW(FMatrixError,"index out of range");
00290         if (y.N()!=N()) DUNE_THROW(FMatrixError,"index out of range");
00291 #endif
00292         for (size_type i=0; i<n; ++i)
00293             y[i] += diag_[i] * x[i];
00294     }
00295 
00297     template<class X, class Y>
00298     void umtv (const X& x, Y& y) const
00299     {
00300 #ifdef DUNE_FMatrix_WITH_CHECKING
00301         if (x.N()!=N()) DUNE_THROW(FMatrixError,"index out of range");
00302         if (y.N()!=M()) DUNE_THROW(FMatrixError,"index out of range");
00303 #endif
00304         for (size_type i=0; i<n; ++i)
00305             y[i] += diag_[i] * x[i];
00306     }
00307 
00309     template<class X, class Y>
00310     void umhv (const X& x, Y& y) const
00311     {
00312 #ifdef DUNE_FMatrix_WITH_CHECKING
00313         if (x.N()!=N()) DUNE_THROW(FMatrixError,"index out of range");
00314         if (y.N()!=M()) DUNE_THROW(FMatrixError,"index out of range");
00315 #endif
00316         for (size_type i=0; i<n; i++)
00317             y[i] += conjugateComplex(diag_[i])*x[i];
00318     }
00319 
00321     template<class X, class Y>
00322     void mmv (const X& x, Y& y) const
00323     {
00324 #ifdef DUNE_FMatrix_WITH_CHECKING
00325         if (x.N()!=M()) DUNE_THROW(FMatrixError,"index out of range");
00326         if (y.N()!=N()) DUNE_THROW(FMatrixError,"index out of range");
00327 #endif
00328         for (size_type i=0; i<n; ++i)
00329             y[i] -= diag_[i] * x[i];
00330     }
00331 
00333     template<class X, class Y>
00334     void mmtv (const X& x, Y& y) const
00335     {
00336 #ifdef DUNE_FMatrix_WITH_CHECKING
00337         if (x.N()!=N()) DUNE_THROW(FMatrixError,"index out of range");
00338         if (y.N()!=M()) DUNE_THROW(FMatrixError,"index out of range");
00339 #endif
00340         for (size_type i=0; i<n; ++i)
00341             y[i] -= diag_[i] * x[i];
00342     }
00343 
00345     template<class X, class Y>
00346     void mmhv (const X& x, Y& y) const
00347     {
00348 #ifdef DUNE_FMatrix_WITH_CHECKING
00349         if (x.N()!=N()) DUNE_THROW(FMatrixError,"index out of range");
00350         if (y.N()!=M()) DUNE_THROW(FMatrixError,"index out of range");
00351 #endif
00352         for (size_type i=0; i<n; i++)
00353             y[i] -= conjugateComplex(diag_[i])*x[i];
00354     }
00355 
00357     template<class X, class Y>
00358     void usmv (const K& alpha, const X& x, Y& y) const
00359     {
00360 #ifdef DUNE_FMatrix_WITH_CHECKING
00361         if (x.N()!=M()) DUNE_THROW(FMatrixError,"index out of range");
00362         if (y.N()!=N()) DUNE_THROW(FMatrixError,"index out of range");
00363 #endif
00364         for (size_type i=0; i<n; i++)
00365             y[i] += alpha * diag_[i] * x[i];
00366     }
00367 
00369     template<class X, class Y>
00370     void usmtv (const K& alpha, const X& x, Y& y) const
00371     {
00372 #ifdef DUNE_FMatrix_WITH_CHECKING
00373         if (x.N()!=N()) DUNE_THROW(FMatrixError,"index out of range");
00374         if (y.N()!=M()) DUNE_THROW(FMatrixError,"index out of range");
00375 #endif
00376         for (size_type i=0; i<n; i++)
00377             y[i] += alpha * diag_[i] * x[i];
00378     }
00379 
00381     template<class X, class Y>
00382     void usmhv (const K& alpha, const X& x, Y& y) const
00383     {
00384 #ifdef DUNE_FMatrix_WITH_CHECKING
00385         if (x.N()!=N()) DUNE_THROW(FMatrixError,"index out of range");
00386         if (y.N()!=M()) DUNE_THROW(FMatrixError,"index out of range");
00387 #endif
00388         for (size_type i=0; i<n; i++)
00389             y[i] += alpha * conjugateComplex(diag_[i]) * x[i];
00390     }
00391 
00392     //===== norms
00393 
00395     double frobenius_norm () const
00396     {
00397         return diag_.two_norm();
00398     }
00399 
00401     double frobenius_norm2 () const
00402     {
00403         return diag_.two_norm2();
00404     }
00405 
00407     double infinity_norm () const
00408     {
00409         return diag_.infinity_norm();
00410     }
00411 
00413     double infinity_norm_real () const
00414     {
00415         return diag_.infinity_norm_real();
00416     }
00417 
00418 
00419 
00420     //===== solve
00421 
00423     template<class V>
00424     void solve (V& x, const V& b) const
00425     {
00426         for (int i=0; i<n; i++)
00427             x[i] = b[i]/diag_[i];
00428     }
00429 
00431     void invert()
00432     {
00433         for (int i=0; i<n; i++)
00434             diag_[i] = 1/diag_[i];
00435     }
00436 
00438     K determinant () const
00439     {
00440         K det = diag_[0];
00441         for (int i=1; i<n; i++)
00442             det *= diag_[i];
00443         return det;
00444     }
00445 
00446 
00447 
00448     //===== sizes
00449 
00451     size_type N () const
00452     {
00453         return n;
00454     }
00455 
00457     size_type M () const
00458     {
00459         return n;
00460     }
00461 
00462 
00463 
00464     //===== query
00465 
00467     bool exists (size_type i, size_type j) const
00468     {
00469 #ifdef DUNE_FMatrix_WITH_CHECKING
00470         if (i<0 || i>=n) DUNE_THROW(FMatrixError,"row index out of range");
00471         if (j<0 || j>=n) DUNE_THROW(FMatrixError,"column index out of range");
00472 #endif
00473         return i==j;
00474     }
00475 
00476 
00477 
00479     friend std::ostream& operator<< (std::ostream& s, const DiagonalMatrix<K,n>& a)
00480     {
00481         for (size_type i=0; i<n; i++) {
00482             for (size_type j=0; j<n; j++)
00483                 s << ((i==j) ? a.diag_[i] : 0) << " ";
00484             s << std::endl;
00485         }
00486         return s;
00487     }
00488 
00490     reference operator[](size_type i)
00491     {
00492         return reference(const_cast<K*>(&diag_[i]), i);
00493     }
00494 
00496     const_reference operator[](size_type i) const
00497     {
00498         return const_reference(const_cast<K*>(&diag_[i]), i);
00499     }
00500 
00502     const K& diagonal(size_type i) const
00503     {
00504         return diag_[i];
00505     }
00506 
00508     K& diagonal(size_type i)
00509     {
00510         return diag_[i];
00511     }
00512 
00514     const FieldVector<K,n>& diagonal() const
00515     {
00516         return diag_;
00517     }
00518 
00520     FieldVector<K,n>& diagonal()
00521     {
00522         return diag_;
00523     }
00524 
00525     private:
00526 
00527     // the data, a FieldVector storing the diagonal
00528     FieldVector<K,n> diag_;
00529 };
00530 
00531 
00532 template<class DiagonalMatrixType>
00533 class DiagonalMatrixWrapper
00534 {
00535         typedef typename DiagonalMatrixType::reference reference;
00536         typedef typename DiagonalMatrixType::const_reference const_reference;
00537         typedef typename DiagonalMatrixType::field_type K;
00538         typedef DiagonalRowVector<K, DiagonalMatrixType::rows> row_type;
00539         typedef std::size_t size_type;
00540         typedef DiagonalMatrixWrapper< DiagonalMatrixType> MyType;
00541 
00542         friend class ContainerWrapperIterator<const MyType, reference, reference>;
00543         friend class ContainerWrapperIterator<const MyType, const_reference, const_reference>;
00544 
00545     public:
00546 
00547         DiagonalMatrixWrapper() :
00548             mat_(0)
00549         {}
00550 
00551         DiagonalMatrixWrapper(const DiagonalMatrixType* mat) :
00552             mat_(const_cast<DiagonalMatrixType*>(mat))
00553         {}
00554 
00555         size_type realIndex(int i) const
00556         {
00557             return i;
00558         }
00559 
00560         row_type* pointer(int i) const
00561         {
00562             row_ = row_type(&(mat_->diagonal(i)), i);
00563             return &row_;
00564         }
00565 
00566         bool identical(const DiagonalMatrixWrapper& other) const
00567         {
00568             return mat_==other.mat_;
00569         }
00570 
00571     private:
00572 
00573         mutable DiagonalMatrixType* mat_;
00574         mutable row_type row_;
00575 };
00576 
00580 template< class K, int n >
00581 class DiagonalRowVectorConst
00582 {
00583     template<class DiagonalMatrixType>
00584     friend class DiagonalMatrixWrapper;
00585     friend class ContainerWrapperIterator<DiagonalRowVectorConst<K,n>, const K, const K&>;
00586 
00587 public:
00588     // remember size of vector
00589     enum { dimension = n };
00590 
00591     // standard constructor and everything is sufficient ...
00592 
00593     //===== type definitions and constants
00594 
00596     typedef K field_type;
00597 
00599     typedef K block_type;
00600 
00602     typedef std::size_t size_type;
00603 
00605     enum {
00607         blocklevel = 1
00608     };
00609 
00611     enum {
00613         size = n
00614     };
00615 
00617     DiagonalRowVectorConst() :
00618         p_(0),
00619         row_(0)
00620     {}
00621 
00623     explicit DiagonalRowVectorConst (K* p, int col) :
00624         p_(p),
00625         row_(col)
00626     {}
00627 
00628     //===== access to components
00629 
00631     const K& operator[] (size_type i) const
00632     {
00633 #ifdef DUNE_FMatrix_WITH_CHECKING
00634         if (i!=row_)
00635             DUNE_THROW(FMatrixError,"index is contained in pattern");
00636 #endif
00637         return *p_;
00638     }
00639 
00640     // check if row is identical to other row (not only identical values)
00641     // since this is a proxy class we need to check equality of the stored pointer
00642     bool identical(const DiagonalRowVectorConst<K,n>& other) const
00643     {
00644         return ((p_ == other.p_) and (row_ == other.row_));
00645     }
00646 
00648     typedef ContainerWrapperIterator<DiagonalRowVectorConst<K,n>, const K, const K&> ConstIterator;
00650     typedef ConstIterator const_iterator;
00651 
00653     ConstIterator begin () const
00654     {
00655         return ConstIterator(*this,0);
00656     }
00657 
00659     ConstIterator end () const
00660     {
00661         return ConstIterator(*this,1);
00662     }
00663 
00668     ConstIterator rbegin() const DUNE_DEPRECATED
00669     {
00670         return beforeEnd();
00671     }
00672 
00675         ConstIterator beforeEnd() const
00676     {
00677         return ConstIterator(*this,0);
00678     }
00679 
00684     ConstIterator rend () const DUNE_DEPRECATED
00685     {
00686         return beforeBegin();
00687     }
00688     
00691         ConstIterator beforeBegin () const
00692     {
00693         return ConstIterator(*this,-1);
00694     }
00695 
00697     bool operator== (const DiagonalRowVectorConst& y) const
00698     {
00699         return ((p_==y.p_) and (row_==y.row_));
00700     }
00701 
00702     //===== sizes
00703 
00705     size_type N () const
00706     {
00707         return n;
00708     }
00709 
00711     size_type dim () const
00712     {
00713         return n;
00714     }
00715 
00717     size_type rowIndex() const
00718     {
00719         return row_;
00720     }
00721 
00723     const K& diagonal() const
00724     {
00725         return *p_;
00726     }
00727 
00728 protected:
00729 
00730     size_type realIndex(int i) const
00731     {
00732         return rowIndex();
00733     }
00734 
00735     K* pointer(size_type i) const
00736     {
00737         return const_cast<K*>(p_);
00738     }
00739 
00740     DiagonalRowVectorConst* operator&()
00741     {
00742         return this;
00743     }
00744 
00745     // the data, very simply a pointer to the diagonal value and the row number
00746     K* p_;
00747     size_type row_;
00748 };
00749 
00750 template< class K, int n >
00751 class DiagonalRowVector : public DiagonalRowVectorConst<K,n>
00752 {
00753     template<class DiagonalMatrixType>
00754     friend class DiagonalMatrixWrapper;
00755     friend class ContainerWrapperIterator<DiagonalRowVector<K,n>, K, K&>;
00756 
00757 public:
00758     // standard constructor and everything is sufficient ...
00759 
00760     //===== type definitions and constants
00761 
00763     typedef K field_type;
00764 
00766     typedef K block_type;
00767 
00769     typedef std::size_t size_type;
00770 
00772     DiagonalRowVector() : DiagonalRowVectorConst<K,n>()
00773     {}
00774 
00776     explicit DiagonalRowVector (K* p, int col) : DiagonalRowVectorConst<K,n>(p, col)
00777     {}
00778 
00779     //===== assignment from scalar
00781     DiagonalRowVector& operator= (const K& k)
00782     {
00783         *p_ = k;
00784         return *this;
00785     }
00786 
00787     //===== access to components
00788 
00790     K& operator[] (size_type i)
00791     {
00792 #ifdef DUNE_FMatrix_WITH_CHECKING
00793         if (i!=row_)
00794             DUNE_THROW(FMatrixError,"index is contained in pattern");
00795 #endif
00796         return *p_;
00797     }
00798 
00800     typedef ContainerWrapperIterator<DiagonalRowVector<K,n>, K, K&> Iterator;
00802     typedef Iterator iterator;
00803 
00805     Iterator begin ()
00806     {
00807         return Iterator(*this, 0);
00808     }
00809 
00811     Iterator end ()
00812     {
00813         return Iterator(*this, 1);
00814     }
00815 
00820     Iterator rbegin() DUNE_DEPRECATED
00821     {
00822         return beforeEnd();
00823     }
00824 
00827         Iterator beforeEnd ()
00828     {
00829         return Iterator(*this, 0);
00830     }
00831 
00836     Iterator rend ()  DUNE_DEPRECATED
00837     {
00838         return beforeBegin();
00839     }
00840 
00843         Iterator beforeBegin ()
00844     {
00845         return Iterator(*this, -1);
00846     }
00847 
00849     typedef ContainerWrapperIterator<DiagonalRowVectorConst<K,n>, const K, const K&> ConstIterator;
00851     typedef ConstIterator const_iterator;
00852 
00853     using DiagonalRowVectorConst<K,n>::identical;
00854     using DiagonalRowVectorConst<K,n>::operator[];
00855     using DiagonalRowVectorConst<K,n>::operator==;
00856     using DiagonalRowVectorConst<K,n>::begin;
00857     using DiagonalRowVectorConst<K,n>::end;
00858     using DiagonalRowVectorConst<K,n>::rbegin;
00859     using DiagonalRowVectorConst<K,n>::rend;
00860     using DiagonalRowVectorConst<K,n>::beforeEnd;
00861     using DiagonalRowVectorConst<K,n>::beforeBegin;
00862     using DiagonalRowVectorConst<K,n>::N;
00863     using DiagonalRowVectorConst<K,n>::dim;
00864     using DiagonalRowVectorConst<K,n>::rowIndex;
00865     using DiagonalRowVectorConst<K,n>::diagonal;
00866 
00867 protected:
00868 
00869     DiagonalRowVector* operator&()
00870     {
00871         return this;
00872     }
00873 
00874 private:
00875 
00876     using DiagonalRowVectorConst<K,n>::p_;
00877     using DiagonalRowVectorConst<K,n>::row_;
00878 };
00879 
00880 
00881 // implement type traits
00882 template<class K, int n>
00883 struct const_reference< DiagonalRowVector<K,n> >
00884 {
00885     typedef DiagonalRowVectorConst<K,n> type;
00886 };
00887 
00888 template<class K, int n>
00889 struct const_reference< DiagonalRowVectorConst<K,n> >
00890 {
00891     typedef DiagonalRowVectorConst<K,n> type;
00892 };
00893 
00894 template<class K, int n>
00895 struct mutable_reference< DiagonalRowVector<K,n> >
00896 {
00897     typedef DiagonalRowVector<K,n> type;
00898 };
00899 
00900 template<class K, int n>
00901 struct mutable_reference< DiagonalRowVectorConst<K,n> >
00902 {
00903     typedef DiagonalRowVector<K,n> type;
00904 };
00905 
00906 
00907 
00930 template<class CW, class T, class R>
00931 class ContainerWrapperIterator : public BidirectionalIteratorFacade<ContainerWrapperIterator<CW,T,R>,T, R, int>
00932 {
00933         typedef typename remove_const<CW>::type NonConstCW;
00934 
00935         friend class ContainerWrapperIterator<CW, typename mutable_reference<T>::type, typename mutable_reference<R>::type>;
00936         friend class ContainerWrapperIterator<CW, typename const_reference<T>::type, typename const_reference<R>::type>;
00937 
00938         typedef ContainerWrapperIterator<CW, typename mutable_reference<T>::type, typename mutable_reference<R>::type> MyType;
00939         typedef ContainerWrapperIterator<CW, typename const_reference<T>::type, typename const_reference<R>::type> MyConstType;
00940 
00941     public:
00942 
00943         // Constructors needed by the facade iterators.
00944         ContainerWrapperIterator():
00945             containerWrapper_(),
00946             position_(0)
00947         {}
00948 
00949         ContainerWrapperIterator(CW containerWrapper, int position) :
00950             containerWrapper_(containerWrapper),
00951             position_(position)
00952         {}
00953 
00954         template<class OtherContainerWrapperIteratorType>
00955         ContainerWrapperIterator(OtherContainerWrapperIteratorType& other):
00956             containerWrapper_(other.containerWrapper_),
00957             position_(other.position_)
00958         {}
00959 
00960         ContainerWrapperIterator(const MyType& other):
00961             containerWrapper_(other.containerWrapper_),
00962             position_(other.position_)
00963         {}
00964 
00965         ContainerWrapperIterator(const MyConstType& other):
00966             containerWrapper_(other.containerWrapper_),
00967             position_(other.position_)
00968         {}
00969 
00970         template<class OtherContainerWrapperIteratorType>
00971         ContainerWrapperIterator& operator=(OtherContainerWrapperIteratorType& other)
00972         {
00973             containerWrapper_ = other.containerWrapper_;
00974             position_ = other.position_;
00975         }
00976 
00977         // This operator is needed since we can not get the address of the
00978         // temporary object returned by dereference
00979         T* operator->() const
00980         {
00981             return containerWrapper_.pointer(position_);
00982         }
00983 
00984         // Methods needed by the forward iterator
00985         bool equals(const MyType& other) const
00986         {
00987             return position_ == other.position_ && containerWrapper_.identical(other.containerWrapper_);
00988         }
00989 
00990         bool equals(const MyConstType& other) const
00991         {
00992             return position_ == other.position_ && containerWrapper_.identical(other.containerWrapper_);
00993         }
00994 
00995         R dereference() const
00996         {
00997             return *containerWrapper_.pointer(position_);
00998         }
00999 
01000         void increment()
01001         {
01002             ++position_;
01003         }
01004 
01005         // Additional function needed by BidirectionalIterator
01006         void decrement()
01007         {
01008             --position_;
01009         }
01010 
01011         // Additional function needed by RandomAccessIterator
01012         R elementAt(int i) const
01013         {
01014             return *containerWrapper_.pointer(position_+i);
01015         }
01016 
01017         void advance(int n)
01018         {
01019             position_=position_+n;
01020         }
01021 
01022         template<class OtherContainerWrapperIteratorType>
01023         std::ptrdiff_t distanceTo(OtherContainerWrapperIteratorType& other) const
01024         {
01025             assert(containerWrapper_.identical(other));
01026             return other.position_ - position_;
01027         }
01028 
01029         std::ptrdiff_t index() const
01030         {
01031             return containerWrapper_.realIndex(position_);
01032         }
01033 
01034     private:
01035         NonConstCW containerWrapper_;
01036         size_t position_;
01037 };
01038 
01039 
01040 
01041 template<class K, int n>
01042 void istl_assign_to_fmatrix(FieldMatrix<K,n,n>& fm, const DiagonalMatrix<K,n>& s)
01043 {
01044     fm = K();
01045     for(int i=0; i<n; ++i)
01046         fm[i][i] = s.diagonal()[i];
01047 }
01048 /* @} */
01049 } // end namespace
01050 #endif