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
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 (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
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
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
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
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
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
00322 B* pold = this->p;
00323
00324 if(capacity>0){
00325
00326 this->p = A::template malloc<B>(capacity);
00327
00328 if(copyOldValues){
00329
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
00338 A::template free<B>(pold);
00339 }
00340 }else{
00341 if(capacity_ > 0)
00342
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
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
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
00413 const BlockVector& a = static_cast<const BlockVector&>(_a);
00414
00415
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
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)
00442 {
00443
00444 if (capacity_!=a.capacity_)
00445 {
00446 if (capacity_>0) A::template free<B>(this->p);
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
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
00468 return this->operator=(static_cast<const BlockVector&>(a));
00469 }
00470
00472 BlockVector& operator= (const field_type& k)
00473 {
00474
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
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
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
00566 const BlockVectorWindow& a = static_cast<const BlockVectorWindow&>(_a);
00567
00568
00569 this->n = a.n;
00570 this->p = a.p;
00571 }
00572
00573
00575 BlockVectorWindow& operator= (const BlockVectorWindow& a)
00576 {
00577
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)
00583 {
00584
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
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
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
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
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
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
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
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
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
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
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
00908 const CompressedBlockVectorWindow& a = static_cast<const CompressedBlockVectorWindow&>(_a);
00909
00910
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
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)
00926 {
00927
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
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
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 }
01008
01009 #endif