exprtmpl.hh

Go to the documentation of this file.
00001 #if ! defined DUNE_EXPRTMPL_HH && DUNE_EXPRESSIONTEMPLATES
00002 #define DUNE_EXPRTMPL_HH
00003 
00004 /*
00005   This file is part of DUNE, a Distributed and Unified Numerics Environment
00006   It is distributed under the terms of the GNU Lesser General Public License version 2.1
00007   See COPYING at the top of the source tree for the full licence.
00008 */
00009 
00020 #include <iostream>
00021 #include <iomanip>
00022 #include <cstdlib>
00023 #include <cmath>
00024 #include <complex>
00025 #include "iteratorfacades.hh"
00026 #include "static_assert.hh"
00027 #include "stdstreams.hh"
00028 
00029 struct Indent
00030 {
00031   int i;
00032   Indent() {
00033     i = 0;
00034   }
00035   void operator ++ ()
00036     {
00037 #ifdef DUNE_VVERBOSE
00038       i += 3;
00039 #endif
00040     };
00041   void operator -- ()
00042     {
00043 #ifdef DUNE_VVERBOSE
00044       i -= 3;
00045 #endif
00046     };
00047 };
00048 
00049 extern Indent INDENT;
00050 
00051 inline std::ostream & operator << (std::ostream & s, const Indent & i)
00052 {
00053 #ifdef DUNE_VVERBOSE
00054   for (int n = 0; n < i.i; n++) s << " ";
00055 #endif
00056   return s;
00057 }
00058 
00059 namespace Dune {
00060 
00061 template<class V> class FlatIterator;
00062 template<class K, int N> class FieldVector;
00063 template<class K, int N, int M> class FieldMatrix;
00064 #warning this header should not know about BCRSMatrix and BlockVector
00065 class ISTLAllocator;
00066 template<class B, class A=ISTLAllocator> class BCRSMatrix;
00067 template<class B, class A=ISTLAllocator> class BlockVector;
00068   
00072 template<class T>
00073 struct BlockType
00074 {
00075 };
00076 template<class T>
00077 struct FieldType
00078 {
00079 };
00080 // FieldType specializations for basic data types
00081 template<>
00082 struct FieldType<double>
00083 {
00084   typedef double type;
00085 };
00086 template<>
00087 struct FieldType<float>
00088 {
00089   typedef float type;
00090 };
00091 template<>
00092 struct FieldType<int>
00093 {
00094   typedef int type;
00095 };
00096 // FieldType specialization for FieldVector
00097 template <class K, int N>
00098 struct FieldType< FieldVector<K,N> >
00099 {
00100   typedef K type;
00101 };
00102 // BlockType specialization for FieldVector
00103 template <class K, int N>
00104 struct BlockType< FieldVector<K,N> >
00105 {
00106   typedef K type;
00107 };
00108 // FieldType specialization for const T
00109 template<class T>
00110 struct FieldType<const T>
00111 {
00112   typedef const typename FieldType<T>::type type;
00113 };
00114 // BlockType specialization for const T
00115 template<class T>
00116 struct BlockType<const T>
00117 {
00118   typedef const typename BlockType<T>::type type;
00119 };
00120 
00121 namespace ExprTmpl {
00122 
00123 /* Important Classes */
00124 template <class V> class ConstRef;
00125 template <class Ex> class Expression;
00126 template <class A, class B, template<class> class Op> class ExBinOp;
00127 template <class I> class Vector;
00128 template <class I> class Matrix;
00129 
00133 template<class T>
00134 struct BlockExpression
00135 {
00136 };
00140 template<class T>
00141 struct ExpressionImp
00142 {
00143 };
00144 
00145 template <class V>
00146 struct ExpressionImp< ExprTmpl::ConstRef<V> >
00147 {
00148   typedef ExprTmpl::ConstRef<V> type;
00149 };
00150 
00151 // TypeTraits
00152 template <>
00153 struct ExpressionImp<double>
00154 {
00155   typedef double type;
00156 };
00157 template <>
00158 struct ExpressionImp<float>
00159 {
00160   typedef float type;
00161 };
00162 template <>
00163 struct ExpressionImp<int>
00164 {
00165   typedef int type;
00166 };
00167 template <class Ex>
00168 struct ExpressionImp< Expression<Ex> >
00169 {
00170   typedef Ex type;
00171 };
00172 
00174 template <class V>
00175 struct isEndOfExpressionRecusion
00176 {
00177   enum{ value=false };
00178 };
00179 
00180 template <>
00181 struct isEndOfExpressionRecusion<double>
00182 {
00183   enum{ value=true };
00184 };
00185 
00186 template <class K>
00187 struct isEndOfExpressionRecusion< FieldVector<K,1> >
00188 {
00189   enum{ value=true };
00190 };
00191 
00192 template <class K>
00193 struct isEndOfExpressionRecusion< std::complex<K> >
00194 {
00195   enum{ value=true };
00196 };
00197 
00198 template <>
00199 struct isEndOfExpressionRecusion<int>
00200 {
00201   enum{ value=true };
00202 };
00203 
00204 template <>
00205 struct isEndOfExpressionRecusion<float>
00206 {
00207   enum{ value=true };
00208 };
00209 
00211 template <class V>
00212 struct BlockExpression< ConstRef<V> >
00213 {
00214   typedef ExprTmpl::Expression<
00215     ExprTmpl::ConstRef<typename BlockType<V>::type> > type;
00216 };
00217 
00219 template<class K, int N>
00220 struct BlockExpression< ConstRef< FieldVector<K,N> > >
00221 {
00222   typedef K type;
00223 };
00224 
00228 template <class Ex>
00229 class Expression
00230 {
00231 public:
00232   Expression(const Ex & x) : ex(x) {}
00233   typedef typename FieldType<Ex>::type field_type;
00234   typedef typename BlockExpression<Ex>::type BlockExpr;
00235   BlockExpr operator[] ( int i ) const {
00236     return ex[i]; }
00237   size_t N() const { return ex.N(); }
00238   double one_norm() const { return eval_one_norm(*this); }
00239   double one_norm_real() const { return eval_one_norm_real(*this); }
00240   double two_norm() const { return sqrt(eval_two_norm2(*this)); }
00241   double two_norm2() const { return eval_two_norm2(*this); }
00242   double infinity_norm() const { return eval_infinity_norm(*this); }
00243   double infinity_norm_real() const { return eval_infinity_norm_real(*this); }
00244 private:
00245   Ex ex;
00246 };
00247 
00251 template <class I>
00252 class Vector {
00253 public:
00254   explicit Vector() {}
00255   typedef typename BlockType<I>::type block_type;
00256   typedef typename FieldType<I>::type field_type;
00258   size_t N() const {
00259     return asImp().N();
00260   }
00261   double one_norm() const { return eval_one_norm(*this); }
00262   double one_norm_real() const { return eval_one_norm_real(*this); }
00263   double two_norm() const { return sqrt(eval_two_norm2(*this)); }
00264   double two_norm2() const { return eval_two_norm2(*this); }
00265   double infinity_norm() const { return eval_infinity_norm(*this); }
00266   double infinity_norm_real() const { return eval_infinity_norm_real(*this); }
00267   block_type & operator[] (int i) {
00268     return asImp()[i];
00269   }
00270   const block_type & operator[] (int i) const {
00271     return asImp()[i];
00272   }
00274   FlatIterator<I> fbegin() { return FlatIterator<I>(asImp().begin()); }
00276   FlatIterator<I> fend() { return FlatIterator<I>(asImp().end()); }
00278   FlatIterator<const I> fbegin() const {
00279     return FlatIterator<const I>(asImp().begin()); }
00281   FlatIterator<const I> fend() const {
00282     return FlatIterator<const I>(asImp().end()); }
00284   template <class E> I& assignFrom(Expression<E>& x) {
00285 #warning should there be a resize?
00286 #ifdef DUNE_ISTL_WITH_CHECKING
00287     assert(N() == x.N());
00288 #endif
00289 #ifdef DUNE_VVERBOSE
00290     Dune::dvverb << INDENT << "Assign Vector from Expression\n";
00291 #endif
00292     ++INDENT;
00293     for (int i=0; i<N(); ++i) { asImp()[i] = x[i]; }
00294     --INDENT;
00295     return asImp();
00296   }
00298   template <class V> I& assignFrom(const Vector<V>& v) {
00299 #ifdef DUNE_ISTL_WITH_CHECKING
00300     assert(N() == v.N());
00301 #endif
00302 #ifdef DUNE_VVERBOSE
00303     Dune::dvverb << INDENT << "Assign Vector from Vector\n";
00304 #endif
00305     ++INDENT;
00306     for (int i=0; i<N(); ++i) { asImp()[i] = v[i]; }
00307     --INDENT;
00308     return asImp();
00309   }
00310   /*
00311   I& assignFrom(const Vector<block_type> & x) {
00312 #ifdef DUNE_VVERBOSE
00313     Dune::dvverb << INDENT << "Assign Vector block_type\n";
00314 #endif
00315     ++INDENT;
00316     for (int i=0; i < asImp().N(); i++) asImp()[i] = x;
00317     --INDENT;
00318     return asImp();
00319   }
00320   */
00321   I& assignFrom(field_type x) {
00322 #ifdef DUNE_VVERBOSE
00323     Dune::dvverb << INDENT << "Assign Vector from field_type\n";
00324 #endif
00325     ++INDENT;
00326     for (size_t i=0; i<N(); ++i) { asImp()[i] = x; }
00327     --INDENT;
00328     return asImp();
00329   }
00330   template <class E> Vector<I>& operator+=(const Expression<E>& x) {
00331     for (size_t i=0; i < asImp().N(); i++) asImp()[i] += x[i];
00332     return asImp();
00333   }
00334   template <class V> Vector<I>& operator+=(const Vector<V>& x) {
00335     for (size_t i=0; i < asImp().N(); i++) asImp()[i] += x[i];
00336     return asImp();
00337   }
00338   template <class E> Vector<I>& operator-=(const Expression<E>& x) {
00339     for (size_t i=0; i < asImp().N(); i++) asImp()[i] -= x[i];
00340     return asImp();
00341   }
00342   template <class V> Vector<I>& operator-=(const Vector<V>& x) {
00343     for (size_t i=0; i < asImp().N(); i++) asImp()[i] -= x[i];
00344     return asImp();
00345   }
00346   Vector<I>& operator+=(field_type x) {
00347     for (size_t i=0; i < asImp().N(); i++) asImp()[i] += x;
00348     return asImp();
00349   }
00350   Vector<I>& operator-=(field_type x) {
00351     for (size_t i=0; i < asImp().N(); i++) asImp()[i] -= x;
00352     return asImp();
00353   }
00354   Vector<I>& operator*=(field_type x) {
00355     for (size_t i=0; i < asImp().N(); i++) asImp()[i] *= x;
00356     return asImp();
00357   }
00358   Vector<I>& operator/=(field_type x) {
00359     for (size_t i=0; i < asImp().N(); i++) asImp()[i] /= x;
00360     return asImp();
00361   }
00362 private:
00363   I & asImp() { return static_cast<I&>(*this); }
00364   const I & asImp() const { return static_cast<const I&>(*this); }
00365 };
00366 
00367 template <class V>
00368 class ConstRef
00369 {
00370 public:
00371   typedef typename FieldType<V>::type field_type;
00372   typedef typename BlockType<V>::type block_type;
00373   typedef typename BlockExpression< ConstRef<V> >::type BlockExpr;
00374   typedef typename ExpressionImp<BlockExpr>::type BlockExprImp;
00375   ConstRef (const Vector<V> & _v) : v(_v) {}  
00376   BlockExpr operator[] (int i) const {
00377 #ifdef DUNE_VVERBOSE
00378     Dune::dvverb << INDENT << "ConstRef->dereference " << v[i] << std::endl;
00379 #endif
00380     return BlockExprImp(v[i]);
00381   }
00382   size_t N() const { return v.N(); };
00383   double one_norm() const { return eval_one_norm(*this); }
00384   double one_norm_real() const { return eval_one_norm_real(*this); }
00385   double two_norm() const { return sqrt(eval_two_norm2(*this)); }
00386   double two_norm2() const { return eval_two_norm2(*this); }
00387   double infinity_norm() const { return eval_infinity_norm(*this); }
00388   double infinity_norm_real() const { return eval_infinity_norm_real(*this); }
00389 private:
00390   const Vector<V> & v;
00391 };
00392 
00393 } // namespace ExprTmpl
00394 
00395 template <class A>
00396 struct FieldType< ExprTmpl::Expression<A> >
00397 {
00398   typedef typename FieldType<A>::type type;
00399 };
00400   
00401 template <class V>
00402 struct FieldType< ExprTmpl::ConstRef<V> >
00403 {
00404   typedef typename FieldType<V>::type type;
00405 };
00406   
00407 template <class I>
00408 struct FieldType< ExprTmpl::Vector<I> >
00409 {
00410   typedef typename FieldType<I>::type type;
00411 };
00412 
00413 // ----
00414 template <class A>
00415 struct BlockType< ExprTmpl::Expression<A> >
00416 {
00417   typedef typename BlockType<A>::type type;
00418 };
00419  
00420 template <class V>
00421 struct BlockType< ExprTmpl::ConstRef<V> >
00422 {
00423   typedef typename BlockType<V>::type type;
00424 };
00425   
00426 template <class I>
00427 struct BlockType< ExprTmpl::Vector<I> >
00428 {
00429   typedef typename BlockType<I>::type type;
00430 };
00431 
00435 template<class M>
00436 struct RowType
00437 {
00438   typedef typename M::row_type type;
00439 };
00440 template<class K, int N, int M>
00441 struct RowType< FieldMatrix<K,N,M> >
00442 {
00443   typedef FieldVector<K,M> type;
00444 };
00445 template <class I>
00446 struct RowType< ExprTmpl::Matrix<I> >
00447 {
00448   typedef typename RowType<I>::type type;
00449 };
00450 // RowType specialization for const T
00451 template<class T>
00452 struct RowType<const T>
00453 {
00454   typedef const typename RowType<T>::type type;
00455 };
00456 
00457 // Matrix-Vector Multiplication
00458 namespace ExprTmpl {
00459 
00463 template <class I>
00464 class Matrix {
00465 public:
00466   explicit Matrix() {}
00467   typedef typename RowType<I>::type row_type;
00468   typedef typename FieldType<I>::type field_type;
00470   size_t N() const {
00471     return asImp().N();
00472   }
00473   int M() const {
00474     return asImp().M();
00475   }
00476   row_type & operator[] (int i) {
00477     return asImp()[i];
00478   }
00479   const row_type & operator[] (int i) const {
00480     return asImp()[i];
00481   }
00482 private:
00483   I & asImp() { return static_cast<I&>(*this); }
00484   const I & asImp() const { return static_cast<const I&>(*this); }
00485 };
00486 
00487 // Trait Structs to extract infos needed for Matrix-Vector Multiplication
00488 template<class M>
00489 struct NestedDepth
00490 {
00491     enum { value = NestedDepth<typename BlockType<M>::type>::value + 1 };
00492 };
00493 
00494 template<class K, int N, int M>
00495 struct NestedDepth< FieldMatrix<K,N,M> >
00496 {
00497     enum { value = 1 };
00498 };
00499 
00500 template<class Me, class M>
00501 struct MyDepth
00502 {
00503     enum { value = MyDepth<Me,typename BlockType<M>::type>::value+1 };
00504 };
00505 
00506 template<class Me>
00507 struct MyDepth<Me,Me>
00508 {
00509     enum { value = 0 };
00510 };
00511 
00512 template<class B, int i>
00513 struct BlockTypeN
00514 {
00515   typedef typename BlockTypeN<typename BlockType<B>::type, i-1>::type type;
00516 };
00517 
00518 template<class B>
00519 struct BlockTypeN<B,0>
00520 {
00521   typedef B type;
00522 };
00523 
00524 template<class B>
00525 struct BlockTypeN<B,-1>
00526 {
00527   typedef B type;
00528 };
00529 
00531 template<class T>
00532 struct ColIteratorType
00533 {
00534   typedef typename T::ColIterator type;
00535 };
00536 
00537 template<class T>
00538 struct ColIteratorType<const T>
00539 {
00540   typedef typename T::ConstColIterator type;
00541 };
00542 
00544 template<class A>
00545 class FlatColIterator :
00546   public ForwardIteratorFacade<FlatColIterator<A>,
00547                                typename FieldType<A>::type,
00548                                typename FieldType<A>::type&,
00549                                int>
00550 {
00551 public:
00552   typedef typename ColIteratorType<A>::type ColBlockIterator;
00553   typedef std::ptrdiff_t DifferenceType;
00554 //    typedef typename BlockIterator::DifferenceType DifferenceType;
00555   typedef typename BlockType<A>::type block_type;
00556   typedef typename FieldType<A>::type field_type;
00557   typedef FlatColIterator<block_type> SubBlockIterator;
00558   FlatColIterator(const ColBlockIterator & i, const int* _M) :
00559     M(_M), it(i),
00560     bit((*i)[(*M)].begin(), M+1),
00561     bend((*i)[(*M)].end(), M+1) {};
00562   void increment ()
00563     {
00564       ++bit;
00565       if (bit == bend)
00566       {
00567         ++it;
00568         bit = (*it)[(*M)].begin();
00569         bend = (*it)[(*M)].end();
00570       }
00571     }
00572   bool equals (const FlatColIterator & fit) const
00573     {
00574       return fit.it == it && fit.bit == bit;
00575     }
00576   const field_type& dereference() const
00577     {
00578       return *bit;
00579     }
00580   template<class V>
00581   const field_type& vectorentry(const Dune::ExprTmpl::Vector<V> & v) const
00582     {
00583       return bit.vectorentry(v[it.index()]);
00584     }
00586   DifferenceType index () const
00587     {
00588       return bit.index();
00589     }
00590   FlatColIterator operator = (const ColBlockIterator & _i)
00591     {
00592       it = _i;
00593       bit = (*it)[(*M)].begin();
00594       bend = (*it)[(*M)].end();
00595       return *this;
00596     }
00597 private:
00598   const int* M;
00599   ColBlockIterator it;
00600   SubBlockIterator bit;
00601   SubBlockIterator bend;
00602 };
00603 
00604 template<class K, int N, int M>
00605 class FlatColIterator<FieldMatrix<K,N,M> > :
00606   public ForwardIteratorFacade<
00607     FlatColIterator< FieldMatrix<K,N,M> >, K, K&, int>
00608 {
00609 public:
00610   typedef
00611     typename ColIteratorType< FieldMatrix<K,N,M> >::type ColBlockIterator;
00612   typedef std::ptrdiff_t DifferenceType;
00613   typedef K field_type;
00614   FlatColIterator(const ColBlockIterator & i, const int*) :
00615     it(i) {};
00616   void increment ()
00617     {
00618       ++it;
00619     }
00620   bool equals (const FlatColIterator & fit) const
00621     {
00622       return fit.it == it;
00623     }
00624   field_type& dereference() const
00625     {
00626       return *it;
00627     }
00628   const field_type& vectorentry(const FieldVector<K,M> & v) const
00629     {
00630       return v[it.index()];
00631     }
00633   DifferenceType index () const
00634     {
00635       return it.index();
00636     }
00637   FlatColIterator operator = (const ColBlockIterator & _i)
00638     {
00639       it = _i;
00640       return *this;
00641     }
00642 private:
00643   ColBlockIterator it;
00644 };
00645 
00646 template<class K, int N, int M>
00647 class FlatColIterator<const FieldMatrix<K,N,M> > :
00648   public ForwardIteratorFacade<
00649     FlatColIterator< const FieldMatrix<K,N,M> >, const K, const K&, int>
00650 {
00651 public:
00652   typedef
00653     typename ColIteratorType< const FieldMatrix<K,N,M> >::type ColBlockIterator;
00654   typedef std::ptrdiff_t DifferenceType;
00655   typedef const K field_type;
00656   FlatColIterator(const ColBlockIterator & i, const int*) :
00657     it(i) {};
00658   void increment ()
00659     {
00660       ++it;
00661     }
00662   bool equals (const FlatColIterator & fit) const
00663     {
00664       return fit.it == it;
00665     }
00666   field_type& dereference() const
00667     {
00668       return *it;
00669     }
00670   const field_type& vectorentry(const FieldVector<K,M> & v) const
00671     {
00672       return v[it.index()];
00673     }
00675   DifferenceType index () const
00676     {
00677       return it.index();
00678     }
00679   FlatColIterator operator = (const ColBlockIterator & _i)
00680     {
00681       it = _i;
00682       return *this;
00683     }
00684 private:
00685   ColBlockIterator it;
00686 };
00687 
00693 template <class B, class Mat, class Vec>
00694 class MatrixMulVector
00695 {
00696 public:
00697   typedef typename
00698     BlockTypeN<MatrixMulVector<Mat,Mat,Vec>, MyDepth<B,Mat>::value-1>::type
00699     ParentBlockType;
00700   typedef
00701     MatrixMulVector<typename BlockType<B>::type,Mat,Vec> SubMatrixMulVector;
00702   typedef typename
00703     Dune::ExprTmpl::BlockExpression< MatrixMulVector<B,Mat,Vec> >::type
00704     BlockExpr;
00705   typedef
00706     typename BlockType<Mat>::type::ColIterator SubColIterator;
00707   typedef typename Dune::FieldType<Vec>::type field_type;
00708   /* constructor */
00709   MatrixMulVector(const Mat & _A, const Vec & _v, int* _M,
00710                   const ParentBlockType & _parent) :
00711     parent(_parent), M(_M), A(_A), v(_v) {};
00712   BlockExpr operator[] (int i) const {
00713     M[MyDepth<B,Mat>::value] = i;
00714     return SubMatrixMulVector(A,v,M,*this);
00715   }
00716   size_t N() const { return -1; };//r.begin()->N(); }
00717   const ParentBlockType & parent;  
00718 private:
00719   mutable int* M;
00720   const Mat & A;
00721   const Vec & v;
00722 };
00723 
00724 template <class Mat, class Vec>
00725 class MatrixMulVector<Mat,Mat,Vec>
00726 {
00727 public:
00728   typedef
00729     MatrixMulVector<typename BlockType<Mat>::type,Mat,Vec> SubMatrixMulVector;
00730   typedef
00731     typename BlockType<Mat>::type::ColIterator SubColIterator;
00732   typedef typename
00733     Dune::ExprTmpl::BlockExpression< MatrixMulVector<Mat,Mat,Vec> >::type
00734     BlockExpr;
00735   typedef typename Dune::FieldType<Vec>::type field_type;
00736   /* constructor */
00737   MatrixMulVector(const Mat & _A, const Vec & _v, int* _M) :
00738     M(_M), A(_A), v(_v) {};
00739   BlockExpr operator[] (int i) const {
00740     M[0] = i;
00741     return SubMatrixMulVector(A,v,M,*this);
00742   }
00743   size_t N() const { return -1; }; // { parent.begin().N(); }
00744 private:
00745   mutable int* M;
00746   const Mat & A;
00747   const Vec & v;
00748 };
00749 
00750 template <class K, int iN, int iM, class Mat, class Vec>
00751 class MatrixMulVector< FieldMatrix<K,iN,iM>, Mat, Vec >
00752 {
00753 public:
00754   typedef typename
00755     BlockTypeN<MatrixMulVector<Mat,Mat,Vec>,
00756                MyDepth<FieldMatrix<K,iN,iM>,Mat>::value-1>::type
00757     ParentBlockType;
00758   /* constructor */
00759   MatrixMulVector(const Mat & _A, const Vec & _v, int* _M,
00760                   const ParentBlockType & _parent) :
00761     parent(_parent), M(_M), A(_A), v(_v ) {};
00762   K operator[] (int i) const {
00763     K x=0;
00764     M[MyDepth<FieldMatrix<K,iN,iM>,Mat>::value] = i;
00765   
00766     FlatColIterator<const Mat> j(A[*M].begin(),M+1);
00767     FlatColIterator<const Mat> endj(A[*M].end(),M+1);
00768     for (; j!=endj; ++j)
00769     {
00770       x   += (*j) * j.vectorentry(v);
00771     }
00772     return x;
00773   }
00774   size_t N() const { return iN; };
00775   const ParentBlockType & parent;
00776 private:
00777   mutable int* M;
00778   const Mat & A;
00779   const Vec & v;
00780 };
00781 
00782 template <class K, int iN, int iM>
00783 class MatrixMulVector< FieldMatrix<K,iN,iM>, FieldMatrix<K,iN,iM>,
00784                        FieldVector<K,iM> >
00785 {
00786 public:
00787   typedef FieldMatrix<K,iN,iM> Mat;
00788   typedef FieldVector<K,iM> Vec;
00789   MatrixMulVector(const Mat & _A, const Vec & _v) :
00790     A(_A), v(_v ){};
00791   K operator[] (int i) const {
00792     K x=0;
00793     typename Mat::ColIterator j = A[i].begin();
00794     typename Mat::ColIterator endj = A[i].end();
00795     for (; j!=endj; ++j)
00796     {
00797       x   += (*j) * j.vectorentry(v);
00798     }
00799     return x;
00800   }
00801   size_t N() const { return iN; };
00802 private:
00803   const Mat & A;
00804   const Vec & v;
00805 };
00806 
00807 template <class M, class A, class B>
00808 struct BlockExpression< MatrixMulVector< M, A, B > >
00809 {
00810   typedef Expression< MatrixMulVector<typename BlockType<M>::type,A,B> > type;
00811 };
00812 
00813 template <class K, int N, int M, class A, class B>
00814 struct BlockExpression< MatrixMulVector< FieldMatrix<K,N,M>, A, B > >
00815 {
00816   typedef K type;
00817 };
00818 
00819 template<class K, int N, int M>
00820 ExprTmpl::Expression<
00821   MatrixMulVector<FieldMatrix<K,N,M>, FieldMatrix<K,N,M>, FieldVector<K,M> > >
00822 operator * ( const FieldMatrix<K,N,M> & A, const FieldVector<K,M> & v )
00823 {
00824   return
00825     ExprTmpl::Expression<
00826       MatrixMulVector<FieldMatrix<K,N,M>, FieldMatrix<K,N,M>, FieldVector<K,M> > >
00827     (
00828       MatrixMulVector<FieldMatrix<K,N,M>, FieldMatrix<K,N,M>, FieldVector<K,M> >
00829       (A, v)
00830       );
00831 }
00832 
00833 // template<class BM, class BV>
00834 // ExprTmpl::Expression<
00835 //   MatrixMulVector<BCRSMatrix<BM>, BCRSMatrix<BM>, BlockVector<BV> > >
00836 // operator * ( const BCRSMatrix<BM> & A, const BlockVector<BV> & v )
00837 // {
00838 //   static int indizes[20];
00839 //   return
00840 //     Expression<
00841 //       MatrixMulVector<BCRSMatrix<BM>, BCRSMatrix<BM>, BlockVector<BV> > >
00842 //     (
00843 //       MatrixMulVector<BCRSMatrix<BM>, BCRSMatrix<BM>, BlockVector<BV> >(A, v, indizes)
00844 //       );
00845 // }
00846 
00847 template<class M, class V>
00848 ExprTmpl::Expression<
00849   MatrixMulVector<Matrix<M>, Matrix<M>, Vector<V> > >
00850 operator * ( const Matrix<M> & A, const Vector<V> & v )
00851 {
00852   static int indizes[20];
00853   return
00854     Expression<
00855       MatrixMulVector<Matrix<M>, Matrix<M>, Vector<V> > >
00856     (
00857       MatrixMulVector<Matrix<M>, Matrix<M>, Vector<V> >(A, v, indizes)
00858       );
00859 }
00860 
00861 template<class I>
00862 struct ColIteratorType< Matrix<I> >
00863 {
00864   typedef typename I::ColIterator type;
00865 };
00866 template<class I>
00867 struct ColIteratorType< const Matrix<I> >
00868 {
00869   typedef typename I::ConstColIterator type;
00870 };
00871 
00872 } // namespace ExprTmpl
00873 
00874 template <class B, class A, class V>
00875 struct FieldType< ExprTmpl::MatrixMulVector<B,A,V> >
00876 {
00877   typedef typename FieldType<V>::type type;
00878 };
00879 template <class I>
00880 struct BlockType< ExprTmpl::Matrix<I> >
00881 {
00882   typedef typename BlockType<I>::type type;
00883 };
00884 template <class I>
00885 struct FieldType< ExprTmpl::Matrix<I> >
00886 {
00887   typedef typename FieldType<I>::type type;
00888 };
00889 
00890 // OPERATORS
00891 
00892 /* Scalar-Expression Operator */
00893 #define OP *
00894 #define ExpressionOpScalar ExpressionMulScalar
00895 #define ScalarOpExpression ScalarMulExpression
00896 #include "exprtmpl/scalar.inc"
00897 
00898 #define OP /
00899 #define ExpressionOpScalar ExpressionDivScalar
00900 #include "exprtmpl/scalar.inc"
00901 
00902 #define OP +
00903 #define ExpressionOpScalar ExpressionAddScalar
00904 #define ScalarOpExpression ScalarAdExpression
00905 #include "exprtmpl/scalar.inc"
00906 
00907 #define OP -
00908 #define ExpressionOpScalar ExpressionMinScalar
00909 #define ScalarOpExpression ScalarMinExpression
00910 #include "exprtmpl/scalar.inc"
00911 
00912 /* Expression-Expression Operator */
00913 #define OP +
00914 #define ExpressionOpExpression ExpressionAddExpression
00915 #include "exprtmpl/exprexpr.inc"
00916 
00917 #define OP -
00918 #define ExpressionOpExpression ExpressionMinExpression
00919 #include "exprtmpl/exprexpr.inc"
00920 
00921 /* one norm (sum over absolute values of entries) */
00922 
00923 #define NORM eval_one_norm
00924 #define NORM_CODE \
00925 { \
00926   typename FieldType<A>::type val=0; \
00927   Dune::dvverb << INDENT << "Infinity Norm of Expression\n"; \
00928   ++INDENT; \
00929   for (size_t i=0; i<a.N(); ++i) { val += eval_one_norm(a[i]); } \
00930   --INDENT; \
00931   return val; \
00932 }
00933 #define VAL_CODE { return std::abs(a); }
00934 #include "exprtmpl/norm.inc"
00935 
00936 template<class K>
00937 inline K eval_one_norm (const std::complex<K>& c)
00938 {
00939   sqrt(c.real()*c.real() + c.imag()*c.imag());
00940 }
00941 
00942 template <class A>
00943 typename FieldType<A>::type
00944 one_norm (const A & a)
00945 {
00946   return eval_one_norm(a);
00947 }
00948 
00949 /* simplified one norm (uses Manhattan norm for complex values) */
00950 
00951 #define NORM eval_one_norm_real
00952 #define NORM_CODE \
00953 { \
00954   typename FieldType<A>::type val=0; \
00955   Dune::dvverb << INDENT << "Infinity Norm of Expression\n"; \
00956   ++INDENT; \
00957   for (size_t i=0; i<a.N(); ++i) { val += eval_one_norm_real(a[i]); } \
00958   --INDENT; \
00959   return val; \
00960 }
00961 #define VAL_CODE { return std::abs(a); }
00962 #include "exprtmpl/norm.inc"
00963 
00964 template<class K>
00965 inline K eval_one_norm_real (const std::complex<K>& c)
00966 {
00967   return eval_one_norm_real(c.real()) + eval_one_norm_real(c.imag());
00968 }
00969 
00970 template <class A>
00971 typename FieldType<A>::type
00972 one_norm_real (const A & a)
00973 {
00974   return eval_one_norm_real(a);
00975 }
00976 
00977 /* two norm sqrt(sum over squared values of entries) */
00978 
00979 template <class A>
00980 typename FieldType<A>::type
00981 two_norm (const A & a)
00982 {
00983   return sqrt(eval_two_norm2(a));
00984 }
00985 
00986 /* sqare of two norm (sum over squared values of entries), need for block recursion */
00987 
00988 #define NORM eval_two_norm2
00989 #define NORM_CODE \
00990 { \
00991   typename FieldType<A>::type val=0; \
00992   Dune::dvverb << INDENT << "Infinity Norm of Expression\n"; \
00993   ++INDENT; \
00994   for (size_t i=0; i<a.N(); ++i) { val += eval_two_norm2(a[i]); } \
00995   --INDENT; \
00996   return val; \
00997 }
00998 #define VAL_CODE { return a*a; }
00999 #include "exprtmpl/norm.inc"
01000 
01001 template<class K>
01002 inline K eval_two_norm2 (const std::complex<K>& c)
01003 {
01004   return c.real()*c.real() + c.imag()*c.imag();
01005 }
01006 
01007 template <class A>
01008 typename FieldType<A>::type
01009 two_norm2 (const A & a)
01010 {
01011   return eval_two_norm2(a);
01012 }
01013 
01014 /* infinity norm (maximum of absolute values of entries) */
01015 
01016 #define NORM eval_infinity_norm
01017 #define NORM_CODE { \
01018   typename FieldType<A>::type val=0; \
01019   Dune::dvverb << INDENT << "Infinity Norm of Expression\n"; \
01020   ++INDENT; \
01021   for (size_t i=0; i<a.N(); ++i) { val = std::max(val,eval_infinity_norm(a[i])); } \
01022   --INDENT; \
01023   return val; \
01024 }
01025 #define VAL_CODE { return a; }
01026 #include "exprtmpl/norm.inc"
01027 
01028 template <class A>
01029 typename FieldType<A>::type
01030 infinity_norm (const A & a)
01031 {
01032   return eval_infinity_norm(a);
01033 }
01034 
01035 /* simplified infinity norm (uses Manhattan norm for complex values) */
01036 
01037 #define NORM eval_infinity_norm_real
01038 #define NORM_CODE { \
01039   typename FieldType<A>::type val=0; \
01040   Dune::dvverb << INDENT << "Infinity Norm of Expression\n"; \
01041   ++INDENT; \
01042   for (size_t i=0; i<a.N(); ++i) { val = std::max(val,eval_infinity_norm(a[i])); } \
01043   --INDENT; \
01044   return val; \
01045 }
01046 #define VAL_CODE { return std::abs(a); }
01047 #include "exprtmpl/norm.inc"
01048 
01049 template<class K>
01050 inline K eval_infinity_norm_real (const std::complex<K>& c)
01051 {
01052   return eval_one_norm_real(c.real()) + eval_one_norm_real(c.imag());
01053 }
01054 
01055 template <class A>
01056 typename FieldType<A>::type
01057 infinity_norm_real (const A & a)
01058 {
01059   return eval_infinity_norm(a);
01060 }
01061 
01062 /* vector * vector */
01063 
01064 namespace ExprTmpl {
01065 
01066 // Vector * Vector
01067 template <class A>
01068 typename FieldType<A>::type
01069 operator * (const Vector<A> & a, const Vector<A> & b)
01070 {
01071   assert(a.N() == b.N());
01072   typename FieldType<A>::type x = 0;
01073   for (size_t i=0; i<a.N(); i++)
01074     x = a[i] * b[i];
01075   return x;
01076 }
01077 
01078 // Expression * Vector
01079 template <class A, class B>
01080 typename FieldType<A>::type
01081 operator * (const Vector<A> & a, const Expression<B> & b)
01082 {
01083   dune_static_assert((is_same<FieldType<A>,FieldType<B> >::value), 
01084                      "Field types of both operands must match!");
01085   assert(a.N() == b.N());
01086   typename FieldType<A>::type x = 0;
01087   for (size_t i=0; i<a.N(); i++)
01088     x = a[i] * b[i];
01089   return x;
01090 }
01091 
01092 // Vector * Expression
01093 template <class A, class B>
01094 typename FieldType<A>::type
01095 operator * (const Expression<A> & a, const Vector<B> & b)
01096 {
01097   dune_static_assert((is_same<FieldType<A>,FieldType<B> >::value), 
01098                      "Field types of both operands must match!");
01099   assert(a.N() == b.N());
01100   typename FieldType<A>::type x = 0;
01101   for (size_t i=0; i<a.N(); i++)
01102     x = a[i] * b[i];
01103   return x;
01104 }
01105 
01106 } // namespace ExprTmpl
01107 
01108 } // namespace Dune
01109 
01110 #endif // DUNE_EXPRTMPL_HH

Generated on Fri Apr 29 2011 with Doxygen (ver 1.7.1) [doxygen-log,error-log].