CppNoddy  0.92
Loading...
Searching...
No Matches
DenseVector.h
Go to the documentation of this file.
1/// \file DenseVector.h
2/// Specification for a templated DenseVector class -- a dense, dynamic, vector object.
3
4#ifndef DENSEVECTOR_H
5#define DENSEVECTOR_H
6
7#include <vector>
8#include <complex>
9#include <algorithm>
10#include <functional>
11#include <string>
12#include <fstream>
13#include <iostream>
14#include <iomanip>
15
16#include <Exceptions.h>
17#include <Functors.h>
18
19namespace CppNoddy {
20
21 // forward declare the matrix classes that will be friends
22 // conversion from banded to vector (for LAPACK routines)
23 // is best done if we allow BandedMatrix direct access to the
24 // storage container vec.
25 template <typename _Type>
26 class BandedMatrix;
27
28 /// An DenseVector class -- a dense vector object.
29 /// This is templated but intended ONLY for double or
30 /// std::complex<double>. We just encapsulate the STL vector
31 /// container and pass through a few simple iterators whilst
32 /// adding appropriate operator overloading and norms.
33 template <typename _Type>
35 public:
36
37 typedef typename std::vector<_Type>::iterator elt_iter;
38 typedef typename std::vector<_Type>::const_iterator elt_citer;
39 typedef typename std::vector<_Type>::reverse_iterator elt_riter;
40 typedef typename std::vector<_Type>::const_reverse_iterator elt_criter;
41
42 /// Constructor for a non-filled vector, to be filled by the user.
44
45 /// Constructor with specified fill-in initialization
46 /// \param fill Data to be initialised to each entry
47 /// \param size The size of the vector to be instantiated
48 DenseVector(const std::size_t& size, const _Type& fill);
49
50 /// Construct a Noddy vector from a contiguous set of real data.
51 /// This will be nasty if you pass the wrong pointer, but is
52 /// useful in interfacing with external libraries
53 /// \param size The number of elements in the vector.
54 /// \param p A pointer to the start of the data.
55 DenseVector(const std::size_t& size, const _Type* p);
56
57 /// A templated implicitly converting copy constructor.
58 /// Note this is specialised for double to double and
59 /// std::complex<double> to std::complex<double> copy construction.
60 /// \param source The DenseVector to be used in the initialising.
61 template <typename _sourceType>
63 // size the current vector
64 m_vec.resize(source.size());
65 elt_iter p_local(m_vec.begin());
67 p_from = source.begin();
68 p_from != source.end();
69 ++p_from, ++p_local) {
70 *p_local = *p_from;
71 }
72 }
73
74 /// Copy assignment
75 /// \param source Object to copy
76 /// \return The new object
78
80
81 /// Pass through to the storage container.
83 return m_vec.begin();
84 }
85
86 /// Pass through to the storage container.
88 return m_vec.rbegin();
89 }
90
91 /// Pass through to the storage container.
92 elt_citer begin() const {
93 return m_vec.begin();
94 }
95
96 /// Pass through to the storage container.
98 return m_vec.rbegin();
99 }
100
101 /// Pass through to the storage container.
103 return m_vec.end();
104 }
105
106 /// Pass through to the storage container.
107 elt_citer end() const {
108 return m_vec.end();
109 }
110
111 /// Pass through to the storage container.
113 return m_vec.rend();
114 }
115
116 /// Pass through to the storage container.
117 elt_criter rend() const {
118 return m_vec.rend();
119 }
120
121 /// Operator overloading for addition
122 /// \param x The dense vector to be added
123 /// \return The sum of 'this' and x
125
126 /// Overloading for +
127 /// \return +this
129
130 /// Operator overloading for subtraction
131 /// \param x The dense vector to be subtracted from 'this'
132 /// \return The subtraction of x from 'this'
134
135 /// Overloading for -
136 /// \return -this
138
139 /// Operator overloading for scalar multiplication
140 /// \param m The scalar multiplier
141 /// \return The 'this' vector scaled by the constant 'm'
142 DenseVector<_Type> operator*(const _Type& m) const;
143
144 /// Operaotr overloading for scalar division
145 /// \param m The scalar divisor
146 /// \return The 'this' vector divided by the constant 'm'
147 DenseVector<_Type> operator/(const _Type& m) const;
148
149 /// Overloading of the [] operator
150 /// \param i The index of the element to be accessed
151 /// \return The element stored at index i (read only)
152 const _Type& operator[](const std::size_t& i) const;
153
154 /// Overloading of the [] operator
155 /// \param i The index of the element to be accessed
156 /// \return The element stored at index i (read/write)
157 _Type& operator[](const std::size_t& i);
158
159 /// Overloading *= for scalar multiplication
160 /// \param m The scalar multiplier
161 /// \return A reference to the 'this' vector multiplied by the scalar
163
164 /// Overloading /= for scalar multiplication
165 /// \param m The scalar divisor
166 /// \return A reference to the 'this' vector divided by the scalar
168
169 /// Overloading the -= operator
170 /// \param x A dense vector that will be subtracted from 'this'
171 /// \return A reference to the 'this' vector after subtraction by x
173
174 /// Overloading the += operator
175 /// \param x A dense vector that will be added to 'this'
176 /// \return A reference to the 'this' vector after addition by x
178
179 /// A pass-thru definition of push_back
180 /// \param fill The data element to be pushed into the vector
181 void push_back(const _Type& fill);
182
183 /// A pass-thru definition of resize
184 /// \param length The target length after resizing
185 void resize(const std::size_t& length);
186
187 /// A pass-thru definition of assign
188 /// \param n The number of elements to assign
189 /// \param elem The element copy to be used in the assign
190 void assign(const std::size_t n, const _Type elem) {
191 m_vec.assign(n, elem);
192 }
193
194 /// A pass-thru definition of clear
195 void clear();
196
197 /// l1-norm.
198 /// \return The square-root of the sum of the squares.
199 double one_norm() const;
200
201 /// l2-norm.
202 /// No attention paid to possible overflow for large vectors.
203 /// \return The square-root of the sum of the squares.
204 double two_norm() const;
205
206 /// Infinity norm.
207 /// \return The maximum (abs) element in the vector.
208 double inf_norm() const;
209
210 /// Scale each element of the vector, equivalent to *=
211 /// \param scale The value to scale each element by.
212 void scale(const _Type& scale);
213
214 /// Add a vector, element wise, equivalent to +=
215 /// \param x The vector to be added to this object.
216 void add(const DenseVector<_Type>& x);
217
218 /// Subtract a vector, element wise, equivalent to -=
219 /// \param x The vector to be subtracted from this object.
220 void sub(const DenseVector<_Type>& x);
221
222 /// A pass-thru definition to get the size of the vector.
223 /// Since the vector is dense, the number of elements is the
224 /// size.
225 /// \return The number of elements in the vector.
226 std::size_t size() const;
227
228 /// Get the number of elements in the vector
229 /// Since the vector is dense, the number of elements is the
230 /// size.
231 /// \return The number of elements in the vector.
232 std::size_t nelts() const;
233
234 /// Reserve space for the vector.
235 /// \param n The number of elements to reserve space for
236 void reserve(const std::size_t& n);
237
238 /// Swap elements i and j.
239 /// \param i The index of the element to swap.
240 /// \param j The index of the other element to swap.
241 void swap(const std::size_t& i, const std::size_t& j);
242
243 /// Dump to std::cout
244 void dump() const;
245
246 /// Dump the contents to a file, each element on a separate line
247 /// \param filename The name of the file to write to
248 /// \param precision Precision of the output strings
249 void dump_file(std::string filename, int precision = 10) const;
250
251 private:
252
253 // friend classes that may access m_vec directly
254 friend class BandedMatrix<_Type>;
255
256 // private storage of the data - encapsulated in std::vector
257 std::vector<_Type> m_vec;
258
259 }
260 ; // end class
261
262
263 // INLINED METHODS BELOW - the dense vector class is used heavily, so
264 // inlining simple access methods and operator overloads will give us
265 // a speed improvement throughout.
266
267 template <typename _Type>
269 {}
270
271 // specialise some copy constructors
272 template <>
273 template <>
275 m_vec = source.m_vec;
276 }
277
278 template <>
279 template <>
280 inline DenseVector<std::complex<double> >::DenseVector(const DenseVector<std::complex<double> >& source) {
281 m_vec = source.m_vec;
282 }
283
284 template <typename _Type>
285 inline _Type& DenseVector<_Type>::operator[](const std::size_t& i) {
286#ifdef PARANOID
287 if((i < 0) || (i >= size())) {
288 std::string problem;
289 problem = " The DenseVector.operator[] method has a range error. \n";
290 throw ExceptionRange(problem, size(), i);
291 }
292#endif
293 return m_vec[ i ];
294 }
295
296 template <typename _Type>
297 inline const _Type& DenseVector<_Type>::operator[](const std::size_t& i) const {
298#ifdef PARANOID
299 if((i < 0) || (i >= size())) {
300 std::string problem;
301 problem = " The DenseVector.operator[] method has a range error. \n";
302 throw ExceptionRange(problem, size(), i);
303 }
304#endif
305 return m_vec[ i ];
306 }
307
308
309 template <typename _Type>
310 inline void DenseVector<_Type>::push_back(const _Type& fill) {
311 m_vec.push_back(fill);
312 }
313
314 template <typename _Type>
315 inline void DenseVector<_Type>::resize(const std::size_t& length) {
316 m_vec.resize(length);
317 }
318
319 template <typename _Type>
321 m_vec.clear();
322 }
323
324 template <typename _Type>
326 return * this;
327 }
328
329 template <typename _Type>
330 inline std::size_t DenseVector<_Type>::size() const {
331 return m_vec.size();
332 }
333
334 template <typename _Type>
335 inline std::size_t DenseVector<_Type>::nelts() const {
336 return m_vec.size();
337 }
338
339 template <typename _Type>
340 inline void DenseVector<_Type>::reserve(const std::size_t& n) {
341 m_vec.reserve(n);
342 }
343
344 template <typename _Type>
346 DenseVector<_Type> temp(*this);
347 temp *= m;
348 return temp;
349 }
350
351 template <typename _Type>
353 // run thru m_vec from begin to end, transforming into
354 // m_vec container starting from begin using functor
355 std::transform(m_vec.begin(), m_vec.end(), m_vec.begin(), scale_functor<_Type, _Type>(m));
356 return *this;
357 }
358
359 template <typename _Type>
361 DenseVector<_Type> temp(*this);
362 temp *= (1. / m);
363 return temp;
364 }
365
366 template <typename _Type>
368 // run thru m_vecfrom begin to end, transforming into
369 // m_vec container starting from begin using functor
370 std::transform(m_vec.begin(), m_vec.end(), m_vec.begin(), scale_functor<_Type, _Type>(1.0 / m));
371 return *this;
372 }
373
374 template <typename _Type>
376#ifdef PARANOID
377 if(x.size() != size()) {
378 std::string problem;
379 problem = " The DenseVector.operator-= method is trying to use \n";
380 problem += " two vectors of unequal length \n";
381 throw ExceptionGeom(problem, size(), x.size());
382 }
383#endif
384 std::transform(m_vec.begin(), m_vec.end(), x.begin(), m_vec.begin(), std::minus<_Type>());
385 return *this;
386 }
387
388 template <typename _Type>
390#ifdef PARANOID
391 if(x.size() != size()) {
392 std::string problem;
393 problem = " The DenseVector.operator+= method is trying to use \n";
394 problem += " two vectors of unequal length \n";
395 throw ExceptionGeom(problem, size(), x.size());
396 }
397#endif
398 std::transform(m_vec.begin(), m_vec.end(), x.begin(), m_vec.begin(), std::plus<_Type>());
399 return *this;
400 }
401
402 template <typename _Type>
404#ifdef PARANOID
405 if(x.size() != size()) {
406 std::string problem;
407 problem = " The DenseVector.operator- method is trying to use \n";
408 problem += " two vectors of unequal length \n";
409 throw ExceptionGeom(problem, size(), x.size());
410 }
411#endif
412 DenseVector<_Type> temp(*this);
413 temp -= x;
414 return temp;
415 }
416
417 template <typename _Type>
419 DenseVector<_Type> temp(*this);
420 temp *= -1;
421 return temp;
422 }
423
424 template <typename _Type>
426#ifdef PARANOID
427 if(x.size() != size()) {
428 std::string problem;
429 problem = " The DenseVector.operator+ method is trying to use \n";
430 problem += " two vectors of unequal length \n";
431 throw ExceptionGeom(problem, size(), x.size());
432 }
433#endif
434 DenseVector<_Type> temp(*this);
435 temp += x;
436 return temp;
437 }
438
439 template <typename _Type>
441 if(this == &source)
442 return *this;
443 m_vec = source.m_vec;
444 return *this;
445 }
446
447}
448#endif
The collection of CppNoddy exceptions.
Some Function Objects that CppNoddy makes use of in algorithms applied to STL containers.
A matrix class that constructs a BANDED matrix.
Definition: BandedMatrix.h:16
An DenseVector class – a dense vector object.
Definition: DenseVector.h:34
elt_citer begin() const
Pass through to the storage container.
Definition: DenseVector.h:92
double one_norm() const
l1-norm.
Definition: DenseVector.cpp:49
std::vector< _Type >::const_reverse_iterator elt_criter
Definition: DenseVector.h:40
void dump_file(std::string filename, int precision=10) const
Dump the contents to a file, each element on a separate line.
void push_back(const _Type &fill)
A pass-thru definition of push_back.
Definition: DenseVector.h:310
std::size_t nelts() const
Get the number of elements in the vector Since the vector is dense, the number of elements is the siz...
Definition: DenseVector.h:335
double inf_norm() const
Infinity norm.
Definition: DenseVector.cpp:59
elt_criter rend() const
Pass through to the storage container.
Definition: DenseVector.h:117
void resize(const std::size_t &length)
A pass-thru definition of resize.
Definition: DenseVector.h:315
void sub(const DenseVector< _Type > &x)
Subtract a vector, element wise, equivalent to -=.
Definition: DenseVector.cpp:44
elt_citer end() const
Pass through to the storage container.
Definition: DenseVector.h:107
void dump() const
Dump to std::cout.
Definition: DenseVector.cpp:64
elt_riter rend()
Pass through to the storage container.
Definition: DenseVector.h:112
DenseVector< _Type > & operator*=(const _Type &m)
Overloading *= for scalar multiplication.
Definition: DenseVector.h:352
void add(const DenseVector< _Type > &x)
Add a vector, element wise, equivalent to +=.
Definition: DenseVector.cpp:39
std::vector< _Type >::reverse_iterator elt_riter
Definition: DenseVector.h:39
DenseVector< _Type > & operator/=(const _Type &m)
Overloading /= for scalar multiplication.
Definition: DenseVector.h:367
DenseVector< _Type > operator+() const
Overloading for +.
Definition: DenseVector.h:325
void reserve(const std::size_t &n)
Reserve space for the vector.
Definition: DenseVector.h:340
std::vector< _Type >::const_iterator elt_citer
Definition: DenseVector.h:38
void swap(const std::size_t &i, const std::size_t &j)
Swap elements i and j.
void clear()
A pass-thru definition of clear.
Definition: DenseVector.h:320
std::size_t size() const
A pass-thru definition to get the size of the vector.
Definition: DenseVector.h:330
_Type & operator[](const std::size_t &i)
Overloading of the [] operator.
Definition: DenseVector.h:285
DenseVector< _Type > operator*(const _Type &m) const
Operator overloading for scalar multiplication.
Definition: DenseVector.h:345
DenseVector< _Type > operator+(const DenseVector< _Type > &x) const
Operator overloading for addition.
Definition: DenseVector.h:425
DenseVector< _Type > & operator-=(const DenseVector< _Type > &x)
Overloading the -= operator.
Definition: DenseVector.h:375
elt_riter rbegin()
Pass through to the storage container.
Definition: DenseVector.h:87
DenseVector(const DenseVector< _sourceType > &source)
A templated implicitly converting copy constructor.
Definition: DenseVector.h:62
const _Type & operator[](const std::size_t &i) const
Overloading of the [] operator.
Definition: DenseVector.h:297
DenseVector & operator=(const DenseVector &source)
Copy assignment.
Definition: DenseVector.h:440
void scale(const _Type &scale)
Scale each element of the vector, equivalent to *=.
Definition: DenseVector.cpp:33
elt_iter begin()
Pass through to the storage container.
Definition: DenseVector.h:82
DenseVector()
Constructor for a non-filled vector, to be filled by the user.
Definition: DenseVector.cpp:17
DenseVector< _Type > operator/(const _Type &m) const
Operaotr overloading for scalar division.
Definition: DenseVector.h:360
DenseVector< _Type > operator-(const DenseVector< _Type > &x) const
Operator overloading for subtraction.
Definition: DenseVector.h:403
void assign(const std::size_t n, const _Type elem)
A pass-thru definition of assign.
Definition: DenseVector.h:190
double two_norm() const
l2-norm.
Definition: DenseVector.cpp:54
elt_iter end()
Pass through to the storage container.
Definition: DenseVector.h:102
elt_criter rbegin() const
Pass through to the storage container.
Definition: DenseVector.h:97
std::vector< _Type >::iterator elt_iter
Definition: DenseVector.h:37
DenseVector< _Type > operator-() const
Overloading for -.
Definition: DenseVector.h:418
DenseVector< _Type > & operator+=(const DenseVector< _Type > &x)
Overloading the += operator.
Definition: DenseVector.h:389
An exception class to be thrown when a container of incorrect geometry used in any class/method.
Definition: Exceptions.h:47
An exception to indicate that a CppNoddy container has been accessed with index/indices outside the m...
Definition: Exceptions.h:117
A unary pure function object that scales through multiplication.
Definition: Functors.h:74
A collection of OO numerical routines aimed at simple (typical) applied problems in continuum mechani...

© 2012

R.E. Hewitt