00001 #if ! defined DUNE_EXPRTMPL_HH && DUNE_EXPRESSIONTEMPLATES
00002 #define DUNE_EXPRTMPL_HH
00003
00004
00005
00006
00007
00008
00009
00020 #include <iostream>
00021 #include <iomanip>
00022 #include <cstdlib>
00023 #include <cmath>
00024 #include <complex>
00025 #include "iteratorfacades.hh"
00026 #include "helpertemplates.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
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
00097 template <class K, int N>
00098 struct FieldType< FieldVector<K,N> >
00099 {
00100 typedef K type;
00101 };
00102
00103 template <class K, int N>
00104 struct BlockType< FieldVector<K,N> >
00105 {
00106 typedef K type;
00107 };
00108
00109 template<class T>
00110 struct FieldType<const T>
00111 {
00112 typedef const typename FieldType<T>::type type;
00113 };
00114
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
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
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
00312
00313
00314
00315
00316
00317
00318
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 }
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
00451 template<class T>
00452 struct RowType<const T>
00453 {
00454 typedef const typename RowType<T>::type type;
00455 };
00456
00457
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
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
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
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; };
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
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; };
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
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
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
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 }
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
00891
00892
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
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
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
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
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
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
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
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
01063
01064 namespace ExprTmpl {
01065
01066
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
01079 template <class A, class B>
01080 typename FieldType<A>::type
01081 operator * (const Vector<A> & a, const Expression<B> & b)
01082 {
01083 IsTrue< is_same<FieldType<A>,FieldType<B> >::value == true >::yes();
01084 assert(a.N() == b.N());
01085 typename FieldType<A>::type x = 0;
01086 for (size_t i=0; i<a.N(); i++)
01087 x = a[i] * b[i];
01088 return x;
01089 }
01090
01091
01092 template <class A, class B>
01093 typename FieldType<A>::type
01094 operator * (const Expression<A> & a, const Vector<B> & b)
01095 {
01096 IsTrue< is_same<FieldType<A>,FieldType<B> >::value == true >::yes();
01097 assert(a.N() == b.N());
01098 typename FieldType<A>::type x = 0;
01099 for (size_t i=0; i<a.N(); i++)
01100 x = a[i] * b[i];
01101 return x;
01102 }
01103
01104 }
01105
01106 }
01107
01108 #endif // DUNE_EXPRTMPL_HH