ztsdb
index.hpp
1 // (C) 2015 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 INDEX_HPP
20 #define INDEX_HPP
21 
22 #include <cstddef>
23 #include <cstdlib>
24 #include <algorithm>
25 #include <vector>
26 #include <iostream>
27 #include "juice/variant.hpp"
28 #include "globals.hpp"
29 #include "vector.hpp"
30 #include "dname.hpp"
31 #include "timezone/interval.hpp"
32 
33 
34 using namespace Juice;
35 
36 namespace arr {
37 
38 
39  template<typename I, typename T, typename U>
40  void subassign_generic(const I& idx,
41  Vector<T>& rv,
42  const U& v,
43  idx_type& vj);
44  template<typename I, typename T, typename U>
45  inline void subassignScalar_generic(const I& idx, Vector<T>& rv, U u);
46 
54  struct NullIndex {
55  const idx_type sz;
56 
57  inline bool getfirst(idx_type& val, idx_type& i) const {
58  i = val = 0;
59  return sz > 0;
60  }
61 
62  inline bool getnext(idx_type& val, idx_type& i) const {
63  val = ++i;
64  if (i < sz) {
65  return true;
66  } else {
67  i = val = 0;
68  return false;
69  }
70  }
71  inline size_t trueSize() const { return size(); }
72  inline size_t size() const { return sz; }
73 
75  template<typename T>
76  inline void subset(Vector<T>& rv, const Vector<T>& v) const {
77  rv = v;
78  }
79 
83  template<typename T, typename U>
84  void subassign(Vector<T>& rv,
85  U& u,
86  idx_type& vj) const {
87  for (idx_type j=0; j<rv.size(); ++j) {
88  setv_checkbefore(rv, j, convert<T,typename U::value_type>(u[vj++]));
89  }
90  }
91 
95  template<typename T, typename U>
96  inline void subassignScalar(Vector<T>& rv, U u) const {
97  for (idx_type j=0; j<rv.size(); ++j) {
98  setv(rv, j, convert<T,U>(u));
99  }
100  }
101 
102  inline void selectNames(Dname& tonames, const Dname& fromnames) const {
103  tonames = fromnames;
104  }
105  };
106 
107 
108  template <typename I>
109  struct IntIndex_T {
110  IntIndex_T(const Vector<I>& vi_p) : vi(vi_p), vidx(vi.size()), uidx(vi.size()) {
111  if (vi.isOrdered()) {
112  vidx = vi;
113  std::iota(uidx.begin(), uidx.end(), 0);
114  }
115  else {
116  const auto& idx = vi.template sort_idx<size_t>();
117  for (idx_type j=0; j<idx.size(); ++j) {
118  setv(vidx, idx[j], vi[j]);
119  setv(uidx, idx[j], j);
120  }
121  }
122  }
123 
124  Vector<I> vi;
125  Vector<size_t> vidx;
126  Vector<size_t> uidx;
127 
128  bool getfirst(idx_type& iv, idx_type& ii) const {
129  if (vi.size()) {
130  ii = 0;
131  iv = vi[0];
132  return true;
133  }
134  else {
135  return false;
136  }
137  }
138 
139  bool getnext(idx_type& iv, idx_type& ii) const {
140  if (vi.size()) {
141  if (++ii < vi.size()) {
142  iv = vi[ii];
143  return true;
144  } else {
145  getfirst(iv, ii);
146  return false;
147  }
148  }
149  else {
150  return false;
151  }
152  }
153 
154  inline size_t trueSize() const {
155  return vi.size();
156  }
157  inline size_t size() const {
158  return trueSize();
159  }
160 
162  template<typename T>
163  inline void subset(Vector<T>& rv, const Vector<T>& v) const {
164  for (idx_type j=0; j<vi.size(); ++j) {
165  if (vi[j] < 0) throw range_error("mixed positive and negative subscripts");
166  if (vi[j] >= v.size()) throw range_error("subscript out of bounds");
167  rv.push_back(v[vi[j]]);
168  }
169  }
170 
175  template<typename T>
176  inline void subset(Vector<T>& rv, const Vector<T>& v, idx_type& ii, idx_type pos) const {
177  for (; ii<vi.size(); ++ii) {
178  if (vi[ii] < 0) throw range_error("mixed positive and negative subscripts");
179  // if no index falls inside the extent of v, then return:
180  if (vi[ii] < pos || vi[ii] >= v.size() + pos) return;
181  rv.push_back(v[vi[ii]-pos]);
182  }
183  }
184 
189  template<typename T, typename U>
190  void subassign(Vector<T>& rv,
191  const U& u,
192  idx_type& vj) const {
193  for (idx_type j=0; j<vi.size(); ++j) {
194  j+1 < vi.size() && vidx[j+1] - vidx[j] == 1 ?
195  setv_checkbefore(rv, vidx[j], convert<T,typename U::value_type>(u[vj+uidx[j]])) :
196  setv(rv, vidx[j], convert<T,typename U::value_type>(u[vj+uidx[j]]));
197  }
198  vj += vi.size();
199  }
200 
201  template<typename T, typename U>
202  inline void subassignScalar(Vector<T>& rv, U u) const {
203  for (idx_type j=0; j<vi.size(); ++j) {
204  j+1 < vi.size() && vidx[j+1] - vidx[j] == 1 ?
205  setv_checkbefore(rv, vidx[j], convert<T,U>(u)) :
206  setv(rv, vidx[j], convert<T,U>(u));
207  }
208  }
209 
210  inline void selectNames(Dname& tonames, const Dname& fromnames) const {
211  if (fromnames.names.size() > 0) {
212  for (idx_type j=0; j<vi.size(); ++j) {
213  if (fromnames.sz <= vi[j]) {
214  throw range_error("subscript out of bounds");
215  } else {
216  tonames.addafter(fromnames.names[vi[j]]);
217  }
218  }
219  } else {
220  tonames = Dname(vi.size());
221  }
222  }
223  }; // struct IntIndex
224 
225 
226  template <typename I>
227  struct IntIndexNeg_T {
228  IntIndexNeg_T(const Vector<I>& vi_p, idx_type sz_p) : vi(vi_p), sz(sz_p)
229  {
230  if (vi.size() && !vi.isOrdered()) {
231  vi.sort();
232  vi.erase(unique(vi.begin(), vi.end()), vi.end());
233  }
234  if (vi.size() && (vi.back() >= sz || !sz)) throw range_error("subscript out of bounds");
235  }
236 
237  Vector<I> vi;
238  idx_type sz;
239 
240  bool getfirst(idx_type& iv, idx_type& ii) const {
241  ii = iv = 0;
242  while (ii < vi.size() && vi[ii] == iv) {
243  ++ii;
244  if (iv < sz) ++iv;
245  }
246  if (iv == sz) {
247  ii = iv = 0;
248  return false;
249  }
250  else {
251  return true;
252  }
253  }
254 
255  bool getnext(idx_type& iv, idx_type& ii) const {
256  ++iv;
257  while (ii < vi.size() && vi[ii] == iv) {
258  ++ii;
259  if (iv < sz) ++iv;
260  }
261  if (iv == sz) {
262  getfirst(iv, ii); // reset, this is needed by the getcol functions
263  return false;
264  }
265  else {
266  return true;
267  }
268  }
269 
270  inline size_t trueSize() const {
271  // the following is always correct as the constructor rejects
272  // any vi value that is out of 0..sz-1:
273  return sz - vi.size();
274  }
275  inline size_t size() const {
276  return trueSize();
277  }
278 
280  template<typename T>
281  inline void subset(Vector<T>& rv, const Vector<T>& v) const {
282  idx_type ii = 0;
283  for (idx_type j=0; j<sz; ++j) {
284  if (ii < vi.size() && vi[ii] == j)
285  ++ii;
286  else
287  rv.push_back(v[j]);
288  }
289  }
290 
295  template<typename T>
296  inline void subset(Vector<T>& rv, const Vector<T>& v,
297  idx_type& ii, idx_type& iv, idx_type pos) const {
298  for (; iv<sz; ++iv) {
299  if (iv >= pos + v.size()) return;
300  if (ii < vi.size() && vi[ii] == iv)
301  ++ii;
302  else
303  rv.push_back(v[iv - pos]);
304  }
305  }
306 
307  template<typename T, typename U>
308  void subassign(Vector<T>& rv,
309  U& u,
310  idx_type& vj) const {
311  subassign_generic(*this, rv, u, vj);
312  }
313 
314  template<typename T, typename U>
315  inline void subassignScalar(Vector<T>& rv, U u) const {
316  subassignScalar_generic(*this, rv, u);
317  }
318 
319  inline void selectNames(Dname& tonames, const Dname& fromnames) const {
320  idx_type ii = 0;
321  if (fromnames.names.size() > 0) {
322  for (idx_type j=0; j<sz; ++j) {
323  if (fromnames.sz <= j) {
324  throw range_error("subscript out of bounds");
325  }
326  if (!(ii < vi.size() && vi[ii] == j)) {
327  tonames.addafter(fromnames.names[j]);
328  }
329  else {
330  ++ii;
331  }
332  }
333  } else {
334  tonames = Dname(size());
335  }
336  }
337  }; // end struct IntIndexNeg_T
338 
339 
340  struct NameIndex {
341  const vector<string> vs;
342  const Dname& names;
343 
344  bool getfirst(idx_type& val, idx_type& i) const {
345  if (vs.size()) {
346  i = 0;
347  val = names[vs[0]];
348  return true;
349  } else {
350  return false;
351  }
352  }
353 
354  bool getnext(idx_type& val, idx_type& i) const {
355  if (++i < vs.size()) {
356  val = names[vs[i]];
357  return true;
358  } else {
359  getfirst(val, i);
360  return false;
361  }
362  }
363 
364  inline size_t trueSize() const { return vs.size(); }
365  inline size_t size() const { return vs.size(); }
366 
367  template<typename T>
368  inline void subset(Vector<T>& rv, const Vector<T>& v) const {
369  for (idx_type j=0; j<vs.size(); ++j) {
370  rv.push_back(v[names[vs[j]]]);
371  }
372  }
373 
374  template<typename T, typename U>
375  void subassign(Vector<T>& rv,
376  const U& u,
377  idx_type& vj) const {
378  subassign_generic(*this, rv, u, vj);
379  }
380 
381  template<typename T, typename U>
382  inline void subassignScalar(Vector<T>& rv, U u) const {
383  subassignScalar_generic(*this, rv, u);
384  }
385 
386  inline void selectNames(Dname& tonames, const Dname& fromnames) const {
387  for (idx_type j=0; j<vs.size(); ++j) {
388  fromnames[vs[j]]; // really just to check if it's there...
389  tonames.addafter(vs[j]);
390  }
391  }
392  }; // end struct NameIndex
393 
394  struct BoolIndex {
395  const Vector<bool>& vb;
396 
397  bool getfirst(idx_type& val, idx_type& i) const {
398  for (i=0; i<vb.size(); ++i) {
399  if (vb[i]) {
400  val = i;
401  return true;
402  }
403  }
404  return false;
405  }
406 
407  bool getnext(idx_type& val, idx_type& i) const {
408  for (; ++i<vb.size(); ++i) {
409  if (vb[i]) {
410  val = i;
411  return true;
412  }
413  }
414  getfirst(val, i);
415  return false;
416  }
417 
418  inline size_t trueSize() const { return size(); }
419  inline size_t size() const { return std::count(vb.cbegin(), vb.cend(), true); }
420 
421  template<typename T>
422  inline void subset(Vector<T>& rv, const Vector<T>& v) const {
423  for (idx_type j=0; j<vb.size(); ++j) {
424  if (vb[j]) {
425  rv.push_back(v[j]);
426  }
427  }
428  }
429 
434  template<typename T>
435  inline void subset(Vector<T>& rv, const Vector<T>& v, idx_type& ii) const {
436  for (idx_type j=0; j<v.size(); ++j) {
437  if (ii >= vb.size()) {
438  throw range_error("subscript out of bounds");
439  }
440  if (vb[ii++]) {
441  rv.push_back(v[j]);
442  }
443  }
444  }
445 
446  template<typename T, typename U>
447  void subassign(Vector<T>& rv,
448  const U& u,
449  idx_type& vj) const {
450  subassign_generic(*this, rv, u, vj);
451  }
452 
453  template<typename T, typename U>
454  inline void subassignScalar(Vector<T>& rv, U u) const {
455  subassignScalar_generic(*this, rv, u);
456  }
457 
458  inline void selectNames(Dname& tonames, const Dname& fromnames) const {
459  if (fromnames.names.size() > 0) {
460  for (idx_type j=0; j<vb.size(); ++j) {
461  if (vb[j]) {
462  if (fromnames.sz <= j) {
463  throw range_error("subscript out of bounds");
464  } else {
465  tonames.addafter(fromnames.names[j]);
466  }
467  }
468  }
469  } else {
470  idx_type nb = size(); // get the number of elements set to true
471  tonames = Dname(nb);
472  }
473  }
474  }; // end struct BoolIndex
475 
476  struct DtimeIndex {
477  const Vector<Global::dtime>& idx; // index
478  const Vector<Global::dtime>& vd;
479 
480  // note: we don't make an assumption on the ordering of idx
481 
482  inline bool getfirst(idx_type& val, idx_type& i) const {
483  while (i < idx.size()) {
484  auto p = bsearch(&idx[i], vd.c_ptr(), vd.size(), sizeof(Global::dtime), comp);
485  if (p) {
486  val = static_cast<Global::dtime*>(p) - vd.c_ptr();
487  return true;
488  }
489  else {
490  ++i;
491  }
492  }
493  return false;
494  }
495 
496  inline bool getnext(idx_type& val, idx_type& i) const {
497  return getfirst(val, ++i);
498  }
499 
500  inline size_t trueSize() const { // LLL really pathetic!
501  idx_type ii = 0, iv = 0;
502  size_t n = 0;
503  while (iv < vd.size() && ii < idx.size()) {
504  if (vd[iv] < idx[ii]) {
505  ++iv;
506  } else if (vd[iv] > idx[ii]) {
507  ++ii;
508  } else {
509  ++iv;
510  ++ii;
511  ++n;
512  }
513  }
514  return n;
515  }
516 
517  inline size_t size() const {
518  // because we don't know in advance the true size of the subset,
519  // for the moment we send back the maximum size LLL
520  return idx.size();
521  }
522 
523  template<typename T>
524  inline void subset(Vector<T>& rv, const Vector<T>& v) const {
525  if (vd.size() != v.size()) {
526  throw range_error("size mismatch between vector to subset and time index");
527  }
528  idx_type i = 0;
529  idx_type val;
530  if (getfirst(val, i)) {
531  rv.push_back(v[val]);
532  while (getnext(val, i)) {
533  rv.push_back(v[val]);
534  }
535  }
536  }
537 
538  template<typename T, typename U>
539  void subassign(Vector<T>& rv,
540  const U& u,
541  idx_type& vj) const {
542  subassign_generic(*this, rv, u, vj);
543  }
544 
545  template<typename T, typename U>
546  inline void subassignScalar(Vector<T>& rv, U u) const {
547  subassignScalar_generic(*this, rv, u);
548  }
549 
550  inline void selectNames(Dname& tonames, const Dname& fromnames) const {
551  if (fromnames.names.size() > 0) {
552  idx_type ii = 0, iv = 0;
553  while (iv < vd.size() && ii < idx.size()) {
554  if (vd[iv] < idx[ii]) {
555  ++iv;
556  } else if (vd[iv] > idx[ii]) {
557  ++ii;
558  } else {
559  tonames.addafter(fromnames.names[iv++]);
560  ++ii;
561  }
562  }
563  } else {
564  idx_type nb = size(); // get the number of elements set to true
565  tonames = Dname(nb);
566  }
567  }
568 
569  private:
571  static inline int comp(const void* a, const void* b)
572  {
573  if (*static_cast<const Global::dtime*>(a) < *static_cast<const Global::dtime*>(b)) return -1;
574  if (*static_cast<const Global::dtime*>(a) > *static_cast<const Global::dtime*>(b)) return 1;
575  return 0;
576  }
577  }; // end struct DtimeIndex
578 
579 
586  struct IntervalIndex {
587  const Vector<tz::interval>& idx; // index
588  const Vector<Global::dtime>& vi;
589 
590  // note: we don't make an assumption on the ordering of idx
591 
592  inline bool getfirst(idx_type& val, idx_type& i) const {
593  while (i < idx.size()) {
594  const auto iter = idx[i].sopen ?
595  std::upper_bound(vi.begin(), vi.end(), idx[i].s) :
596  std::lower_bound(vi.begin(), vi.end(), idx[i].s);
597  val = iter - vi.begin();
598  if (iter == vi.end() || (!idx[i].eopen ? vi[val] > idx[i].e : vi[val] >= idx[i].e)) {
599  ++i;
600  }
601  else {
602  return true;
603  }
604  }
605  return false;
606  }
607 
608  inline bool getnext(idx_type& val, idx_type& i) const {
609  ++val;
610  while (val < vi.size() && i < idx.size()) {
611  if (!idx[i].sopen ? vi[val] < idx[i].s : vi[val] <= idx[i].s) {
612  ++val;
613  } else if (!idx[i].eopen ? vi[val] > idx[i].e : vi[val] >= idx[i].e) {
614  if (!getfirst(val, ++i)) {
615  return false;
616  }
617  else {
618  return true;
619  }
620  } else {
621  return true;
622  }
623  }
624  return false;
625  }
626 
627  inline size_t trueSize() const {
628  size_t n = 0;
629  idx_type iv=0, ii=0;
630  while (iv < vi.size() && ii < idx.size()) {
631  if (!idx[ii].sopen ? vi[iv] < idx[ii].s : vi[iv] <= idx[ii].s) {
632  ++iv;
633  } else if (!idx[ii].eopen ? vi[iv] > idx[ii].e : vi[iv] >= idx[ii].e) {
634  ++ii;
635  } else {
636  ++iv;
637  ++n;
638  }
639  }
640  return n;
641  }
642 
643  inline size_t size() const {
644  // because we don't know in advance the true size of the subset,
645  // we send back the maximum potential size (which is the size of
646  // the dtime vector):
647  return vi.size();
648  }
649 
650  template<typename T>
651  inline void subset(Vector<T>& rv, const Vector<T>& v) const {
652  if (vi.size() != v.size()) {
653  std::cout << "vi.size(): " << vi.size() << " v.size(): " << v.size() << std::endl;
654  throw range_error("size mismatch between vector to subset and time index");
655  }
656  idx_type i = 0;
657  idx_type val;
658  if (getfirst(val, i)) {
659  rv.push_back(v[val]);
660  while (getnext(val, i)) {
661  rv.push_back(v[val]);
662  }
663  }
664  }
665 
666  template<typename T, typename U>
667  void subassign(Vector<T>& rv,
668  const U& u,
669  idx_type& vj) const {
670  subassign_generic(*this, rv, u, vj);
671  }
672 
673  template<typename T, typename U>
674  inline void subassignScalar(Vector<T>& rv, U u) const {
675  subassignScalar_generic(*this, rv, u);
676  }
677 
678  inline void selectNames(Dname& tonames, const Dname& fromnames) const {
679  if (fromnames.names.size() > 0) {
680  idx_type ii = 0, iv = 0;
681  while (iv < vi.size() && ii < idx.size()) {
682  if (!idx[ii].sopen ? vi[iv] < idx[ii].s : vi[iv] <= idx[ii].s) {
683  ++iv;
684  } else if (!idx[ii].eopen ? vi[iv] > idx[ii].e : vi[iv] >= idx[ii].e) {
685  ++ii;
686  } else {
687  tonames.addafter(fromnames.names[iv++]);
688  }
689  }
690  } else {
691  idx_type nb = size(); // get the number of elements set to true
692  tonames = Dname(nb);
693  }
694  }
695 
696  }; // end struct IntervalIndex
697 
698 
707 
710 
711  struct Index {
712  typedef Variant<NullIndex,
713  IntIndex,
714  IntIndexNeg,
715  NameIndex,
716  BoolIndex,
717  DtimeIndex,
719  > VIdx;
720 
721  VIdx idx;
722 
723  Index(const NullIndex& i) : idx(i) { }
724  Index(const IntIndex& i) : idx(i) { }
725  Index(const IntIndexNeg& i): idx(i) { }
726  Index(const NameIndex& i) : idx(i) { }
727  Index(const BoolIndex& i) : idx(i) { }
728  Index(const DtimeIndex& i) : idx(i) { }
729  Index(const IntervalIndex& i) : idx(i) { }
730 
731  enum IdxType {
732  it_null,
733  it_int,
734  it_int_neg,
735  it_names,
736  it_bool,
737  it_dtime,
738  it_interval
739  };
740 
741  inline size_t trueSize() const {
742  switch (idx.which()) {
743  case it_null:
744  return get<NullIndex>(idx).trueSize();
745  case it_int:
746  return get<IntIndex>(idx).trueSize();
747  case it_int_neg:
748  return get<IntIndexNeg>(idx).trueSize();
749  case it_names:
750  return get<NameIndex>(idx).trueSize();
751  case it_bool:
752  return get<BoolIndex>(idx).trueSize();
753  case it_dtime:
754  return get<DtimeIndex>(idx).trueSize();
755  case it_interval:
756  return get<IntervalIndex>(idx).trueSize();
757  default:
758  throw std::range_error("Index::trueSize: unknown index type");
759  }
760  }
761 
762  inline size_t size() const {
763  switch (idx.which()) {
764  case it_null:
765  return get<NullIndex>(idx).size();
766  case it_int:
767  return get<IntIndex>(idx).size();
768  case it_int_neg:
769  return get<IntIndexNeg>(idx).size();
770  case it_names:
771  return get<NameIndex>(idx).size();
772  case it_bool:
773  return get<BoolIndex>(idx).size();
774  case it_dtime:
775  return get<DtimeIndex>(idx).size();
776  case it_interval:
777  return get<IntervalIndex>(idx).size();
778  default:
779  throw std::range_error("Index::size: unknown index type");
780  }
781  }
782 
783  inline bool getfirst(idx_type& val, idx_type& ii) const {
784  switch (idx.which()) {
785  case it_null:
786  return get<NullIndex>(idx).getfirst(val, ii);
787  case it_int:
788  return get<IntIndex>(idx).getfirst(val, ii);
789  case it_int_neg:
790  return get<IntIndexNeg>(idx).getfirst(val, ii);
791  case it_names:
792  return get<NameIndex>(idx).getfirst(val, ii);
793  case it_bool:
794  return get<BoolIndex>(idx).getfirst(val, ii);
795  case it_dtime:
796  return get<DtimeIndex>(idx).getfirst(val, ii);
797  case it_interval:
798  return get<IntervalIndex>(idx).getfirst(val, ii);
799  default:
800  throw range_error("Index::getfirst: unknown index type");
801  }
802  }
803 
804  inline bool getnext(idx_type& val, idx_type& ii) const {
805  switch (idx.which()) {
806  case it_null:
807  return get<NullIndex>(idx).getnext(val, ii);
808  case it_int:
809  return get<IntIndex>(idx).getnext(val, ii);
810  case it_int_neg:
811  return get<IntIndexNeg>(idx).getnext(val, ii);
812  case it_names:
813  return get<NameIndex>(idx).getnext(val, ii);
814  case it_bool:
815  return get<BoolIndex>(idx).getnext(val, ii);
816  case it_dtime:
817  return get<DtimeIndex>(idx).getnext(val, ii);
818  case it_interval:
819  return get<IntervalIndex>(idx).getnext(val, ii);
820  default:
821  throw range_error("Index::getnext: unknown index type");
822  }
823  }
824 
825  template<typename T>
826  inline void subset(Vector<T>& rv, const Vector<T>& v) const {
827  switch (idx.which()) {
828  case it_null:
829  get<NullIndex>(idx).subset(rv, v);
830  break;
831  case it_int:
832  get<IntIndex>(idx).subset(rv, v);
833  break;
834  case it_int_neg:
835  get<IntIndexNeg>(idx).subset(rv, v);
836  break;
837  case it_names:
838  get<NameIndex>(idx).subset(rv, v);
839  break;
840  case it_bool:
841  get<BoolIndex>(idx).subset(rv, v);
842  break;
843  case it_dtime:
844  get<DtimeIndex>(idx).subset(rv, v);
845  break;
846  case it_interval:
847  get<IntervalIndex>(idx).subset(rv, v);
848  break;
849  default:
850  throw range_error("Index::subset: unknown index type");
851  }
852  }
853 
854  template<typename T>
855  inline void subset(Vector<T>& rv, const Vector<T>& v,
856  idx_type& ii, idx_type& iv, idx_type pos) const {
857  switch (idx.which()) {
858  case it_null:
859  get<NullIndex>(idx).subset(rv, v);
860  break;
861  case it_int:
862  get<IntIndex>(idx).subset(rv, v, ii, pos);
863  break;
864  case it_int_neg:
865  get<IntIndexNeg>(idx).subset(rv, v, ii, iv, pos);
866  break;
867  case it_bool:
868  get<BoolIndex>(idx).subset(rv, v, ii);
869  break;
870  case it_names:
871  case it_interval:
872  case it_dtime:
873  throw range_error("can't do a vector subset with this index type");
874  default:
875  throw range_error("Index::subset: unknown index type");
876  }
877  }
878 
879  template<typename T, typename U>
880  void subassign(Vector<T>& rv,
881  const U& v,
882  idx_type& vj) const {
883  switch (idx.which()) {
884  case it_null:
885  get<NullIndex>(idx).subassign(rv, v, vj);
886  break;
887  case it_int:
888  get<IntIndex>(idx).subassign(rv, v, vj);
889  break;
890  case it_int_neg:
891  get<IntIndexNeg>(idx).subassign(rv, v, vj);
892  break;
893  case it_names:
894  get<NameIndex>(idx).subassign(rv, v, vj);
895  break;
896  case it_bool:
897  get<BoolIndex>(idx).subassign(rv, v, vj);
898  break;
899  case it_dtime:
900  get<DtimeIndex>(idx).subassign(rv, v, vj);
901  break;
902  case it_interval:
903  get<IntervalIndex>(idx).subassign(rv, v, vj);
904  break;
905  default:
906  throw range_error("Index::subassign: unknown index type");
907  }
908  }
909 
910  template<typename T, typename U>
911  void subassignScalar(Vector<T>& rv, U u) const {
912  switch (idx.which()) {
913  case it_null:
914  get<NullIndex>(idx).subassignScalar(rv, u);
915  break;
916  case it_int:
917  get<IntIndex>(idx).subassignScalar(rv, u);
918  break;
919  case it_int_neg:
920  get<IntIndexNeg>(idx).subassignScalar(rv, u);
921  break;
922  case it_names:
923  get<NameIndex>(idx).subassignScalar(rv, u);
924  break;
925  case it_bool:
926  get<BoolIndex>(idx).subassignScalar(rv, u);
927  break;
928  case it_dtime:
929  get<DtimeIndex>(idx).subassignScalar(rv, u);
930  break;
931  case it_interval:
932  get<IntervalIndex>(idx).subassignScalar(rv, u);
933  break;
934  default:
935  throw range_error("Index::subassignScalar: unknown index type");
936  }
937  }
938 
939  inline void selectNames(Dname& tonames, const Dname& fromnames) const {
940  switch (idx.which()) {
941  case it_null:
942  get<NullIndex>(idx).selectNames(tonames, fromnames);
943  break;
944  case it_int:
945  get<IntIndex>(idx).selectNames(tonames, fromnames);
946  break;
947  case it_int_neg:
948  get<IntIndexNeg>(idx).selectNames(tonames, fromnames);
949  break;
950  case it_names:
951  get<NameIndex>(idx).selectNames(tonames, fromnames);
952  break;
953  case it_bool:
954  get<BoolIndex>(idx).selectNames(tonames, fromnames);
955  break;
956  case it_dtime:
957  get<DtimeIndex>(idx).selectNames(tonames, fromnames);
958  break;
959  case it_interval:
960  get<IntervalIndex>(idx).selectNames(tonames, fromnames);
961  break;
962  default:
963  throw range_error("Index::selectNames: unknown index type");
964  }
965  }
966 
967  static inline bool getfirstcol(idx_type& col,
968  vector<idx_type>& val,
969  vector<idx_type>& pi,
970  const vector<Index>& i,
971  const Vector<idx_type>& dim)
972  {
973  // get the first index:
974  for (idx_type pd = 1; pd<dim.size(); ++pd) {
975  if (!i[pd].getfirst(val[pd], pi[pd])) {
976  return false;
977  }
978  }
979 
980  // figure out the column at which it is:
981  col = 0;
982  idx_type mul = 1;
983  for (idx_type k=1; k<dim.size(); ++k) {
984  if (val[k] >= dim[k]) {
985  throw range_error("subscript out of bounds");
986  }
987  col += val[k]*mul;
988  mul *= dim[k];
989  }
990 
991  return true;
992  }
993 
994  static inline bool getnextcol(idx_type& col,
995  vector<idx_type>& val,
996  vector<idx_type>& pi,
997  const vector<Index>& i,
998  const Vector<idx_type>& dim)
999  {
1000  // get the next index:
1001  idx_type pd = 1;
1002  while (pd < dim.size() && !i[pd].getnext(val[pd], pi[pd])) {
1003  ++pd;
1004  }
1005  if (pd >= dim.size()) {
1006  return false;
1007  }
1008 
1009  // figure out the column:
1010  col = 0;
1011  idx_type mul = 1;
1012  for (idx_type k=1; k<dim.size(); ++k) {
1013  if (val[k] >= dim[k]) {
1014  throw range_error("subscript out of bounds");
1015  }
1016  col += val[k]*mul;
1017  mul *= dim[k];
1018  }
1019  return true;
1020  }
1021 
1022  };
1023 
1024 
1025  template<typename I, typename T, typename U>
1026  void subassign_generic(const I& idx,
1027  Vector<T>& rv,
1028  const U& u,
1029  idx_type& vj) {
1030  // find first j:
1031  idx_type ii = 0, j = 0, nextj = 0;
1032  std::cout << "subassign_generic entry j: " << j << ", vj: " << vj << std::endl;
1033  std::cout << "u.size(): " << u.size() << std::endl;
1034  if (!idx.getfirst(j, ii)) return;
1035  nextj = j; // start search for next from j
1036 
1037  // loop finding nextj:
1038  while (idx.getnext(nextj, ii)) {
1039  std::cout << "we found next and nextj: " << nextj << ", j: " << j << ", ii: " << ii << std::endl;
1040  if (nextj - j <= 1) setv_checkbefore(rv, j, convert<T,typename U::value_type>(u[vj++]));
1041  else if (nextj - j > 1) setv(rv, j, convert<T,typename U::value_type>(u[vj++]));
1042  j = nextj;
1043  }
1044 
1045  // finish the last one:
1046  std::cout << "last j: " << j << ", vj: " << vj << std::endl;
1047  setv(rv, j, convert<T,typename U::value_type>(u[vj++]));
1048  std::cout << "vj is: " << vj << std::endl;
1049  }
1050 
1051 
1052  template<typename I, typename T, typename U>
1053  inline void subassignScalar_generic(const I& idx, Vector<T>& rv, U u) {
1054  // find first j:
1055  idx_type ii = 0, j = 0, nextj = 0;
1056  if (!idx.getfirst(j, ii)) return;
1057  nextj = j; // start search for next from j
1058 
1059  // loop finding nextj:
1060  while (idx.getnext(nextj, ii)) {
1061  if (nextj - j <= 1) setv_checkbefore(rv, j, convert<T,U>(u));
1062  else if (nextj - j > 1) setv(rv, j, convert<T,U>(u));
1063  j = nextj;
1064  }
1065 
1066  // finish the last one:
1067  setv(rv, j, convert<T,U>(u));
1068  }
1069 
1070 
1071 }
1072 
1073 #endif
arr::DtimeIndex
Definition: index.hpp:476
arr::BoolIndex::subset
void subset(Vector< T > &rv, const Vector< T > &v, idx_type &ii) const
Definition: index.hpp:435
arr::IntIndex_T::subset
void subset(Vector< T > &rv, const Vector< T > &v) const
Subset 'v' and store in 'rv'.
Definition: index.hpp:163
arr::NullIndex::subassignScalar
void subassignScalar(Vector< T > &rv, U u) const
Definition: index.hpp:96
arr::Vector< T >
arr::NullIndex::subassign
void subassign(Vector< T > &rv, U &u, idx_type &vj) const
Definition: index.hpp:84
val
Contains the types that constitute the output of an evaluation by the interpreter.
Definition: display.hpp:31
arr::IntIndex_T
Definition: index.hpp:109
arr::Index
Definition: index.hpp:711
arr::IntervalIndex
Definition: index.hpp:586
arr::IntIndex_T::subset
void subset(Vector< T > &rv, const Vector< T > &v, idx_type &ii, idx_type pos) const
Definition: index.hpp:176
arr::IntIndex_T::subassign
void subassign(Vector< T > &rv, const U &u, idx_type &vj) const
Definition: index.hpp:190
arr::IntIndexNeg_T
Definition: index.hpp:227
arr::IntIndexNeg_T::subset
void subset(Vector< T > &rv, const Vector< T > &v, idx_type &ii, idx_type &iv, idx_type pos) const
Definition: index.hpp:296
arr::Dname
Definition: dname.hpp:32
arr::NameIndex
Definition: index.hpp:340
arr
Contains the classes and functions that implement a multidimentional array type.
Definition: allocator.hpp:29
arr::IntIndexNeg_T::subset
void subset(Vector< T > &rv, const Vector< T > &v) const
Subset 'v' and store in 'rv'.
Definition: index.hpp:281
arr::NullIndex
Definition: index.hpp:54
arr::NullIndex::subset
void subset(Vector< T > &rv, const Vector< T > &v) const
Subset 'v' according to this index and put the result into 'rv'.
Definition: index.hpp:76
arr::convert
val::Value convert(const double &u)
these are the set of "conversions" of a type to itself
Definition: base_funcs_array.cpp:61
arr::BoolIndex
Definition: index.hpp:394