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

Last change on this file since 439 was 439, checked in by Markus Ringnér, 16 years ago

Fixed istream parsing when separator is last on line: a trailing NaN is generated

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