dune-common  2.4.1-rc2
densevector.hh
Go to the documentation of this file.
1 // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 // vi: set et ts=4 sw=2 sts=2:
3 #ifndef DUNE_DENSEVECTOR_HH
4 #define DUNE_DENSEVECTOR_HH
5 
6 #include <limits>
7 #include <type_traits>
8 
9 #include "genericiterator.hh"
10 #include "ftraits.hh"
11 #include "matvectraits.hh"
12 #include "promotiontraits.hh"
13 #include "dotproduct.hh"
14 
15 namespace Dune {
16 
17  // forward declaration of template
18  template<typename V> class DenseVector;
19 
20  template<typename V>
21  struct FieldTraits< DenseVector<V> >
22  {
25  };
26 
36  namespace fvmeta
37  {
42  template<class K>
43  inline typename FieldTraits<K>::real_type absreal (const K& k)
44  {
45  using std::abs;
46  return abs(k);
47  }
48 
53  template<class K>
54  inline typename FieldTraits<K>::real_type absreal (const std::complex<K>& c)
55  {
56  using std::abs;
57  return abs(c.real()) + abs(c.imag());
58  }
59 
64  template<class K>
65  inline typename FieldTraits<K>::real_type abs2 (const K& k)
66  {
67  return k*k;
68  }
69 
74  template<class K>
75  inline typename FieldTraits<K>::real_type abs2 (const std::complex<K>& c)
76  {
77  return c.real()*c.real() + c.imag()*c.imag();
78  }
79 
84  template<class K, bool isInteger = std::numeric_limits<K>::is_integer>
85  struct Sqrt
86  {
87  static inline typename FieldTraits<K>::real_type sqrt (const K& k)
88  {
89  using std::sqrt;
90  return sqrt(k);
91  }
92  };
93 
98  template<class K>
99  struct Sqrt<K, true>
100  {
101  static inline typename FieldTraits<K>::real_type sqrt (const K& k)
102  {
103  using std::sqrt;
104  return typename FieldTraits<K>::real_type(sqrt(double(k)));
105  }
106  };
107 
112  template<class K>
113  inline typename FieldTraits<K>::real_type sqrt (const K& k)
114  {
115  return Sqrt<K>::sqrt(k);
116  }
117 
118  }
119 
124  template<class C, class T, class R =T&>
126  public Dune::RandomAccessIteratorFacade<DenseIterator<C,T,R>,T, R, std::ptrdiff_t>
127  {
128  friend class DenseIterator<typename remove_const<C>::type, typename remove_const<T>::type, typename mutable_reference<R>::type >;
129  friend class DenseIterator<const typename remove_const<C>::type, const typename remove_const<T>::type, typename const_reference<R>::type >;
130 
131  typedef DenseIterator<typename remove_const<C>::type, typename remove_const<T>::type, typename mutable_reference<R>::type > MutableIterator;
132  typedef DenseIterator<const typename remove_const<C>::type, const typename remove_const<T>::type, typename const_reference<R>::type > ConstIterator;
133  public:
134 
138  typedef std::ptrdiff_t DifferenceType;
139 
143  typedef typename C::size_type SizeType;
144 
145  // Constructors needed by the base iterators.
147  : container_(0), position_()
148  {}
149 
150  DenseIterator(C& cont, SizeType pos)
151  : container_(&cont), position_(pos)
152  {}
153 
155  : container_(other.container_), position_(other.position_)
156  {}
157 
159  : container_(other.container_), position_(other.position_)
160  {}
161 
162  // Methods needed by the forward iterator
163  bool equals(const MutableIterator &other) const
164  {
165  return position_ == other.position_ && container_ == other.container_;
166  }
167 
168 
169  bool equals(const ConstIterator & other) const
170  {
171  return position_ == other.position_ && container_ == other.container_;
172  }
173 
174  R dereference() const {
175  return container_->operator[](position_);
176  }
177 
178  void increment(){
179  ++position_;
180  }
181 
182  // Additional function needed by BidirectionalIterator
183  void decrement(){
184  --position_;
185  }
186 
187  // Additional function needed by RandomAccessIterator
189  return container_->operator[](position_+i);
190  }
191 
193  position_=position_+n;
194  }
195 
196  DifferenceType distanceTo(DenseIterator<const typename remove_const<C>::type,const typename remove_const<T>::type> other) const
197  {
198  assert(other.container_==container_);
199  return other.position_ - position_;
200  }
201 
202  DifferenceType distanceTo(DenseIterator<typename remove_const<C>::type, typename remove_const<T>::type> other) const
203  {
204  assert(other.container_==container_);
205  return other.position_ - position_;
206  }
207 
209  SizeType index () const
210  {
211  return this->position_;
212  }
213 
214  private:
215  C *container_;
216  SizeType position_;
217  };
218 
232  template<typename V>
233  class DenseVector
234  {
235  typedef DenseMatVecTraits<V> Traits;
236  // typedef typename Traits::value_type K;
237 
238  // Curiously recurring template pattern
239  V & asImp() { return static_cast<V&>(*this); }
240  const V & asImp() const { return static_cast<const V&>(*this); }
241 
242  // prohibit copying
243  DenseVector ( const DenseVector & );
244 
245  protected:
246  // construction allowed to derived classes only
248 
249  public:
250  //===== type definitions and constants
251 
253  typedef typename Traits::derived_type derived_type;
254 
256  typedef typename Traits::value_type value_type;
257 
259  typedef typename Traits::value_type field_type;
260 
262  typedef typename Traits::value_type block_type;
263 
265  typedef typename Traits::size_type size_type;
266 
268  enum {
271  };
272 
273  //===== assignment from scalar
276  {
277  for (size_type i=0; i<size(); i++)
278  asImp()[i] = k;
279  return asImp();
280  }
281 
282  //===== access to components
283 
286  {
287  return asImp().vec_access(i);
288  }
289 
291  {
292  return asImp().vec_access(i);
293  }
294 
296  size_type size() const
297  {
298  return asImp().vec_size();
299  }
300 
305 
308  {
309  return Iterator(*this,0);
310  }
311 
314  {
315  return Iterator(*this,size());
316  }
317 
321  {
322  return Iterator(*this,size()-1);
323  }
324 
328  {
329  return Iterator(*this,-1);
330  }
331 
334  {
335  return Iterator(*this,std::min(i,size()));
336  }
337 
342 
345  {
346  return ConstIterator(*this,0);
347  }
348 
351  {
352  return ConstIterator(*this,size());
353  }
354 
358  {
359  return ConstIterator(*this,size()-1);
360  }
361 
365  {
366  return ConstIterator(*this,-1);
367  }
368 
371  {
372  return ConstIterator(*this,std::min(i,size()));
373  }
374 
375  //===== vector space arithmetic
376 
378  template <class Other>
380  {
381  assert(y.size() == size());
382  for (size_type i=0; i<size(); i++)
383  (*this)[i] += y[i];
384  return asImp();
385  }
386 
388  template <class Other>
390  {
391  assert(y.size() == size());
392  for (size_type i=0; i<size(); i++)
393  (*this)[i] -= y[i];
394  return asImp();
395  }
396 
398  template <class Other>
400  {
401  derived_type z = asImp();
402  return (z+=b);
403  }
404 
406  template <class Other>
408  {
409  derived_type z = asImp();
410  return (z-=b);
411  }
412 
414 
422  template <typename ValueType>
423  typename std::enable_if<
424  std::is_convertible<ValueType, value_type>::value,
426  >::type&
427  operator+= (const ValueType& kk)
428  {
429  const value_type& k = kk;
430  for (size_type i=0; i<size(); i++)
431  (*this)[i] += k;
432  return asImp();
433  }
434 
436 
444  template <typename ValueType>
445  typename std::enable_if<
446  std::is_convertible<ValueType, value_type>::value,
448  >::type&
449  operator-= (const ValueType& kk)
450  {
451  const value_type& k = kk;
452  for (size_type i=0; i<size(); i++)
453  (*this)[i] -= k;
454  return asImp();
455  }
456 
458 
466  template <typename ValueType>
467  typename std::enable_if<
468  std::is_convertible<ValueType, value_type>::value,
470  >::type&
471  operator*= (const ValueType& kk)
472  {
473  const value_type& k = kk;
474  for (size_type i=0; i<size(); i++)
475  (*this)[i] *= k;
476  return asImp();
477  }
478 
480 
488  template <typename ValueType>
489  typename std::enable_if<
490  std::is_convertible<ValueType, value_type>::value,
492  >::type&
493  operator/= (const ValueType& kk)
494  {
495  const value_type& k = kk;
496  for (size_type i=0; i<size(); i++)
497  (*this)[i] /= k;
498  return asImp();
499  }
500 
502  template <class Other>
503  bool operator== (const DenseVector<Other>& y) const
504  {
505  assert(y.size() == size());
506  for (size_type i=0; i<size(); i++)
507  if ((*this)[i]!=y[i])
508  return false;
509 
510  return true;
511  }
512 
514  template <class Other>
515  bool operator!= (const DenseVector<Other>& y) const
516  {
517  return !operator==(y);
518  }
519 
520 
522  template <class Other>
524  {
525  assert(y.size() == size());
526  for (size_type i=0; i<size(); i++)
527  (*this)[i] += a*y[i];
528  return asImp();
529  }
530 
538  template<class Other>
539  typename PromotionTraits<field_type,typename DenseVector<Other>::field_type>::PromotedType operator* (const DenseVector<Other>& y) const {
540  typedef typename PromotionTraits<field_type, typename DenseVector<Other>::field_type>::PromotedType PromotedType;
541  PromotedType result(0);
542  assert(y.size() == size());
543  for (size_type i=0; i<size(); i++) {
544  result += PromotedType((*this)[i]*y[i]);
545  }
546  return result;
547  }
548 
556  template<class Other>
557  typename PromotionTraits<field_type,typename DenseVector<Other>::field_type>::PromotedType dot(const DenseVector<Other>& y) const {
558  typedef typename PromotionTraits<field_type, typename DenseVector<Other>::field_type>::PromotedType PromotedType;
559  PromotedType result(0);
560  assert(y.size() == size());
561  for (size_type i=0; i<size(); i++) {
562  result += Dune::dot((*this)[i],y[i]);
563  }
564  return result;
565  }
566 
567  //===== norms
568 
571  using std::abs;
572  typename FieldTraits<value_type>::real_type result( 0 );
573  for (size_type i=0; i<size(); i++)
574  result += abs((*this)[i]);
575  return result;
576  }
577 
578 
581  {
582  typename FieldTraits<value_type>::real_type result( 0 );
583  for (size_type i=0; i<size(); i++)
584  result += fvmeta::absreal((*this)[i]);
585  return result;
586  }
587 
590  {
591  typename FieldTraits<value_type>::real_type result( 0 );
592  for (size_type i=0; i<size(); i++)
593  result += fvmeta::abs2((*this)[i]);
594  return fvmeta::sqrt(result);
595  }
596 
599  {
600  typename FieldTraits<value_type>::real_type result( 0 );
601  for (size_type i=0; i<size(); i++)
602  result += fvmeta::abs2((*this)[i]);
603  return result;
604  }
605 
608  {
609  using std::abs;
610  using std::max;
611  typedef typename FieldTraits<value_type>::real_type real_type;
612 
613  if (size() == 0)
614  return 0.0;
615 
616  ConstIterator it = begin();
617  real_type max_val = abs(*it);
618  for (it = it + 1; it != end(); ++it)
619  max_val = max(max_val, real_type(abs(*it)));
620 
621  return max_val;
622  }
623 
626  {
627  using std::max;
628 
629  if (size() == 0)
630  return 0.0;
631 
632  ConstIterator it = begin();
633  typename FieldTraits<value_type>::real_type max_val = fvmeta::absreal(*it);
634  for (it = it + 1; it != end(); ++it)
635  max_val = max(max_val, fvmeta::absreal(*it));
636 
637  return max_val;
638  }
639 
640  //===== sizes
641 
643  size_type N () const
644  {
645  return size();
646  }
647 
649  size_type dim () const
650  {
651  return size();
652  }
653 
654  };
655 
664  template<typename V>
665  std::ostream& operator<< (std::ostream& s, const DenseVector<V>& v)
666  {
667  for (typename DenseVector<V>::size_type i=0; i<v.size(); i++)
668  s << ((i>0) ? " " : "") << v[i];
669  return s;
670  }
671 
674 } // end namespace
675 
676 #endif // DUNE_DENSEVECTOR_HH
DifferenceType distanceTo(DenseIterator< typename remove_const< C >::type, typename remove_const< T >::type > other) const
Definition: densevector.hh:202
enable_if<!IsVector< A >::value &&!is_same< typename FieldTraits< A >::field_type, typename FieldTraits< A >::real_type >::value, typename PromotionTraits< A, B >::PromotedType >::type dot(const A &a, const B &b)
computes the dot product for fundamental data types according to Petsc's VectDot function: dot(a...
Definition: dotproduct.hh:44
size_type size() const
size method
Definition: densevector.hh:296
Definition: ftraits.hh:22
Base class for stl conformant forward iterators.
Definition: iteratorfacades.hh:424
ConstIterator beforeEnd() const
Definition: densevector.hh:357
FieldTraits< value_type >::real_type one_norm() const
one norm (sum over absolute values of entries)
Definition: densevector.hh:570
C::size_type SizeType
The type to index the underlying container.
Definition: densevector.hh:143
Traits::value_type field_type
export the type representing the field
Definition: densevector.hh:259
derived_type & operator+=(const DenseVector< Other > &y)
vector space addition
Definition: densevector.hh:379
char c
Definition: alignment.hh:33
Traits::derived_type derived_type
type of derived vector class
Definition: densevector.hh:253
FieldTraits< value_type >::real_type infinity_norm_real() const
simplified infinity norm (uses Manhattan norm for complex values)
Definition: densevector.hh:625
DifferenceType distanceTo(DenseIterator< const typename remove_const< C >::type, const typename remove_const< T >::type > other) const
Definition: densevector.hh:196
ConstIterator const_iterator
typedef for stl compliant access
Definition: densevector.hh:341
std::enable_if< std::is_convertible< ValueType, value_type >::value, derived_type >::type & operator/=(const ValueType &kk)
vector space division by scalar
Definition: densevector.hh:493
FieldTraits< typename DenseMatVecTraits< V >::value_type >::field_type field_type
Definition: densevector.hh:23
size_type N() const
number of blocks in the vector (are of size 1 here)
Definition: densevector.hh:643
void advance(DifferenceType n)
Definition: densevector.hh:192
bool equals(const ConstIterator &other) const
Definition: densevector.hh:169
Generic iterator class for dense vector and matrix implementations.
Definition: densevector.hh:125
T real_type
export the type representing the real type of the field
Definition: ftraits.hh:27
Documentation of the traits classes you need to write for each implementation of DenseVector or Dense...
void increment()
Definition: densevector.hh:178
Iterator iterator
typedef for stl compliant access
Definition: densevector.hh:304
FieldTraits< value_type >::real_type two_norm() const
two norm sqrt(sum over squared values of entries)
Definition: densevector.hh:589
FieldTraits< value_type >::real_type two_norm2() const
square of two norm (sum over squared values of entries), need for block recursion ...
Definition: densevector.hh:598
derived_type operator-(const DenseVector< Other > &b) const
Binary vector subtraction.
Definition: densevector.hh:407
Interface for a class of dense vectors over a given field.
Definition: densevector.hh:18
DenseIterator< const DenseVector, const value_type > ConstIterator
ConstIterator class for sequential access.
Definition: densevector.hh:339
Provides some promotion traits.
Iterator beforeBegin()
Definition: densevector.hh:327
get the 'mutable' version of a reference to a const object
Definition: genericiterator.hh:113
derived_type & operator-=(const DenseVector< Other > &y)
vector space subtraction
Definition: densevector.hh:389
DenseIterator(const ConstIterator &other)
Definition: densevector.hh:158
ConstIterator find(size_type i) const
return iterator to given element or end()
Definition: densevector.hh:370
value_type & operator[](size_type i)
random access
Definition: densevector.hh:285
ConstIterator end() const
end ConstIterator
Definition: densevector.hh:350
Type traits to determine the type of reals (when working with complex numbers)
Iterator find(size_type i)
return iterator to given element or end()
Definition: densevector.hh:333
PromotionTraits< field_type, typename DenseVector< Other >::field_type >::PromotedType operator*(const DenseVector< Other > &y) const
indefinite vector dot product which corresponds to Petsc's VecTDot
Definition: densevector.hh:539
FieldTraits< typename DenseMatVecTraits< V >::value_type >::real_type real_type
Definition: densevector.hh:24
bool equals(const MutableIterator &other) const
Definition: densevector.hh:163
void decrement()
Definition: densevector.hh:183
bool operator==(const DenseVector< Other > &y) const
Binary vector comparison.
Definition: densevector.hh:503
Iterator end()
end iterator
Definition: densevector.hh:313
derived_type & axpy(const value_type &a, const DenseVector< Other > &y)
vector space axpy operation ( *this += a y )
Definition: densevector.hh:523
std::ptrdiff_t DifferenceType
The type of the difference between two positions.
Definition: densevector.hh:138
size_type dim() const
dimension of the vector space
Definition: densevector.hh:649
derived_type & operator=(const value_type &k)
Assignment operator for scalar.
Definition: densevector.hh:275
R dereference() const
Definition: densevector.hh:174
DenseIterator(const MutableIterator &other)
Definition: densevector.hh:154
std::size_t position_
The current position in the buffer.
Definition: variablesizecommunicator.hh:136
DenseIterator< DenseVector, value_type > Iterator
Iterator class for sequential access.
Definition: densevector.hh:302
Iterator beforeEnd()
Definition: densevector.hh:320
SizeType index() const
return index
Definition: densevector.hh:209
Iterator begin()
begin iterator
Definition: densevector.hh:307
R elementAt(DifferenceType i) const
Definition: densevector.hh:188
PromotionTraits< field_type, typename DenseVector< Other >::field_type >::PromotedType dot(const DenseVector< Other > &y) const
vector dot product which corresponds to Petsc's VecDot
Definition: densevector.hh:557
The number of block levels we contain.
Definition: densevector.hh:270
FieldTraits< value_type >::real_type infinity_norm() const
infinity norm (maximum of absolute values of entries)
Definition: densevector.hh:607
ConstIterator begin() const
begin ConstIterator
Definition: densevector.hh:344
Traits::size_type size_type
The type used for the index access and size operation.
Definition: densevector.hh:265
std::enable_if< std::is_convertible< ValueType, value_type >::value, derived_type >::type & operator*=(const ValueType &kk)
vector space multiplication with scalar
Definition: densevector.hh:471
Traits::value_type block_type
export the type representing the components
Definition: densevector.hh:262
Provides the functions dot(a,b) := and dotT(a,b) := .
DenseVector()
Definition: densevector.hh:247
DenseIterator(C &cont, SizeType pos)
Definition: densevector.hh:150
FieldTraits< value_type >::real_type one_norm_real() const
simplified one norm (uses Manhattan norm for complex values)
Definition: densevector.hh:580
Traits::value_type value_type
export the type representing the field
Definition: densevector.hh:256
bool operator!=(const DenseVector< Other > &y) const
Binary vector incomparison.
Definition: densevector.hh:515
derived_type operator+(const DenseVector< Other > &b) const
Binary vector addition.
Definition: densevector.hh:399
Implements a generic iterator class for writing stl conformant iterators.
ConstIterator beforeBegin() const
Definition: densevector.hh:364