Loading [MathJax]/extensions/tex2jax.js

DUNE PDELab (unstable)

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// SPDX-FileCopyrightInfo: Copyright © DUNE Project contributors, see file LICENSE.md in module root
4// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
5#ifndef DUNE_DENSEVECTOR_HH
6#define DUNE_DENSEVECTOR_HH
7
8#include <algorithm>
9#include <limits>
10#include <type_traits>
11
12#include "std/cmath.hh"
13#include "genericiterator.hh"
14#include "ftraits.hh"
15#include "matvectraits.hh"
16#include "promotiontraits.hh"
17#include "dotproduct.hh"
18#include "boundschecking.hh"
19
20namespace Dune {
21
22 // forward declaration of template
23 template<typename V> class DenseVector;
24
25 template<typename V>
26 struct FieldTraits< DenseVector<V> >
27 {
28 typedef typename FieldTraits< typename DenseMatVecTraits<V>::value_type >::field_type field_type;
29 typedef typename FieldTraits< typename DenseMatVecTraits<V>::value_type >::real_type real_type;
30 };
31
41 namespace fvmeta
42 {
47 template<class K>
48 constexpr typename FieldTraits<K>::real_type absreal (const K& k)
49 {
50 using Std::abs;
51 return abs(k);
52 }
53
58 template<class K>
59 constexpr typename FieldTraits<K>::real_type absreal (const std::complex<K>& c)
60 {
61 using Std::abs;
62 return abs(c.real()) + abs(c.imag());
63 }
64
69 template<class K>
70 constexpr typename FieldTraits<K>::real_type abs2 (const K& k)
71 {
72 return k*k;
73 }
74
79 template<class K>
80 constexpr typename FieldTraits<K>::real_type abs2 (const std::complex<K>& c)
81 {
82 return c.real()*c.real() + c.imag()*c.imag();
83 }
84
89 template<class K, bool isInteger = std::numeric_limits<K>::is_integer>
90 struct Sqrt
91 {
92 static constexpr typename FieldTraits<K>::real_type sqrt (const K& k)
93 {
94 using Std::sqrt;
95 return sqrt(k);
96 }
97 };
98
103 template<class K>
104 struct Sqrt<K, true>
105 {
106 static constexpr typename FieldTraits<K>::real_type sqrt (const K& k)
107 {
108 using Std::sqrt;
109 return typename FieldTraits<K>::real_type(sqrt(double(k)));
110 }
111 };
112
117 template<class K>
118 static constexpr typename FieldTraits<K>::real_type sqrt (const K& k)
119 {
120 return Sqrt<K>::sqrt(k);
121 }
122
123 }
124
129 template<class C, class T, class R =T&>
131 public Dune::RandomAccessIteratorFacade<DenseIterator<C,T,R>,T, R, std::ptrdiff_t>
132 {
133 friend class DenseIterator<typename std::remove_const<C>::type, typename std::remove_const<T>::type, typename mutable_reference<R>::type >;
134 friend class DenseIterator<const typename std::remove_const<C>::type, const typename std::remove_const<T>::type, typename const_reference<R>::type >;
135
136 typedef DenseIterator<typename std::remove_const<C>::type, typename std::remove_const<T>::type, typename mutable_reference<R>::type > MutableIterator;
137 typedef DenseIterator<const typename std::remove_const<C>::type, const typename std::remove_const<T>::type, typename const_reference<R>::type > ConstIterator;
138 public:
139
143 typedef std::ptrdiff_t DifferenceType;
144
148 typedef typename C::size_type SizeType;
149
150 // Constructors needed by the base iterators.
151 constexpr DenseIterator()
152 : container_(0), position_()
153 {}
154
155 constexpr DenseIterator(C& cont, SizeType pos)
156 : container_(&cont), position_(pos)
157 {}
158
159 constexpr DenseIterator(const MutableIterator & other)
160 : container_(other.container_), position_(other.position_)
161 {}
162
163 constexpr DenseIterator(const ConstIterator & other)
164 : container_(other.container_), position_(other.position_)
165 {}
166
167 // Methods needed by the forward iterator
168 constexpr bool equals(const MutableIterator &other) const
169 {
170 return position_ == other.position_ && container_ == other.container_;
171 }
172
173
174 constexpr bool equals(const ConstIterator & other) const
175 {
176 return position_ == other.position_ && container_ == other.container_;
177 }
178
179 constexpr R dereference() const {
180 return container_->operator[](position_);
181 }
182
183 constexpr void increment(){
184 ++position_;
185 }
186
187 // Additional function needed by BidirectionalIterator
188 constexpr void decrement(){
189 --position_;
190 }
191
192 // Additional function needed by RandomAccessIterator
193 constexpr R elementAt(DifferenceType i) const {
194 return container_->operator[](position_+i);
195 }
196
197 constexpr void advance(DifferenceType n){
198 position_=position_+n;
199 }
200
201 constexpr DifferenceType distanceTo(DenseIterator<const typename std::remove_const<C>::type,const typename std::remove_const<T>::type> other) const
202 {
203 assert(other.container_==container_);
204 return static_cast< DifferenceType >( other.position_ ) - static_cast< DifferenceType >( position_ );
205 }
206
207 constexpr DifferenceType distanceTo(DenseIterator<typename std::remove_const<C>::type, typename std::remove_const<T>::type> other) const
208 {
209 assert(other.container_==container_);
210 return static_cast< DifferenceType >( other.position_ ) - static_cast< DifferenceType >( position_ );
211 }
212
214 constexpr SizeType index () const
215 {
216 return this->position_;
217 }
218
219 private:
220 C *container_;
221 SizeType position_;
222 };
223
228 template<typename V>
230 {
231 typedef DenseMatVecTraits<V> Traits;
232 // typedef typename Traits::value_type K;
233
234 // Curiously recurring template pattern
235 constexpr V & asImp() { return static_cast<V&>(*this); }
236 constexpr const V & asImp() const { return static_cast<const V&>(*this); }
237
238 protected:
239 // construction allowed to derived classes only
240 constexpr DenseVector() = default;
241 // copying only allowed by derived classes
242 constexpr DenseVector(const DenseVector&) = default;
243
244 public:
245 //===== type definitions and constants
246
248 typedef typename Traits::derived_type derived_type;
249
251 typedef typename Traits::value_type value_type;
252
254 typedef typename FieldTraits< value_type >::field_type field_type;
255
257 typedef typename Traits::value_type block_type;
258
260 typedef typename Traits::size_type size_type;
261
263 constexpr static int blocklevel = 1;
264
265 //===== assignment from scalar
267 constexpr inline derived_type& operator= (const value_type& k)
268 {
269 for (size_type i=0; i<size(); i++)
270 asImp()[i] = k;
271 return asImp();
272 }
273
274 //===== assignment from other DenseVectors
275 protected:
277 constexpr DenseVector& operator=(const DenseVector&) = default;
278
279 public:
280
282 template <typename W,
283 std::enable_if_t<
284 std::is_assignable<value_type&, typename DenseVector<W>::value_type>::value, int> = 0>
285 constexpr derived_type& operator= (const DenseVector<W>& other)
286 {
287 assert(other.size() == size());
288 for (size_type i=0; i<size(); i++)
289 asImp()[i] = other[i];
290 return asImp();
291 }
292
293 //===== access to components
294
297 {
298 return asImp()[i];
299 }
300
301 constexpr const value_type & operator[] (size_type i) const
302 {
303 return asImp()[i];
304 }
305
307 constexpr value_type& front()
308 {
309 return asImp()[0];
310 }
311
313 constexpr const value_type& front() const
314 {
315 return asImp()[0];
316 }
317
319 constexpr value_type& back()
320 {
321 return asImp()[size()-1];
322 }
323
325 constexpr const value_type& back() const
326 {
327 return asImp()[size()-1];
328 }
329
331 constexpr bool empty() const
332 {
333 return size() == 0;
334 }
335
337 constexpr size_type size() const
338 {
339 return asImp().size();
340 }
341
346
348 constexpr Iterator begin ()
349 {
350 return Iterator(*this,0);
351 }
352
354 constexpr Iterator end ()
355 {
356 return Iterator(*this,size());
357 }
358
361 constexpr Iterator beforeEnd ()
362 {
363 return Iterator(*this,size()-1);
364 }
365
369 {
370 return Iterator(*this,-1);
371 }
372
374 constexpr Iterator find (size_type i)
375 {
376 return Iterator(*this,std::min(i,size()));
377 }
378
383
385 constexpr ConstIterator begin () const
386 {
387 return ConstIterator(*this,0);
388 }
389
391 constexpr ConstIterator end () const
392 {
393 return ConstIterator(*this,size());
394 }
395
398 constexpr ConstIterator beforeEnd () const
399 {
400 return ConstIterator(*this,size()-1);
401 }
402
405 constexpr ConstIterator beforeBegin () const
406 {
407 return ConstIterator(*this,-1);
408 }
409
411 constexpr ConstIterator find (size_type i) const
412 {
413 return ConstIterator(*this,std::min(i,size()));
414 }
415
416 //===== vector space arithmetic
417
419 template <class Other>
421 {
422 DUNE_ASSERT_BOUNDS(x.size() == size());
423 for (size_type i=0; i<size(); i++)
424 (*this)[i] += x[i];
425 return asImp();
426 }
427
429 template <class Other>
431 {
432 DUNE_ASSERT_BOUNDS(x.size() == size());
433 for (size_type i=0; i<size(); i++)
434 (*this)[i] -= x[i];
435 return asImp();
436 }
437
439 template <class Other>
441 {
442 derived_type z = asImp();
443 return (z+=b);
444 }
445
447 template <class Other>
449 {
450 derived_type z = asImp();
451 return (z-=b);
452 }
453
455 constexpr derived_type operator- () const
456 {
457 V result;
458 using idx_type = typename decltype(result)::size_type;
459
460 for (idx_type i = 0; i < size(); ++i)
461 result[i] = -asImp()[i];
462
463 return result;
464 }
465
467
475 template <typename ValueType>
476 constexpr typename std::enable_if<
477 std::is_convertible<ValueType, value_type>::value,
479 >::type&
480 operator+= (const ValueType& kk)
481 {
482 const value_type& k = kk;
483 for (size_type i=0; i<size(); i++)
484 (*this)[i] += k;
485 return asImp();
486 }
487
489
497 template <typename ValueType>
498 constexpr typename std::enable_if<
499 std::is_convertible<ValueType, value_type>::value,
501 >::type&
502 operator-= (const ValueType& kk)
503 {
504 const value_type& k = kk;
505 for (size_type i=0; i<size(); i++)
506 (*this)[i] -= k;
507 return asImp();
508 }
509
511
519 template <typename FieldType>
520 constexpr typename std::enable_if<
521 std::is_convertible<FieldType, field_type>::value,
523 >::type&
524 operator*= (const FieldType& kk)
525 {
526 const field_type& k = kk;
527 for (size_type i=0; i<size(); i++)
528 (*this)[i] *= k;
529 return asImp();
530 }
531
533
541 template <typename FieldType>
542 constexpr typename std::enable_if<
543 std::is_convertible<FieldType, field_type>::value,
545 >::type&
546 operator/= (const FieldType& kk)
547 {
548 const field_type& k = kk;
549 for (size_type i=0; i<size(); i++)
550 (*this)[i] /= k;
551 return asImp();
552 }
553
555 template <class Other>
556 constexpr bool operator== (const DenseVector<Other>& x) const
557 {
558 DUNE_ASSERT_BOUNDS(x.size() == size());
559 for (size_type i=0; i<size(); i++)
560 if ((*this)[i]!=x[i])
561 return false;
562
563 return true;
564 }
565
567 template <class Other>
568 constexpr bool operator!= (const DenseVector<Other>& x) const
569 {
570 return !operator==(x);
571 }
572
573
575 template <class Other>
576 constexpr derived_type& axpy (const field_type& a, const DenseVector<Other>& x)
577 {
578 DUNE_ASSERT_BOUNDS(x.size() == size());
579 for (size_type i=0; i<size(); i++)
580 (*this)[i] += a*x[i];
581 return asImp();
582 }
583
591 template<class Other>
593 typedef typename PromotionTraits<field_type, typename DenseVector<Other>::field_type>::PromotedType PromotedType;
594 PromotedType result(0);
595 assert(x.size() == size());
596 for (size_type i=0; i<size(); i++) {
597 result += PromotedType((*this)[i]*x[i]);
598 }
599 return result;
600 }
601
609 template<class Other>
611 typedef typename PromotionTraits<field_type, typename DenseVector<Other>::field_type>::PromotedType PromotedType;
612 PromotedType result(0);
613 assert(x.size() == size());
614 for (size_type i=0; i<size(); i++) {
615 result += Dune::dot((*this)[i],x[i]);
616 }
617 return result;
618 }
619
620 //===== norms
621
623 constexpr typename FieldTraits<value_type>::real_type one_norm() const {
624 using std::abs;
625 typename FieldTraits<value_type>::real_type result( 0 );
626 for (size_type i=0; i<size(); i++)
627 result += abs((*this)[i]);
628 return result;
629 }
630
631
633 constexpr typename FieldTraits<value_type>::real_type one_norm_real () const
634 {
635 typename FieldTraits<value_type>::real_type result( 0 );
636 for (size_type i=0; i<size(); i++)
637 result += fvmeta::absreal((*this)[i]);
638 return result;
639 }
640
642 constexpr typename FieldTraits<value_type>::real_type two_norm () const
643 {
644 typename FieldTraits<value_type>::real_type result( 0 );
645 for (size_type i=0; i<size(); i++)
646 result += fvmeta::abs2((*this)[i]);
647 return fvmeta::sqrt(result);
648 }
649
651 constexpr typename FieldTraits<value_type>::real_type two_norm2 () const
652 {
653 typename FieldTraits<value_type>::real_type result( 0 );
654 for (size_type i=0; i<size(); i++)
655 result += fvmeta::abs2((*this)[i]);
656 return result;
657 }
658
660 template <typename vt = value_type,
661 typename std::enable_if<!HasNaN<vt>::value, int>::type = 0>
662 constexpr typename FieldTraits<vt>::real_type infinity_norm() const {
663 using real_type = typename FieldTraits<vt>::real_type;
664 using std::abs;
665 using std::max;
666
667 real_type norm = 0;
668 for (auto const &x : *this) {
669 real_type const a = abs(x);
670 norm = max(a, norm);
671 }
672 return norm;
673 }
674
676 template <typename vt = value_type,
677 typename std::enable_if<!HasNaN<vt>::value, int>::type = 0>
678 constexpr typename FieldTraits<vt>::real_type infinity_norm_real() const {
679 using real_type = typename FieldTraits<vt>::real_type;
680 using std::max;
681
682 real_type norm = 0;
683 for (auto const &x : *this) {
684 real_type const a = fvmeta::absreal(x);
685 norm = max(a, norm);
686 }
687 return norm;
688 }
689
691 template <typename vt = value_type,
692 typename std::enable_if<HasNaN<vt>::value, int>::type = 0>
693 constexpr typename FieldTraits<vt>::real_type infinity_norm() const {
694 using real_type = typename FieldTraits<vt>::real_type;
695 using std::abs;
696 using std::max;
697
698 real_type norm = 0;
699 real_type isNaN = 1;
700 for (auto const &x : *this) {
701 real_type const a = abs(x);
702 norm = max(a, norm);
703 isNaN += a;
704 }
705 return norm * (isNaN / isNaN);
706 }
707
709 template <typename vt = value_type,
710 typename std::enable_if<HasNaN<vt>::value, int>::type = 0>
711 constexpr typename FieldTraits<vt>::real_type infinity_norm_real() const {
712 using real_type = typename FieldTraits<vt>::real_type;
713 using std::max;
714
715 real_type norm = 0;
716 real_type isNaN = 1;
717 for (auto const &x : *this) {
718 real_type const a = fvmeta::absreal(x);
719 norm = max(a, norm);
720 isNaN += a;
721 }
722 return norm * (isNaN / isNaN);
723 }
724
725 //===== sizes
726
728 constexpr size_type N () const
729 {
730 return size();
731 }
732
734 constexpr size_type dim () const
735 {
736 return size();
737 }
738
739 };
740
749 template<typename V>
750 std::ostream& operator<< (std::ostream& s, const DenseVector<V>& v)
751 {
752 for (typename DenseVector<V>::size_type i=0; i<v.size(); i++)
753 s << ((i>0) ? " " : "") << v[i];
754 return s;
755 }
756
759} // end namespace
760
761#endif // DUNE_DENSEVECTOR_HH
Macro for wrapping boundary checks.
Generic iterator class for dense vector and matrix implementations.
Definition: densevector.hh:132
constexpr SizeType index() const
return index
Definition: densevector.hh:214
std::ptrdiff_t DifferenceType
The type of the difference between two positions.
Definition: densevector.hh:143
C::size_type SizeType
The type to index the underlying container.
Definition: densevector.hh:148
Interface for a class of dense vectors over a given field.
Definition: densevector.hh:230
Traits::value_type value_type
export the type representing the field
Definition: densevector.hh:251
constexpr derived_type operator-() const
Vector negation.
Definition: densevector.hh:455
constexpr const value_type & front() const
return reference to first element
Definition: densevector.hh:313
ConstIterator const_iterator
typedef for stl compliant access
Definition: densevector.hh:382
constexpr const value_type & back() const
return reference to last element
Definition: densevector.hh:325
Iterator iterator
typedef for stl compliant access
Definition: densevector.hh:345
constexpr size_type N() const
number of blocks in the vector (are of size 1 here)
Definition: densevector.hh:728
constexpr bool empty() const
checks whether the container is empty
Definition: densevector.hh:331
constexpr std::enable_if< std::is_convertible< FieldType, field_type >::value, derived_type >::type & operator*=(const FieldType &kk)
vector space multiplication with scalar
Definition: densevector.hh:524
DenseIterator< const DenseVector, const value_type > ConstIterator
ConstIterator class for sequential access.
Definition: densevector.hh:380
constexpr FieldTraits< value_type >::real_type two_norm() const
two norm sqrt(sum over squared values of entries)
Definition: densevector.hh:642
constexpr derived_type & axpy(const field_type &a, const DenseVector< Other > &x)
vector space axpy operation ( *this += a x )
Definition: densevector.hh:576
Traits::derived_type derived_type
type of derived vector class
Definition: densevector.hh:248
constexpr Iterator end()
end iterator
Definition: densevector.hh:354
constexpr DenseVector & operator=(const DenseVector &)=default
Assignment operator for other DenseVector of same type.
constexpr derived_type & operator+=(const DenseVector< Other > &x)
vector space addition
Definition: densevector.hh:420
constexpr derived_type operator+(const DenseVector< Other > &b) const
Binary vector addition.
Definition: densevector.hh:440
constexpr 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:651
static constexpr int blocklevel
The number of block levels we contain. This is the leaf, that is, 1.
Definition: densevector.hh:263
constexpr bool operator!=(const DenseVector< Other > &x) const
Binary vector incomparison.
Definition: densevector.hh:568
Traits::size_type size_type
The type used for the index access and size operation.
Definition: densevector.hh:260
constexpr ConstIterator beforeEnd() const
Definition: densevector.hh:398
DenseIterator< DenseVector, value_type > Iterator
Iterator class for sequential access.
Definition: densevector.hh:343
constexpr Iterator beforeEnd()
Definition: densevector.hh:361
constexpr ConstIterator begin() const
begin ConstIterator
Definition: densevector.hh:385
constexpr std::enable_if< std::is_convertible< FieldType, field_type >::value, derived_type >::type & operator/=(const FieldType &kk)
vector space division by scalar
Definition: densevector.hh:546
constexpr ConstIterator end() const
end ConstIterator
Definition: densevector.hh:391
constexpr size_type dim() const
dimension of the vector space
Definition: densevector.hh:734
constexpr FieldTraits< vt >::real_type infinity_norm() const
infinity norm (maximum of absolute values of entries)
Definition: densevector.hh:662
constexpr derived_type & operator-=(const DenseVector< Other > &x)
vector space subtraction
Definition: densevector.hh:430
constexpr value_type & back()
return reference to last element
Definition: densevector.hh:319
constexpr derived_type & operator=(const value_type &k)
Assignment operator for scalar.
Definition: densevector.hh:267
constexpr FieldTraits< value_type >::real_type one_norm_real() const
simplified one norm (uses Manhattan norm for complex values)
Definition: densevector.hh:633
constexpr Iterator beforeBegin()
Definition: densevector.hh:368
Traits::value_type block_type
export the type representing the components
Definition: densevector.hh:257
constexpr Iterator find(size_type i)
return iterator to given element or end()
Definition: densevector.hh:374
constexpr FieldTraits< vt >::real_type infinity_norm_real() const
simplified infinity norm (uses Manhattan norm for complex values)
Definition: densevector.hh:678
FieldTraits< value_type >::field_type field_type
export the type representing the field
Definition: densevector.hh:254
constexpr bool operator==(const DenseVector< Other > &x) const
Binary vector comparison.
Definition: densevector.hh:556
constexpr Iterator begin()
begin iterator
Definition: densevector.hh:348
constexpr ConstIterator beforeBegin() const
Definition: densevector.hh:405
constexpr FieldTraits< value_type >::real_type one_norm() const
one norm (sum over absolute values of entries)
Definition: densevector.hh:623
constexpr PromotionTraits< field_type, typenameDenseVector< Other >::field_type >::PromotedType operator*(const DenseVector< Other > &x) const
indefinite vector dot product which corresponds to Petsc's VecTDot
Definition: densevector.hh:592
constexpr PromotionTraits< field_type, typenameDenseVector< Other >::field_type >::PromotedType dot(const DenseVector< Other > &x) const
vector dot product which corresponds to Petsc's VecDot
Definition: densevector.hh:610
constexpr ConstIterator find(size_type i) const
return iterator to given element or end()
Definition: densevector.hh:411
constexpr value_type & front()
return reference to first element
Definition: densevector.hh:307
constexpr size_type size() const
size method
Definition: densevector.hh:337
constexpr value_type & operator[](size_type i)
random access
Definition: densevector.hh:296
Base class for stl conformant forward iterators.
Definition: iteratorfacades.hh:435
Provides the functions dot(a,b) := and dotT(a,b) := .
Type traits to determine the type of reals (when working with complex numbers)
Implements a generic iterator class for writing stl conformant iterators.
#define DUNE_ASSERT_BOUNDS(cond)
If DUNE_CHECK_BOUNDS is defined: check if condition cond holds; otherwise, do nothing.
Definition: boundschecking.hh:30
auto dot(const A &a, const B &b) -> typename std::enable_if< IsNumber< A >::value &&!IsVector< A >::value &&!std::is_same< typename FieldTraits< A >::field_type, typename FieldTraits< A >::real_type > ::value, decltype(conj(a) *b)>::type
computes the dot product for fundamental data types according to Petsc's VectDot function: dot(a,...
Definition: dotproduct.hh:42
constexpr auto max
Function object that returns the greater of the given values.
Definition: hybridutilities.hh:485
constexpr auto min
Function object that returns the smaller of the given values.
Definition: hybridutilities.hh:507
Documentation of the traits classes you need to write for each implementation of DenseVector or Dense...
bool isNaN(const FieldVector< K, SIZE > &b, PriorityTag< 2 >, ADLTag)
Returns whether any entry is NaN.
Definition: fvector.hh:630
Dune namespace.
Definition: alignedallocator.hh:13
STL namespace.
Compute type of the result of an arithmetic operation involving two different number types.
Compute type of the result of an arithmetic operation involving two different number types.
Definition: promotiontraits.hh:27
get the 'mutable' version of a reference to a const object
Definition: genericiterator.hh:116
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden & Uni Heidelberg  |  generated with Hugo v0.111.3 (Apr 5, 23:02, 2025)