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

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

Fixes #195.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 10.4 KB
Line 
1// $Id: vector.cc 782 2007-03-05 21:17:31Z 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    if (!view_)
95      throw utility::GSL_error("vector::vector failed to setup view");
96    proxy_v_ = v_ = &(view_->vector);
97  }
98
99
100  vector::vector(const matrix& m, size_t i, bool row)
101    : v_(NULL), view_(NULL)
102  {
103    view_const_ = new gsl_vector_const_view(row ?
104                                   gsl_matrix_const_row   (m.gsl_matrix_p(),i) :
105                                   gsl_matrix_const_column(m.gsl_matrix_p(),i) );
106    if (!view_const_)
107      throw utility::GSL_error("vector::vector failed to setup view");
108    proxy_v_ = v_const_ = &(view_const_->vector);
109  }
110
111
112  vector::vector(std::istream& is, char sep)
113    throw (utility::IO_error, std::exception)
114    : v_const_(NULL), view_(NULL), view_const_(NULL)
115  {
116    // read the data file and store in stl vectors (dynamically
117    // expandable)
118    std::vector<std::vector<double> > data_matrix;
119    u_int nof_columns=0;
120    u_int nof_rows=0;
121    std::string line;
122    while(getline(is, line, '\n')) {
123      // Empty lines
124      if (!line.size())
125          continue;
126      nof_rows++;
127
128      std::vector<double> v;
129      std::string element;
130      std::stringstream ss(line);
131      bool ok=true;
132      while(ok) {
133        if(sep=='\0')
134          ok=(ss>>element);
135        else 
136          ok=getline(ss, element, sep);
137        if(!ok)
138          break;       
139
140        if(utility::is_double(element)) {
141          v.push_back(atof(element.c_str()));
142        }
143        else if (!element.size() || utility::is_nan(element)) {
144          v.push_back(std::numeric_limits<double>::quiet_NaN());
145        }
146        else {
147          std::stringstream ss("Warning: '");
148          ss << element << "' is not an integer.";
149          throw IO_error(ss.str());
150        }
151      } 
152      if(sep!='\0' && line[line.size()-1]==sep) // add NaN for final separator
153          v.push_back(std::numeric_limits<double>::quiet_NaN());
154      if (!nof_columns)
155        nof_columns=v.size();
156      else if (nof_rows && (nof_columns>1)) {
157        std::ostringstream s;
158        s << "vector::vector(std::istream&) data file error:\n"
159          << "    File has inconsistent number of rows (" << nof_rows
160          << ") and columns (" << nof_columns
161          << ").\n    Expected a row or a column vector.";
162        throw utility::IO_error(s.str());
163      }
164      else if (v.size()!=nof_columns) {
165        std::ostringstream s;
166        s << "vector::vector(std::istream&) data file error:\n"
167          << "    Line " << nof_rows << " has " << v.size()
168          << " columns; expected " << nof_columns << " column.";
169        throw utility::IO_error(s.str());
170      }
171      data_matrix.push_back(v);
172    }
173
174    // manipulate the state of the stream to be good
175    is.clear(std::ios::goodbit);
176    // convert the data to a gsl vector
177    proxy_v_ = v_ = gsl_vector_alloc(nof_rows*nof_columns);
178    if (!v_)
179      throw utility::GSL_error("vector::vector failed to allocate memory");
180    size_t n=0;
181    // if gsl error handler disabled, out of bounds index will not
182    // abort the program.
183    for (size_t i=0; i<nof_rows; i++)
184      for (size_t j=0; j<nof_columns; j++) 
185        gsl_vector_set( v_, n++, data_matrix[i][j] );
186  }
187
188
189  vector::~vector(void)
190  {
191    if (view_)
192      delete view_;
193    else if (view_const_)
194      delete view_const_;
195    else if (v_)
196      gsl_vector_free(v_);
197  }
198
199
200  gsl_vector* vector::create_gsl_vector_copy(void) const
201  {
202    gsl_vector* vec = gsl_vector_alloc(size());
203    if (!vec)
204      throw utility::GSL_error("vector::create_gsl_vector_copy failed to allocate memory");
205    if (gsl_vector_memcpy(vec, proxy_v_))
206      throw utility::GSL_error("vector::create_gsl_matrix_copy dimension mis-match");
207    return vec;
208  }
209
210
211  void vector::div(const vector& other)
212  {
213    int status=gsl_vector_div(v_,other.v_);
214    if (status)
215      throw utility::GSL_error(std::string("vector::div",status));
216  }
217
218
219  const gsl_vector* vector::gsl_vector_p(void) const
220  {
221    return proxy_v_;
222  }
223
224
225  gsl_vector* vector::gsl_vector_p(void)
226  {
227    return v_;
228  }
229
230
231  bool vector::isview(void) const
232  {
233    return view_ || view_const_;
234  }
235
236
237  void vector::mul(const vector& other)
238  {
239    int status=gsl_vector_mul(v_,other.v_);
240    if (status)
241      throw utility::GSL_error(std::string("vector::mul",status));
242  }
243
244
245  void vector::reverse(void)
246  {
247    gsl_vector_reverse(v_);
248  }
249
250
251  void vector::set(const vector& vec)
252  {
253    if (gsl_vector_memcpy(v_,vec.v_))
254      throw utility::GSL_error("vector::set dimension mis-match");
255  }
256
257
258  void vector::set_all(const double& value)
259  {
260    gsl_vector_set_all(v_,value);
261  }
262
263
264  size_t vector::size(void) const
265  {
266    if (!proxy_v_)
267      return 0;
268    return proxy_v_->size;
269  }
270
271
272  void vector::swap(size_t i, size_t j)
273  {
274    int status=gsl_vector_swap_elements(v_, i, j);
275    if (status)
276      throw utility::GSL_error(std::string("vector::swap_elements",status));
277  }
278
279
280  double& vector::operator()(size_t i)
281  {
282    double* d=gsl_vector_ptr(v_, i);
283    if (!d)
284      throw utility::GSL_error("vector::operator()",GSL_EINVAL);
285    return *d;
286  }
287
288
289  const double& vector::operator()(size_t i) const
290  {
291    const double* d=gsl_vector_const_ptr(proxy_v_, i);
292    if (!d)
293      throw utility::GSL_error("vector::operator()",GSL_EINVAL);
294    return *d;
295  }
296
297
298  double& vector::operator[](size_t i)
299  {
300    return this->operator()(i);
301  }
302
303
304  const double& vector::operator[](size_t i) const
305  {
306    return this->operator()(i);
307  }
308
309
310  bool vector::operator==(const vector& a) const
311  {
312    if (size()!=a.size())
313      return false;
314    // if gsl error handler disabled, out of bounds index will not
315    // abort the program.
316    for (size_t i=0; i<size(); ++i)
317      if (gsl_vector_get(proxy_v_,i)!=a(i))
318        return false;
319    return true;
320  }
321
322
323  double vector::operator*( const vector &other ) const
324  {
325    double res = 0.0;;
326    for ( size_t i = 0; i < size(); ++i ) 
327      res += other(i) * (*this)(i);
328    return res;
329  }
330
331
332  const vector& vector::operator=( const vector& other )
333  {
334    if( this != &other ) {
335      if (view_)
336        delete view_;
337      else if (view_const_)
338        delete view_const_;
339      else if ( v_ )
340        gsl_vector_free( v_ );
341      v_const_=NULL;
342      proxy_v_ = v_ = other.create_gsl_vector_copy();
343    }
344    return *this;
345  } 
346
347
348  const vector& vector::operator+=(const vector& other)
349  {
350    int status=gsl_vector_add(v_,other. v_);
351    if (status)
352      throw utility::GSL_error(std::string("vector::add", status));
353    return *this;
354  }
355
356
357  const vector& vector::operator+=(double d)
358  {
359    gsl_vector_add_constant(v_, d);
360    return *this;
361  }
362
363
364  const vector& vector::operator-=(const vector& other)
365  {
366    int status=gsl_vector_sub(v_, other.v_);
367    if (status)
368      throw utility::GSL_error(std::string("vector::sub", status));
369    return *this;
370  }
371
372
373  const vector& vector::operator*=(const double d)
374  {
375    gsl_vector_scale(v_, d);
376    return *this;
377  }
378
379
380  bool isnull(const vector& v)
381  {
382    return gsl_vector_isnull(v.gsl_vector_p());
383  }
384
385
386  double max(const vector& v)
387  {
388    return gsl_vector_max(v.gsl_vector_p());
389  }
390
391
392  size_t max_index(const vector& v)
393  {
394    return gsl_vector_max_index(v.gsl_vector_p());
395  }
396
397
398  double min(const vector& v)
399  {
400    return gsl_vector_min(v.gsl_vector_p());
401  }
402
403
404  size_t min_index(const vector& v)
405  {
406    return gsl_vector_min_index(v.gsl_vector_p());
407  }
408
409
410  std::pair<double,double> minmax(const vector& v)
411  {
412    std::pair<double,double> minmax;
413    gsl_vector_minmax(v.gsl_vector_p(), &minmax.first, &minmax.second);
414    return minmax;
415  }
416
417
418  std::pair<size_t,size_t> minmax_index(const vector& v)
419  {
420    std::pair<size_t,size_t> minmax;
421    gsl_vector_minmax_index(v.gsl_vector_p(), &minmax.first, &minmax.second);
422    return minmax;
423  }
424
425
426  void set_basis(vector& v, size_t i)
427  {
428    gsl_vector_set_basis(v.gsl_vector_p(),i);
429  }
430
431
432  void sort(vector& v)
433  {
434    gsl_sort_vector(v.gsl_vector_p());
435  }
436
437
438  double sum(const vector& v)
439  {
440    double sum = 0;
441    size_t vsize=v.size();
442    for (size_t i=0; i<vsize; ++i)
443      sum += v[i];
444    return sum;
445  }
446
447
448  void swap(vector& v, vector& w)
449  {
450    int status=gsl_vector_swap(v.gsl_vector_p(),w.gsl_vector_p());
451    if (status)
452      throw utility::GSL_error(std::string("swap(vector&,vector&)",status));
453  }
454
455
456  std::ostream& operator<<(std::ostream& s, const vector& a)
457  {
458    s.setf(std::ios::dec);
459    s.precision(12);
460    for (size_t j = 0; j < a.size(); ++j) {
461      s << a[j];
462      if ( (j+1)<a.size() )
463        s << s.fill();
464    }
465    return s;
466  }
467
468}}} // of namespace utility, yat, and thep
Note: See TracBrowser for help on using the repository browser.