bvector.hh

Go to the documentation of this file.
00001 #ifndef DUNE_BVECTOR_HH
00002 #define DUNE_BVECTOR_HH
00003 
00004 #include<cmath>
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 (size_type 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
00131 
00133     double one_norm () const
00134         {
00135           double sum=0;
00136           for (size_type i=0; i<this->n; ++i) sum += (*this)[i].one_norm();
00137           return sum;
00138         }
00139 
00141     double one_norm_real () const
00142         {
00143           double sum=0;
00144           for (size_type i=0; i<this->n; ++i) sum += (*this)[i].one_norm_real();
00145           return sum;
00146         }
00147 
00149     double two_norm () const
00150         {
00151           double sum=0;
00152           for (size_type i=0; i<this->n; ++i) sum += (*this)[i].two_norm2();
00153           return sqrt(sum);
00154         }
00155 
00157     double two_norm2 () const
00158         {
00159           double sum=0;
00160           for (size_type i=0; i<this->n; ++i) sum += (*this)[i].two_norm2();
00161           return sum;
00162         }
00163 
00165     double infinity_norm () const
00166         {
00167           double max=0;
00168           for (size_type i=0; i<this->n; ++i) max = std::max(max,(*this)[i].infinity_norm());
00169           return max;
00170         }
00171 
00173         double infinity_norm_real () const
00174         {
00175           double max=0;
00176           for (size_type i=0; i<this->n; ++i) max = std::max(max,(*this)[i].infinity_norm_real());
00177           return max;
00178         }
00179 
00180         //===== sizes
00181 
00183         size_type N () const
00184         {
00185           return this->n;
00186         }
00187 
00189         size_type dim () const
00190         {
00191           size_type d=0;
00192           for (size_type i=0; i<this->n; i++)
00193                 d += (*this)[i].dim();
00194           return d;
00195         }
00196 
00197   protected:
00199         block_vector_unmanaged () : base_array_unmanaged<B,A>()
00200         {       }
00201   };
00202    
00218   template<class B, class A=ISTLAllocator>
00219   class BlockVector : public block_vector_unmanaged<B,A>
00220   {
00221   public:
00222 
00223         //===== type definitions and constants
00224 
00226         typedef typename B::field_type field_type;
00227 
00229         typedef B block_type;
00230 
00232         typedef A allocator_type;
00233 
00235     typedef typename A::size_type size_type;
00236     
00238         enum {
00240           blocklevel = B::blocklevel+1};
00241 
00243         typedef typename block_vector_unmanaged<B,A>::Iterator Iterator;
00244 
00246         typedef typename block_vector_unmanaged<B,A>::ConstIterator ConstIterator;
00247 
00248         //===== constructors and such
00249 
00251     BlockVector () : block_vector_unmanaged<B,A>(),
00252                      capacity_(0)
00253         {
00254           this->n = 0;
00255         }
00256 
00258         explicit BlockVector (size_type _n)
00259         {
00260           this->n = _n;
00261           capacity_ = _n;
00262           if (capacity_>0) 
00263                 this->p = A::template malloc<B>(capacity_);
00264           else
00265                 {
00266                   this->p = 0;
00267                   this->n = 0;
00268                   capacity_ = 0;
00269                 }
00270         }
00271 
00283     BlockVector (size_type _n, size_type capacity)
00284     {
00285           this->n = _n;
00286           if(this->n > capacity)
00287             capacity_ = _n;
00288           else
00289             capacity_ = capacity;
00290           
00291           if (capacity_>0) 
00292                 this->p = A::template malloc<B>(capacity_);
00293           else
00294                 {
00295                   this->p = 0;
00296                   this->n = 0;
00297                   capacity_ = 0;
00298                 }
00299     }
00300     
00301 
00318     void reserve(size_type capacity, bool copyOldValues=true)
00319     {
00320       if(capacity >= block_vector_unmanaged<B,A>::N() && capacity != capacity_){
00321           // save the old data
00322           B* pold = this->p;
00323 
00324         if(capacity>0){
00325           // create new array with capacity
00326           this->p = A::template malloc<B>(capacity);
00327           
00328           if(copyOldValues){
00329             // copy the old values
00330             B* to = this->p;
00331             B* from = pold;
00332         
00333             for(size_type i=0; i < block_vector_unmanaged<B,A>::N(); ++i, ++from, ++to)
00334               *to = *from;
00335 
00336         if(capacity_ > 0)
00337           // free old data
00338           A::template free<B>(pold);
00339           }
00340         }else{
00341           if(capacity_ > 0)
00342           // free old data
00343           this->p = 0;
00344           capacity_ = 0;
00345         }
00346         
00347         capacity_ = capacity;
00348       }
00349     }
00350     
00357     size_type capacity() const
00358     {
00359       return capacity_;
00360     }
00361         
00376     void resize(size_type size, bool copyOldValues=true)
00377     {
00378       if(size > block_vector_unmanaged<B,A>::N())
00379         if(capacity_ < size)
00380           this->reserve(size, copyOldValues);
00381 
00382       if(size >=0)
00383         this->n=size;
00384     }
00385     
00386       
00387     
00388       
00390       BlockVector (const BlockVector& a) :
00391       block_vector_unmanaged<B,A>(a)
00392         {
00393           // allocate memory with same size as a
00394           this->n = a.n;
00395           capacity_ = a.capacity_;
00396 
00397           if (capacity_>0) 
00398                 this->p = A::template malloc<B>(capacity_);
00399           else
00400                 {
00401                   this->n = 0;
00402                   this->p = 0;
00403                 }
00404 
00405           // and copy elements
00406           for (size_type i=0; i<this->n; i++) this->p[i]=a.p[i];
00407         }
00408 
00410         BlockVector (const block_vector_unmanaged<B,A>& _a) 
00411         {
00412           // upcast, because protected data inaccessible
00413           const BlockVector& a = static_cast<const BlockVector&>(_a);
00414 
00415           // allocate memory with same size as a
00416           this->n = a.n;
00417           capacity_ = a.capacity_;
00418 
00419           if (capacity_>0) 
00420                 this->p = A::template malloc<B>(capacity_);
00421           else
00422                 {
00423                   this->n = 0;
00424                   this->p = 0;
00425                   capacity_ = 0;
00426                 }
00427 
00428           // and copy elements
00429           for (size_type i=0; i<this->n; i++) this->p[i]=a.p[i];
00430         }
00431 
00433         ~BlockVector () 
00434         { 
00435           if (capacity_>0) A::template free<B>(this->p); 
00436         }
00437 
00439         BlockVector& operator= (const BlockVector& a)
00440         {
00441           if (&a!=this) // check if this and a are different objects
00442                 {
00443                   // adjust size of vector
00444                   if (capacity_!=a.capacity_) // check if size is different
00445                         {
00446                           if (capacity_>0) A::template free<B>(this->p); // delete old memory
00447                           capacity_ = a.capacity_;
00448                           if (capacity_>0) 
00449                                 this->p = A::template malloc<B>(capacity_);
00450                           else
00451                                 {
00452                                   this->p = 0;
00453                                   capacity_ = 0;
00454                                 }
00455                         }
00456                   this->n = a.n;
00457                   // copy data
00458                   for (size_type i=0; i<this->n; i++) 
00459                     this->p[i]=a.p[i];
00460                 }
00461           return *this;
00462         }
00463 
00465         BlockVector& operator= (const block_vector_unmanaged<B,A>& a)
00466         {
00467           // forward to regular assignement operator
00468           return this->operator=(static_cast<const BlockVector&>(a));
00469         }
00470     
00472         BlockVector& operator= (const field_type& k)
00473         {
00474           // forward to operator= in base class
00475           (static_cast<block_vector_unmanaged<B,A>&>(*this)) = k;
00476           return *this;   
00477         }
00478   protected:
00479     size_type capacity_;
00480   };
00481 
00483 
00484     template<class K, class A>
00485     std::ostream& operator<< (std::ostream& s, const BlockVector<K, A>& v)
00486   {
00487     typedef typename  BlockVector<K, A>::size_type size_type;
00488     
00489       for (size_type i=0; i<v.size(); i++)
00490           s << v[i] << std::endl;
00491 
00492       return s;
00493   }
00494 
00511   template<class B, class A=ISTLAllocator>
00512   class BlockVectorWindow : public block_vector_unmanaged<B,A>
00513   {
00514   public:
00515 
00516         //===== type definitions and constants
00517 
00519         typedef typename B::field_type field_type;
00520 
00522         typedef B block_type;
00523 
00525         typedef A allocator_type;
00526 
00528     typedef typename A::size_type size_type;
00529     
00531         enum {
00533           blocklevel = B::blocklevel+1
00534         };
00535 
00537         typedef typename block_vector_unmanaged<B,A>::Iterator Iterator;
00538 
00540         typedef typename block_vector_unmanaged<B,A>::ConstIterator ConstIterator;
00541 
00542 
00543         //===== constructors and such
00545         BlockVectorWindow () : block_vector_unmanaged<B,A>()
00546         {       }
00547 
00549         BlockVectorWindow (B* _p, size_type _n)
00550         {
00551           this->n = _n;
00552           this->p = _p;
00553         }
00554 
00556         BlockVectorWindow (const BlockVectorWindow& a)
00557         {
00558           this->n = a.n;
00559           this->p = a.p;
00560         }
00561 
00563         BlockVectorWindow (const block_vector_unmanaged<B,A>& _a) 
00564         {
00565           // cast needed to access protected data
00566           const BlockVectorWindow& a = static_cast<const BlockVectorWindow&>(_a);
00567 
00568           // make me point to the other's data
00569           this->n = a.n;
00570           this->p = a.p;
00571         }
00572 
00573 
00575         BlockVectorWindow& operator= (const BlockVectorWindow& a)
00576         {
00577           // check correct size
00578 #ifdef DUNE_ISTL_WITH_CHECKING
00579           if (this->n!=a.N()) DUNE_THROW(ISTLError,"vector size mismatch");
00580 #endif
00581 
00582           if (&a!=this) // check if this and a are different objects
00583                 {
00584                   // copy data
00585                   for (size_type i=0; i<this->n; i++) this->p[i]=a.p[i];
00586                 }
00587           return *this;
00588         }
00589 
00591         BlockVectorWindow& operator= (const block_vector_unmanaged<B,A>& a)
00592         {
00593           // forward to regular assignment operator
00594           return this->operator=(static_cast<const BlockVectorWindow&>(a));
00595         }
00596 
00598         BlockVectorWindow& operator= (const field_type& k)
00599         {
00600           (static_cast<block_vector_unmanaged<B,A>&>(*this)) = k;
00601           return *this;   
00602         }
00603 
00604 
00605         //===== window manipulation methods
00606 
00608         void set (size_type _n, B* _p)
00609         {
00610           this->n = _n;
00611           this->p = _p;
00612         }
00613 
00615         void setsize (size_type _n)
00616         {
00617           this->n = _n;
00618         }
00619 
00621         void setptr (B* _p)
00622         {
00623           this->p = _p;
00624         }
00625 
00627         B* getptr ()
00628         {
00629           return this->p;
00630         }
00631 
00633         size_type getsize ()
00634         {
00635           return this->n;
00636         }
00637   };
00638 
00639 
00640 
00649   template<class B, class A=ISTLAllocator>
00650   class compressed_block_vector_unmanaged : public compressed_base_array_unmanaged<B,A>
00651   {
00652   public:
00653 
00654         //===== type definitions and constants
00655 
00657         typedef typename B::field_type field_type;
00658 
00660         typedef B block_type;
00661 
00663         typedef A allocator_type;
00664 
00666         typedef typename compressed_base_array_unmanaged<B,A>::iterator Iterator;
00667 
00669         typedef typename compressed_base_array_unmanaged<B,A>::const_iterator ConstIterator;
00670 
00672     typedef typename A::size_type size_type;
00673     
00674         //===== assignment from scalar
00675 
00676         compressed_block_vector_unmanaged& operator= (const field_type& k)
00677         {
00678           for (size_type i=0; i<this->n; i++)
00679                 (this->p)[i] = k;
00680           return *this;   
00681         }
00682 
00683 
00684         //===== vector space arithmetic
00685 
00687         template<class V>
00688         compressed_block_vector_unmanaged& operator+= (const V& y)
00689         {
00690 #ifdef DUNE_ISTL_WITH_CHECKING
00691           if (!includesindexset(y)) DUNE_THROW(ISTLError,"index set mismatch");
00692 #endif
00693           for (size_type i=0; i<y.n; ++i) this->operator[](y.j[i]) += y.p[i];
00694           return *this;
00695         }
00696 
00698         template<class V>
00699         compressed_block_vector_unmanaged& operator-= (const V& y)
00700         {
00701 #ifdef DUNE_ISTL_WITH_CHECKING
00702           if (!includesindexset(y)) DUNE_THROW(ISTLError,"index set mismatch");
00703 #endif
00704           for (size_type i=0; i<y.n; ++i) this->operator[](y.j[i]) -= y.p[i];
00705           return *this;
00706         }
00707 
00709         template<class V>
00710         compressed_block_vector_unmanaged& axpy (const field_type& a, const V& y)
00711         {
00712 #ifdef DUNE_ISTL_WITH_CHECKING
00713           if (!includesindexset(y)) DUNE_THROW(ISTLError,"index set mismatch");
00714 #endif
00715           for (size_type i=0; i<y.n; ++i) (this->operator[](y.j[i])).axpy(a,y.p[i]);
00716           return *this;
00717         }
00718 
00720         compressed_block_vector_unmanaged& operator*= (const field_type& k)
00721         {
00722           for (size_type i=0; i<this->n; ++i) (this->p)[i] *= k;
00723           return *this;
00724         }
00725 
00727         compressed_block_vector_unmanaged& operator/= (const field_type& k)
00728         {
00729           for (size_type i=0; i<this->n; ++i) (this->p)[i] /= k;
00730           return *this;
00731         }
00732 
00733 
00734         //===== Euclidean scalar product
00735 
00737     field_type operator* (const compressed_block_vector_unmanaged& y) const
00738         {
00739 #ifdef DUNE_ISTL_WITH_CHECKING
00740           if (!includesindexset(y) || !y.includesindexset(*this) )
00741             DUNE_THROW(ISTLError,"index set mismatch");
00742 #endif
00743           field_type sum=0;
00744           for (size_type i=0; i<this->n; ++i) 
00745                 sum += (this->p)[i] * y[(this->j)[i]];
00746           return sum;
00747         }
00748 
00749 
00750         //===== norms
00751 
00753     double one_norm () const
00754         {
00755           double sum=0;
00756           for (size_type i=0; i<this->n; ++i) sum += (this->p)[i].one_norm();
00757           return sum;
00758         }
00759 
00761     double one_norm_real () const
00762         {
00763           double sum=0;
00764           for (size_type i=0; i<this->n; ++i) sum += (this->p)[i].one_norm_real();
00765           return sum;
00766         }
00767 
00769     double two_norm () const
00770         {
00771           double sum=0;
00772           for (size_type i=0; i<this->n; ++i) sum += (this->p)[i].two_norm2();
00773           return sqrt(sum);
00774         }
00775 
00777     double two_norm2 () const
00778         {
00779           double sum=0;
00780           for (size_type i=0; i<this->n; ++i) sum += (this->p)[i].two_norm2();
00781           return sum;
00782         }
00783 
00785     double infinity_norm () const
00786         {
00787           double max=0;
00788           for (size_type i=0; i<this->n; ++i) max = std::max(max,(this->p)[i].infinity_norm());
00789           return max;
00790         }
00791 
00793         double infinity_norm_real () const
00794         {
00795           double max=0;
00796           for (size_type i=0; i<this->n; ++i) max = std::max(max,(this->p)[i].infinity_norm_real());
00797           return max;
00798         }
00799 
00800 
00801         //===== sizes
00802 
00804         size_type N () const
00805         {
00806           return this->n;
00807         }
00808 
00810         size_type dim () const
00811         {
00812           size_type d=0;
00813           for (size_type i=0; i<this->n; i++)
00814                 d += (this->p)[i].dim();
00815           return d;
00816         }
00817 
00818   protected:
00820         compressed_block_vector_unmanaged () : compressed_base_array_unmanaged<B,A>()
00821         {       }
00822 
00824         template<class V>
00825         bool includesindexset (const V& y)
00826         {
00827           typename V::ConstIterator e=this->end();
00828           for (size_type i=0; i<y.n; i++)
00829                 if (find(y.j[i])==e)
00830                   return false;
00831           return true;
00832         }
00833   };
00834 
00835 
00852   template<class B, class A=ISTLAllocator>
00853   class CompressedBlockVectorWindow : public compressed_block_vector_unmanaged<B,A>
00854   {
00855   public:
00856 
00857         //===== type definitions and constants
00858 
00860         typedef typename B::field_type field_type;
00861 
00863         typedef B block_type;
00864 
00866         typedef A allocator_type;
00867 
00869     typedef typename A::size_type size_type;
00870     
00872         enum {
00874           blocklevel = B::blocklevel+1};
00875 
00877         typedef typename compressed_block_vector_unmanaged<B,A>::Iterator Iterator;
00878 
00880         typedef typename compressed_block_vector_unmanaged<B,A>::ConstIterator ConstIterator;
00881 
00882 
00883         //===== constructors and such
00885         CompressedBlockVectorWindow () : compressed_block_vector_unmanaged<B,A>()
00886         {       }
00887 
00889         CompressedBlockVectorWindow (B* _p, size_type* _j, size_type _n)
00890         {
00891           this->n = _n;
00892           this->p = _p;
00893           this->j = _j;
00894         }
00895 
00897         CompressedBlockVectorWindow (const CompressedBlockVectorWindow& a)
00898         {
00899           this->n = a.n;
00900           this->p = a.p;
00901           this->j = a.j;
00902         }
00903 
00905         CompressedBlockVectorWindow (const compressed_block_vector_unmanaged<B,A>& _a) 
00906         {
00907           // cast needed to access protected data (upcast)
00908           const CompressedBlockVectorWindow& a = static_cast<const CompressedBlockVectorWindow&>(_a);
00909 
00910           // make me point to the other's data
00911           this->n = a.n;
00912           this->p = a.p;
00913           this->j = a.j;
00914         }
00915 
00916 
00918         CompressedBlockVectorWindow& operator= (const CompressedBlockVectorWindow& a)
00919         {
00920           // check correct size
00921 #ifdef DUNE_ISTL_WITH_CHECKING
00922           if (this->n!=a.N()) DUNE_THROW(ISTLError,"vector size mismatch");
00923 #endif
00924 
00925           if (&a!=this) // check if this and a are different objects
00926                 {
00927                   // copy data
00928                   for (size_type i=0; i<this->n; i++) this->p[i]=a.p[i];
00929                   for (size_type i=0; i<this->n; i++) this->j[i]=a.j[i];
00930                 }
00931           return *this;
00932         }
00933 
00935         CompressedBlockVectorWindow& operator= (const compressed_block_vector_unmanaged<B,A>& a)
00936         {
00937           // forward to regular assignment operator
00938           return this->operator=(static_cast<const CompressedBlockVectorWindow&>(a));
00939         }
00940 
00942         CompressedBlockVectorWindow& operator= (const field_type& k)
00943         {
00944           (static_cast<compressed_block_vector_unmanaged<B,A>&>(*this)) = k;
00945           return *this;   
00946         }
00947 
00948 
00949         //===== window manipulation methods
00950 
00952         void set (size_type _n, B* _p, size_type* _j)
00953         {
00954           this->n = _n;
00955           this->p = _p;
00956           this->j = _j;
00957         }
00958 
00960         void setsize (size_type _n)
00961         {
00962           this->n = _n;
00963         }
00964 
00966         void setptr (B* _p)
00967         {
00968           this->p = _p;
00969         }
00970 
00972         void setindexptr (size_type* _j)
00973         {
00974           this->j = _j;
00975         }
00976 
00978         B* getptr ()
00979         {
00980           return this->p;
00981         }
00982 
00984         size_type* getindexptr ()
00985         {
00986           return this->j;
00987         }
00988 
00990         const B* getptr () const
00991         {
00992           return this->p;
00993         }
00994 
00996         const size_type* getindexptr () const
00997         {
00998           return this->j;
00999         }
01001         size_type getsize () const
01002         {
01003           return this->n;
01004         }
01005   };
01006 
01007 } // end namespace
01008 
01009 #endif
Generated on Sat Apr 24 11:13:45 2010 for dune-istl by  doxygen 1.6.3