source: trunk/yat/utility/vector.h @ 754

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

Addresses #2 and #65. Continued adding GSL_error exceptions, and added doxygen briefs.

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