Newer
Older
// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
// vi: set et ts=4 sw=2 sts=2:
#ifndef DUNE_DENSEVECTOR_HH
#define DUNE_DENSEVECTOR_HH
#include <limits>
#include "genericiterator.hh"
#include "ftraits.hh"
namespace Dune {
// forward declaration of template
template<class S> class DenseVector;
template<class S>
struct FieldTraits< DenseVector<S> >
{
typedef const typename FieldTraits<typename S::value_type>::field_type field_type;
typedef const typename FieldTraits<typename S::value_type>::real_type real_type;
};
/** @defgroup DenseMatVec Dense Matrix and Vector Template Library
@ingroup Common
@{
*/
* \brief This file implements a the dense vector interface, with an exchangeable storage class
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
*/
namespace fvmeta
{
/**
\private
\memberof Dune::DenseVector
*/
template<class K>
inline typename FieldTraits<K>::real_type absreal (const K& k)
{
return std::abs(k);
}
/**
\private
\memberof Dune::DenseVector
*/
template<class K>
inline typename FieldTraits<K>::real_type absreal (const std::complex<K>& c)
{
return std::abs(c.real()) + std::abs(c.imag());
}
/**
\private
\memberof Dune::DenseVector
*/
template<class K>
inline typename FieldTraits<K>::real_type abs2 (const K& k)
{
return k*k;
}
/**
\private
\memberof Dune::DenseVector
*/
template<class K>
inline typename FieldTraits<K>::real_type abs2 (const std::complex<K>& c)
{
return c.real()*c.real() + c.imag()*c.imag();
}
/**
\private
\memberof Dune::DenseVector
*/
template<class K, bool isInteger = std::numeric_limits<K>::is_integer>
struct Sqrt
{
static inline typename FieldTraits<K>::real_type sqrt (const K& k)
{
return std::sqrt(k);
}
};
/**
\private
\memberof Dune::DenseVector
*/
template<class K>
struct Sqrt<K, true>
{
static inline typename FieldTraits<K>::real_type sqrt (const K& k)
{
return typename FieldTraits<K>::real_type(std::sqrt(double(k)));
}
};
/**
\private
\memberof Dune::DenseVector
*/
template<class K>
inline typename FieldTraits<K>::real_type sqrt (const K& k)
{
return Sqrt<K>::sqrt(k);
}
}
/*! \brief Generic iterator class for dense vector and matrix implementations
provides sequential access to DenseVector, FieldVector and FieldMatrix
*/
template<class C, class T>
class DenseIterator :
public Dune::RandomAccessIteratorFacade<DenseIterator<C,T>,T, T&, std::ptrdiff_t>
{
friend class DenseIterator<typename remove_const<C>::type, typename remove_const<T>::type >;
friend class DenseIterator<const typename remove_const<C>::type, const typename remove_const<T>::type >;
public:
/**
* @brief The type of the difference between two positions.
*/
typedef std::ptrdiff_t DifferenceType;
/**
* @brief The type to index the underlying container.
*/
typedef typename C::size_type SizeType;
// Constructors needed by the base iterators.
DenseIterator()
: container_(0), position_()
{}
DenseIterator(C& cont, SizeType pos)
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
: container_(&cont), position_(pos)
{}
DenseIterator(const DenseIterator<typename remove_const<C>::type, typename remove_const<T>::type >& other)
: container_(other.container_), position_(other.position_)
{}
// Methods needed by the forward iterator
bool equals(const DenseIterator<typename remove_const<C>::type,typename remove_const<T>::type>& other) const
{
return position_ == other.position_ && container_ == other.container_;
}
bool equals(const DenseIterator<const typename remove_const<C>::type,const typename remove_const<T>::type>& other) const
{
return position_ == other.position_ && container_ == other.container_;
}
T& dereference() const {
return container_->operator[](position_);
}
void increment(){
++position_;
}
// Additional function needed by BidirectionalIterator
void decrement(){
--position_;
}
// Additional function needed by RandomAccessIterator
T& elementAt(DifferenceType i) const {
return container_->operator[](position_+i);
}
void advance(DifferenceType n){
position_=position_+n;
}
DifferenceType distanceTo(DenseIterator<const typename remove_const<C>::type,const typename remove_const<T>::type> other) const
{
assert(other.container_==container_);
return other.position_ - position_;
}
DifferenceType distanceTo(DenseIterator<typename remove_const<C>::type, typename remove_const<T>::type> other) const
{
assert(other.container_==container_);
return other.position_ - position_;
}
//! return index
SizeType index () const
{
return this->position_;
}
private:
C *container_;
SizeType position_;
};
/** \brief Interface for a class of dense vectors over a given field.
*
* \tparam K the field type (use float, double, complex, etc)
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
* \tparam S storage class (e.g. std::array<K,Size> or std::vector<K>)
*/
template<typename S>
class DenseVector : S
{
typedef typename S::value_type K;
public:
//===== type definitions and constants
//! export the type representing the field
typedef typename S::value_type field_type;
//! export the type representing the components
typedef typename S::value_type block_type;
//! The type used for the index access and size operation
typedef typename S::size_type size_type;
//! We are at the leaf of the block recursion
enum {
//! The number of block levels we contain
blocklevel = 1
};
// pull in methods from the storage class
//! random access
using S::operator[];
//! size method
using S::size;
//! Constructor making uninitialized vector
DenseVector() {}
//! Constructor making vector with identical values
DenseVector (size_type n, const K& t) : S(n,t) {}
//===== assignment from scalar
//! Assignment operator for scalar
DenseVector& operator= (const K& k)
{
for (size_type i=0; i<size(); i++)
(*this)[i] = k;
return *this;
}
//===== dynamic size related methods
//! Resize the vector. (only possible if S support resizing)
void resize(size_type size)
{
S::resize(size);
}
//! Get the capacity of the vector.
size_type capacity() const
{
return S::capacity();
}
//===== access to components
//! Iterator class for sequential access
typedef DenseIterator<S,K> Iterator;
//! typedef for stl compliant access
typedef Iterator iterator;
//! begin iterator
Iterator begin ()
{
return Iterator(*this,0);
}
//! end iterator
Iterator end ()
{
return Iterator(*this,size());
}
//! begin iterator
Iterator rbegin ()
{
return Iterator(*this,size()-1);
}
//! end iterator
Iterator rend ()
{
return Iterator(*this,-1);
}
//! return iterator to given element or end()
Iterator find (size_type i)
{
return Iterator(*this,std::min(i,size()));
}
//! ConstIterator class for sequential access
typedef DenseIterator<const S,const K> ConstIterator;
//! typedef for stl compliant access
typedef ConstIterator const_iterator;
//! begin ConstIterator
ConstIterator begin () const
{
return ConstIterator(*this,0);
}
//! end ConstIterator
ConstIterator end () const
{
return ConstIterator(*this,size());
}
//! begin ConstIterator
ConstIterator rbegin () const
{
return ConstIterator(*this,size()-1);
}
//! end ConstIterator
ConstIterator rend () const
{
return ConstIterator(*this,-1);
}
//! return iterator to given element or end()
ConstIterator find (size_type i) const
{
return Iterator(*this,std::min(i,size()));
}
//===== vector space arithmetic
//! vector space addition
DenseVector& operator+= (const DenseVector& y)
{
assert(y.size() == size());
for (size_type i=0; i<size(); i++)
(*this)[i] += y[i];
return *this;
}
//! vector space subtraction
DenseVector& operator-= (const DenseVector& y)
{
assert(y.size() == size());
for (size_type i=0; i<size(); i++)
(*this)[i] -= y[i];
return *this;
}
//! Binary vector addition
DenseVector operator+ (const DenseVector& b) const
{
DenseVector z = *this;
return (z+=b);
}
//! Binary vector subtraction
DenseVector operator- (const DenseVector& b) const
{
DenseVector z = *this;
return (z-=b);
}
//! vector space add scalar to all comps
DenseVector& operator+= (const K& k)
{
for (size_type i=0; i<size(); i++)
(*this)[i] += k;
return *this;
}
//! vector space subtract scalar from all comps
DenseVector& operator-= (const K& k)
{
for (size_type i=0; i<size(); i++)
(*this)[i] -= k;
return *this;
}
//! vector space multiplication with scalar
DenseVector& operator*= (const K& k)
{
for (size_type i=0; i<size(); i++)
(*this)[i] *= k;
return *this;
}
//! vector space division by scalar
DenseVector& operator/= (const K& k)
{
for (size_type i=0; i<size(); i++)
(*this)[i] /= k;
return *this;
}
//! Binary vector comparison
bool operator== (const DenseVector& y) const
{
assert(y.size() == size());
for (size_type i=0; i<size(); i++)
if ((*this)[i]!=y[i])
return false;
return true;
}
//! Binary vector incomparison
bool operator!= (const DenseVector& y) const
{
return !operator==(y);
}
//! vector space axpy operation ( *this += a y )
DenseVector& axpy (const K& a, const DenseVector& y)
{
assert(y.size() == size());
for (size_type i=0; i<size(); i++)
(*this)[i] += a*y[i];
return *this;
}
//===== Euclidean scalar product
//! scalar product (x^T y)
K operator* (const DenseVector& y) const
{
assert(y.size() == size());
K result = 0;
for (size_type i=0; i<size(); i++)
result += (*this)[i]*y[i];
return result;
}
//===== norms
//! one norm (sum over absolute values of entries)
typename FieldTraits<K>::real_type one_norm() const {
typename FieldTraits<K>::real_type result = 0;
for (size_type i=0; i<size(); i++)
result += std::abs((*this)[i]);
return result;
}
//! simplified one norm (uses Manhattan norm for complex values)
typename FieldTraits<K>::real_type one_norm_real () const
{
typename FieldTraits<K>::real_type result = 0;
for (size_type i=0; i<size(); i++)
result += fvmeta::absreal((*this)[i]);
return result;
}
//! two norm sqrt(sum over squared values of entries)
typename FieldTraits<K>::real_type two_norm () const
{
typename FieldTraits<K>::real_type result = 0;
for (size_type i=0; i<size(); i++)
result += fvmeta::abs2((*this)[i]);
return fvmeta::sqrt(result);
}
//! square of two norm (sum over squared values of entries), need for block recursion
typename FieldTraits<K>::real_type two_norm2 () const
{
typename FieldTraits<K>::real_type result = 0;
for (size_type i=0; i<size(); i++)
result += fvmeta::abs2((*this)[i]);
return result;
}
//! infinity norm (maximum of absolute values of entries)
typename FieldTraits<K>::real_type infinity_norm () const
{
typename FieldTraits<K>::real_type result = 0;
for (size_type i=0; i<size(); i++)
result = std::max(result, std::abs((*this)[i]));
return result;
}
//! simplified infinity norm (uses Manhattan norm for complex values)
typename FieldTraits<K>::real_type infinity_norm_real () const
{
typename FieldTraits<K>::real_type result = 0;
for (size_type i=0; i<size(); i++)
result = std::max(result, fvmeta::absreal((*this)[i]));
return result;
}
//===== sizes
//! number of blocks in the vector (are of size 1 here)
size_type N () const
{
return size();
}
//! dimension of the vector space
size_type dim () const
{
return size();
}
private:
};
/** \brief Write a DenseVector to an output stream
* \relates DenseVector
*
* \param[in] s std :: ostream to write to
* \param[in] v DenseVector to write
*
* \returns the output stream (s)
*/
template<typename S>
std::ostream& operator<< (std::ostream& s, const DenseVector<S>& v)
{
for (typename DenseVector<S>::size_type i=0; i<v.size(); i++)
s << ((i>0) ? " " : "") << v[i];
return s;
}
/** @} end documentation */
} // end namespace
#endif // DUNE_DENSEVECTOR_HH