source: branches/better_matrix_class/lib/gslapi/vector.h @ 415

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

Removed some gslapi copy intensive operators.
Made gslapi assignment operators ignore views, and change them
into normal vectors if assigned.
Cleaning up of code aswell.

  • 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 415 2005-12-01 15:52:36Z 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.