source: trunk/se/lu/thep/wenni/lib/c++_tools/gslapi/vector.h @ 110

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

Updated parts of C++ tools.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 15.2 KB
Line 
1// $Id: vector.h 110 2006-06-13 22:03:40Z jari $
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.