source: branches/peters_vector/lib/gslapi/vector.h @ 468

Last change on this file since 468 was 468, checked in by Peter, 16 years ago

made gslapi::vector inherit from VectorAbstract?

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 14.3 KB
Line 
1// $Id: vector.h 468 2005-12-17 01:15:53Z peter $
2
3#ifndef _theplu_gslapi_vector_
4#define _theplu_gslapi_vector_
5
6#include <c++_tools/classifier/VectorAbstract.h>
7#include <c++_tools/utility/Exception.h>
8
9#include <iostream>
10#include <vector>
11#include <utility>
12
13#include <gsl/gsl_vector.h>
14#include <gsl/gsl_sort_vector.h>
15
16namespace theplu {
17namespace gslapi {
18
19  class matrix;
20
21  ///
22  /// This is the C++ tools interface to GSL vector. 'double' is the
23  /// only type supported, maybe we should add a 'complex' type as
24  /// well in the future.
25  ///
26  /// \par[File streams] Reading and writing vectors to file streams
27  /// are of course supported. These are implemented without using GSL
28  /// functionality, and thus binary read and write to streams are not
29  /// supported.
30  ///
31  /// \par[Vector views] GSL vector views are supported and these are
32  /// disguised as ordinary gslapi::vectors. A support function is
33  /// added, gslapi::vector::isview(), that can be used to check if a
34  /// vector object is a view. Note that view vectors do not own the
35  /// undelying data, and a view is not valid if the vector owning the
36  /// data is deallocated.
37  ///
38  /// @note Missing support to underlying GSL vector features can in
39  /// principle be included to this class if requested by the user
40  /// community.
41  ///
42  class vector : public classifier::VectorAbstract
43  {
44  public:
45
46    ///
47    /// The default constructor.
48    ///
49    inline vector(void) : v_(NULL), view_(NULL), const_view_(NULL) {}
50
51    ///
52    /// Constructor. Allocates memory space for \a n elements, and
53    /// sets all elements to \a init_value.
54    ///
55    inline vector(const size_t n,const double init_value=0)
56      : view_(NULL), const_view_(NULL)
57      { v_ = gsl_vector_alloc(n); set_all(init_value); }
58
59    ///
60    /// The copy constructor.
61    ///
62    /// @note If the object to be copied is a vector view, the values
63    /// of the view will be copied, i.e. the view is not copied.
64    ///
65    inline vector(const vector& other) : view_(NULL), const_view_(NULL)
66      { v_ = other.create_gsl_vector_copy(); }
67
68    ///
69    /// Vector view constructor.
70    ///
71    /// Create a view of vector \a v, with starting index \a offset,
72    /// size \a n, and an optional \a stride.
73    ///
74    /// A vector view can be used as any vector with the difference
75    /// that changes made to the view will also change the object that
76    /// is viewed. Also, using the copy constructor will create a new
77    /// vector object that is a copy of whatever is viewed. If a copy
78    /// of the view is needed then you should use this constructor to
79    /// obtain a copy.
80    ///
81    /// @note If the object viewed by the view goes out of scope or is
82    /// deleted, the view becomes invalid and the result of further
83    /// use is undefined.
84    ///
85    vector(vector& v, size_t offset, size_t n, size_t stride=1);
86
87    ///
88    /// Vector const view constructor.
89    ///
90    /// Create a view of vector \a v, with starting index \a offset,
91    /// size \a n, and an optional \a stride.
92    ///
93    /// A vector view can be used as any const vector. Using the copy
94    /// constructor will create a new vector object that is a copy of
95    /// whatever is viewed. If a copy of the view is needed then you
96    /// should use this constructor to obtain a copy.
97    ///
98    /// @note If the object viewed by the view goes out of scope or is
99    /// deleted, the view becomes invalid and the result of further
100    /// use is undefined.
101    ///
102    vector(const vector& v, size_t offset, size_t n, size_t stride=1);
103
104    ///
105    /// Matrix row/column view constructor.
106    ///
107    /// Create a row/column vector view of matrix \a m, pointing at
108    /// row/column \a i. The parameter \a row is used to set whether
109    /// the view should be a row or column view. If \a row is set to
110    /// true, the view will be a row view (default behaviour), and,
111    /// naturally, a column view otherwise.
112    ///
113    /// A vector view can be used as any vector with the difference
114    /// that changes made to the view will also change the object that
115    /// is viewed. Also, using the copy constructor will create a new
116    /// vector object that is a copy of whatever is viewed. If a copy
117    /// of the view is needed then you should use the vector view
118    /// constructor to obtain a copy.
119    ///
120    /// @note If the object viewed by the view goes out of scope or is
121    /// deleted, the view becomes invalid and the result of further
122    /// use is undefined.
123    ///
124    vector(matrix& m, size_t i, bool row=true);
125
126    ///
127    /// Matrix row/column const view constructor.
128    ///
129    /// Create a row/column vector view of matrix \a m, pointing at
130    /// row/column \a i. The parameter \a row is used to set whether
131    /// the view should be a row or column view. If \a row is set to
132    /// true, the view will be a row view (default behaviour), and,
133    /// naturally, a column view otherwise.
134    ///
135    /// A const vector view can be used as any const vector. Using the
136    /// copy constructor will create a new vector object that is a
137    /// copy of whatever is viewed. If a copy of the view is needed
138    /// then you should use the vector view constructor to obtain a
139    /// copy.
140    ///
141    /// @note If the object viewed by the view goes out of scope or is
142    /// deleted, the view becomes invalid and the result of further
143    /// use is undefined.
144    ///
145    vector(const matrix& m, size_t i, bool row=true);
146
147    ///
148    /// The istream constructor.
149    ///
150    /// Either elements should be separated
151    /// with white space characters (default), or elements should be separated
152    /// by the delimiter \a sep. When delimiter \a sep is used empty elements
153    /// are stored as NaN's (except that empty lines are ignored). The
154    /// end of input to the vector is at end of file marker.
155    ///
156    explicit vector(std::istream &, char sep='\0') throw (utility::IO_error,std::exception);
157
158    ///
159    /// The destructor.
160    ///
161    ~vector(void);
162
163    ///
164    /// Vector addition, \f$this_i = this_i + other_i \; \forall i\f$.
165    ///
166    /// @return GSL_SUCCESS on normal exit.
167    ///
168    // Jari, group as vector_operators
169    inline int add(const vector& other) { return gsl_vector_add(v_,other.v_); }
170
171    ///
172    /// Add a constant to a vector, \f$this_i = this_i + term \;
173    /// \forall i\f$.
174    ///
175    /// @return GSL_SUCCESS on normal exit.
176    ///
177    // Jari, group as vector_operators
178    inline int add(double term) { return gsl_vector_add_constant(v_,term); }
179
180    ///
181    /// This function performs element-wise division, \f$this_i =
182    /// this_i/other_i \; \forall i\f$.
183    ///
184    /// @return GSL_SUCCESS on normal exit.
185    ///
186    // Jari, doxygen group as Vector operators
187    inline int div(const vector& other) { return gsl_vector_div(v_,other.v_); }
188
189    ///
190    /// @return A const pointer to the internal GSL vector,
191    ///
192    inline const gsl_vector* gsl_vector_p(void) const { return v_; }
193
194    ///
195    /// @return A pointer to the internal GSL vector,
196    ///
197    inline gsl_vector* gsl_vector_p(void) { return v_; }
198
199    ///
200    /// @return True if all elements in the vector is zero, false
201    /// othwerwise;
202    ///
203    inline bool isnull(void) const { return gsl_vector_isnull(v_); }
204
205    ///
206    /// Check if the vector object is a view (sub-vector) to another
207    /// vector.
208    ///
209    /// @return True if the object is a view, false othwerwise.
210    ///
211    inline bool isview(void) const { return view_ || const_view_; }
212
213    ///
214    /// @return The maximum value of the vector.
215    ///
216    // Jari, doxygen group as Finding maximum and minimum elements
217    inline double max(void) const { return gsl_vector_max(v_); }
218
219    ///
220    /// @return The element index to the maximum value of the
221    /// vector. The lowest index has precedence.
222    ///
223    // Jari, doxygen group as Finding maximum and minimum elements
224    inline size_t max_index(void) const { return gsl_vector_max_index(v_); }
225
226    ///
227    /// @return The minimum value of the vector.
228    ///
229    // Jari, doxygen group as Finding maximum and minimum elements
230    inline double min(void) const { return gsl_vector_min(v_); }
231
232    ///
233    /// @return The element index to the minimum value of the
234    /// vector. The lowest index has precedence.
235    ///
236    // Jari, doxygen group as Finding maximum and minimum elements
237    inline size_t min_index(void) const { return gsl_vector_min_index(v_); }
238
239    ///
240    /// @return The minimum and maximum values of the vector, as the
241    /// \a first and \a second member of the returned \a pair,
242    /// respectively.
243    ///
244    // Jari, doxygen group as Finding maximum and minimum elements
245    std::pair<double,double> minmax(void) const;
246
247    ///
248    /// @return The indecies to the minimum and maximum values of the
249    /// vector, as the \a first and \a second member of the returned
250    /// \a pair, respectively. The lowest index has precedence.
251    ///
252    // Jari, doxygen group as Finding maximum and minimum elements
253    std::pair<size_t,size_t> minmax_index(void) const;
254
255    ///
256    /// This function performs element-wise multiplication, \f$this_i =
257    /// this_i * other_i \; \forall i\f$.
258    ///
259    /// @return GSL_SUCCESS on normal exit.
260    ///
261    // Jari, doxygen group as Vector operators
262    inline int mul(const vector& other) { return gsl_vector_mul(v_,other.v_); }
263
264    ///
265    /// Reverse the order of elements in the vector.
266    ///
267    /// @return GSL_SUCCESS on normal exit.
268    ///
269    // Jari, doxygen group as Exchanging elements
270    inline int reverse(void) { return gsl_vector_reverse(v_);}
271
272    ///
273    /// Rescale vector, \f$this_i = this_i * factor \; \forall i\f$.
274    ///
275    /// @return GSL_SUCCESS on normal exit.
276    ///
277    // Jari, doxygen group as Vector operators
278    inline int scale(double factor) { return gsl_vector_scale(v_,factor); }
279
280    ///
281    /// Set element values to values in \a vec. This function is
282    /// needed for assignment of viewed elements.
283    ///
284    /// @return Whatever GSL returns.
285    ///
286    /// @note No check on size is done.
287    ///
288    /// @see const vector& operator=(const vector&)
289    ///
290    inline int set(const vector& vec) { return gsl_vector_memcpy(v_,vec.v_); }
291
292    ///
293    /// Set all elements to \a value.
294    ///
295    // Jari, doxygen group as Initializing vector elements
296    inline void set_all(const double& value) { gsl_vector_set_all(v_,value); }
297
298    ///
299    /// Makes a basis vector by setting all elements to
300    /// zero except the \a i-th element which is set to
301    /// one.
302    ///
303    // Jari, doxygen group as Initializing vector elements
304    inline void set_basis(const size_t i) { gsl_vector_set_basis(v_,i); }
305   
306    ///
307    /// Set all elements to zero.
308    ///
309    // Jari, doxygen group as Initializing vector elements
310    inline void set_zero(void) { gsl_vector_set_zero(v_); }
311
312    ///
313    /// @return the number of elements in the vector.
314    ///
315    inline size_t size(void) const { return v_->size; }
316
317    ///
318    /// Sort the elements in the vector.
319    ///
320    /// Bug in gsl: if vector contains NaN an infinite loop is entered.
321    ///
322    // Markus to Jari, doxygen group as Exchanging elements ????
323    inline void sort(void) { gsl_sort_vector(v_);}
324
325
326    ///
327    /// Vector subtraction, \f$this_i = this_i - other_i \; \forall i\f$.
328    ///
329    /// @return GSL_SUCCESS on normal exit.
330    ///
331    // Jari, doxygen group as Vector operators
332    inline int sub(const vector& other) { return gsl_vector_sub(v_,other.v_); }
333
334    ///
335    /// Calculate the sum of all vector elements.
336    ///
337    /// @return The sum.
338    ///
339    // Jari, doxygen group as "Extends GSL".
340    double sum(void) const;
341
342    ///
343    /// Swap vector elements by copying. The two vectors must have the
344    /// same length.
345    ///
346    /// @return GSL_SUCCESS on normal exit.
347    ///
348    inline int swap(vector& other) { return gsl_vector_swap(v_,other.v_); }
349
350    ///
351    /// Exchange elements \a i and \a j.
352    ///
353    /// @return GSL_SUCCESS on normal exit.
354    ///
355    // Jari, doxygen group as Exchanging elements
356    inline int
357    swap_elements(size_t i,size_t j) { return gsl_vector_swap_elements(v_,i,j);}
358
359    ///
360    /// Element access operator.
361    ///
362    /// @return Reference to element \a i.
363    ///
364    // Jari, doxygen group as Accessing vector elements
365    inline double& operator()(size_t i) { return *gsl_vector_ptr(v_,i); }
366
367    ///
368    /// Const element access operator.
369    ///
370    /// @return The value of element \a i.
371    ///
372    // Jari, doxygen group as Accessing vector elements
373    inline const double&
374    operator()(size_t i) const { return *gsl_vector_const_ptr(v_,i); }
375
376    ///
377    /// Element access operator.
378    ///
379    /// @return Reference to element \a i.
380    ///
381    // Jari, doxygen group as Accessing vector elements
382    inline double& operator[](size_t i) { return *gsl_vector_ptr(v_,i); }
383
384    ///
385    /// Const element access operator.
386    ///
387    /// @return The value of element \a i.
388    ///
389    // Jari, doxygen group as Accessing vector elements
390    inline const double&
391    operator[](size_t i) const { return *gsl_vector_const_ptr(v_,i); }
392
393    ///
394    /// @return The dot product.
395    ///
396    double operator*( const vector &other ) const;
397
398    ///
399    /// Comparison operator. Takes linear time.
400    ///
401    /// @return True if the sequence of the elements in the vectors
402    /// are element/wise equal.
403    ///
404    bool operator==(const vector&) const;
405
406    ///
407    /// The assignment operator. There is no requirements on
408    /// dimensions, i.e. the vector is remapped in memory if
409    /// necessary. This implies that in general views cannot be
410    /// assigned using this operator. Views will be mutated into
411    /// normal vectors. The only exception to this behaviour on views
412    /// is when self-assignemnt is done, since self-assignment is
413    /// ignored.
414    ///
415    /// @return A const reference to the resulting vector.
416    ///
417    /// @see int set(const vector&)
418    ///
419    const vector& operator=(const vector&);
420
421    ///
422    /// Addition and assign operator.
423    ///
424    /// @return A const reference to the resulting vector.
425    ///
426    inline const vector&
427    operator+=(const vector& other) { gsl_vector_add(v_,other.v_); return *this;}
428
429    ///
430    /// Subtract and assign operator.
431    ///
432    /// @return A const reference to the resulting vector.
433    ///
434    inline const vector&
435    operator-=(const vector& other) { gsl_vector_sub(v_,other.v_); return *this;}
436
437    ///
438    /// Multiply with scalar and assign operator.
439    ///
440    /// @return A const reference to the resulting vector.
441    ///
442    inline const vector&
443    operator*=(const double d) { gsl_vector_scale(v_,d); return *this; }
444
445
446  private:
447
448    ///
449    /// Create a new copy of the internal GSL vector.
450    ///
451    /// Necessary memory for the new GSL vector is allocated and the
452    /// caller is responsible for freeing the allocated memory.
453    ///
454    /// @return A pointer to a copy of the internal GSL vector.
455    ///
456    gsl_vector* create_gsl_vector_copy(void) const;
457
458    gsl_vector* v_;
459    gsl_vector_view* view_;
460    gsl_vector_const_view* const_view_;
461  };
462
463  ///
464  /// The output operator for the vector class.
465  ///
466  std::ostream& operator<<(std::ostream&, const vector& );
467
468
469}} // of namespace gslapi and namespace theplu
470
471#endif
Note: See TracBrowser for help on using the repository browser.