- Home
- About DUNE
- Download
- Documentation
- Community
- Development
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].