densevector.hh

Go to the documentation of this file.
00001 // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
00002 // vi: set et ts=4 sw=2 sts=2:
00003 #ifndef DUNE_DENSEVECTOR_HH
00004 #define DUNE_DENSEVECTOR_HH
00005 
00006 #include<limits>
00007 
00008 #include "genericiterator.hh"
00009 #include "ftraits.hh"
00010 #include "matvectraits.hh"
00011 
00012 namespace Dune {
00013 
00014   // forward declaration of template
00015   template<typename V> class DenseVector;
00016 
00017   template<typename V>
00018   struct FieldTraits< DenseVector<V> >
00019   {
00020     typedef typename FieldTraits< typename DenseMatVecTraits<V>::value_type >::field_type field_type;
00021     typedef typename FieldTraits< typename DenseMatVecTraits<V>::value_type >::real_type real_type;
00022   };
00023 
00033   namespace fvmeta
00034   {
00039     template<class K>
00040     inline typename FieldTraits<K>::real_type absreal (const K& k)
00041     {
00042       return std::abs(k);
00043     }
00044 
00049     template<class K>
00050     inline typename FieldTraits<K>::real_type absreal (const std::complex<K>& c)
00051     {
00052       return std::abs(c.real()) + std::abs(c.imag());
00053     }
00054 
00059     template<class K>
00060     inline typename FieldTraits<K>::real_type abs2 (const K& k)
00061     {
00062       return k*k;
00063     }
00064     
00069     template<class K>
00070     inline typename FieldTraits<K>::real_type abs2 (const std::complex<K>& c)
00071     {
00072       return c.real()*c.real() + c.imag()*c.imag();
00073     }
00074     
00079     template<class K, bool isInteger = std::numeric_limits<K>::is_integer>
00080     struct Sqrt
00081     {
00082       static inline typename FieldTraits<K>::real_type sqrt (const K& k)
00083       {
00084         return std::sqrt(k);
00085       }
00086     };
00087     
00092     template<class K>
00093     struct Sqrt<K, true>
00094     {
00095       static inline typename FieldTraits<K>::real_type sqrt (const K& k)
00096       {
00097         return typename FieldTraits<K>::real_type(std::sqrt(double(k)));
00098       }
00099     };
00100     
00105     template<class K>
00106     inline typename FieldTraits<K>::real_type sqrt (const K& k)
00107     {
00108       return Sqrt<K>::sqrt(k);
00109     }
00110 
00111   }
00112 
00117   template<class C, class T>
00118   class DenseIterator : 
00119     public Dune::RandomAccessIteratorFacade<DenseIterator<C,T>,T, T&, std::ptrdiff_t>
00120   {
00121     friend class DenseIterator<typename remove_const<C>::type, typename remove_const<T>::type >;
00122     friend class DenseIterator<const typename remove_const<C>::type, const typename remove_const<T>::type >;
00123     
00124   public:
00125     
00129     typedef std::ptrdiff_t DifferenceType;
00130 
00134     typedef typename C::size_type SizeType;
00135     
00136     // Constructors needed by the base iterators.
00137     DenseIterator()
00138       : container_(0), position_()
00139     {}
00140     
00141     DenseIterator(C& cont, SizeType pos)
00142       : container_(&cont), position_(pos)
00143     {}
00144     
00145     DenseIterator(const DenseIterator<typename remove_const<C>::type, typename remove_const<T>::type >& other)
00146       : container_(other.container_), position_(other.position_)
00147     {}
00148     
00149     // Methods needed by the forward iterator
00150     bool equals(const DenseIterator<typename remove_const<C>::type,typename remove_const<T>::type>& other) const
00151     {
00152       return position_ == other.position_ && container_ == other.container_;
00153     }
00154     
00155     
00156     bool equals(const DenseIterator<const typename remove_const<C>::type,const typename remove_const<T>::type>& other) const
00157     {
00158       return position_ == other.position_ && container_ == other.container_;
00159     }
00160     
00161     T& dereference() const{
00162       return container_->operator[](position_);
00163     }
00164     
00165     void increment(){
00166       ++position_;
00167     }
00168     
00169     // Additional function needed by BidirectionalIterator
00170     void decrement(){
00171       --position_;
00172     }
00173     
00174     // Additional function needed by RandomAccessIterator
00175     T& elementAt(DifferenceType i)const{
00176       return container_->operator[](position_+i);
00177     }
00178     
00179     void advance(DifferenceType n){
00180       position_=position_+n;
00181     }
00182     
00183     DifferenceType distanceTo(DenseIterator<const typename remove_const<C>::type,const typename remove_const<T>::type> other)const
00184     {
00185       assert(other.container_==container_);
00186       return other.position_ - position_;
00187     }
00188     
00189     DifferenceType distanceTo(DenseIterator<typename remove_const<C>::type, typename remove_const<T>::type> other)const
00190     {
00191       assert(other.container_==container_);
00192       return other.position_ - position_;
00193     }
00194     
00196     SizeType index () const
00197     {
00198       return this->position_;
00199     }
00200     
00201   private:
00202     C *container_;
00203     SizeType position_;
00204   };
00205 
00219   template<typename V>
00220   class DenseVector
00221   {
00222     typedef DenseMatVecTraits<V> Traits;
00223     // typedef typename Traits::value_type K;
00224 
00225     // Curiously recurring template pattern
00226     V & asImp() { return static_cast<V&>(*this); }
00227     const V & asImp() const { return static_cast<const V&>(*this); }
00228     
00229   public:
00230     //===== type definitions and constants
00231 
00233     typedef typename Traits::derived_type derived_type;
00234 
00236     typedef typename Traits::value_type value_type;
00237 
00239     typedef typename Traits::value_type field_type;
00240 
00242     typedef typename Traits::value_type block_type;
00243 
00245     typedef typename Traits::size_type size_type;
00246     
00248     enum {
00250       blocklevel = 1
00251     };
00252 
00253     //===== assignment from scalar
00255     inline derived_type& operator= (const value_type& k)
00256     {
00257       for (size_type i=0; i<size(); i++)
00258         asImp()[i] = k;
00259       return asImp();   
00260     }
00261 
00262     //===== access to components
00263 
00265     value_type & operator[] (size_type i)
00266     {
00267       return asImp().vec_access(i);
00268     }
00269 
00270     const value_type & operator[] (size_type i) const
00271     {
00272       return asImp().vec_access(i);
00273     }
00274 
00276     size_type size() const
00277     {
00278       return asImp().vec_size();
00279     }
00280         
00282     typedef DenseIterator<DenseVector,value_type> Iterator;
00284     typedef Iterator iterator;
00285     
00287     Iterator begin ()
00288     {
00289       return Iterator(*this,0);
00290     }
00291 
00293     Iterator end ()
00294     {
00295       return Iterator(*this,size());
00296     }
00297 
00302     Iterator rbegin() DUNE_DEPRECATED
00303     {
00304       return beforeBegin();
00305     }
00306     
00309     Iterator beforeEnd ()
00310     {
00311       return Iterator(*this,size()-1);
00312     }
00313 
00318     Iterator rend () DUNE_DEPRECATED
00319     {
00320       return beforeBegin();
00321     }
00322     
00325     Iterator beforeBegin ()
00326     {
00327       return Iterator(*this,-1);
00328     }
00329 
00331     Iterator find (size_type i)
00332     {
00333       return Iterator(*this,std::min(i,size()));
00334     }
00335 
00337     typedef DenseIterator<const DenseVector,const value_type> ConstIterator;
00339     typedef ConstIterator const_iterator;
00340 
00342     ConstIterator begin () const
00343     {
00344       return ConstIterator(*this,0);
00345     }
00346 
00348     ConstIterator end () const
00349     {
00350       return ConstIterator(*this,size());
00351     }
00352 
00357     ConstIterator rbegin() const DUNE_DEPRECATED
00358     {
00359       return beforeEnd();
00360     }
00361 
00364     ConstIterator beforeEnd () const
00365     {
00366       return ConstIterator(*this,size()-1);
00367     }
00368 
00373     ConstIterator rend () const DUNE_DEPRECATED
00374     {
00375       return beforeBegin();
00376     }
00377     
00380     ConstIterator beforeBegin () const
00381     {
00382       return ConstIterator(*this,-1);
00383     }
00384 
00386     ConstIterator find (size_type i) const
00387     {
00388       return ConstIterator(*this,std::min(i,size()));
00389     }
00390     
00391     //===== vector space arithmetic
00392 
00394     derived_type& operator+= (const DenseVector& y)
00395     {
00396       assert(y.size() == size());
00397       for (size_type i=0; i<size(); i++)
00398         (*this)[i] += y[i];
00399       return asImp();
00400     }
00401 
00403     derived_type& operator-= (const DenseVector& y)
00404     {
00405       assert(y.size() == size());
00406       for (size_type i=0; i<size(); i++)
00407         (*this)[i] -= y[i];
00408       return asImp();
00409     }
00410 
00412     derived_type operator+ (const DenseVector& b) const
00413     {
00414       derived_type z = asImp();
00415       return (z+=b);
00416     }
00417 
00419     derived_type operator- (const DenseVector& b) const
00420     {
00421       derived_type z = asImp();
00422       return (z-=b);
00423     }
00424 
00426     derived_type& operator+= (const value_type& k)
00427     {
00428       for (size_type i=0; i<size(); i++)
00429         (*this)[i] += k;
00430       return asImp();
00431     }
00432 
00434     derived_type& operator-= (const value_type& k)
00435     {
00436       for (size_type i=0; i<size(); i++)
00437         (*this)[i] -= k;
00438       return asImp();
00439     }
00440 
00442     derived_type& operator*= (const value_type& k)
00443     {
00444       for (size_type i=0; i<size(); i++)
00445         (*this)[i] *= k;
00446       return asImp();
00447     }
00448 
00450     derived_type& operator/= (const value_type& k)
00451     {
00452       for (size_type i=0; i<size(); i++)
00453         (*this)[i] /= k;
00454       return asImp();
00455     }
00456 
00458     bool operator== (const DenseVector& y) const
00459     {
00460       assert(y.size() == size());
00461       for (size_type i=0; i<size(); i++)
00462         if ((*this)[i]!=y[i])
00463           return false;
00464 
00465       return true;
00466     }
00467 
00469     bool operator!= (const DenseVector& y) const
00470     {
00471       return !operator==(y);
00472     }
00473     
00474 
00476     derived_type& axpy (const value_type& a, const DenseVector& y)
00477     {
00478       assert(y.size() == size());
00479       for (size_type i=0; i<size(); i++)
00480         (*this)[i] += a*y[i];
00481       return asImp();
00482     }
00483 
00484     //===== Euclidean scalar product
00485 
00487     value_type operator* (const DenseVector& y) const
00488     {
00489       assert(y.size() == size());
00490       value_type result( 0 );
00491       for (size_type i=0; i<size(); i++)
00492         result += (*this)[i]*y[i];
00493       return result;
00494     }
00495 
00496     //===== norms
00497 
00499     typename FieldTraits<value_type>::real_type one_norm() const {
00500       typename FieldTraits<value_type>::real_type result( 0 );
00501       for (size_type i=0; i<size(); i++)
00502         result += std::abs((*this)[i]);
00503       return result;
00504     }
00505 
00506 
00508     typename FieldTraits<value_type>::real_type one_norm_real () const
00509     {
00510       typename FieldTraits<value_type>::real_type result( 0 );
00511       for (size_type i=0; i<size(); i++)
00512         result += fvmeta::absreal((*this)[i]);
00513       return result;
00514     }
00515 
00517     typename FieldTraits<value_type>::real_type two_norm () const
00518     {
00519       typename FieldTraits<value_type>::real_type result( 0 );
00520       for (size_type i=0; i<size(); i++)
00521         result += fvmeta::abs2((*this)[i]);
00522       return fvmeta::sqrt(result);
00523     }
00524 
00526     typename FieldTraits<value_type>::real_type two_norm2 () const
00527     {
00528       typename FieldTraits<value_type>::real_type result( 0 );
00529       for (size_type i=0; i<size(); i++)
00530         result += fvmeta::abs2((*this)[i]);
00531       return result;
00532     }
00533 
00535     typename FieldTraits<value_type>::real_type infinity_norm () const
00536     {
00537       typename FieldTraits<value_type>::real_type result( 0 );
00538       for (size_type i=0; i<size(); i++)
00539         result = std::max(result, std::abs((*this)[i]));
00540       return result;
00541     }
00542 
00544     typename FieldTraits<value_type>::real_type infinity_norm_real () const
00545     {
00546       typename FieldTraits<value_type>::real_type result( 0 );
00547       for (size_type i=0; i<size(); i++)
00548         result = std::max(result, fvmeta::absreal((*this)[i]));
00549       return result;
00550     }
00551 
00552     //===== sizes
00553 
00555     size_type N () const
00556     {
00557       return size();
00558     }
00559 
00561     size_type dim () const
00562     {
00563       return size();
00564     }
00565 
00566   };
00567 
00576   template<typename V>
00577   std::ostream& operator<< (std::ostream& s, const DenseVector<V>& v)
00578   {
00579     for (typename DenseVector<V>::size_type i=0; i<v.size(); i++)
00580       s << ((i>0) ? " " : "") << v[i];
00581     return s;
00582   }
00583 
00586 } // end namespace
00587 
00588 #endif // DUNE_DENSEVECTOR_HH

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