source: trunk/c++_tools/gslapi/vector.h @ 610

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

Fixed comments so they pass without some of the complaits from doxygen. Have not looked at the actual contents of comments

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