bvector.hh

Go to the documentation of this file.
00001 #ifndef DUNE_BVECTOR_HH
00002 #define DUNE_BVECTOR_HH
00003 
00004 #include<math.h>
00005 #include<complex>
00006 
00007 #include "istlexception.hh"
00008 #include "allocator.hh"
00009 #include "basearray.hh"
00010 
00018 namespace Dune {
00019 
00020  
00032   template<class B, class A=ISTLAllocator>
00033   class block_vector_unmanaged : public base_array_unmanaged<B,A>
00034   {
00035   public:
00036 
00037         //===== type definitions and constants
00038 
00040         typedef typename B::field_type field_type;
00041 
00043         typedef B block_type;
00044 
00046         typedef A allocator_type;
00047 
00049     typedef typename A::size_type size_type;
00050     
00052         typedef typename base_array_unmanaged<B,A>::iterator Iterator;
00053 
00055         typedef typename base_array_unmanaged<B,A>::const_iterator ConstIterator;
00056 
00058         typedef B value_type;
00059 
00060         //===== assignment from scalar
00062 
00063         block_vector_unmanaged& operator= (const field_type& k)
00064         {
00065           for (size_type i=0; i<this->n; i++)
00066                 (*this)[i] = k;
00067           return *this;   
00068         }
00069 
00070         //===== vector space arithmetic
00072         block_vector_unmanaged& operator+= (const block_vector_unmanaged& y)
00073         {
00074 #ifdef DUNE_ISTL_WITH_CHECKING
00075           if (this->n!=y.N()) DUNE_THROW(ISTLError,"vector size mismatch");
00076 #endif
00077           for (size_type i=0; i<this->n; ++i) (*this)[i] += y[i];
00078           return *this;
00079         }
00080 
00082         block_vector_unmanaged& operator-= (const block_vector_unmanaged& y)
00083         {
00084 #ifdef DUNE_ISTL_WITH_CHECKING
00085           if (this->n!=y.N()) DUNE_THROW(ISTLError,"vector size mismatch");
00086 #endif
00087           for (size_type i=0; i<this->n; ++i) (*this)[i] -= y[i];
00088           return *this;
00089         }
00090 
00092         block_vector_unmanaged& operator*= (const field_type& k)
00093         {
00094           for (size_type i=0; i<this->n; ++i) (*this)[i] *= k;
00095           return *this;
00096         }
00097 
00099         block_vector_unmanaged& operator/= (const field_type& k)
00100         {
00101           for (int i=0; i<this->n; ++i) (*this)[i] /= k;
00102           return *this;
00103         }
00104 
00106         block_vector_unmanaged& axpy (const field_type& a, const block_vector_unmanaged& y)
00107         {
00108 #ifdef DUNE_ISTL_WITH_CHECKING
00109           if (this->n!=y.N()) DUNE_THROW(ISTLError,"vector size mismatch");
00110 #endif
00111           for (size_type i=0; i<this->n; ++i) (*this)[i].axpy(a,y[i]);
00112           return *this;
00113         }
00114 
00115 
00116         //===== Euclidean scalar product
00117 
00119     field_type operator* (const block_vector_unmanaged& y) const
00120         {
00121 #ifdef DUNE_ISTL_WITH_CHECKING
00122           if (this->n!=y.N()) DUNE_THROW(ISTLError,"vector size mismatch");
00123 #endif
00124           field_type sum=0;
00125           for (size_type i=0; i<this->n; ++i) sum += (*this)[i]*y[i];
00126           return sum;
00127         }
00128 
00129 
00130         //===== norms
00132     double one_norm () const
00133         {
00134           double sum=0;
00135           for (size_type i=0; i<this->n; ++i) sum += (*this)[i].one_norm();
00136           return sum;
00137         }
00138 
00140     double one_norm_real () const
00141         {
00142           double sum=0;
00143           for (size_type i=0; i<this->n; ++i) sum += (*this)[i].one_norm_real();
00144           return sum;
00145         }
00146 
00148     double two_norm () const
00149         {
00150           double sum=0;
00151           for (size_type i=0; i<this->n; ++i) sum += (*this)[i].two_norm2();
00152           return sqrt(sum);
00153         }
00154 
00156     double two_norm2 () const
00157         {
00158           double sum=0;
00159           for (size_type i=0; i<this->n; ++i) sum += (*this)[i].two_norm2();
00160           return sum;
00161         }
00162 
00164     double infinity_norm () const
00165         {
00166           double max=0;
00167           for (size_type i=0; i<this->n; ++i) max = std::max(max,(*this)[i].infinity_norm());
00168           return max;
00169         }
00170 
00172         double infinity_norm_real () const
00173         {
00174           double max=0;
00175           for (size_type i=0; i<this->n; ++i) max = std::max(max,(*this)[i].infinity_norm_real());
00176           return max;
00177         }
00178 
00179         //===== sizes
00180 
00182         size_type N () const
00183         {
00184           return this->n;
00185         }
00186 
00188         size_type dim () const
00189         {
00190           size_type d=0;
00191           for (size_type i=0; i<this->n; i++)
00192                 d += (*this)[i].dim();
00193           return d;
00194         }
00195 
00196   protected:
00198         block_vector_unmanaged () : base_array_unmanaged<B,A>()
00199         {       }
00200   };
00201    
00217   template<class B, class A=ISTLAllocator>
00218   class BlockVector : public block_vector_unmanaged<B,A>
00219   {
00220   public:
00221 
00222         //===== type definitions and constants
00223 
00225         typedef typename B::field_type field_type;
00226 
00228         typedef B block_type;
00229 
00231         typedef A allocator_type;
00232 
00234     typedef typename A::size_type size_type;
00235     
00237         enum {
00239           blocklevel = B::blocklevel+1};
00240 
00242         typedef typename block_vector_unmanaged<B,A>::Iterator Iterator;
00243 
00245         typedef typename block_vector_unmanaged<B,A>::ConstIterator ConstIterator;
00246 
00247         //===== constructors and such
00248 
00250     BlockVector () : block_vector_unmanaged<B,A>(),
00251                      capacity_(0)
00252         {
00253           this->n = 0;
00254         }
00255 
00257         BlockVector (size_type _n)
00258         {
00259           this->n = _n;
00260           capacity_ = _n;
00261           if (capacity_>0) 
00262                 this->p = A::template malloc<B>(capacity_);
00263           else
00264                 {
00265                   this->p = 0;
00266                   this->n = 0;
00267                   capacity_ = 0;
00268                 }
00269         }
00270 
00271     BlockVector (size_type _n, size_type capacity)
00272     {
00273           this->n = _n;
00274           if(this->n > capacity)
00275             capacity_ = _n;
00276           else
00277             capacity_ = capacity;
00278           
00279           if (capacity_>0) 
00280                 this->p = A::template malloc<B>(capacity_);
00281           else
00282                 {
00283                   this->p = 0;
00284                   this->n = 0;
00285                   capacity_ = 0;
00286                 }
00287     }
00288     
00289 
00306     void reserve(size_type capacity, bool copyOldValues=true)
00307     {
00308       if(capacity >= block_vector_unmanaged<B,A>::N() && capacity != capacity_){
00309           // save the old data
00310           B* pold = this->p;
00311 
00312         if(capacity>0){
00313           // create new array with capacity
00314           this->p = A::template malloc<B>(capacity);
00315           
00316           if(copyOldValues){
00317             // copy the old values
00318             B* to = this->p;
00319             B* from = pold;
00320         
00321             for(size_type i=0; i < block_vector_unmanaged<B,A>::N(); ++i, ++from, ++to)
00322               *to = *from;
00323 
00324         if(capacity_ > 0)
00325           // free old data
00326           A::template free<B>(pold);
00327           }
00328         }else{
00329           if(capacity_ > 0)
00330           // free old data
00331           this->p = 0;
00332           capacity_ = 0;
00333         }
00334         
00335         capacity_ = capacity;
00336       }
00337     }
00338     
00345     size_type capacity() const
00346     {
00347       return capacity_;
00348     }
00349         
00364     void resize(size_type size, bool copyOldValues=true)
00365     {
00366       if(size > block_vector_unmanaged<B,A>::N())
00367         if(capacity_ < size)
00368           this->reserve(size, copyOldValues);
00369 
00370       if(size >=0)
00371         this->n=size;
00372     }
00373     
00375         BlockVector (const BlockVector& a) :
00376       block_vector_unmanaged<B,A>(a)
00377         {
00378           // allocate memory with same size as a
00379           this->n = a.n;
00380           capacity_ = a.capacity_;
00381 
00382           if (capacity_>0) 
00383                 this->p = A::template malloc<B>(capacity_);
00384           else
00385                 {
00386                   this->n = 0;
00387                   this->p = 0;
00388                 }
00389 
00390           // and copy elements
00391           for (size_type i=0; i<this->n; i++) this->p[i]=a.p[i];
00392         }
00393 
00395         BlockVector (const block_vector_unmanaged<B,A>& _a) 
00396         {
00397           // upcast, because protected data inaccessible
00398           const BlockVector& a = static_cast<const BlockVector&>(_a);
00399 
00400           // allocate memory with same size as a
00401           this->n = a.n;
00402           capacity_ = a.capacity_;
00403 
00404           if (capacity_>0) 
00405                 this->p = A::template malloc<B>(capacity_);
00406           else
00407                 {
00408                   this->n = 0;
00409                   this->p = 0;
00410                   capacity_ = 0;
00411                 }
00412 
00413           // and copy elements
00414           for (size_type i=0; i<this->n; i++) this->p[i]=a.p[i];
00415         }
00416 
00418         ~BlockVector () 
00419         { 
00420           if (capacity_>0) A::template free<B>(this->p); 
00421         }
00422 
00424         BlockVector& operator= (const BlockVector& a)
00425         {
00426           if (&a!=this) // check if this and a are different objects
00427                 {
00428                   // adjust size of vector
00429                   if (capacity_!=a.capacity_) // check if size is different
00430                         {
00431                           if (capacity_>0) A::template free<B>(this->p); // delete old memory
00432                           capacity_ = a.capacity_;
00433                           if (capacity_>0) 
00434                                 this->p = A::template malloc<B>(capacity_);
00435                           else
00436                                 {
00437                                   this->p = 0;
00438                                   capacity_ = 0;
00439                                 }
00440                         }
00441                   this->n = a.n;
00442                   // copy data
00443                   for (size_type i=0; i<this->n; i++) 
00444                     this->p[i]=a.p[i];
00445                 }
00446           return *this;
00447         }
00448 
00450         BlockVector& operator= (const block_vector_unmanaged<B,A>& a)
00451         {
00452           // forward to regular assignement operator
00453           return this->operator=(static_cast<const BlockVector&>(a));
00454         }
00455     
00457         BlockVector& operator= (const field_type& k)
00458         {
00459           // forward to operator= in base class
00460           (static_cast<block_vector_unmanaged<B,A>&>(*this)) = k;
00461           return *this;   
00462         }
00463   protected:
00464     size_type capacity_;
00465   };
00466 
00468 
00469     template<class K, class A>
00470     std::ostream& operator<< (std::ostream& s, const BlockVector<K, A>& v)
00471   {
00472     typedef typename  BlockVector<K, A>::size_type size_type;
00473     
00474       for (size_type i=0; i<v.size(); i++)
00475           s << v[i] << std::endl;
00476 
00477       return s;
00478   }
00479 
00496   template<class B, class A=ISTLAllocator>
00497   class BlockVectorWindow : public block_vector_unmanaged<B,A>
00498   {
00499   public:
00500 
00501         //===== type definitions and constants
00502 
00504         typedef typename B::field_type field_type;
00505 
00507         typedef B block_type;
00508 
00510         typedef A allocator_type;
00511 
00513     typedef typename A::size_type size_type;
00514     
00516         enum {
00518           blocklevel = B::blocklevel+1
00519         };
00520 
00522         typedef typename block_vector_unmanaged<B,A>::Iterator Iterator;
00523 
00525         typedef typename block_vector_unmanaged<B,A>::ConstIterator ConstIterator;
00526 
00527 
00528         //===== constructors and such
00530         BlockVectorWindow () : block_vector_unmanaged<B,A>()
00531         {       }
00532 
00534         BlockVectorWindow (B* _p, size_type _n)
00535         {
00536           this->n = _n;
00537           this->p = _p;
00538         }
00539 
00541         BlockVectorWindow (const BlockVectorWindow& a)
00542         {
00543           this->n = a.n;
00544           this->p = a.p;
00545         }
00546 
00548         BlockVectorWindow (const block_vector_unmanaged<B,A>& _a) 
00549         {
00550           // cast needed to access protected data
00551           const BlockVectorWindow& a = static_cast<const BlockVectorWindow&>(_a);
00552 
00553           // make me point to the other's data
00554           this->n = a.n;
00555           this->p = a.p;
00556         }
00557 
00558 
00560         BlockVectorWindow& operator= (const BlockVectorWindow& a)
00561         {
00562           // check correct size
00563 #ifdef DUNE_ISTL_WITH_CHECKING
00564           if (this->n!=a.N()) DUNE_THROW(ISTLError,"vector size mismatch");
00565 #endif
00566 
00567           if (&a!=this) // check if this and a are different objects
00568                 {
00569                   // copy data
00570                   for (size_type i=0; i<this->n; i++) this->p[i]=a.p[i];
00571                 }
00572           return *this;
00573         }
00574 
00576         BlockVectorWindow& operator= (const block_vector_unmanaged<B,A>& a)
00577         {
00578           // forward to regular assignment operator
00579           return this->operator=(static_cast<const BlockVectorWindow&>(a));
00580         }
00581 
00583         BlockVectorWindow& operator= (const field_type& k)
00584         {
00585           (static_cast<block_vector_unmanaged<B,A>&>(*this)) = k;
00586           return *this;   
00587         }
00588 
00589 
00590         //===== window manipulation methods
00591 
00593         void set (size_type _n, B* _p)
00594         {
00595           this->n = _n;
00596           this->p = _p;
00597         }
00598 
00600         void setsize (size_type _n)
00601         {
00602           this->n = _n;
00603         }
00604 
00606         void setptr (B* _p)
00607         {
00608           this->p = _p;
00609         }
00610 
00612         B* getptr ()
00613         {
00614           return this->p;
00615         }
00616 
00618         size_type getsize ()
00619         {
00620           return this->n;
00621         }
00622   };
00623 
00624 
00625 
00634   template<class B, class A=ISTLAllocator>
00635   class compressed_block_vector_unmanaged : public compressed_base_array_unmanaged<B,A>
00636   {
00637   public:
00638 
00639         //===== type definitions and constants
00640 
00642         typedef typename B::field_type field_type;
00643 
00645         typedef B block_type;
00646 
00648         typedef A allocator_type;
00649 
00651         typedef typename compressed_base_array_unmanaged<B,A>::iterator Iterator;
00652 
00654         typedef typename compressed_base_array_unmanaged<B,A>::const_iterator ConstIterator;
00655 
00657     typedef typename A::size_type size_type;
00658     
00659         //===== assignment from scalar
00660 
00661         compressed_block_vector_unmanaged& operator= (const field_type& k)
00662         {
00663           for (size_type i=0; i<this->n; i++)
00664                 (this->p)[i] = k;
00665           return *this;   
00666         }
00667 
00668 
00669         //===== vector space arithmetic
00670 
00672         template<class V>
00673         compressed_block_vector_unmanaged& operator+= (const V& y)
00674         {
00675 #ifdef DUNE_ISTL_WITH_CHECKING
00676           if (!includesindexset(y)) DUNE_THROW(ISTLError,"index set mismatch");
00677 #endif
00678           for (size_type i=0; i<y.n; ++i) this->operator[](y.j[i]) += y.p[i];
00679           return *this;
00680         }
00681 
00683         template<class V>
00684         compressed_block_vector_unmanaged& operator-= (const V& y)
00685         {
00686 #ifdef DUNE_ISTL_WITH_CHECKING
00687           if (!includesindexset(y)) DUNE_THROW(ISTLError,"index set mismatch");
00688 #endif
00689           for (size_type i=0; i<y.n; ++i) this->operator[](y.j[i]) -= y.p[i];
00690           return *this;
00691         }
00692 
00694         template<class V>
00695         compressed_block_vector_unmanaged& axpy (const field_type& a, const V& y)
00696         {
00697 #ifdef DUNE_ISTL_WITH_CHECKING
00698           if (!includesindexset(y)) DUNE_THROW(ISTLError,"index set mismatch");
00699 #endif
00700           for (size_type i=0; i<y.n; ++i) (this->operator[](y.j[i])).axpy(a,y.p[i]);
00701           return *this;
00702         }
00703 
00705         compressed_block_vector_unmanaged& operator*= (const field_type& k)
00706         {
00707           for (size_type i=0; i<this->n; ++i) (this->p)[i] *= k;
00708           return *this;
00709         }
00710 
00712         compressed_block_vector_unmanaged& operator/= (const field_type& k)
00713         {
00714           for (size_type i=0; i<this->n; ++i) (this->p)[i] /= k;
00715           return *this;
00716         }
00717 
00718 
00719         //===== Euclidean scalar product
00720 
00722     field_type operator* (const compressed_block_vector_unmanaged& y) const
00723         {
00724 #ifdef DUNE_ISTL_WITH_CHECKING
00725           if (!includesindexset(y) || !y.includesindexset(*this) )
00726             DUNE_THROW(ISTLError,"index set mismatch");
00727 #endif
00728           field_type sum=0;
00729           for (size_type i=0; i<this->n; ++i) 
00730                 sum += (this->p)[i] * y[(this->j)[i]];
00731           return sum;
00732         }
00733 
00734 
00735         //===== norms
00736 
00738     double one_norm () const
00739         {
00740           double sum=0;
00741           for (size_type i=0; i<this->n; ++i) sum += (this->p)[i].one_norm();
00742           return sum;
00743         }
00744 
00746     double one_norm_real () const
00747         {
00748           double sum=0;
00749           for (size_type i=0; i<this->n; ++i) sum += (this->p)[i].one_norm_real();
00750           return sum;
00751         }
00752 
00754     double two_norm () const
00755         {
00756           double sum=0;
00757           for (size_type i=0; i<this->n; ++i) sum += (this->p)[i].two_norm2();
00758           return sqrt(sum);
00759         }
00760 
00762     double two_norm2 () const
00763         {
00764           double sum=0;
00765           for (size_type i=0; i<this->n; ++i) sum += (this->p)[i].two_norm2();
00766           return sum;
00767         }
00768 
00770     double infinity_norm () const
00771         {
00772           double max=0;
00773           for (size_type i=0; i<this->n; ++i) max = std::max(max,(this->p)[i].infinity_norm());
00774           return max;
00775         }
00776 
00778         double infinity_norm_real () const
00779         {
00780           double max=0;
00781           for (size_type i=0; i<this->n; ++i) max = std::max(max,(this->p)[i].infinity_norm_real());
00782           return max;
00783         }
00784 
00785 
00786         //===== sizes
00787 
00789         size_type N () const
00790         {
00791           return this->n;
00792         }
00793 
00795         size_type dim () const
00796         {
00797           size_type d=0;
00798           for (size_type i=0; i<this->n; i++)
00799                 d += (this->p)[i].dim();
00800           return d;
00801         }
00802 
00803   protected:
00805         compressed_block_vector_unmanaged () : compressed_base_array_unmanaged<B,A>()
00806         {       }
00807 
00809         template<class V>
00810         bool includesindexset (const V& y)
00811         {
00812           typename V::ConstIterator e=this->end();
00813           for (size_type i=0; i<y.n; i++)
00814                 if (find(y.j[i])==e)
00815                   return false;
00816           return true;
00817         }
00818   };
00819 
00820 
00837   template<class B, class A=ISTLAllocator>
00838   class CompressedBlockVectorWindow : public compressed_block_vector_unmanaged<B,A>
00839   {
00840   public:
00841 
00842         //===== type definitions and constants
00843 
00845         typedef typename B::field_type field_type;
00846 
00848         typedef B block_type;
00849 
00851         typedef A allocator_type;
00852 
00854     typedef typename A::size_type size_type;
00855     
00857         enum {
00859           blocklevel = B::blocklevel+1};
00860 
00862         typedef typename compressed_block_vector_unmanaged<B,A>::Iterator Iterator;
00863 
00865         typedef typename compressed_block_vector_unmanaged<B,A>::ConstIterator ConstIterator;
00866 
00867 
00868         //===== constructors and such
00870         CompressedBlockVectorWindow () : compressed_block_vector_unmanaged<B,A>()
00871         {       }
00872 
00874         CompressedBlockVectorWindow (B* _p, size_type* _j, size_type _n)
00875         {
00876           this->n = _n;
00877           this->p = _p;
00878           this->j = _j;
00879         }
00880 
00882         CompressedBlockVectorWindow (const CompressedBlockVectorWindow& a)
00883         {
00884           this->n = a.n;
00885           this->p = a.p;
00886           this->j = a.j;
00887         }
00888 
00890         CompressedBlockVectorWindow (const compressed_block_vector_unmanaged<B,A>& _a) 
00891         {
00892           // cast needed to access protected data (upcast)
00893           const CompressedBlockVectorWindow& a = static_cast<const CompressedBlockVectorWindow&>(_a);
00894 
00895           // make me point to the other's data
00896           this->n = a.n;
00897           this->p = a.p;
00898           this->j = a.j;
00899         }
00900 
00901 
00903         CompressedBlockVectorWindow& operator= (const CompressedBlockVectorWindow& a)
00904         {
00905           // check correct size
00906 #ifdef DUNE_ISTL_WITH_CHECKING
00907           if (this->n!=a.N()) DUNE_THROW(ISTLError,"vector size mismatch");
00908 #endif
00909 
00910           if (&a!=this) // check if this and a are different objects
00911                 {
00912                   // copy data
00913                   for (size_type i=0; i<this->n; i++) this->p[i]=a.p[i];
00914                   for (size_type i=0; i<this->n; i++) this->j[i]=a.j[i];
00915                 }
00916           return *this;
00917         }
00918 
00920         CompressedBlockVectorWindow& operator= (const compressed_block_vector_unmanaged<B,A>& a)
00921         {
00922           // forward to regular assignment operator
00923           return this->operator=(static_cast<const CompressedBlockVectorWindow&>(a));
00924         }
00925 
00927         CompressedBlockVectorWindow& operator= (const field_type& k)
00928         {
00929           (static_cast<compressed_block_vector_unmanaged<B,A>&>(*this)) = k;
00930           return *this;   
00931         }
00932 
00933 
00934         //===== window manipulation methods
00935 
00937         void set (size_type _n, B* _p, size_type* _j)
00938         {
00939           this->n = _n;
00940           this->p = _p;
00941           this->j = _j;
00942         }
00943 
00945         void setsize (size_type _n)
00946         {
00947           this->n = _n;
00948         }
00949 
00951         void setptr (B* _p)
00952         {
00953           this->p = _p;
00954         }
00955 
00957         void setindexptr (size_type* _j)
00958         {
00959           this->j = _j;
00960         }
00961 
00963         B* getptr ()
00964         {
00965           return this->p;
00966         }
00967 
00969         size_type* getindexptr ()
00970         {
00971           return this->j;
00972         }
00973 
00975         const B* getptr () const
00976         {
00977           return this->p;
00978         }
00979 
00981         const size_type* getindexptr () const
00982         {
00983           return this->j;
00984         }
00986         size_type getsize () const
00987         {
00988           return this->n;
00989         }
00990   };
00991 
00992 } // end namespace
00993 
00994 #endif

Generated on 12 Dec 2007 with Doxygen (ver 1.5.1)