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

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

Improved memory usage of NNIFileConverter.

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