fvector.hh

Go to the documentation of this file.
00001 // $Id: fvector.hh 4953 2007-07-12 14:58:01Z christi $
00002 #ifndef DUNE_FVECTOR_HH
00003 #define DUNE_FVECTOR_HH
00004 
00005 #include<cmath>
00006 #include<cstddef>
00007 #include<complex>
00008 
00009 #include "exceptions.hh"
00010 #include "genericiterator.hh"
00011 
00012 namespace Dune {
00013 
00024   // forward declaration of template
00025   template<class K, int n> class FieldVector;
00026   
00027   template<class K>
00028   inline double fvmeta_absreal (const K& k)
00029   {
00030       return std::abs(k);
00031   }
00032 
00033   template<class K>
00034   inline double fvmeta_absreal (const std::complex<K>& c)
00035   {
00036         return fvmeta_abs(c.real()) + fvmeta_abs(c.imag());
00037   }
00038 
00039   template<class K>
00040   inline double fvmeta_abs2 (const K& k)
00041   {
00042         return k*k;
00043   }
00044 
00045   template<class K>
00046   inline double fvmeta_abs2 (const std::complex<K>& c)
00047   {
00048         return c.real()*c.real() + c.imag()*c.imag();
00049   }
00050 
00052   template<class C, class T>
00053   class FieldIterator : 
00054     public Dune::RandomAccessIteratorFacade<FieldIterator<C,T>,T, T&, int>
00055   {
00056     friend class FieldIterator<typename Dune::RemoveConst<C>::Type, typename Dune::RemoveConst<T>::Type >;
00057     friend class FieldIterator<const typename Dune::RemoveConst<C>::Type, const typename Dune::RemoveConst<T>::Type >;
00058     
00059   public:
00060     
00064     typedef std::ptrdiff_t DifferenceType;
00065     
00066     // Constructors needed by the base iterators.
00067     FieldIterator()
00068       : container_(0), position_(0)
00069       {}
00070     
00071     FieldIterator(C& cont, DifferenceType pos)
00072       : container_(&cont), position_(pos)
00073       {}
00074     
00075     FieldIterator(const FieldIterator<typename Dune::RemoveConst<C>::Type, typename Dune::RemoveConst<T>::Type >& other)
00076       : container_(other.container_), position_(other.position_)
00077       {}
00078     
00079     // Methods needed by the forward iterator
00080     bool equals(const FieldIterator<typename Dune::RemoveConst<C>::Type,typename Dune::RemoveConst<T>::Type>& other) const
00081       {
00082         return position_ == other.position_ && container_ == other.container_;
00083       }
00084     
00085     
00086     bool equals(const FieldIterator<const typename Dune::RemoveConst<C>::Type,const typename Dune::RemoveConst<T>::Type>& other) const
00087       {
00088         return position_ == other.position_ && container_ == other.container_;
00089       }
00090     
00091     T& dereference() const{
00092       return container_->operator[](position_);
00093     }
00094     
00095     void increment(){
00096       ++position_;
00097     }
00098     
00099     // Additional function needed by BidirectionalIterator
00100     void decrement(){
00101       --position_;
00102     }
00103     
00104     // Additional function needed by RandomAccessIterator
00105     T& elementAt(DifferenceType i)const{
00106       return container_->operator[](position_+i);
00107     }
00108     
00109     void advance(DifferenceType n){
00110       position_=position_+n;
00111     }
00112     
00113     std::ptrdiff_t distanceTo(FieldIterator<const typename Dune::RemoveConst<C>::Type,const typename Dune::RemoveConst<T>::Type> other)const
00114       {
00115         assert(other.container_==container_);
00116         return other.position_ - position_;
00117       }
00118     
00119     std::ptrdiff_t distanceTo(FieldIterator<typename Dune::RemoveConst<C>::Type, typename Dune::RemoveConst<T>::Type> other)const
00120       {
00121         assert(other.container_==container_);
00122         return other.position_ - position_;
00123       }
00124     
00126     DifferenceType index () const
00127       {
00128         return this->position_;
00129       }
00130     
00131   private:
00132     C *container_;
00133     DifferenceType position_;
00134   };
00135 
00137   template<class T>
00138   struct IteratorType
00139   {
00140     typedef typename T::Iterator type;
00141   };
00142   
00143   template<class T>
00144   struct IteratorType<const T>
00145   {
00146     typedef typename T::ConstIterator type;
00147   };
00148   
00158   template<class K, int SIZE>
00159   class FieldVector
00160   {
00161   public:
00162         // remember size of vector 
00163         enum { dimension = SIZE };
00164 
00165         // standard constructor and everything is sufficient ...
00166 
00167         //===== type definitions and constants
00168 
00170         typedef K field_type;
00171 
00173         typedef K block_type;
00174 
00176     typedef std::size_t size_type;
00177     
00179         enum {
00181           blocklevel = 1
00182         };
00183 
00185         enum {
00187           size = SIZE
00188         };
00189 
00191         FieldVector() {}
00192 
00194         explicit FieldVector (const K& t)
00195         {
00196           for (size_type i=0; i<SIZE; i++) p[i] = t;
00197         }
00198 
00199         //===== assignment from scalar
00201         FieldVector& operator= (const K& k)
00202         {
00203             //fvmeta_assignscalar<SIZE-1>::assignscalar(*this,k);
00204             for (size_type i=0; i<SIZE; i++)
00205                 p[i] = k;
00206           return *this;   
00207         }
00208 
00209         //===== access to components
00210 
00212         K& operator[] (size_type i)
00213         {
00214 #ifdef DUNE_ISTL_WITH_CHECKING
00215           if (i<0 || i>=SIZE) DUNE_THROW(MathError,"index out of range");
00216 #endif
00217           return p[i];
00218         }
00219 
00221         const K& operator[] (size_type i) const
00222         {
00223 #ifdef DUNE_ISTL_WITH_CHECKING
00224           if (i<0 || i>=SIZE) DUNE_THROW(MathError,"index out of range");
00225 #endif
00226           return p[i];
00227         }
00228 
00230     typedef FieldIterator<FieldVector<K,SIZE>,K> Iterator;
00232     typedef Iterator iterator;
00233     
00235         Iterator begin ()
00236         {
00237           return Iterator(*this,0);
00238         }
00239 
00241         Iterator end ()
00242         {
00243           return Iterator(*this,SIZE);
00244         }
00245 
00247         Iterator rbegin ()
00248         {
00249           return Iterator(*this,SIZE-1);
00250         }
00251 
00253         Iterator rend ()
00254         {
00255           return Iterator(*this,-1);
00256         }
00257 
00259         Iterator find (size_type i)
00260         {
00261           if (i<SIZE)
00262                 return Iterator(*this,i);
00263           else
00264                 return Iterator(*this,SIZE);
00265         }
00266 
00268     typedef FieldIterator<const FieldVector<K,SIZE>,const K> ConstIterator;
00270     typedef ConstIterator const_iterator;
00271 
00273         ConstIterator begin () const
00274         {
00275           return ConstIterator(*this,0);
00276         }
00277 
00279         ConstIterator end () const
00280         {
00281           return ConstIterator(*this,SIZE);
00282         }
00283 
00285         ConstIterator rbegin () const
00286         {
00287           return ConstIterator(*this,SIZE-1);
00288         }
00289 
00291         ConstIterator rend () const
00292         {
00293           return ConstIterator(*this,-1);
00294         }
00295 
00297         ConstIterator find (size_type i) const
00298         {
00299           if (i<SIZE)
00300                 return ConstIterator(*this,i);
00301           else
00302                 return ConstIterator(*this,SIZE);
00303         }
00304     
00305         //===== vector space arithmetic
00306 
00308         FieldVector& operator+= (const FieldVector& y)
00309         {
00310             for (size_type i=0; i<SIZE; i++)
00311                 p[i] += y.p[i];
00312           return *this;
00313         }
00314 
00316         FieldVector& operator-= (const FieldVector& y)
00317         {
00318             for (size_type i=0; i<SIZE; i++)
00319                 p[i] -= y.p[i];
00320           return *this;
00321         }
00322 
00324         FieldVector<K, size> operator+ (const FieldVector<K, size>& b) const
00325         {
00326           FieldVector<K, size> z = *this;
00327           return (z+=b);
00328         }
00329 
00331         FieldVector<K, size> operator- (const FieldVector<K, size>& b) const
00332         {
00333           FieldVector<K, size> z = *this;
00334           return (z-=b);
00335         }
00336 
00338         FieldVector& operator+= (const K& k)
00339         {
00340             for (size_type i=0; i<SIZE; i++)
00341                 p[i] += k;
00342           return *this;
00343         }
00344 
00346         FieldVector& operator-= (const K& k)
00347         {
00348             for (size_type i=0; i<SIZE; i++)
00349                 p[i] -= k;
00350           return *this;
00351         }
00352 
00354         FieldVector& operator*= (const K& k)
00355         {
00356             for (size_type i=0; i<SIZE; i++)
00357                 p[i] *= k;
00358           return *this;
00359         }
00360 
00362         FieldVector& operator/= (const K& k)
00363         {
00364           for (size_type i=0; i<SIZE; i++)
00365               p[i] /= k;
00366           return *this;
00367         }
00368 
00370         bool operator== (const FieldVector& y) const
00371         {
00372             for (size_type i=0; i<SIZE; i++)
00373                 if (p[i]!=y.p[i])
00374                     return false;
00375 
00376             return true;
00377         }
00378 
00380         FieldVector& axpy (const K& a, const FieldVector& y)
00381         {
00382             for (size_type i=0; i<SIZE; i++)
00383                 p[i] += a*y.p[i];
00384           return *this;
00385         }
00386 
00387         //===== Euclidean scalar product
00388 
00390     K operator* (const FieldVector& y) const
00391         {
00392             K result = 0;
00393             for (int i=0; i<size; i++)
00394                 result += p[i]*y[i];
00395             return result;
00396         }
00397 
00398 
00399         //===== norms
00400 
00402       double one_norm() const {
00403           double result = 0;
00404           for (int i=0; i<size; i++)
00405               result += std::abs(p[i]);
00406           return result;
00407       }
00408 
00409 
00411     double one_norm_real () const
00412         {
00413           double result = 0;
00414           for (int i=0; i<size; i++)
00415               result += fvmeta_absreal(p[i]);
00416           return result;
00417         }
00418 
00420     double two_norm () const
00421         {
00422           double result = 0;
00423           for (int i=0; i<size; i++)
00424               result += fvmeta_abs2(p[i]);
00425           return std::sqrt(result);
00426         }
00427 
00429       double two_norm2 () const
00430         {
00431             double result = 0;
00432             for (int i=0; i<size; i++)
00433                 result += fvmeta_abs2(p[i]);
00434             return result;
00435         }
00436 
00438     double infinity_norm () const
00439         {
00440           double result = 0;
00441             for (int i=0; i<size; i++)
00442                 result = std::max(result, std::abs(p[i]));
00443             return result;
00444         }
00445 
00447         double infinity_norm_real () const
00448         {
00449             double result = 0;
00450             for (int i=0; i<size; i++)
00451                 result = std::max(result, fvmeta_absreal(p[i]));
00452             return result;
00453         }
00454 
00455         //===== sizes
00456 
00458         size_type N () const
00459         {
00460           return SIZE;
00461         }
00462 
00464         size_type dim () const
00465         {
00466           return SIZE;
00467         }
00468 
00469   private:
00470         // the data, very simply a built in array
00471       K p[(SIZE > 0) ? SIZE : 1]; 
00472   };
00473 
00475   template<typename K, int n>
00476   std::ostream& operator<< (std::ostream& s, const FieldVector<K,n>& v)
00477   {
00478       for (typename FieldVector<K,n>::size_type i=0; i<n; i++)
00479               s << ((i>0) ? " " : "") << v[i];
00480       return s;
00481   }
00482 
00483   
00484   // forward declarations
00485   template<class K, int n, int m> class FieldMatrix;
00486 
00489   template<class K>
00490   class FieldVector<K,1>
00491   {
00492     enum { n = 1 };
00493   public:
00494         friend class FieldMatrix<K,1,1>;
00495 
00496         //===== type definitions and constants
00497 
00499         typedef K field_type;
00500 
00502         typedef K block_type;
00503 
00505     typedef std::size_t size_type;
00506     
00508         enum {blocklevel = 1};
00509 
00511         enum {size = 1};
00512 
00514         enum {dimension = 1};
00515 
00516         //===== construction
00517 
00519         FieldVector ()
00520         {       }
00521 
00523         FieldVector (const K& k)
00524         {
00525           p = k;
00526         }
00527 
00529         FieldVector& operator= (const K& k)
00530         {
00531           p = k;
00532           return *this;   
00533         }
00534 
00535         //===== access to components
00536 
00538         K& operator[] (size_type i)
00539         {
00540 #ifdef DUNE_ISTL_WITH_CHECKING
00541           if (i != 0) DUNE_THROW(MathError,"index out of range");
00542 #endif
00543           return p;
00544         }
00545 
00547         const K& operator[] (size_type i) const
00548         {
00549 #ifdef DUNE_ISTL_WITH_CHECKING
00550           if (i != 0) DUNE_THROW(MathError,"index out of range");
00551 #endif
00552           return p;
00553         }
00554 
00556     typedef FieldIterator<FieldVector<K,n>,K> Iterator;
00558     typedef Iterator iterator;
00559     
00561         Iterator begin ()
00562         {
00563           return Iterator(*this,0);
00564         }
00565 
00567         Iterator end ()
00568         {
00569           return Iterator(*this,n);
00570         }
00571 
00573         Iterator rbegin ()
00574         {
00575           return Iterator(*this,n-1);
00576         }
00577 
00579         Iterator rend ()
00580         {
00581           return Iterator(*this,-1);
00582         }
00583 
00585         Iterator find (size_type i)
00586         {
00587           if (i<n)
00588                 return Iterator(*this,i);
00589           else
00590                 return Iterator(*this,n);
00591         }
00592 
00594     typedef FieldIterator<const FieldVector<K,n>,const K> ConstIterator;
00596     typedef ConstIterator const_iterator;
00597 
00599         ConstIterator begin () const
00600         {
00601           return ConstIterator(*this,0);
00602         }
00603 
00605         ConstIterator end () const
00606         {
00607           return ConstIterator(*this,n);
00608         }
00609 
00611         ConstIterator rbegin () const
00612         {
00613           return ConstIterator(*this,n-1);
00614         }
00615 
00617         ConstIterator rend () const
00618         {
00619           return ConstIterator(*this,-1);
00620         }
00621 
00623         ConstIterator find (size_type i) const
00624         {
00625           if (i<n)
00626                 return ConstIterator(*this,i);
00627           else
00628                 return ConstIterator(*this,n);
00629         }
00630         //===== vector space arithmetic
00631 
00633         FieldVector& operator+= (const FieldVector& y)
00634         {
00635           p += y.p;
00636           return *this;
00637         }
00638 
00640         FieldVector& operator-= (const FieldVector& y)
00641         {
00642           p -= y.p;
00643           return *this;
00644         }
00645 
00647         FieldVector& operator+= (const K& k)
00648         {
00649           p += k;
00650           return *this;
00651         }
00652 
00654         FieldVector& operator-= (const K& k)
00655         {
00656           p -= k;
00657           return *this;
00658         }
00659 
00661         FieldVector& operator*= (const K& k)
00662         {
00663           p *= k;
00664           return *this;
00665         }
00666 
00668         FieldVector& operator/= (const K& k)
00669         {
00670           p /= k;
00671           return *this;
00672         }
00673 
00675         FieldVector& axpy (const K& a, const FieldVector& y)
00676         {
00677           p += a*y.p;
00678           return *this;
00679         }
00680 
00681         //===== norms
00682 
00684     double one_norm () const
00685         {
00686             return std::abs(p);
00687         }
00688 
00690     double one_norm_real () const
00691         {
00692           return fvmeta_abs_real(p);
00693         }
00694 
00696     double two_norm () const
00697         {
00698           return sqrt(fvmeta_abs2(p));
00699         }
00700 
00702     double two_norm2 () const
00703         {
00704           return fvmeta_abs2(p);
00705         }
00706 
00708     double infinity_norm () const
00709         {
00710             return std::abs(p);
00711         }
00712 
00714         double infinity_norm_real () const
00715         {
00716           return fvmeta_abs_real(p);
00717         }
00718 
00719 
00720         //===== sizes
00721 
00723         size_type N () const
00724         {
00725           return 1;
00726         }
00727 
00729         size_type dim () const
00730         {
00731           return 1;
00732         }
00733 
00734         //===== conversion operator
00735 
00737         operator K () {return p;}
00738 
00740         operator K () const {return p;}
00741 
00742   private:
00743         // the data
00744         K p; 
00745   };
00746 
00748   template<class K>
00749   inline FieldVector<K,1> operator+ (const FieldVector<K,1>& a, const FieldVector<K,1>& b)
00750   {
00751     FieldVector<K,1> z = a;
00752     return (z+=b);
00753   }
00754   
00756   template<class K>
00757   inline FieldVector<K,1> operator- (const FieldVector<K,1>& a, const FieldVector<K,1>& b)
00758   {
00759     FieldVector<K,1> z = a;
00760     return (z-=b);
00761   }
00762   
00764   template<class K>
00765   inline FieldVector<K,1> operator+ (const FieldVector<K,1>& a, const K b)
00766   {
00767     FieldVector<K,1> z = a;
00768     return (z[0]+=b);
00769   }
00770   
00772   template<class K>
00773   inline FieldVector<K,1> operator- (const FieldVector<K,1>& a, const K b)
00774   {
00775     FieldVector<K,1> z = a;
00776     return (z[0]-=b);
00777   }
00778 
00780   template<class K>
00781   inline FieldVector<K,1> operator+ (const K a, const FieldVector<K,1>& b)
00782   {
00783     FieldVector<K,1> z = a;
00784     return (z[0]+=b);
00785   }
00786   
00788   template<class K>
00789   inline FieldVector<K,1> operator- (const K a, const FieldVector<K,1>& b)
00790   {
00791     FieldVector<K,1> z = a;
00792     return (z[0]-=b);
00793   }
00794 
00797 } // end namespace
00798 
00799 #endif

Generated on 12 Dec 2007 with Doxygen (ver 1.5.1)