source: trunk/yat/utility/vector.cc @ 755

Last change on this file since 755 was 755, 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: 10.3 KB
Line 
1// $Id: vector.cc 755 2007-02-18 00:01:39Z 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, Peter Johansson
8  Copyright (C) 2007 Jari Häkkinen
9
10  This file is part of the yat library, http://lev.thep.lu.se/trac/yat
11
12  The yat library is free software; you can redistribute it and/or
13  modify it under the terms of the GNU General Public License as
14  published by the Free Software Foundation; either version 2 of the
15  License, or (at your option) any later version.
16
17  The yat library is distributed in the hope that it will be useful,
18  but WITHOUT ANY WARRANTY; without even the implied warranty of
19  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#include "vector.h"
29#include "matrix.h"
30#include "utility.h"
31
32#include <iostream>
33#include <sstream>
34#include <vector>
35#include <utility>
36
37namespace theplu {
38namespace yat {
39namespace utility {
40
41
42  vector::vector(void)
43    : v_(NULL), v_const_(NULL), view_(NULL), view_const_(NULL), proxy_v_(NULL)
44  {
45  }
46
47
48  vector::vector(size_t n, double init_value)
49    : v_(gsl_vector_alloc(n)), v_const_(NULL), view_(NULL), view_const_(NULL),
50      proxy_v_(v_)
51  {
52    if (!v_)
53      throw utility::GSL_error("vector::vector failed to allocate memory");
54
55    set_all(init_value);
56  }
57
58
59  vector::vector(const vector& other)
60    : v_(other.create_gsl_vector_copy()), v_const_(NULL), view_(NULL),
61      view_const_(NULL), proxy_v_(v_)
62  {
63  }
64
65
66  vector::vector(vector& v, size_t offset, size_t n, size_t stride)
67    : v_const_(NULL), view_const_(NULL)
68  {
69    view_ = new gsl_vector_view(gsl_vector_subvector_with_stride(v.v_,offset,
70                                                                 stride,n));
71    if (!view_)
72      throw utility::GSL_error("vector::vector failed to setup view");
73    proxy_v_ = v_ = &(view_->vector);
74  }
75
76
77  vector::vector(const vector& v, size_t offset, size_t n, size_t stride)
78    : v_(NULL), view_(NULL)
79  {
80    view_const_ = new gsl_vector_const_view(
81                   gsl_vector_const_subvector_with_stride(v.v_,offset,stride,n));
82    if (!view_const_)
83      throw utility::GSL_error("vector::vector failed to setup view");
84    proxy_v_ = v_const_ = &(view_const_->vector);
85  }
86
87
88  vector::vector(matrix& m, size_t i, bool row)
89    : v_const_(NULL), view_const_(NULL)
90  {
91    view_=new gsl_vector_view(row ?
92                              gsl_matrix_row   (m.gsl_matrix_p(),i) :
93                              gsl_matrix_column(m.gsl_matrix_p(),i)  );
94    proxy_v_ = v_ = &(view_->vector);
95  }
96
97
98  vector::vector(const matrix& m, size_t i, bool row)
99    : v_(NULL), view_(NULL)
100  {
101    view_const_ = new gsl_vector_const_view(row ?
102                                   gsl_matrix_const_row   (m.gsl_matrix_p(),i) :
103                                   gsl_matrix_const_column(m.gsl_matrix_p(),i) );
104    proxy_v_ = v_const_ = &(view_const_->vector);
105  }
106
107
108  vector::vector(std::istream& is, char sep)
109    throw (utility::IO_error, std::exception)
110    : v_const_(NULL), view_(NULL), view_const_(NULL)
111  {
112    // read the data file and store in stl vectors (dynamically
113    // expandable)
114    std::vector<std::vector<double> > data_matrix;
115    u_int nof_columns=0;
116    u_int nof_rows=0;
117    std::string line;
118    while(getline(is, line, '\n')) {
119      // Empty lines
120      if (!line.size())
121          continue;
122      nof_rows++;
123
124      std::vector<double> v;
125      std::string element;
126      std::stringstream ss(line);
127      bool ok=true;
128      while(ok) {
129        if(sep=='\0')
130          ok=(ss>>element);
131        else 
132          ok=getline(ss, element, sep);
133        if(!ok)
134          break;       
135
136        if(utility::is_double(element)) {
137          v.push_back(atof(element.c_str()));
138        }
139        else if (!element.size() || utility::is_nan(element)) {
140          v.push_back(std::numeric_limits<double>::quiet_NaN());
141        }
142        else {
143          // Jari, this should be communicated with as an exception.
144          // std::cerr << "Warning: '" << element
145          //           << "' is not an integer." << std::endl;
146        }
147      } 
148      if(sep!='\0' && line[line.size()-1]==sep) // add NaN for final separator
149          v.push_back(std::numeric_limits<double>::quiet_NaN());
150      if (!nof_columns)
151        nof_columns=v.size();
152      else if (nof_rows && (nof_columns>1)) {
153        std::ostringstream s;
154        s << "vector::vector(std::istream&) data file error:\n"
155          << "    File has inconsistent number of rows (" << nof_rows
156          << ") and columns (" << nof_columns
157          << ").\n    Expected a row or a column vector.";
158        throw utility::IO_error(s.str());
159      }
160      else if (v.size()!=nof_columns) {
161        std::ostringstream s;
162        s << "vector::vector(std::istream&) data file error:\n"
163          << "    Line " << nof_rows << " has " << v.size()
164          << " columns; expected " << nof_columns << " column.";
165        throw utility::IO_error(s.str());
166      }
167      data_matrix.push_back(v);
168    }
169
170    // manipulate the state of the stream to be good
171    is.clear(std::ios::goodbit);
172    // convert the data to a gsl vector
173    proxy_v_ = v_ = gsl_vector_alloc(nof_rows*nof_columns);
174    if (!v_)
175      throw utility::GSL_error("vector::vector failed to allocate memory");
176    size_t n=0;
177    // if gsl error handler disabled, out of bounds index will not
178    // abort the program.
179    for (size_t i=0; i<nof_rows; i++)
180      for (size_t j=0; j<nof_columns; j++) 
181        gsl_vector_set( v_, n++, data_matrix[i][j] );
182  }
183
184
185  vector::~vector(void)
186  {
187    if (view_)
188      delete view_;
189    else if (view_const_)
190      delete view_const_;
191    else if (v_)
192      gsl_vector_free(v_);
193  }
194
195
196  void vector::add(const vector& other)
197  {
198    int status=gsl_vector_add(v_,other.v_);
199    if (status)
200      throw utility::GSL_error(std::string("vector::add",status));
201  }
202
203
204  void vector::add(double term)
205  {
206    gsl_vector_add_constant(v_,term);
207  }
208
209
210  gsl_vector* vector::create_gsl_vector_copy(void) const
211  {
212    gsl_vector* vec = gsl_vector_alloc(size());
213    if (!vec)
214      throw utility::GSL_error("vector::create_gsl_vector_copy failed to allocate memory");
215    if (gsl_vector_memcpy(vec, proxy_v_))
216      throw utility::GSL_error("vector::create_gsl_matrix_copy dimension mis-match");
217    return vec;
218  }
219
220
221  void vector::div(const vector& other)
222  {
223    int status=gsl_vector_div(v_,other.v_);
224    if (status)
225      throw utility::GSL_error(std::string("vector::div",status));
226  }
227
228
229  const gsl_vector* vector::gsl_vector_p(void) const
230  {
231    return proxy_v_;
232  }
233
234
235  gsl_vector* vector::gsl_vector_p(void)
236  {
237    return v_;
238  }
239
240
241  bool vector::isnull(void) const
242  {
243    return gsl_vector_isnull(proxy_v_);
244  }
245
246
247  bool vector::isview(void) const
248  {
249    return view_ || view_const_;
250  }
251
252
253  double vector::max(void) const
254  {
255    return gsl_vector_max(proxy_v_);
256  }
257
258
259  size_t vector::max_index(void) const
260  {
261    return gsl_vector_max_index(proxy_v_);
262  }
263
264
265  double vector::min(void) const
266  {
267    return gsl_vector_min(proxy_v_);
268  }
269
270
271  size_t vector::min_index(void) const
272  {
273    return gsl_vector_min_index(proxy_v_);
274  }
275
276
277  std::pair<double,double> vector::minmax(void) const
278  {
279    double min, max;
280    gsl_vector_minmax(proxy_v_, &min, &max);
281    return std::pair<double,double>(min,max);
282  }
283
284
285  std::pair<size_t,size_t> vector::minmax_index(void) const
286  {
287    size_t min_index, max_index;
288    gsl_vector_minmax_index(proxy_v_, &min_index, &max_index);
289    return std::pair<size_t,size_t>(min_index,max_index);
290  }
291
292
293  void vector::mul(const vector& other)
294  {
295    int status=gsl_vector_mul(v_,other.v_);
296    if (status)
297      throw utility::GSL_error(std::string("vector::mul",status));
298  }
299
300
301  void vector::reverse(void)
302  {
303    gsl_vector_reverse(v_);
304  }
305
306
307  void vector::scale(double factor)
308  {
309    gsl_vector_scale(v_,factor);
310  }
311
312
313  void vector::set(const vector& vec)
314  {
315    if (gsl_vector_memcpy(v_,vec.v_))
316      throw utility::GSL_error("vector::set dimension mis-match");
317  }
318
319
320  void vector::set_all(const double& value)
321  {
322    gsl_vector_set_all(v_,value);
323  }
324
325
326  void vector::set_basis(const size_t i)
327  {
328    gsl_vector_set_basis(v_,i);
329  }
330
331
332  void vector::set_zero(void)
333  {
334    gsl_vector_set_zero(v_);
335  }
336
337
338  size_t vector::size(void) const
339  {
340    if (!proxy_v_)
341      return 0;
342    return proxy_v_->size;
343  }
344
345
346  void vector::sort(void)
347  {
348    gsl_sort_vector(v_);
349  }
350
351
352  void vector::sub(const vector& other)
353  {
354    int status=gsl_vector_sub(v_,other.v_);
355    if (status)
356      throw utility::GSL_error(std::string("vector::sub",status));
357  }
358
359
360  double vector::sum(void) const
361  {
362    double sum = 0;
363    for (size_t i=0; i<size(); i++)
364      sum += (*this)(i);
365    return( sum );
366  }
367
368
369  void vector::swap(vector& other)
370  {
371    int status=gsl_vector_swap(v_,other.v_);
372    if (status)
373      throw utility::GSL_error(std::string("vector::swap",status));
374  }
375
376
377  void vector::swap_elements(size_t i, size_t j)
378  {
379    int status=gsl_vector_swap_elements(v_, i, j);
380    if (status)
381      throw utility::GSL_error(std::string("vector::swap_elements",status));
382  }
383
384
385  double& vector::operator()(size_t i)
386  {
387    double* d=gsl_vector_ptr(v_, i);
388    if (!d)
389      throw utility::GSL_error("vector::operator()",GSL_EINVAL);
390    return *d;
391  }
392
393
394  const double& vector::operator()(size_t i) const
395  {
396    const double* d=gsl_vector_const_ptr(proxy_v_, i);
397    if (!d)
398      throw utility::GSL_error("vector::operator()",GSL_EINVAL);
399    return *d;
400  }
401
402
403  double& vector::operator[](size_t i)
404  {
405    return *gsl_vector_ptr(v_,i);
406  }
407
408
409  const double& vector::operator[](size_t i) const
410  {
411    return *gsl_vector_const_ptr(proxy_v_,i);
412  }
413
414
415  bool vector::operator==(const vector& a) const
416  {
417    if (size()!=a.size())
418      return false;
419    for (size_t i=0; i<size(); ++i)
420      if (gsl_vector_get(proxy_v_,i)!=a(i))
421        return false;
422    return true;
423  }
424
425
426  double vector::operator*( const vector &other ) const
427  {
428    double res = 0.0;;
429    for ( size_t i = 0; i < size(); ++i ) 
430      res += other(i) * (*this)(i);
431    return res;
432  }
433
434
435  const vector& vector::operator=( const vector& other )
436  {
437    if( this != &other ) {
438      if (view_)
439        delete view_;
440      else if (view_const_)
441        delete view_const_;
442      else if ( v_ )
443        gsl_vector_free( v_ );
444      v_const_=NULL;
445      proxy_v_ = v_ = other.create_gsl_vector_copy();
446    }
447    return *this;
448  } 
449
450
451  const vector& vector::operator+=(const vector& other)
452  {
453    add(other);
454    return *this;
455  }
456
457
458  const vector& vector::operator-=(const vector& other)
459  {
460    sub(other);
461    return *this;
462  }
463
464
465  const vector& vector::operator*=(const double d)
466  {
467    scale(d);
468    return *this;
469  }
470
471
472  std::ostream& operator<<(std::ostream& s, const vector& a)
473  {
474    s.setf(std::ios::dec);
475    s.precision(12);
476    for (size_t j = 0; j < a.size(); ++j) {
477      s << a[j];
478      if ( (j+1)<a.size() )
479        s << s.fill();
480    }
481    return s;
482  }
483
484}}} // of namespace utility, yat, and thep
Note: See TracBrowser for help on using the repository browser.