source: trunk/yat/utility/VectorBase.cc @ 3780

Last change on this file since 3780 was 3780, checked in by Peter, 5 years ago

simplify code (slightly)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
  • Property svndigest:ignore set to 1008
File size: 7.9 KB
Line 
1// $Id: VectorBase.cc 3780 2018-12-06 06:57:02Z peter $
2
3/*
4  Copyright (C) 2003 Daniel Dalevi, Peter Johansson
5  Copyright (C) 2004 Jari Häkkinen, Peter Johansson
6  Copyright (C) 2005, 2006, 2007 Jari Häkkinen, Peter Johansson, Markus Ringnér
7  Copyright (C) 2008 Jari Häkkinen, Peter Johansson
8  Copyright (C) 2009, 2011, 2012, 2016, 2017, 2018 Peter Johansson
9
10  This file is part of the yat library, http://dev.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 3 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 yat. If not, see <http://www.gnu.org/licenses/>.
24*/
25
26#include <config.h>
27
28#include "VectorBase.h"
29#include "Vector.h"
30#include "utility.h"
31
32#include <gsl/gsl_blas.h>
33#include <gsl/gsl_sort_vector.h>
34
35#include <algorithm>
36#include <cassert>
37#include <cmath>
38#include <limits>
39#include <numeric>
40#include <ostream>
41#include <string>
42#include <utility>
43#include <vector>
44
45namespace theplu {
46namespace yat {
47namespace utility {
48
49
50  VectorBase::VectorBase(const gsl_vector* v)
51    : const_vec_(v)
52  {
53  }
54
55
56  VectorBase::~VectorBase(void)
57  {
58  }
59
60
61  VectorBase::const_iterator VectorBase::begin(void) const
62  {
63    if (const_vec_)
64      return const_iterator(&(this->operator()(0)), const_vec_->stride);
65    return const_iterator(NULL, 1);
66  }
67
68
69  VectorBase::const_iterator VectorBase::end(void) const
70  {
71    if (const_vec_)
72      return const_iterator(&(this->operator()(0))+const_vec_->stride*size(),
73                            const_vec_->stride);
74    return const_iterator(NULL, 1);
75  }
76
77
78  bool VectorBase::equal(const VectorBase& other, const double d) const
79  {
80    if (this==&other)
81      return true;
82    if (size()!=other.size())
83      return false;
84    // if gsl error handler disabled, out of bounds index will not
85    // abort the program.
86    for (size_t i=0; i<size(); ++i)
87      if (std::abs( (*this)(i)-other(i) ) > d ||
88          std::isnan((*this)(i)) || std::isnan(other(i)) )
89        return false;
90    return true;
91  }
92
93
94  const gsl_vector* VectorBase::gsl_vector_p(void) const
95  {
96    return const_vec_;
97  }
98
99
100  size_t VectorBase::size(void) const
101  {
102    if (!const_vec_)
103      return 0;
104    return const_vec_->size;
105  }
106
107
108  const double& VectorBase::operator()(size_t i) const
109  {
110    const double* d=gsl_vector_const_ptr(const_vec_, i);
111    if (!d)
112      throw utility::GSL_error("VectorBase::operator()",GSL_EINVAL);
113    return *d;
114  }
115
116
117  bool VectorBase::operator==(const VectorBase& other) const
118  {
119    return equal(other);
120  }
121
122
123  bool VectorBase::operator!=(const VectorBase& other) const
124  {
125    return !equal(other);
126  }
127
128
129  double VectorBase::operator*( const VectorBase &other ) const
130  {
131    double res = 0.0;;
132    gsl_blas_ddot(gsl_vector_p(), other.gsl_vector_p(), &res);
133    return res;
134  }
135
136
137  bool isnull(const VectorBase& v)
138  {
139    return gsl_vector_isnull(v.gsl_vector_p());
140  }
141
142
143  double max(const VectorBase& v)
144  {
145    return gsl_vector_max(v.gsl_vector_p());
146  }
147
148
149  size_t max_index(const VectorBase& v)
150  {
151    return gsl_vector_max_index(v.gsl_vector_p());
152  }
153
154
155  double min(const VectorBase& v)
156  {
157    return gsl_vector_min(v.gsl_vector_p());
158  }
159
160
161  size_t min_index(const VectorBase& v)
162  {
163    return gsl_vector_min_index(v.gsl_vector_p());
164  }
165
166
167  bool nan(const VectorBase& templat, Vector& flag)
168  {
169    flag.resize(templat.size());
170    return binary_weight(templat.begin(), templat.end(), flag.begin());
171  }
172
173
174  void sort_index(std::vector<size_t>& sort_index, const VectorBase& invec)
175  {
176    assert(invec.gsl_vector_p());
177    gsl_permutation* p = gsl_permutation_alloc(invec.size());
178    int status=gsl_sort_vector_index(p,invec.gsl_vector_p());
179    if (status) {
180      gsl_permutation_free(p);
181      throw utility::GSL_error("sort_index(vector&,const VectorBase&)",status);
182    }
183    std::vector<size_t> tmp(p->data,p->data+p->size);
184    sort_index.swap(tmp);
185    gsl_permutation_free(p);
186  }
187
188
189  void sort_smallest_index(std::vector<size_t>& sort_index, size_t k,
190                            const VectorBase& invec)
191  {
192    assert(invec.gsl_vector_p());
193    assert(k<=invec.size());
194    sort_index.resize(k);
195    gsl_sort_vector_smallest_index(&sort_index[0],k,invec.gsl_vector_p());
196  }
197
198  void sort_largest_index(std::vector<size_t>& sort_index, size_t k,
199                            const VectorBase& invec)
200  {
201    assert(invec.gsl_vector_p());
202    assert(k<=invec.size());
203    sort_index.resize(k);
204    gsl_sort_vector_largest_index(&sort_index[0],k,invec.gsl_vector_p());
205  }
206
207
208  double sum(const VectorBase& v)
209  {
210    return std::accumulate(v.begin(), v.end(), 0.0);
211  }
212
213
214  std::ostream& operator<<(std::ostream& s, const VectorBase& a)
215  {
216    s.setf(std::ios::dec);
217    std::streamsize precision = s.precision();
218    s.precision(std::numeric_limits<double>().digits10);
219    for (size_t j = 0; j < a.size(); ++j) {
220      if (j)
221        s << s.fill();
222      s << a(j);
223    }
224    s.precision(precision);
225    return s;
226  }
227
228  namespace detail
229  {
230    gsl_vector* create_gsl_vector_copy(const gsl_vector* other)
231    {
232      if (!other)
233        return NULL;
234      gsl_vector* vec = create_gsl_vector(other->size);
235      if (gsl_vector_memcpy(vec, other))
236        throw utility::GSL_error("create_gsl_vector_copy memcpy failed");
237      return vec;
238    }
239
240
241    gsl_vector* create_gsl_vector(size_t n)
242    {
243      if (!n)
244        return NULL;
245      gsl_vector* vec = gsl_vector_alloc(n);
246      if (!vec)
247        throw utility::GSL_error("gsl_vector_alloc failed");
248      return vec;
249    }
250
251
252    gsl_vector* create_gsl_vector(size_t n, double value)
253    {
254      if (!n)
255        return NULL;
256      if (value) {
257        gsl_vector* vec = create_gsl_vector(n);
258        gsl_vector_set_all(vec, value);
259        return vec;
260      }
261      gsl_vector* vec = gsl_vector_calloc(n);
262      if (!vec)
263        throw utility::GSL_error("gsl_vector_calloc failed");
264      return vec;
265    }
266
267
268    bool overlap(const gsl_vector* a, const gsl_vector* b)
269    {
270      assert(a);
271      assert(b);
272      assert(a->size);
273      assert(b->size);
274      const double* a_first = gsl_vector_const_ptr(a, 0);
275      const double* a_last = gsl_vector_const_ptr(a, a->size-1);
276      const double* b_first = gsl_vector_const_ptr(b, 0);
277      const double* b_last = gsl_vector_const_ptr(b, b->size-1);
278
279      return (a_last >= b_first) && (b_last >= a_first);
280    }
281
282
283    bool serial_overlap(const gsl_vector* a, const gsl_vector* b)
284    {
285      assert(a);
286      assert(b);
287      assert(a->size);
288      assert(b->size);
289      assert(a->size == b->size);
290      /*
291        ABCDEFGHIJKLMNOPQRSTUVWXYZ
292        0ab
293        1  b a
294        2   b    a
295        3    b       a
296        4     b          a
297        5      b             a
298        6       b                a
299
300        a_first in mem pos A
301        a_last in mem pos Y
302        b_first in mem pos B
303        b_last in mem pos H
304
305        Both a[1] and b[3] point to mem pos E
306
307        From this follows that a mem pos is problematic if it
308        fullfils the following:
309        1) It lies inside [a_first, a_last]
310        2) It lies inside [b_first, b_last]
311
312        3) The b-line is below the a-line for that position, which is
313        a linear condition, hence no intermediate extreme point, and
314        we only need to look at the boundaries.
315      */
316
317      const double* a_first = gsl_vector_const_ptr(a, 0);
318      const double* a_last = gsl_vector_const_ptr(a, a->size-1);
319      const double* b_first = gsl_vector_const_ptr(b, 0);
320      const double* b_last = gsl_vector_const_ptr(b, b->size-1);
321      if ((a_last >= b_first) && (b_last >= a_first)) {
322        const double* first = std::max(a_first, b_first);
323        const double* last = std::min(a_last, b_last);
324        assert(first <= last);
325
326        // check whether b-line is below a-line in first or last,
327        // which is equivalent index(b) > index(a)
328
329        // index in x for a is calculated as:
330        // (x - a_first) / a->stride
331        // so
332        // (x - b_first) * a->stride > (x - a_first) * b->stride)
333        return ((first - b_first) * a->stride >
334                (first - a_first) * b->stride) ||
335          ((last - b_first) * a->stride >
336           (last - a_first) * b->stride);
337      }
338      return false;
339    }
340
341  }
342
343}}} // of namespace utility, yat, and thep
Note: See TracBrowser for help on using the repository browser.