- Home
- About DUNE
- Download
- Documentation
- Community
- Development
00001 // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- 00002 // vi: set et ts=4 sw=2 sts=2: 00003 00004 #ifndef DUNE_BVECTOR_HH 00005 #define DUNE_BVECTOR_HH 00006 00007 #include<cmath> 00008 #include<complex> 00009 #include<memory> 00010 00011 #include "istlexception.hh" 00012 #include "basearray.hh" 00013 00021 namespace Dune { 00022 00023 00035 template<class B, class A=std::allocator<B> > 00036 class block_vector_unmanaged : public base_array_unmanaged<B,A> 00037 { 00038 public: 00039 00040 //===== type definitions and constants 00041 00043 typedef typename B::field_type field_type; 00044 00046 typedef B block_type; 00047 00049 typedef A allocator_type; 00050 00052 typedef typename A::size_type size_type; 00053 00055 typedef typename base_array_unmanaged<B,A>::iterator Iterator; 00056 00058 typedef typename base_array_unmanaged<B,A>::const_iterator ConstIterator; 00059 00061 typedef B value_type; 00062 00063 //===== assignment from scalar 00065 00066 block_vector_unmanaged& operator= (const field_type& k) 00067 { 00068 for (size_type i=0; i<this->n; i++) 00069 (*this)[i] = k; 00070 return *this; 00071 } 00072 00073 //===== vector space arithmetic 00075 block_vector_unmanaged& operator+= (const block_vector_unmanaged& y) 00076 { 00077 #ifdef DUNE_ISTL_WITH_CHECKING 00078 if (this->n!=y.N()) DUNE_THROW(ISTLError,"vector size mismatch"); 00079 #endif 00080 for (size_type i=0; i<this->n; ++i) (*this)[i] += y[i]; 00081 return *this; 00082 } 00083 00085 block_vector_unmanaged& operator-= (const block_vector_unmanaged& y) 00086 { 00087 #ifdef DUNE_ISTL_WITH_CHECKING 00088 if (this->n!=y.N()) DUNE_THROW(ISTLError,"vector size mismatch"); 00089 #endif 00090 for (size_type i=0; i<this->n; ++i) (*this)[i] -= y[i]; 00091 return *this; 00092 } 00093 00095 block_vector_unmanaged& operator*= (const field_type& k) 00096 { 00097 for (size_type i=0; i<this->n; ++i) (*this)[i] *= k; 00098 return *this; 00099 } 00100 00102 block_vector_unmanaged& operator/= (const field_type& k) 00103 { 00104 for (size_type i=0; i<this->n; ++i) (*this)[i] /= k; 00105 return *this; 00106 } 00107 00109 block_vector_unmanaged& axpy (const field_type& a, const block_vector_unmanaged& y) 00110 { 00111 #ifdef DUNE_ISTL_WITH_CHECKING 00112 if (this->n!=y.N()) DUNE_THROW(ISTLError,"vector size mismatch"); 00113 #endif 00114 for (size_type i=0; i<this->n; ++i) (*this)[i].axpy(a,y[i]); 00115 return *this; 00116 } 00117 00118 00119 //===== Euclidean scalar product 00120 00122 field_type operator* (const block_vector_unmanaged& y) const 00123 { 00124 #ifdef DUNE_ISTL_WITH_CHECKING 00125 if (this->n!=y.N()) DUNE_THROW(ISTLError,"vector size mismatch"); 00126 #endif 00127 field_type sum=0; 00128 for (size_type i=0; i<this->n; ++i) sum += (*this)[i]*y[i]; 00129 return sum; 00130 } 00131 00132 00133 //===== norms 00134 00136 double one_norm () const 00137 { 00138 double sum=0; 00139 for (size_type i=0; i<this->n; ++i) sum += (*this)[i].one_norm(); 00140 return sum; 00141 } 00142 00144 double one_norm_real () const 00145 { 00146 double sum=0; 00147 for (size_type i=0; i<this->n; ++i) sum += (*this)[i].one_norm_real(); 00148 return sum; 00149 } 00150 00152 double two_norm () const 00153 { 00154 double sum=0; 00155 for (size_type i=0; i<this->n; ++i) sum += (*this)[i].two_norm2(); 00156 return sqrt(sum); 00157 } 00158 00160 double two_norm2 () const 00161 { 00162 double sum=0; 00163 for (size_type i=0; i<this->n; ++i) sum += (*this)[i].two_norm2(); 00164 return sum; 00165 } 00166 00168 double infinity_norm () const 00169 { 00170 double max=0; 00171 for (size_type i=0; i<this->n; ++i) max = std::max(max,(*this)[i].infinity_norm()); 00172 return max; 00173 } 00174 00176 double infinity_norm_real () const 00177 { 00178 double max=0; 00179 for (size_type i=0; i<this->n; ++i) max = std::max(max,(*this)[i].infinity_norm_real()); 00180 return max; 00181 } 00182 00183 //===== sizes 00184 00186 size_type N () const 00187 { 00188 return this->n; 00189 } 00190 00192 size_type dim () const 00193 { 00194 size_type d=0; 00195 for (size_type i=0; i<this->n; i++) 00196 d += (*this)[i].dim(); 00197 return d; 00198 } 00199 00200 protected: 00202 block_vector_unmanaged () : base_array_unmanaged<B,A>() 00203 { } 00204 }; 00205 00221 template<class B, class A=std::allocator<B> > 00222 class BlockVector : public block_vector_unmanaged<B,A> 00223 { 00224 public: 00225 00226 //===== type definitions and constants 00227 00229 typedef typename B::field_type field_type; 00230 00232 typedef B block_type; 00233 00235 typedef A allocator_type; 00236 00238 typedef typename A::size_type size_type; 00239 00241 enum { 00243 blocklevel = B::blocklevel+1}; 00244 00246 typedef typename block_vector_unmanaged<B,A>::Iterator Iterator; 00247 00249 typedef typename block_vector_unmanaged<B,A>::ConstIterator ConstIterator; 00250 00251 //===== constructors and such 00252 00254 BlockVector () : block_vector_unmanaged<B,A>(), 00255 capacity_(0) 00256 {} 00257 00259 explicit BlockVector (size_type _n) 00260 { 00261 this->n = _n; 00262 capacity_ = _n; 00263 if (capacity_>0) { 00264 this->p = this->allocator_.allocate(capacity_); 00265 // actually construct the objects 00266 new(this->p) B[capacity_]; 00267 } else 00268 { 00269 this->p = 0; 00270 this->n = 0; 00271 capacity_ = 0; 00272 } 00273 } 00274 00286 BlockVector (size_type _n, size_type capacity) 00287 { 00288 this->n = _n; 00289 if(this->n > capacity) 00290 capacity_ = _n; 00291 else 00292 capacity_ = capacity; 00293 00294 if (capacity_>0) { 00295 this->p = this->allocator_.allocate(capacity_); 00296 new (this->p) B[capacity_]; 00297 } else 00298 { 00299 this->p = 0; 00300 this->n = 0; 00301 capacity_ = 0; 00302 } 00303 } 00304 00305 00322 void reserve(size_type capacity, bool copyOldValues=true) 00323 { 00324 if(capacity >= block_vector_unmanaged<B,A>::N() && capacity != capacity_){ 00325 // save the old data 00326 B* pold = this->p; 00327 00328 if(capacity>0){ 00329 // create new array with capacity 00330 this->p = this->allocator_.allocate(capacity); 00331 new (this->p) B[capacity]; 00332 00333 if(copyOldValues){ 00334 // copy the old values 00335 B* to = this->p; 00336 B* from = pold; 00337 00338 for(size_type i=0; i < block_vector_unmanaged<B,A>::N(); ++i, ++from, ++to) 00339 *to = *from; 00340 00341 if(capacity_ > 0) { 00342 // Destruct old objects and free memory 00343 int i=capacity_; 00344 while (i) 00345 pold[--i].~B(); 00346 this->allocator_.deallocate(pold,capacity_); 00347 } 00348 } 00349 }else{ 00350 if(capacity_ > 0) 00351 // free old data 00352 this->p = 0; 00353 capacity_ = 0; 00354 } 00355 00356 capacity_ = capacity; 00357 } 00358 } 00359 00366 size_type capacity() const 00367 { 00368 return capacity_; 00369 } 00370 00385 void resize(size_type size, bool copyOldValues=true) 00386 { 00387 if(size > block_vector_unmanaged<B,A>::N()) 00388 if(capacity_ < size) 00389 this->reserve(size, copyOldValues); 00390 00391 if(size >=0) 00392 this->n=size; 00393 } 00394 00395 00396 00397 00399 BlockVector (const BlockVector& a) : 00400 block_vector_unmanaged<B,A>(a) 00401 { 00402 // allocate memory with same size as a 00403 this->n = a.n; 00404 capacity_ = a.capacity_; 00405 00406 if (capacity_>0) { 00407 this->p = this->allocator_.allocate(capacity_); 00408 new (this->p) B[capacity_]; 00409 } else 00410 { 00411 this->n = 0; 00412 this->p = 0; 00413 } 00414 00415 // and copy elements 00416 for (size_type i=0; i<this->n; i++) this->p[i]=a.p[i]; 00417 } 00418 00420 BlockVector (const block_vector_unmanaged<B,A>& _a) 00421 { 00422 // upcast, because protected data inaccessible 00423 const BlockVector& a = static_cast<const BlockVector&>(_a); 00424 00425 // allocate memory with same size as a 00426 this->n = a.n; 00427 capacity_ = a.capacity_; 00428 00429 if (capacity_>0) { 00430 this->p = this->allocator_.allocate(capacity_); 00431 new (this->p) B[capacity_]; 00432 } else 00433 { 00434 this->n = 0; 00435 this->p = 0; 00436 capacity_ = 0; 00437 } 00438 00439 // and copy elements 00440 for (size_type i=0; i<this->n; i++) this->p[i]=a.p[i]; 00441 } 00442 00444 ~BlockVector () 00445 { 00446 if (capacity_>0) { 00447 int i=capacity_; 00448 while (i) 00449 this->p[--i].~B(); 00450 this->allocator_.deallocate(this->p,capacity_); 00451 } 00452 } 00453 00455 BlockVector& operator= (const BlockVector& a) 00456 { 00457 if (&a!=this) // check if this and a are different objects 00458 { 00459 // adjust size of vector 00460 if (capacity_!=a.capacity_) // check if size is different 00461 { 00462 if (capacity_>0) { 00463 int i=capacity_; 00464 while (i) 00465 this->p[--i].~B(); 00466 this->allocator_.deallocate(this->p,capacity_); // free old memory 00467 } 00468 capacity_ = a.capacity_; 00469 if (capacity_>0) { 00470 this->p = this->allocator_.allocate(capacity_); 00471 new (this->p) B[capacity_]; 00472 } else 00473 { 00474 this->p = 0; 00475 capacity_ = 0; 00476 } 00477 } 00478 this->n = a.n; 00479 // copy data 00480 for (size_type i=0; i<this->n; i++) 00481 this->p[i]=a.p[i]; 00482 } 00483 return *this; 00484 } 00485 00487 BlockVector& operator= (const block_vector_unmanaged<B,A>& a) 00488 { 00489 // forward to regular assignement operator 00490 return this->operator=(static_cast<const BlockVector&>(a)); 00491 } 00492 00494 BlockVector& operator= (const field_type& k) 00495 { 00496 // forward to operator= in base class 00497 (static_cast<block_vector_unmanaged<B,A>&>(*this)) = k; 00498 return *this; 00499 } 00500 protected: 00501 size_type capacity_; 00502 00503 A allocator_; 00504 00505 }; 00506 00508 00509 template<class K, class A> 00510 std::ostream& operator<< (std::ostream& s, const BlockVector<K, A>& v) 00511 { 00512 typedef typename BlockVector<K, A>::size_type size_type; 00513 00514 for (size_type i=0; i<v.size(); i++) 00515 s << v[i] << std::endl; 00516 00517 return s; 00518 } 00519 00536 template<class B, class A=std::allocator<B> > 00537 class BlockVectorWindow : public block_vector_unmanaged<B,A> 00538 { 00539 public: 00540 00541 //===== type definitions and constants 00542 00544 typedef typename B::field_type field_type; 00545 00547 typedef B block_type; 00548 00550 typedef A allocator_type; 00551 00553 typedef typename A::size_type size_type; 00554 00556 enum { 00558 blocklevel = B::blocklevel+1 00559 }; 00560 00562 typedef typename block_vector_unmanaged<B,A>::Iterator Iterator; 00563 00565 typedef typename block_vector_unmanaged<B,A>::ConstIterator ConstIterator; 00566 00567 00568 //===== constructors and such 00570 BlockVectorWindow () : block_vector_unmanaged<B,A>() 00571 { } 00572 00574 BlockVectorWindow (B* _p, size_type _n) 00575 { 00576 this->n = _n; 00577 this->p = _p; 00578 } 00579 00581 BlockVectorWindow (const BlockVectorWindow& a) 00582 { 00583 this->n = a.n; 00584 this->p = a.p; 00585 } 00586 00588 BlockVectorWindow (const block_vector_unmanaged<B,A>& _a) 00589 { 00590 // cast needed to access protected data 00591 const BlockVectorWindow& a = static_cast<const BlockVectorWindow&>(_a); 00592 00593 // make me point to the other's data 00594 this->n = a.n; 00595 this->p = a.p; 00596 } 00597 00598 00600 BlockVectorWindow& operator= (const BlockVectorWindow& a) 00601 { 00602 // check correct size 00603 #ifdef DUNE_ISTL_WITH_CHECKING 00604 if (this->n!=a.N()) DUNE_THROW(ISTLError,"vector size mismatch"); 00605 #endif 00606 00607 if (&a!=this) // check if this and a are different objects 00608 { 00609 // copy data 00610 for (size_type i=0; i<this->n; i++) this->p[i]=a.p[i]; 00611 } 00612 return *this; 00613 } 00614 00616 BlockVectorWindow& operator= (const block_vector_unmanaged<B,A>& a) 00617 { 00618 // forward to regular assignment operator 00619 return this->operator=(static_cast<const BlockVectorWindow&>(a)); 00620 } 00621 00623 BlockVectorWindow& operator= (const field_type& k) 00624 { 00625 (static_cast<block_vector_unmanaged<B,A>&>(*this)) = k; 00626 return *this; 00627 } 00628 00629 00630 //===== window manipulation methods 00631 00633 void set (size_type _n, B* _p) 00634 { 00635 this->n = _n; 00636 this->p = _p; 00637 } 00638 00640 void setsize (size_type _n) 00641 { 00642 this->n = _n; 00643 } 00644 00646 void setptr (B* _p) 00647 { 00648 this->p = _p; 00649 } 00650 00652 B* getptr () 00653 { 00654 return this->p; 00655 } 00656 00658 size_type getsize () 00659 { 00660 return this->n; 00661 } 00662 }; 00663 00664 00665 00674 template<class B, class A=std::allocator<B> > 00675 class compressed_block_vector_unmanaged : public compressed_base_array_unmanaged<B,A> 00676 { 00677 public: 00678 00679 //===== type definitions and constants 00680 00682 typedef typename B::field_type field_type; 00683 00685 typedef B block_type; 00686 00688 typedef A allocator_type; 00689 00691 typedef typename compressed_base_array_unmanaged<B,A>::iterator Iterator; 00692 00694 typedef typename compressed_base_array_unmanaged<B,A>::const_iterator ConstIterator; 00695 00697 typedef typename A::size_type size_type; 00698 00699 //===== assignment from scalar 00700 00701 compressed_block_vector_unmanaged& operator= (const field_type& k) 00702 { 00703 for (size_type i=0; i<this->n; i++) 00704 (this->p)[i] = k; 00705 return *this; 00706 } 00707 00708 00709 //===== vector space arithmetic 00710 00712 template<class V> 00713 compressed_block_vector_unmanaged& operator+= (const V& y) 00714 { 00715 #ifdef DUNE_ISTL_WITH_CHECKING 00716 if (!includesindexset(y)) DUNE_THROW(ISTLError,"index set mismatch"); 00717 #endif 00718 for (size_type i=0; i<y.n; ++i) this->operator[](y.j[i]) += y.p[i]; 00719 return *this; 00720 } 00721 00723 template<class V> 00724 compressed_block_vector_unmanaged& operator-= (const V& y) 00725 { 00726 #ifdef DUNE_ISTL_WITH_CHECKING 00727 if (!includesindexset(y)) DUNE_THROW(ISTLError,"index set mismatch"); 00728 #endif 00729 for (size_type i=0; i<y.n; ++i) this->operator[](y.j[i]) -= y.p[i]; 00730 return *this; 00731 } 00732 00734 template<class V> 00735 compressed_block_vector_unmanaged& axpy (const field_type& a, const V& y) 00736 { 00737 #ifdef DUNE_ISTL_WITH_CHECKING 00738 if (!includesindexset(y)) DUNE_THROW(ISTLError,"index set mismatch"); 00739 #endif 00740 for (size_type i=0; i<y.n; ++i) (this->operator[](y.j[i])).axpy(a,y.p[i]); 00741 return *this; 00742 } 00743 00745 compressed_block_vector_unmanaged& operator*= (const field_type& k) 00746 { 00747 for (size_type i=0; i<this->n; ++i) (this->p)[i] *= k; 00748 return *this; 00749 } 00750 00752 compressed_block_vector_unmanaged& operator/= (const field_type& k) 00753 { 00754 for (size_type i=0; i<this->n; ++i) (this->p)[i] /= k; 00755 return *this; 00756 } 00757 00758 00759 //===== Euclidean scalar product 00760 00762 field_type operator* (const compressed_block_vector_unmanaged& y) const 00763 { 00764 #ifdef DUNE_ISTL_WITH_CHECKING 00765 if (!includesindexset(y) || !y.includesindexset(*this) ) 00766 DUNE_THROW(ISTLError,"index set mismatch"); 00767 #endif 00768 field_type sum=0; 00769 for (size_type i=0; i<this->n; ++i) 00770 sum += (this->p)[i] * y[(this->j)[i]]; 00771 return sum; 00772 } 00773 00774 00775 //===== norms 00776 00778 double one_norm () const 00779 { 00780 double sum=0; 00781 for (size_type i=0; i<this->n; ++i) sum += (this->p)[i].one_norm(); 00782 return sum; 00783 } 00784 00786 double one_norm_real () const 00787 { 00788 double sum=0; 00789 for (size_type i=0; i<this->n; ++i) sum += (this->p)[i].one_norm_real(); 00790 return sum; 00791 } 00792 00794 double two_norm () const 00795 { 00796 double sum=0; 00797 for (size_type i=0; i<this->n; ++i) sum += (this->p)[i].two_norm2(); 00798 return sqrt(sum); 00799 } 00800 00802 double two_norm2 () const 00803 { 00804 double sum=0; 00805 for (size_type i=0; i<this->n; ++i) sum += (this->p)[i].two_norm2(); 00806 return sum; 00807 } 00808 00810 double infinity_norm () const 00811 { 00812 double max=0; 00813 for (size_type i=0; i<this->n; ++i) max = std::max(max,(this->p)[i].infinity_norm()); 00814 return max; 00815 } 00816 00818 double infinity_norm_real () const 00819 { 00820 double max=0; 00821 for (size_type i=0; i<this->n; ++i) max = std::max(max,(this->p)[i].infinity_norm_real()); 00822 return max; 00823 } 00824 00825 00826 //===== sizes 00827 00829 size_type N () const 00830 { 00831 return this->n; 00832 } 00833 00835 size_type dim () const 00836 { 00837 size_type d=0; 00838 for (size_type i=0; i<this->n; i++) 00839 d += (this->p)[i].dim(); 00840 return d; 00841 } 00842 00843 protected: 00845 compressed_block_vector_unmanaged () : compressed_base_array_unmanaged<B,A>() 00846 { } 00847 00849 template<class V> 00850 bool includesindexset (const V& y) 00851 { 00852 typename V::ConstIterator e=this->end(); 00853 for (size_type i=0; i<y.n; i++) 00854 if (find(y.j[i])==e) 00855 return false; 00856 return true; 00857 } 00858 }; 00859 00860 00877 template<class B, class A=std::allocator<B> > 00878 class CompressedBlockVectorWindow : public compressed_block_vector_unmanaged<B,A> 00879 { 00880 public: 00881 00882 //===== type definitions and constants 00883 00885 typedef typename B::field_type field_type; 00886 00888 typedef B block_type; 00889 00891 typedef A allocator_type; 00892 00894 typedef typename A::size_type size_type; 00895 00897 enum { 00899 blocklevel = B::blocklevel+1}; 00900 00902 typedef typename compressed_block_vector_unmanaged<B,A>::Iterator Iterator; 00903 00905 typedef typename compressed_block_vector_unmanaged<B,A>::ConstIterator ConstIterator; 00906 00907 00908 //===== constructors and such 00910 CompressedBlockVectorWindow () : compressed_block_vector_unmanaged<B,A>() 00911 { } 00912 00914 CompressedBlockVectorWindow (B* _p, size_type* _j, size_type _n) 00915 { 00916 this->n = _n; 00917 this->p = _p; 00918 this->j = _j; 00919 } 00920 00922 CompressedBlockVectorWindow (const CompressedBlockVectorWindow& a) 00923 { 00924 this->n = a.n; 00925 this->p = a.p; 00926 this->j = a.j; 00927 } 00928 00930 CompressedBlockVectorWindow (const compressed_block_vector_unmanaged<B,A>& _a) 00931 { 00932 // cast needed to access protected data (upcast) 00933 const CompressedBlockVectorWindow& a = static_cast<const CompressedBlockVectorWindow&>(_a); 00934 00935 // make me point to the other's data 00936 this->n = a.n; 00937 this->p = a.p; 00938 this->j = a.j; 00939 } 00940 00941 00943 CompressedBlockVectorWindow& operator= (const CompressedBlockVectorWindow& a) 00944 { 00945 // check correct size 00946 #ifdef DUNE_ISTL_WITH_CHECKING 00947 if (this->n!=a.N()) DUNE_THROW(ISTLError,"vector size mismatch"); 00948 #endif 00949 00950 if (&a!=this) // check if this and a are different objects 00951 { 00952 // copy data 00953 for (size_type i=0; i<this->n; i++) this->p[i]=a.p[i]; 00954 for (size_type i=0; i<this->n; i++) this->j[i]=a.j[i]; 00955 } 00956 return *this; 00957 } 00958 00960 CompressedBlockVectorWindow& operator= (const compressed_block_vector_unmanaged<B,A>& a) 00961 { 00962 // forward to regular assignment operator 00963 return this->operator=(static_cast<const CompressedBlockVectorWindow&>(a)); 00964 } 00965 00967 CompressedBlockVectorWindow& operator= (const field_type& k) 00968 { 00969 (static_cast<compressed_block_vector_unmanaged<B,A>&>(*this)) = k; 00970 return *this; 00971 } 00972 00973 00974 //===== window manipulation methods 00975 00977 void set (size_type _n, B* _p, size_type* _j) 00978 { 00979 this->n = _n; 00980 this->p = _p; 00981 this->j = _j; 00982 } 00983 00985 void setsize (size_type _n) 00986 { 00987 this->n = _n; 00988 } 00989 00991 void setptr (B* _p) 00992 { 00993 this->p = _p; 00994 } 00995 00997 void setindexptr (size_type* _j) 00998 { 00999 this->j = _j; 01000 } 01001 01003 B* getptr () 01004 { 01005 return this->p; 01006 } 01007 01009 size_type* getindexptr () 01010 { 01011 return this->j; 01012 } 01013 01015 const B* getptr () const 01016 { 01017 return this->p; 01018 } 01019 01021 const size_type* getindexptr () const 01022 { 01023 return this->j; 01024 } 01026 size_type getsize () const 01027 { 01028 return this->n; 01029 } 01030 }; 01031 01032 } // end namespace 01033 01034 #endif
Generated on Fri Apr 29 2011 with Doxygen (ver 1.7.1) [doxygen-log,error-log].