Dune Core Modules (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 {
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
215 constexpr DifferenceType distanceTo(DenseIterator<const typename std::remove_const<C>::type,const typename std::remove_const<T>::type> other) const
216 {
217 assert(other.container_==container_);
218 return static_cast< DifferenceType >( other.position_ ) - static_cast< DifferenceType >( position_ );
219 }
220
221 constexpr DifferenceType distanceTo(DenseIterator<typename std::remove_const<C>::type, typename std::remove_const<T>::type> other) const
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 {
245 typedef DenseMatVecTraits<V> Traits;
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 protected:
253 // construction allowed to derived classes only
254 constexpr DenseVector() = default;
255 // copying only allowed by derived classes
256 constexpr DenseVector(const DenseVector&) = default;
257
258 public:
259 //===== type definitions and constants
260
262 typedef typename Traits::derived_type derived_type;
263
265 typedef typename Traits::value_type value_type;
266
268 typedef typename FieldTraits< value_type >::field_type field_type;
269
271 typedef typename Traits::value_type block_type;
272
274 typedef typename Traits::size_type size_type;
275
277 constexpr static int blocklevel = 1;
278
279 //===== assignment from scalar
281 constexpr inline derived_type& operator= (const value_type& k)
282 {
283 for (size_type i=0; i<size(); i++)
284 asImp()[i] = k;
285 return asImp();
286 }
287
288 //===== assignment from other DenseVectors
289 protected:
291 constexpr DenseVector& operator=(const DenseVector&) = default;
292
293 public:
294
296 template <typename W,
297 std::enable_if_t<
298 std::is_assignable<value_type&, typename DenseVector<W>::value_type>::value, int> = 0>
299 constexpr derived_type& operator= (const DenseVector<W>& other)
300 {
301 assert(other.size() == size());
302 for (size_type i=0; i<size(); i++)
303 asImp()[i] = other[i];
304 return asImp();
305 }
306
307 //===== access to components
308
311 {
312 return asImp()[i];
313 }
314
315 constexpr const value_type & operator[] (size_type i) const
316 {
317 return asImp()[i];
318 }
319
321 constexpr value_type& front()
322 {
323 return asImp()[0];
324 }
325
327 constexpr const value_type& front() const
328 {
329 return asImp()[0];
330 }
331
333 constexpr value_type& back()
334 {
335 return asImp()[size()-1];
336 }
337
339 constexpr const value_type& back() const
340 {
341 return asImp()[size()-1];
342 }
343
345 constexpr bool empty() const
346 {
347 return size() == 0;
348 }
349
351 constexpr size_type size() const
352 {
353 return asImp().size();
354 }
355
360
362 constexpr Iterator begin ()
363 {
364 return Iterator(*this,0);
365 }
366
368 constexpr Iterator end ()
369 {
370 return Iterator(*this,size());
371 }
372
375 constexpr Iterator beforeEnd ()
376 {
377 return Iterator(*this,size()-1);
378 }
379
383 {
384 return Iterator(*this,-1);
385 }
386
388 constexpr Iterator find (size_type i)
389 {
390 return Iterator(*this,std::min(i,size()));
391 }
392
397
399 constexpr ConstIterator begin () const
400 {
401 return ConstIterator(*this,0);
402 }
403
405 constexpr ConstIterator end () const
406 {
407 return ConstIterator(*this,size());
408 }
409
412 constexpr ConstIterator beforeEnd () const
413 {
414 return ConstIterator(*this,size()-1);
415 }
416
419 constexpr ConstIterator beforeBegin () const
420 {
421 return ConstIterator(*this,-1);
422 }
423
425 constexpr ConstIterator find (size_type i) const
426 {
427 return ConstIterator(*this,std::min(i,size()));
428 }
429
430 //===== vector space arithmetic
431
433 template <class Other>
435 {
436 DUNE_ASSERT_BOUNDS(x.size() == size());
437 for (size_type i=0; i<size(); i++)
438 (*this)[i] += x[i];
439 return asImp();
440 }
441
443 template <class Other>
445 {
446 DUNE_ASSERT_BOUNDS(x.size() == size());
447 for (size_type i=0; i<size(); i++)
448 (*this)[i] -= x[i];
449 return asImp();
450 }
451
453 template <class Other>
455 {
456 derived_type z = asImp();
457 return (z+=b);
458 }
459
461 template <class Other>
463 {
464 derived_type z = asImp();
465 return (z-=b);
466 }
467
469 constexpr derived_type operator- () const
470 {
471 V result;
472 using idx_type = typename decltype(result)::size_type;
473
474 for (idx_type i = 0; i < size(); ++i)
475 result[i] = -asImp()[i];
476
477 return result;
478 }
479
481
489 template <typename ValueType>
490 constexpr typename std::enable_if<
491 std::is_convertible<ValueType, value_type>::value,
493 >::type&
494 operator+= (const ValueType& kk)
495 {
496 const value_type& k = kk;
497 for (size_type i=0; i<size(); i++)
498 (*this)[i] += k;
499 return asImp();
500 }
501
503
511 template <typename ValueType>
512 constexpr typename std::enable_if<
513 std::is_convertible<ValueType, value_type>::value,
515 >::type&
516 operator-= (const ValueType& kk)
517 {
518 const value_type& k = kk;
519 for (size_type i=0; i<size(); i++)
520 (*this)[i] -= k;
521 return asImp();
522 }
523
525
533 template <typename FieldType>
534 constexpr typename std::enable_if<
535 std::is_convertible<FieldType, field_type>::value,
537 >::type&
538 operator*= (const FieldType& kk)
539 {
540 const field_type& k = kk;
541 for (size_type i=0; i<size(); i++)
542 (*this)[i] *= k;
543 return asImp();
544 }
545
547
555 template <typename FieldType>
556 constexpr typename std::enable_if<
557 std::is_convertible<FieldType, field_type>::value,
559 >::type&
560 operator/= (const FieldType& kk)
561 {
562 const field_type& k = kk;
563 for (size_type i=0; i<size(); i++)
564 (*this)[i] /= k;
565 return asImp();
566 }
567
569 template <class Other>
570 constexpr bool operator== (const DenseVector<Other>& x) const
571 {
572 DUNE_ASSERT_BOUNDS(x.size() == size());
573 for (size_type i=0; i<size(); i++)
574 if ((*this)[i]!=x[i])
575 return false;
576
577 return true;
578 }
579
581 template <class Other>
582 constexpr bool operator!= (const DenseVector<Other>& x) const
583 {
584 return !operator==(x);
585 }
586
587
589 template <class Other>
590 constexpr derived_type& axpy (const field_type& a, const DenseVector<Other>& x)
591 {
592 DUNE_ASSERT_BOUNDS(x.size() == size());
593 for (size_type i=0; i<size(); i++)
594 (*this)[i] += a*x[i];
595 return asImp();
596 }
597
605 template<class Other>
607 typedef typename PromotionTraits<field_type, typename DenseVector<Other>::field_type>::PromotedType PromotedType;
608 PromotedType result(0);
609 assert(x.size() == size());
610 for (size_type i=0; i<size(); i++) {
611 result += PromotedType((*this)[i]*x[i]);
612 }
613 return result;
614 }
615
623 template<class Other>
625 typedef typename PromotionTraits<field_type, typename DenseVector<Other>::field_type>::PromotedType PromotedType;
626 PromotedType result(0);
627 assert(x.size() == size());
628 for (size_type i=0; i<size(); i++) {
629 result += Dune::dot((*this)[i],x[i]);
630 }
631 return result;
632 }
633
634 //===== norms
635
637 constexpr typename FieldTraits<value_type>::real_type one_norm() const {
638 using std::abs;
639 typename FieldTraits<value_type>::real_type result( 0 );
640 for (size_type i=0; i<size(); i++)
641 result += abs((*this)[i]);
642 return result;
643 }
644
645
647 constexpr typename FieldTraits<value_type>::real_type one_norm_real () const
648 {
649 typename FieldTraits<value_type>::real_type result( 0 );
650 for (size_type i=0; i<size(); i++)
651 result += fvmeta::absreal((*this)[i]);
652 return result;
653 }
654
656 constexpr typename FieldTraits<value_type>::real_type two_norm () const
657 {
658 typename FieldTraits<value_type>::real_type result( 0 );
659 for (size_type i=0; i<size(); i++)
660 result += fvmeta::abs2((*this)[i]);
661 return fvmeta::sqrt(result);
662 }
663
665 constexpr typename FieldTraits<value_type>::real_type two_norm2 () const
666 {
667 typename FieldTraits<value_type>::real_type result( 0 );
668 for (size_type i=0; i<size(); i++)
669 result += fvmeta::abs2((*this)[i]);
670 return result;
671 }
672
674 template <typename vt = value_type,
675 typename std::enable_if<!HasNaN<vt>::value, int>::type = 0>
676 constexpr typename FieldTraits<vt>::real_type infinity_norm() const {
677 using real_type = typename FieldTraits<vt>::real_type;
678 using std::abs;
679 using std::max;
680
681 real_type norm = 0;
682 for (auto const &x : *this) {
683 real_type const a = abs(x);
684 norm = max(a, norm);
685 }
686 return norm;
687 }
688
690 template <typename vt = value_type,
691 typename std::enable_if<!HasNaN<vt>::value, int>::type = 0>
692 constexpr typename FieldTraits<vt>::real_type infinity_norm_real() const {
693 using real_type = typename FieldTraits<vt>::real_type;
694 using std::max;
695
696 real_type norm = 0;
697 for (auto const &x : *this) {
698 real_type const a = fvmeta::absreal(x);
699 norm = max(a, norm);
700 }
701 return norm;
702 }
703
705 template <typename vt = value_type,
706 typename std::enable_if<HasNaN<vt>::value, int>::type = 0>
707 constexpr typename FieldTraits<vt>::real_type infinity_norm() const {
708 using real_type = typename FieldTraits<vt>::real_type;
709 using std::abs;
710 using std::max;
711
712 real_type norm = 0;
713 real_type isNaN = 1;
714 for (auto const &x : *this) {
715 real_type const a = abs(x);
716 norm = max(a, norm);
717 isNaN += a;
718 }
719 return norm * (isNaN / isNaN);
720 }
721
723 template <typename vt = value_type,
724 typename std::enable_if<HasNaN<vt>::value, int>::type = 0>
725 constexpr typename FieldTraits<vt>::real_type infinity_norm_real() const {
726 using real_type = typename FieldTraits<vt>::real_type;
727 using std::max;
728
729 real_type norm = 0;
730 real_type isNaN = 1;
731 for (auto const &x : *this) {
732 real_type const a = fvmeta::absreal(x);
733 norm = max(a, norm);
734 isNaN += a;
735 }
736 return norm * (isNaN / isNaN);
737 }
738
739 //===== sizes
740
742 constexpr size_type N () const
743 {
744 return size();
745 }
746
748 constexpr size_type dim () const
749 {
750 return size();
751 }
752
753 };
754
763 template<typename V>
764 std::ostream& operator<< (std::ostream& s, const DenseVector<V>& v)
765 {
766 for (typename DenseVector<V>::size_type i=0; i<v.size(); i++)
767 s << ((i>0) ? " " : "") << v[i];
768 return s;
769 }
770
773} // end namespace
774
775#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:228
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:244
Traits::value_type value_type
export the type representing the field
Definition: densevector.hh:265
constexpr derived_type operator-() const
Vector negation.
Definition: densevector.hh:469
constexpr const value_type & front() const
return reference to first element
Definition: densevector.hh:327
ConstIterator const_iterator
typedef for stl compliant access
Definition: densevector.hh:396
constexpr const value_type & back() const
return reference to last element
Definition: densevector.hh:339
Iterator iterator
typedef for stl compliant access
Definition: densevector.hh:359
constexpr size_type N() const
number of blocks in the vector (are of size 1 here)
Definition: densevector.hh:742
constexpr bool empty() const
checks whether the container is empty
Definition: densevector.hh:345
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:538
DenseIterator< const DenseVector, const value_type > ConstIterator
ConstIterator class for sequential access.
Definition: densevector.hh:394
constexpr FieldTraits< value_type >::real_type two_norm() const
two norm sqrt(sum over squared values of entries)
Definition: densevector.hh:656
constexpr derived_type & axpy(const field_type &a, const DenseVector< Other > &x)
vector space axpy operation ( *this += a x )
Definition: densevector.hh:590
Traits::derived_type derived_type
type of derived vector class
Definition: densevector.hh:262
constexpr Iterator end()
end iterator
Definition: densevector.hh:368
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:434
constexpr derived_type operator+(const DenseVector< Other > &b) const
Binary vector addition.
Definition: densevector.hh:454
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:665
static constexpr int blocklevel
The number of block levels we contain. This is the leaf, that is, 1.
Definition: densevector.hh:277
constexpr bool operator!=(const DenseVector< Other > &x) const
Binary vector incomparison.
Definition: densevector.hh:582
Traits::size_type size_type
The type used for the index access and size operation.
Definition: densevector.hh:274
constexpr ConstIterator beforeEnd() const
Definition: densevector.hh:412
DenseIterator< DenseVector, value_type > Iterator
Iterator class for sequential access.
Definition: densevector.hh:357
constexpr Iterator beforeEnd()
Definition: densevector.hh:375
constexpr ConstIterator begin() const
begin ConstIterator
Definition: densevector.hh:399
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:560
constexpr ConstIterator end() const
end ConstIterator
Definition: densevector.hh:405
constexpr size_type dim() const
dimension of the vector space
Definition: densevector.hh:748
constexpr FieldTraits< vt >::real_type infinity_norm() const
infinity norm (maximum of absolute values of entries)
Definition: densevector.hh:676
constexpr derived_type & operator-=(const DenseVector< Other > &x)
vector space subtraction
Definition: densevector.hh:444
constexpr value_type & back()
return reference to last element
Definition: densevector.hh:333
constexpr derived_type & operator=(const value_type &k)
Assignment operator for scalar.
Definition: densevector.hh:281
constexpr FieldTraits< value_type >::real_type one_norm_real() const
simplified one norm (uses Manhattan norm for complex values)
Definition: densevector.hh:647
constexpr Iterator beforeBegin()
Definition: densevector.hh:382
Traits::value_type block_type
export the type representing the components
Definition: densevector.hh:271
constexpr Iterator find(size_type i)
return iterator to given element or end()
Definition: densevector.hh:388
constexpr FieldTraits< vt >::real_type infinity_norm_real() const
simplified infinity norm (uses Manhattan norm for complex values)
Definition: densevector.hh:692
FieldTraits< value_type >::field_type field_type
export the type representing the field
Definition: densevector.hh:268
constexpr bool operator==(const DenseVector< Other > &x) const
Binary vector comparison.
Definition: densevector.hh:570
constexpr Iterator begin()
begin iterator
Definition: densevector.hh:362
constexpr ConstIterator beforeBegin() const
Definition: densevector.hh:419
constexpr FieldTraits< value_type >::real_type one_norm() const
one norm (sum over absolute values of entries)
Definition: densevector.hh:637
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:606
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:624
constexpr ConstIterator find(size_type i) const
return iterator to given element or end()
Definition: densevector.hh:425
constexpr value_type & front()
return reference to first element
Definition: densevector.hh:321
constexpr size_type size() const
size method
Definition: densevector.hh:351
constexpr value_type & operator[](size_type i)
random access
Definition: densevector.hh:310
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:40
constexpr auto max
Function object that returns the greater of the given values.
Definition: hybridutilities.hh:489
constexpr auto min
Function object that returns the smaller of the given values.
Definition: hybridutilities.hh:511
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:458
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 (Jan 8, 23:33, 2026)