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
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
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
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
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
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
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
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
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
00310 B* pold = this->p;
00311
00312 if(capacity>0){
00313
00314 this->p = A::template malloc<B>(capacity);
00315
00316 if(copyOldValues){
00317
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
00326 A::template free<B>(pold);
00327 }
00328 }else{
00329 if(capacity_ > 0)
00330
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
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
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
00398 const BlockVector& a = static_cast<const BlockVector&>(_a);
00399
00400
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
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)
00427 {
00428
00429 if (capacity_!=a.capacity_)
00430 {
00431 if (capacity_>0) A::template free<B>(this->p);
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
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
00453 return this->operator=(static_cast<const BlockVector&>(a));
00454 }
00455
00457 BlockVector& operator= (const field_type& k)
00458 {
00459
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
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
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
00551 const BlockVectorWindow& a = static_cast<const BlockVectorWindow&>(_a);
00552
00553
00554 this->n = a.n;
00555 this->p = a.p;
00556 }
00557
00558
00560 BlockVectorWindow& operator= (const BlockVectorWindow& a)
00561 {
00562
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)
00568 {
00569
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
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
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
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
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
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
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
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
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
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
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
00893 const CompressedBlockVectorWindow& a = static_cast<const CompressedBlockVectorWindow&>(_a);
00894
00895
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
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)
00911 {
00912
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
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
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 }
00993
00994 #endif