ztsdb
ztime_vector.hpp
1 // (C) 2016,2017 Leonardo Silvestri
2 //
3 // This file is part of ztsdb.
4 //
5 // ztsdb is free software: you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation, either version 3 of the License, or
8 // (at your option) any later version.
9 //
10 // ztsdb is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with ztsdb. If not, see <http://www.gnu.org/licenses/>.
17 
18 
19 #ifndef ZTIME_VECTOR_HPP
20 #define ZTIME_VECTOR_HPP
21 
22 
23 
24 #include "../vector.hpp"
25 #include "../globals.hpp"
26 #include "../misc.hpp"
27 #include "../pseudovector.hpp"
28 //#include "zone.hpp"
29 #include "interval.hpp" // prob not needed? LLL
30 #include "ztime.hpp"
31 
32 
33 namespace ztsdb {
34 
35  template <typename T>
36  arr::Vector<T> seq(T from, T to, tz::period by, const tz::Zone& z);
37  template <typename T>
38  arr::Vector<T> seq(T from, tz::period by, size_t n, const tz::Zone& z);
39 
40 }
41 
42 
43 namespace arr { // should be in tz? LLL
44 
45  // align -----------------------------------
46 
50 
51  template <typename T, typename U>
52  struct PseudoVectorTz {
53  PseudoVectorTz(const Vector<U>& v_p, const tz::Zone& tz_p) :
54  v(v_p), scalar(v.size() == 1), first_elt(v[0]), tz(tz_p) { }
55  inline const U operator[](size_t i) const { return scalar ? first_elt : v[i]; }
56 
57  inline const T plus(T t, U u) const { return tz::plus(t, u, tz); }
58 
59  private:
60  const Vector<U>& v;
61  const bool scalar;
62  const U& first_elt;
63  const tz::Zone& tz;
64  };
65 
66 
67  template <typename I, typename NANF,
68  typename DS, typename DE>
69  arr::Vector<I> align_idx(const arr::Vector<Global::dtime>& x,
71  const DS& start,
72  const DE& end)
73  {
74  arr::Vector<I> res;
75  size_t ix = 0, iy = 0;
76 
77  // for each point in y, we try to find a matching point or set of
78  // points in x:
79  for (iy=0; iy<y.size(); iy++) {
80  auto ystart = start.plus(y[iy], start[iy]);
81  auto yend = end.plus(y[iy], end[iy]);
82 
83  // advance until we have a point in x that is in the interval
84  // defined around yi:
85  while (ix <= x.size() && x[ix] < ystart) ++ix;
86  if (ix >= x.size() || x[ix] > yend) {
87  res.push_back(NANF::f());
88  continue;
89  }
90 
91  // find the closest point in the interval:
92  while (ix+1 < x.size() && x[ix+1] <= yend && tz::abs(x[ix] - y[iy]) > tz::abs(x[ix+1] - y[iy])) ++ix;
93  res.push_back(ix + 1); // +1 because of R numbering start convention
94  }
95  return res;
96  }
97 
98 
102  template <typename T, typename NANF,
103  typename DS, typename DE>
105  const arr::Vector<Global::dtime>& y,
106  const arr::Vector<T>& xdata,
107  arr::Vector<T>& ydata,
108  const DS& start,
109  const DE& end)
110  {
111  size_t ix = 0, iy = 0;
112 
113  if (xdata.size() != x.size()) throw std::out_of_range("'xdata' must have same size as 'x'");
114 
115  // for each point in y, we try to find a matching point or set of
116  // points in x:
117  for (iy=0; iy<y.size(); iy++) {
118  auto ystart = start.plus(y[iy], start[iy]);
119  auto yend = end.plus(y[iy], end[iy]);
120 
121  // advance until we have a point in x that is in the interval
122  // defined around yi:
123  while (ix < x.size() && x[ix] < ystart) ++ix;
124  if (ix >= x.size() || x[ix] > yend) {
125  ydata.push_back(NANF::f());
126  continue;
127  }
128 
129  // find the closest point in the interval:
130  while (ix+1 < x.size() && x[ix+1] <= yend && tz::abs(x[ix] - y[iy]) > tz::abs(x[ix+1] - y[iy]))
131  ++ix;
132  ydata.push_back(xdata[ix]);
133  }
134  }
135 
136 
137  template <typename T, typename F,
138  typename DS, typename DE>
139  void align_func(const arr::Vector<Global::dtime>& x,
140  const arr::Vector<Global::dtime>& y,
141  const arr::Vector<T>& xdata,
142  arr::Vector<T>& ydata,
143  const DS& start,
144  const DE& end)
145  {
146  size_t ix = 0, iy = 0;
147 
148  if (xdata.size() != x.size()) throw std::out_of_range("'xdata' must have same size as 'x'");
149 
150  // for each point in y, we try to find a matching point or set of
151  // points in x:
152  for (iy=0; iy<y.size(); iy++) {
153  auto ystart = start.plus(y[iy], start[iy]);
154  auto yend = end.plus(y[iy], end[iy]);
155 
156  // advance until we have a point in x that is in the interval
157  // defined around yi:
158  auto iter = std::lower_bound(x.begin() + ix, x.end(), ystart);
159  ix = iter - x.begin();
160 
161  if (ix >= x.size() || x[ix] >= yend) {
162  ydata.push_back(F::f(xdata.end(), xdata.end())); // empty interval
163  continue;
164  }
165  typename arr::Vector<T>::const_iterator istart(xdata, ix);
166  auto first_ix = ix;
167 
168  // find the last point in the interval:
169  iter = std::lower_bound(x.begin() + ix, x.end(), yend);
170  ix = iter - x.begin();
171  while (ix < x.size() && x[ix] < yend) ++ix;
172  typename arr::Vector<T>::const_iterator iend(xdata, ix);
173 
174  ydata.push_back(F::f(istart, iend));
175 
176  // reset ix to the first ix found, because the intervals
177  // specified could overlap:
178  ix = first_ix;
179  }
180  }
181 
182  template <typename T, typename F>
183  void op_zts(const arr::Vector<Global::dtime>& x,
184  const arr::Vector<Global::dtime>& y,
185  const arr::Vector<T>& xdata,
186  arr::Vector<T>& ydata)
187  {
188  size_t ix = 0;
189 
190  if (xdata.size() != x.size()) throw std::out_of_range("'xdata' must have same size as 'x'");
191 
192  // for each point in x, we try to find a matching point or set of
193  // points in y:
194  auto from_yiter = y.begin();
195  for (ix=0; ix<x.size(); ix++) {
196  auto to_yiter = std::lower_bound(from_yiter, y.end(), x[ix]);
197  if (to_yiter == y.end()) continue;
198 
199  auto iy_s = from_yiter-y.begin();
200  auto iy_e = to_yiter-y.begin();
201  F::f(xdata[ix], ydata.begin() + iy_s, ydata.begin() + iy_e);
202 
203  from_yiter = to_yiter;
204  }
205  }
206 
207 } // namespace arr
208 
209 
210 #endif
arr::align_closest
zts align_closest(const zts &ts, const Array< Global::dtime > &y, const DS &start, const DE &end)
alignment functions:
Definition: zts.hpp:151
tz::Zone
Definition: zone.hpp:38
tz::period
Definition: period.hpp:30
arr::Vector< T >
tz
Timezone handling and temporal types and functions depending on timezones.
Definition: period.hpp:28
arr::vector_const_iterator
Definition: vector_base.hpp:56
NANF
Definition: base_funcs_set.cpp:205
arr
Contains the classes and functions that implement a multidimentional array type.
Definition: allocator.hpp:29
arr::PseudoVectorTz
Definition: ztime_vector.hpp:52
arr::align_func
zts align_func(const zts &ts, const Array< Global::dtime > &y, const DS &start, const DE &end)
align_func
Definition: zts.hpp:176