dune-common 2.12-git
Loading...
Searching...
No Matches
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>
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
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 {
161 (*this) = other;
162 }
163
164 constexpr DenseIterator(const ConstIterator & other)
165 {
166 (*this) = other;
167 }
168
169 constexpr DenseIterator & operator= (const ConstIterator & other) {
170 container_ = other.container_;
171 position_ = other.position_;
172 return *this;
173 }
174
175 constexpr DenseIterator & operator= (const MutableIterator & other) {
176 container_ = other.container_;
177 position_ = other.position_;
178 return *this;
179 }
180
181 // Methods needed by the forward iterator
182 constexpr bool equals(const MutableIterator &other) const
183 {
184 return position_ == other.position_ && container_ == other.container_;
185 }
186
187
188 constexpr bool equals(const ConstIterator & other) const
189 {
190 return position_ == other.position_ && container_ == other.container_;
191 }
192
193 constexpr R dereference() const {
194 return container_->operator[](position_);
195 }
196
197 constexpr void increment(){
198 ++position_;
199 }
200
201 // Additional function needed by BidirectionalIterator
202 constexpr void decrement(){
203 --position_;
204 }
205
206 // Additional function needed by RandomAccessIterator
207 constexpr R elementAt(DifferenceType i) const {
208 return container_->operator[](position_+i);
209 }
210
211 constexpr void advance(DifferenceType n){
212 position_=position_+n;
213 }
214
216 {
217 assert(other.container_==container_);
218 return static_cast< DifferenceType >( other.position_ ) - static_cast< DifferenceType >( position_ );
219 }
220
222 {
223 assert(other.container_==container_);
224 return static_cast< DifferenceType >( other.position_ ) - static_cast< DifferenceType >( position_ );
225 }
226
228 constexpr SizeType index () const
229 {
230 return this->position_;
231 }
232
233 private:
234 C *container_;
235 SizeType position_;
236 };
237
242 template<typename V>
244 {
246 // typedef typename Traits::value_type K;
247
248 // Curiously recurring template pattern
249 constexpr V & asImp() { return static_cast<V&>(*this); }
250 constexpr const V & asImp() const { return static_cast<const V&>(*this); }
251
252 template<class OtherV>
253 static constexpr bool isDenseVector = std::is_base_of_v<DenseVector<OtherV>, OtherV>;
254
255 protected:
256 // construction allowed to derived classes only
257 constexpr DenseVector() = default;
258 // copying only allowed by derived classes
259 constexpr DenseVector(const DenseVector&) = default;
260
261 public:
262 //===== type definitions and constants
263
265 typedef typename Traits::derived_type derived_type;
266
268 typedef typename Traits::value_type value_type;
269
272
274 typedef typename Traits::value_type block_type;
275
277 typedef typename Traits::size_type size_type;
278
280 constexpr static int blocklevel = 1;
281
282 //===== assignment from scalar
284 constexpr inline derived_type& operator= (const value_type& k)
285 {
286 for (size_type i=0; i<size(); i++)
287 asImp()[i] = k;
288 return asImp();
289 }
290
291 //===== assignment from other DenseVectors
292 protected:
294 constexpr DenseVector& operator=(const DenseVector&) = default;
295
296 public:
297
299 template <typename W,
302 constexpr derived_type& operator= (const DenseVector<W>& other)
303 {
304 assert(other.size() == size());
305 for (size_type i=0; i<size(); i++)
306 asImp()[i] = other[i];
307 return asImp();
308 }
309
310 //===== access to components
311
314 {
315 return asImp()[i];
316 }
317
318 constexpr const value_type & operator[] (size_type i) const
319 {
320 return asImp()[i];
321 }
322
324 constexpr value_type& front()
325 {
326 return asImp()[0];
327 }
328
330 constexpr const value_type& front() const
331 {
332 return asImp()[0];
333 }
334
336 constexpr value_type& back()
337 {
338 return asImp()[size()-1];
339 }
340
342 constexpr const value_type& back() const
343 {
344 return asImp()[size()-1];
345 }
346
348 constexpr bool empty() const
349 {
350 return size() == 0;
351 }
352
354 constexpr size_type size() const
355 {
356 return asImp().size();
357 }
358
363
365 constexpr Iterator begin ()
366 {
367 return Iterator(*this,0);
368 }
369
371 constexpr Iterator end ()
372 {
373 return Iterator(*this,size());
374 }
375
378 constexpr Iterator beforeEnd ()
379 {
380 return Iterator(*this,size()-1);
381 }
382
386 {
387 return Iterator(*this,-1);
388 }
389
391 constexpr Iterator find (size_type i)
392 {
393 return Iterator(*this,std::min(i,size()));
394 }
395
400
402 constexpr ConstIterator begin () const
403 {
404 return ConstIterator(*this,0);
405 }
406
408 constexpr ConstIterator end () const
409 {
410 return ConstIterator(*this,size());
411 }
412
415 constexpr ConstIterator beforeEnd () const
416 {
417 return ConstIterator(*this,size()-1);
418 }
419
422 constexpr ConstIterator beforeBegin () const
423 {
424 return ConstIterator(*this,-1);
425 }
426
428 constexpr ConstIterator find (size_type i) const
429 {
430 return ConstIterator(*this,std::min(i,size()));
431 }
432
433 //===== vector space arithmetic
434
436 template <class Other>
438 {
439 DUNE_ASSERT_BOUNDS(x.size() == size());
440 for (size_type i=0; i<size(); i++)
441 (*this)[i] += x[i];
442 return asImp();
443 }
444
446 template <class Other>
448 {
449 DUNE_ASSERT_BOUNDS(x.size() == size());
450 for (size_type i=0; i<size(); i++)
451 (*this)[i] -= x[i];
452 return asImp();
453 }
454
456 template <class Other>
458 {
459 derived_type z = asImp();
460 return (z+=b);
461 }
462
464 template <class Other>
466 {
467 derived_type z = asImp();
468 return (z-=b);
469 }
470
472 constexpr derived_type operator- () const
473 {
474 V result;
475 using idx_type = typename decltype(result)::size_type;
476
477 for (idx_type i = 0; i < size(); ++i)
478 result[i] = -asImp()[i];
479
480 return result;
481 }
482
484
492 template <typename ValueType>
493 constexpr typename std::enable_if<
494 (not isDenseVector<ValueType>) and
497 >::type&
498 operator+= (const ValueType& kk)
499 {
500 const value_type& k = kk;
501 for (size_type i=0; i<size(); i++)
502 (*this)[i] += k;
503 return asImp();
504 }
505
507
515 template <typename ValueType>
516 constexpr typename std::enable_if<
517 (not isDenseVector<ValueType>) and
520 >::type&
521 operator-= (const ValueType& kk)
522 {
523 const value_type& k = kk;
524 for (size_type i=0; i<size(); i++)
525 (*this)[i] -= k;
526 return asImp();
527 }
528
530
538 template <typename FieldType>
539 constexpr typename std::enable_if<
540 (not isDenseVector<FieldType>) and
543 >::type&
544 operator*= (const FieldType& kk)
545 {
546 const field_type& k = kk;
547 for (size_type i=0; i<size(); i++)
548 (*this)[i] *= k;
549 return asImp();
550 }
551
553
561 template <typename FieldType>
562 constexpr typename std::enable_if<
563 (not isDenseVector<FieldType>) and
566 >::type&
567 operator/= (const FieldType& kk)
568 {
569 const field_type& k = kk;
570 for (size_type i=0; i<size(); i++)
571 (*this)[i] /= k;
572 return asImp();
573 }
574
576 template <class Other>
577 constexpr bool operator== (const DenseVector<Other>& x) const
578 {
579 DUNE_ASSERT_BOUNDS(x.size() == size());
580 for (size_type i=0; i<size(); i++)
581 if ((*this)[i]!=x[i])
582 return false;
583
584 return true;
585 }
586
588 template <class Other>
589 constexpr bool operator!= (const DenseVector<Other>& x) const
590 {
591 return !operator==(x);
592 }
593
594
596 template <class Other>
597 constexpr derived_type& axpy (const field_type& a, const DenseVector<Other>& x)
598 {
599 DUNE_ASSERT_BOUNDS(x.size() == size());
600 for (size_type i=0; i<size(); i++)
601 (*this)[i] += a*x[i];
602 return asImp();
603 }
604
612 template<class Other>
614 typedef typename PromotionTraits<field_type, typename DenseVector<Other>::field_type>::PromotedType PromotedType;
615 PromotedType result(0);
616 assert(x.size() == size());
617 for (size_type i=0; i<size(); i++) {
618 result += PromotedType((*this)[i]*x[i]);
619 }
620 return result;
621 }
622
630 template<class Other>
632 typedef typename PromotionTraits<field_type, typename DenseVector<Other>::field_type>::PromotedType PromotedType;
633 PromotedType result(0);
634 assert(x.size() == size());
635 for (size_type i=0; i<size(); i++) {
636 result += Dune::dot((*this)[i],x[i]);
637 }
638 return result;
639 }
640
641 //===== norms
642
644 constexpr typename FieldTraits<value_type>::real_type one_norm() const {
645 using std::abs;
646 typename FieldTraits<value_type>::real_type result( 0 );
647 for (size_type i=0; i<size(); i++)
648 result += abs((*this)[i]);
649 return result;
650 }
651
652
655 {
656 typename FieldTraits<value_type>::real_type result( 0 );
657 for (size_type i=0; i<size(); i++)
658 result += fvmeta::absreal((*this)[i]);
659 return result;
660 }
661
664 {
665 typename FieldTraits<value_type>::real_type result( 0 );
666 for (size_type i=0; i<size(); i++)
667 result += fvmeta::abs2((*this)[i]);
668 return fvmeta::sqrt(result);
669 }
670
673 {
674 typename FieldTraits<value_type>::real_type result( 0 );
675 for (size_type i=0; i<size(); i++)
676 result += fvmeta::abs2((*this)[i]);
677 return result;
678 }
679
681 template <typename vt = value_type,
682 typename std::enable_if<!HasNaN<vt>::value, int>::type = 0>
683 constexpr typename FieldTraits<vt>::real_type infinity_norm() const {
684 using real_type = typename FieldTraits<vt>::real_type;
685 using std::abs;
686 using std::max;
687
688 real_type norm = 0;
689 for (auto const &x : *this) {
690 real_type const a = abs(x);
691 norm = max(a, norm);
692 }
693 return norm;
694 }
695
697 template <typename vt = value_type,
698 typename std::enable_if<!HasNaN<vt>::value, int>::type = 0>
700 using real_type = typename FieldTraits<vt>::real_type;
701 using std::max;
702
703 real_type norm = 0;
704 for (auto const &x : *this) {
705 real_type const a = fvmeta::absreal(x);
706 norm = max(a, norm);
707 }
708 return norm;
709 }
710
712 template <typename vt = value_type,
713 typename std::enable_if<HasNaN<vt>::value, int>::type = 0>
714 constexpr typename FieldTraits<vt>::real_type infinity_norm() const {
715 using real_type = typename FieldTraits<vt>::real_type;
716 using std::abs;
717 using std::max;
718
719 real_type norm = 0;
720 real_type isNaN = 1;
721 for (auto const &x : *this) {
722 real_type const a = abs(x);
723 norm = max(a, norm);
724 isNaN += a;
725 }
726 return norm * (isNaN / isNaN);
727 }
728
730 template <typename vt = value_type,
731 typename std::enable_if<HasNaN<vt>::value, int>::type = 0>
733 using real_type = typename FieldTraits<vt>::real_type;
734 using std::max;
735
736 real_type norm = 0;
737 real_type isNaN = 1;
738 for (auto const &x : *this) {
739 real_type const a = fvmeta::absreal(x);
740 norm = max(a, norm);
741 isNaN += a;
742 }
743 return norm * (isNaN / isNaN);
744 }
745
746 //===== sizes
747
749 constexpr size_type N () const
750 {
751 return size();
752 }
753
755 constexpr size_type dim () const
756 {
757 return size();
758 }
759
760 };
761
770 template<typename V>
772 {
773 for (typename DenseVector<V>::size_type i=0; i<v.size(); i++)
774 s << ((i>0) ? " " : "") << v[i];
775 return s;
776 }
777
780} // end namespace
781
782#endif // DUNE_DENSEVECTOR_HH
Macro for wrapping boundary checks.
Type traits to determine the type of reals (when working with complex numbers)
Implements a generic iterator class for writing stl conformant iterators.
Documentation of the traits classes you need to write for each implementation of DenseVector or Dense...
Compute type of the result of an arithmetic operation involving two different number types.
Provides the functions dot(a,b) := and dotT(a,b) := .
#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:40
std::ostream & operator<<(std::ostream &s, const bigunsignedint< k > &x)
Definition bigunsignedint.hh:301
STL namespace.
Dune namespace
Definition alignedallocator.hh:13
constexpr auto sqrt(T t)
Definition cmath.hh:39
constexpr T abs(T t)
Definition cmath.hh:27
Interface for a class of dense vectors over a given field.
Definition densevector.hh:244
Traits::value_type value_type
export the type representing the field
Definition densevector.hh:268
constexpr derived_type operator-() const
Vector negation.
Definition densevector.hh:472
constexpr const value_type & front() const
return reference to first element
Definition densevector.hh:330
ConstIterator const_iterator
typedef for stl compliant access
Definition densevector.hh:399
constexpr const value_type & back() const
return reference to last element
Definition densevector.hh:342
Iterator iterator
typedef for stl compliant access
Definition densevector.hh:362
constexpr size_type N() const
number of blocks in the vector (are of size 1 here)
Definition densevector.hh:749
constexpr bool empty() const
checks whether the container is empty
Definition densevector.hh:348
DenseIterator< const DenseVector, const value_type > ConstIterator
ConstIterator class for sequential access.
Definition densevector.hh:397
constexpr FieldTraits< value_type >::real_type two_norm() const
two norm sqrt(sum over squared values of entries)
Definition densevector.hh:663
constexpr derived_type & axpy(const field_type &a, const DenseVector< Other > &x)
vector space axpy operation ( *this += a x )
Definition densevector.hh:597
Traits::derived_type derived_type
type of derived vector class
Definition densevector.hh:265
constexpr Iterator end()
end iterator
Definition densevector.hh:371
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:437
constexpr derived_type operator+(const DenseVector< Other > &b) const
Binary vector addition.
Definition densevector.hh:457
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:672
static constexpr int blocklevel
The number of block levels we contain. This is the leaf, that is, 1.
Definition densevector.hh:280
constexpr bool operator!=(const DenseVector< Other > &x) const
Binary vector incomparison.
Definition densevector.hh:589
Traits::size_type size_type
The type used for the index access and size operation.
Definition densevector.hh:277
constexpr ConstIterator beforeEnd() const
Definition densevector.hh:415
DenseIterator< DenseVector, value_type > Iterator
Iterator class for sequential access.
Definition densevector.hh:360
constexpr Iterator beforeEnd()
Definition densevector.hh:378
constexpr ConstIterator begin() const
begin ConstIterator
Definition densevector.hh:402
constexpr ConstIterator end() const
end ConstIterator
Definition densevector.hh:408
constexpr size_type dim() const
dimension of the vector space
Definition densevector.hh:755
constexpr FieldTraits< vt >::real_type infinity_norm() const
infinity norm (maximum of absolute values of entries)
Definition densevector.hh:683
constexpr derived_type & operator-=(const DenseVector< Other > &x)
vector space subtraction
Definition densevector.hh:447
constexpr DenseVector()=default
constexpr value_type & back()
return reference to last element
Definition densevector.hh:336
constexpr derived_type & operator=(const value_type &k)
Assignment operator for scalar.
Definition densevector.hh:284
constexpr FieldTraits< value_type >::real_type one_norm_real() const
simplified one norm (uses Manhattan norm for complex values)
Definition densevector.hh:654
constexpr Iterator beforeBegin()
Definition densevector.hh:385
Traits::value_type block_type
export the type representing the components
Definition densevector.hh:274
constexpr Iterator find(size_type i)
return iterator to given element or end()
Definition densevector.hh:391
constexpr FieldTraits< vt >::real_type infinity_norm_real() const
simplified infinity norm (uses Manhattan norm for complex values)
Definition densevector.hh:699
FieldTraits< value_type >::field_type field_type
export the type representing the field
Definition densevector.hh:271
constexpr DenseVector(const DenseVector &)=default
constexpr bool operator==(const DenseVector< Other > &x) const
Binary vector comparison.
Definition densevector.hh:577
constexpr Iterator begin()
begin iterator
Definition densevector.hh:365
constexpr ConstIterator beforeBegin() const
Definition densevector.hh:422
constexpr FieldTraits< value_type >::real_type one_norm() const
one norm (sum over absolute values of entries)
Definition densevector.hh:644
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:613
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:631
constexpr ConstIterator find(size_type i) const
return iterator to given element or end()
Definition densevector.hh:428
constexpr value_type & front()
return reference to first element
Definition densevector.hh:324
constexpr size_type size() const
size method
Definition densevector.hh:354
constexpr value_type & operator[](size_type i)
random access
Definition densevector.hh:313
FieldTraits< typenameDenseMatVecTraits< V >::value_type >::real_type real_type
Definition densevector.hh:29
FieldTraits< typenameDenseMatVecTraits< V >::value_type >::field_type field_type
Definition densevector.hh:28
Generic iterator class for dense vector and matrix implementations.
Definition densevector.hh:132
constexpr R dereference() const
Definition densevector.hh:193
constexpr R elementAt(DifferenceType i) const
Definition densevector.hh:207
constexpr DenseIterator(const MutableIterator &other)
Definition densevector.hh:159
constexpr DifferenceType distanceTo(DenseIterator< typename std::remove_const< C >::type, typename std::remove_const< T >::type > other) const
Definition densevector.hh:221
constexpr DenseIterator(const ConstIterator &other)
Definition densevector.hh:164
constexpr DenseIterator & operator=(const ConstIterator &other)
Definition densevector.hh:169
constexpr bool equals(const MutableIterator &other) const
Definition densevector.hh:182
constexpr bool equals(const ConstIterator &other) const
Definition densevector.hh:188
constexpr SizeType index() const
return index
Definition densevector.hh:228
constexpr void increment()
Definition densevector.hh:197
constexpr void decrement()
Definition densevector.hh:202
constexpr DifferenceType distanceTo(DenseIterator< const typename std::remove_const< C >::type, const typename std::remove_const< T >::type > other) const
Definition densevector.hh:215
constexpr DenseIterator(C &cont, SizeType pos)
Definition densevector.hh:155
constexpr void advance(DifferenceType n)
Definition densevector.hh:211
C::size_type SizeType
The type to index the underlying container.
Definition densevector.hh:148
Definition ftraits.hh:26
T field_type
export the type representing the field
Definition ftraits.hh:28
T real_type
export the type representing the real type of the field
Definition ftraits.hh:30
get the 'mutable' version of a reference to a const object
Definition genericiterator.hh:116
Base class for stl conformant forward iterators.
Definition iteratorfacades.hh:435
Definition matvectraits.hh:31
Compute type of the result of an arithmetic operation involving two different number types.
Definition promotiontraits.hh:27
T imag(T... args)
T max(T... args)
T min(T... args)
T real(T... args)
T sqrt(T... args)