dune-common  2.3.0
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 
8 #include "genericiterator.hh"
9 #include "ftraits.hh"
10 #include "matvectraits.hh"
11 #include "promotiontraits.hh"
12 #include "dotproduct.hh"
13 
14 namespace Dune {
15 
16  // forward declaration of template
17  template<typename V> class DenseVector;
18 
19  template<typename V>
20  struct FieldTraits< DenseVector<V> >
21  {
24  };
25 
35  namespace fvmeta
36  {
41  template<class K>
42  inline typename FieldTraits<K>::real_type absreal (const K& k)
43  {
44  return std::abs(k);
45  }
46 
51  template<class K>
52  inline typename FieldTraits<K>::real_type absreal (const std::complex<K>& c)
53  {
54  return std::abs(c.real()) + std::abs(c.imag());
55  }
56 
61  template<class K>
62  inline typename FieldTraits<K>::real_type abs2 (const K& k)
63  {
64  return k*k;
65  }
66 
71  template<class K>
72  inline typename FieldTraits<K>::real_type abs2 (const std::complex<K>& c)
73  {
74  return c.real()*c.real() + c.imag()*c.imag();
75  }
76 
81  template<class K, bool isInteger = std::numeric_limits<K>::is_integer>
82  struct Sqrt
83  {
84  static inline typename FieldTraits<K>::real_type sqrt (const K& k)
85  {
86  return std::sqrt(k);
87  }
88  };
89 
94  template<class K>
95  struct Sqrt<K, true>
96  {
97  static inline typename FieldTraits<K>::real_type sqrt (const K& k)
98  {
99  return typename FieldTraits<K>::real_type(std::sqrt(double(k)));
100  }
101  };
102 
107  template<class K>
108  inline typename FieldTraits<K>::real_type sqrt (const K& k)
109  {
110  return Sqrt<K>::sqrt(k);
111  }
112 
113  }
114 
119  template<class C, class T>
121  public Dune::RandomAccessIteratorFacade<DenseIterator<C,T>,T, T&, std::ptrdiff_t>
122  {
123  friend class DenseIterator<typename remove_const<C>::type, typename remove_const<T>::type >;
124  friend class DenseIterator<const typename remove_const<C>::type, const typename remove_const<T>::type >;
125 
126  public:
127 
131  typedef std::ptrdiff_t DifferenceType;
132 
136  typedef typename C::size_type SizeType;
137 
138  // Constructors needed by the base iterators.
140  : container_(0), position_()
141  {}
142 
143  DenseIterator(C& cont, SizeType pos)
144  : container_(&cont), position_(pos)
145  {}
146 
148  : container_(other.container_), position_(other.position_)
149  {}
150 
151  // Methods needed by the forward iterator
152  bool equals(const DenseIterator<typename remove_const<C>::type,typename remove_const<T>::type>& other) const
153  {
154  return position_ == other.position_ && container_ == other.container_;
155  }
156 
157 
158  bool equals(const DenseIterator<const typename remove_const<C>::type,const typename remove_const<T>::type>& other) const
159  {
160  return position_ == other.position_ && container_ == other.container_;
161  }
162 
163  T& dereference() const {
164  return container_->operator[](position_);
165  }
166 
167  void increment(){
168  ++position_;
169  }
170 
171  // Additional function needed by BidirectionalIterator
172  void decrement(){
173  --position_;
174  }
175 
176  // Additional function needed by RandomAccessIterator
177  T& elementAt(DifferenceType i) const {
178  return container_->operator[](position_+i);
179  }
180 
182  position_=position_+n;
183  }
184 
186  {
187  assert(other.container_==container_);
188  return other.position_ - position_;
189  }
190 
192  {
193  assert(other.container_==container_);
194  return other.position_ - position_;
195  }
196 
198  SizeType index () const
199  {
200  return this->position_;
201  }
202 
203  private:
204  C *container_;
205  SizeType position_;
206  };
207 
221  template<typename V>
223  {
225  // typedef typename Traits::value_type K;
226 
227  // Curiously recurring template pattern
228  V & asImp() { return static_cast<V&>(*this); }
229  const V & asImp() const { return static_cast<const V&>(*this); }
230 
231  // prohibit copying
232  DenseVector ( const DenseVector & );
233 
234  protected:
235  // construction allowed to derived classes only
237 
238  public:
239  //===== type definitions and constants
240 
243 
245  typedef typename Traits::value_type value_type;
246 
248  typedef typename Traits::value_type field_type;
249 
251  typedef typename Traits::value_type block_type;
252 
254  typedef typename Traits::size_type size_type;
255 
257  enum {
260  };
261 
262  //===== assignment from scalar
265  {
266  for (size_type i=0; i<size(); i++)
267  asImp()[i] = k;
268  return asImp();
269  }
270 
271  //===== access to components
272 
275  {
276  return asImp().vec_access(i);
277  }
278 
280  {
281  return asImp().vec_access(i);
282  }
283 
285  size_type size() const
286  {
287  return asImp().vec_size();
288  }
289 
294 
297  {
298  return Iterator(*this,0);
299  }
300 
303  {
304  return Iterator(*this,size());
305  }
306 
310  {
311  return Iterator(*this,size()-1);
312  }
313 
317  {
318  return Iterator(*this,-1);
319  }
320 
323  {
324  return Iterator(*this,std::min(i,size()));
325  }
326 
331 
334  {
335  return ConstIterator(*this,0);
336  }
337 
340  {
341  return ConstIterator(*this,size());
342  }
343 
347  {
348  return ConstIterator(*this,size()-1);
349  }
350 
354  {
355  return ConstIterator(*this,-1);
356  }
357 
360  {
361  return ConstIterator(*this,std::min(i,size()));
362  }
363 
364  //===== vector space arithmetic
365 
367  template <class Other>
369  {
370  assert(y.size() == size());
371  for (size_type i=0; i<size(); i++)
372  (*this)[i] += y[i];
373  return asImp();
374  }
375 
377  template <class Other>
379  {
380  assert(y.size() == size());
381  for (size_type i=0; i<size(); i++)
382  (*this)[i] -= y[i];
383  return asImp();
384  }
385 
387  template <class Other>
389  {
390  derived_type z = asImp();
391  return (z+=b);
392  }
393 
395  template <class Other>
397  {
398  derived_type z = asImp();
399  return (z-=b);
400  }
401 
404  {
405  for (size_type i=0; i<size(); i++)
406  (*this)[i] += k;
407  return asImp();
408  }
409 
412  {
413  for (size_type i=0; i<size(); i++)
414  (*this)[i] -= k;
415  return asImp();
416  }
417 
420  {
421  for (size_type i=0; i<size(); i++)
422  (*this)[i] *= k;
423  return asImp();
424  }
425 
428  {
429  for (size_type i=0; i<size(); i++)
430  (*this)[i] /= k;
431  return asImp();
432  }
433 
435  template <class Other>
436  bool operator== (const DenseVector<Other>& y) const
437  {
438  assert(y.size() == size());
439  for (size_type i=0; i<size(); i++)
440  if ((*this)[i]!=y[i])
441  return false;
442 
443  return true;
444  }
445 
447  template <class Other>
448  bool operator!= (const DenseVector<Other>& y) const
449  {
450  return !operator==(y);
451  }
452 
453 
455  template <class Other>
457  {
458  assert(y.size() == size());
459  for (size_type i=0; i<size(); i++)
460  (*this)[i] += a*y[i];
461  return asImp();
462  }
463 
471  template<class Other>
472  typename PromotionTraits<field_type,typename DenseVector<Other>::field_type>::PromotedType operator* (const DenseVector<Other>& y) const {
473  typedef typename PromotionTraits<field_type, typename DenseVector<Other>::field_type>::PromotedType PromotedType;
474  PromotedType result(0);
475  assert(y.size() == size());
476  for (size_type i=0; i<size(); i++) {
477  result += PromotedType((*this)[i]*y[i]);
478  }
479  return result;
480  }
481 
489  template<class Other>
490  typename PromotionTraits<field_type,typename DenseVector<Other>::field_type>::PromotedType dot(const DenseVector<Other>& y) const {
491  typedef typename PromotionTraits<field_type, typename DenseVector<Other>::field_type>::PromotedType PromotedType;
492  PromotedType result(0);
493  assert(y.size() == size());
494  for (size_type i=0; i<size(); i++) {
495  result += Dune::dot((*this)[i],y[i]);
496  }
497  return result;
498  }
499 
500  //===== norms
501 
504  typename FieldTraits<value_type>::real_type result( 0 );
505  for (size_type i=0; i<size(); i++)
506  result += std::abs((*this)[i]);
507  return result;
508  }
509 
510 
513  {
514  typename FieldTraits<value_type>::real_type result( 0 );
515  for (size_type i=0; i<size(); i++)
516  result += fvmeta::absreal((*this)[i]);
517  return result;
518  }
519 
522  {
523  typename FieldTraits<value_type>::real_type result( 0 );
524  for (size_type i=0; i<size(); i++)
525  result += fvmeta::abs2((*this)[i]);
526  return fvmeta::sqrt(result);
527  }
528 
531  {
532  typename FieldTraits<value_type>::real_type result( 0 );
533  for (size_type i=0; i<size(); i++)
534  result += fvmeta::abs2((*this)[i]);
535  return result;
536  }
537 
540  {
541  if (size() == 0)
542  return 0.0;
543 
544  ConstIterator it = begin();
545  typename FieldTraits<value_type>::real_type max = std::abs(*it);
546  for (it = it + 1; it != end(); ++it)
547  max = std::max(max, std::abs(*it));
548 
549  return max;
550  }
551 
554  {
555  if (size() == 0)
556  return 0.0;
557 
558  ConstIterator it = begin();
559  typename FieldTraits<value_type>::real_type max = fvmeta::absreal(*it);
560  for (it = it + 1; it != end(); ++it)
561  max = std::max(max, fvmeta::absreal(*it));
562 
563  return max;
564  }
565 
566  //===== sizes
567 
569  size_type N () const
570  {
571  return size();
572  }
573 
575  size_type dim () const
576  {
577  return size();
578  }
579 
580  };
581 
590  template<typename V>
591  std::ostream& operator<< (std::ostream& s, const DenseVector<V>& v)
592  {
593  for (typename DenseVector<V>::size_type i=0; i<v.size(); i++)
594  s << ((i>0) ? " " : "") << v[i];
595  return s;
596  }
597 
600 } // end namespace
601 
602 #endif // DUNE_DENSEVECTOR_HH