source: trunk/lib/gslapi/vector.h @ 560

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

I dont know what happened, but everything is changed...

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