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

Last change on this file since 420 was 420, checked in by Jari Häkkinen, 16 years ago

Merged better_matrix_class changes r402:419 into the trunk.

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