utils.hpp
Go to the documentation of this file.
1 
6 #ifndef UTILS_HPP
7 #define UTILS_HPP 1
8 
9 #include <vector>
10 #include <algorithm>
11 #include "universal_error.hpp"
12 #include <cassert>
13 #include "boost/container/flat_map.hpp"
14 #include <iostream>
15 
16 using std::vector;
17 
22 bool is_nan(double x);
23 
30 vector<double> linspace(double xl, double xh, int n);
31 
38 vector<double> arange(double x_min, double x_max, double dx);
39 
45 template <class T> vector<T> operator+
46 (vector<T> const& v1, vector<T> const& v2)
47 {
48  assert(v1.size() == v2.size() && "Vectors must have the same length");
49  vector<T> res(v1.size());
50  for (size_t i = 0; i < v1.size(); ++i)
51  res[i] = v1[i] + v2[i];
52  return res;
53 }
54 
60 template<class T> vector<T> operator+
61 (const vector<T>& v, const T& t)
62 {
63  vector<T> res(v.size());
64  for (size_t i = 0, endp = v.size(); i < endp; ++i)
65  res[i] = v[i] + t;
66  return res;
67 }
68 
74 template<class T> vector<T> operator+
75 (const T& t, const vector<T>& v)
76 {
77  return v + t;
78 }
79 
85 template<class T> vector<T>& operator+=
86 (vector<T>& v, const T& t)
87 {
88  for (size_t i = 0, endp = v.size(); i < endp; ++i)
89  v[i] += t;
90  return v;
91 }
92 
98 template <class T> vector<T> operator-
99 (vector<T> const& v1, vector<T> const& v2)
100 {
101  if (v1.size() != v2.size())
102  throw UniversalError("Vectors must have the same length");
103 
104  vector<T> res(v1.size());
105  for (size_t i = 0; i < v1.size(); ++i)
106  res[i] = v1[i] - v2[i];
107  return res;
108 }
109 
115 template <class T> vector<T> operator*
116 (double d, vector<T> const& v)
117 {
118  vector<T> res(v.size());
119  for (size_t i = 0; i < v.size(); ++i)
120  res[i] = d*v[i];
121  return res;
122 }
123 
133 template <typename T>
134 T BiLinearInterpolation(const vector<T>& x, const vector<T>& y, const std::vector<std::vector<T> >& z, T xi, T yi);
135 
136 template <typename T>
137 T BiLinearInterpolation(const vector<T>& x, const vector<T>& y, const std::vector<std::vector<T> >& z, T xi, T yi)
138 {
139  typename vector<T>::const_iterator itx = upper_bound(x.begin(), x.end(), xi);
140  if (itx == x.end())
141  {
142  if (xi > x.back())
143  {
144  std::cout << "X too large in BiLinearInterpolation, x_i " << xi << " max X " << x.back() << std::endl;
145  throw;
146  }
147  else
148  --itx;
149  }
150  if (itx == x.begin())
151  {
152  if (*itx < x.at(0))
153  {
154  std::cout << "X too small in BiLinearInterpolation, x_i " << xi << " min X " << x.at(0) << std::endl;
155  throw;
156  }
157  }
158  typename vector<T>::const_iterator ity = upper_bound(y.begin(), y.end(), yi);
159  if (ity == y.end())
160  {
161  if (yi > y.back())
162  {
163  std::cout << "Y too large in LinearInterpolation, y_i " << yi << " max Y " << y.back() << std::endl;
164  throw;
165  }
166  else
167  --ity;
168  }
169  if (ity == y.begin())
170  {
171  if (*ity < y.at(0))
172  {
173  std::cout << "Y too small in LinearInterpolation, y_i " << yi << " min Y " << y.at(0) << std::endl;
174  throw;
175  }
176  }
177 
178  T delta = 1.0 / ((*itx - *(itx - 1)) * (*ity - *(ity - 1)));
179  size_t idx = static_cast<std::size_t>(itx - x.begin());
180  size_t idy = static_cast<std::size_t>(ity - y.begin());
181  return (z[idx - 1][idy - 1] * (*itx - xi) * (*ity - yi) + z[idx][idy - 1] * (xi - *(itx - 1)) * (*ity - yi)
182  + z[idx - 1][idy] * (*itx - xi) * (yi - *(ity - 1)) + z[idx][idy] * (xi - *(itx - 1))
183  * (yi - *(ity - 1))) * delta;
184 }
185 
193 template <typename T>
194 T LinearInterpolation(const vector<T> &x, const vector<T> &y, T xi);
195 
196 template <typename T>
197 T LinearInterpolation(const vector<T> &x, const vector<T> &y, T xi)
198 {
199  typename vector<T>::const_iterator it = upper_bound(x.begin(), x.end(), xi);
200  if (it == x.end())
201  {
202  std::cout << "X too large in LinearInterpolation, x_i " << xi << " max X " << x.back() << std::endl;
203  throw;
204  }
205  if (it == x.begin())
206  {
207  if (*it < x.at(0))
208  {
209  std::cout << "X too small in LinearInterpolation, x_i " << xi << " min X " << x.at(0) << std::endl;
210  throw;
211  }
212  }
213  if (*it == xi)
214  return y[static_cast<std::size_t>(it - x.begin())];
215 
216  return y[static_cast<std::size_t>(it - x.begin())] + (xi - *it)* (y[static_cast<std::size_t>(it - 1 - x.begin())]
217  - y[static_cast<std::size_t>(it - x.begin())]) / (*(it - 1) - *it);
218 }
219 
228 template <typename T>
229 T LinearInterpolation(typename vector<T>::const_iterator itx_begin, typename vector<T>::const_iterator itx_end,
230  typename vector<T>::const_iterator ity_begin, T xi);
231 
232 template <typename T>
233 T LinearInterpolation(typename vector<T>::const_iterator itx_begin, typename vector<T>::const_iterator itx_end,
234  typename vector<T>::const_iterator ity_begin, T xi)
235 {
236  typename vector<T>::const_iterator it = upper_bound(itx_begin, itx_end, xi);
237  if (it == itx_end)
238  {
239  std::cout << "X too large in LinearInterpolation, x_i " << xi << " max X " << *itx_end << std::endl;
240  throw;
241  }
242  if (it == itx_begin)
243  {
244  if (*it < *itx_begin)
245  {
246  std::cout << "X too small in LinearInterpolation, x_i " << xi << " min X " << *itx_begin << std::endl;
247  throw;
248  }
249  }
250  const size_t toadd = static_cast<std::size_t>(it - itx_begin);
251  if (*it == xi)
252  return *(ity_begin + toadd);
253 
254  return *(ity_begin + toadd) + (xi - *it) * (*(ity_begin + toadd + 1) - *(ity_begin + toadd)) / (*(it - 1) - *it);
255 }
256 
261 double min(vector<double> const& v);
262 
267 double max(vector<double> const& v);
268 
274 template <class T> void RemoveVector
275 (vector<T> &v, vector<int> &indeces)
276 {
277  if (indeces.empty())
278  return;
279  sort(indeces.begin(), indeces.end());
280  vector<T> result;
281  result.reserve(v.size() - indeces.size());
282  int counter = 0;
283  for (size_t i = 0; i < static_cast<size_t>(indeces.back()); ++i)
284  {
285  if (size_t(indeces[size_t(counter)]) == i)
286  ++counter;
287  else
288  result.push_back(v[i]);
289  }
290  for (size_t i = static_cast<size_t>(indeces.back()) + 1; i < v.size(); ++i)
291  result.push_back(v[i]);
292  v = result;
293 }
294 
300 template <class T> void RemoveVector
301 (vector<T> &v, vector<size_t> &indeces)
302 {
303  if (indeces.empty())
304  return;
305  sort(indeces.begin(), indeces.end());
306  vector<T> result;
307  result.reserve(v.size() - indeces.size());
308  size_t counter = 0;
309  for (size_t i = 0; i < indeces.back(); ++i)
310  {
311  if (indeces[counter] == i)
312  ++counter;
313  else
314  result.push_back(v[i]);
315  }
316  for (size_t i = indeces.back() + 1; i < v.size(); ++i)
317  result.push_back(v[i]);
318  v = result;
319 }
326 template <class T> vector<T> VectorValues(vector<T> const&v, vector<int> const &index)
327 {
328  if (index.empty() || v.empty())
329  return vector<T>();
330 
331  vector<T> result(index.size());
332  for (size_t i = 0; i < index.size(); ++i)
333  result.at(i) = v.at(static_cast<size_t>(index.at(i)));
334  return result;
335 }
336 
343 template <class T> vector<T> VectorValues
344 (vector<T> const&v,
345  vector<size_t> const &index)
346 {
347  if (index.empty() || v.empty())
348  return vector<T>();
349 
350  vector<T> result(index.size());
351  for (size_t i = 0; i < index.size(); ++i)
352  result.at(i) = v.at(index.at(i));
353  return result;
354 }
355 
361 template <class T> T VectorSum(vector<T> const&v)
362 {
363  if (v.empty())
364  return 0;
365  T result = v[0];
366  for (size_t i = 1; i < v.size(); ++i)
367  result += v[i];
368  return result;
369 }
370 
376 template <class T> vector<T> unique(vector<T> const& v)
377 {
378  size_t n = v.size();
379  vector<T> res;
380  res.reserve(n);
381  if (n == 0)
382  return res;
383  res.push_back(v[0]);
384  for (typename vector<T>::const_iterator it = v.begin() + 1; it != v.end(); ++it)
385  if (*it == *(it - 1))
386  continue;
387  else
388  res.push_back(*it);
389  return res;
390 }
391 
397 template <class T> vector<int> unique_index(vector<T> const& v)
398 {
399  if (v.empty())
400  return vector<int>();
401 
402  vector<int> res;
403  res.push_back(0);
404  for (size_t i = 1; i < v.size(); ++i)
405  if (v[i] != v[i - 1])
406  res.push_back(static_cast<int>(i));
407  return res;
408 }
409 
416 template <class T> vector<T> RemoveList(vector<T> const&v, vector<T> const&list)
417 {
418  vector<T> res;
419  for (size_t i = 0; i < v.size(); ++i)
420  if (!binary_search(list.begin(), list.end(), v[i]))
421  res.push_back(v[i]);
422  return res;
423 }
424 
431 template <class T> void RemoveVal(vector<T> &vec, T val)
432 {
433  for (size_t i = 0; i < vec.size(); ++i)
434  {
435  if (vec[i] == val)
436  {
437  vec.erase(vec.begin() + static_cast<long>(i));
438  return;
439  }
440  }
441 }
442 
449 template <class T> bool InVector(vector<T> const&vec, T val)
450 {
451  int n = vec.size();
452  for (int i = 0; i < n; ++i)
453  if (vec[i] == val)
454  return true;
455  return false;
456 }
457 
464 template <class T> int IndexInVector(vector<T> const&vec, T val)
465 {
466  int n = vec.size();
467  for (int i = 0; i < n; ++i)
468  if (vec[i] == val)
469  return i;
470  throw UniversalError("Value not found in vector");
471 }
477 template <class T> void ReArrangeVector(vector<T> &v, vector<int> const& indeces)
478 {
479  const vector<T> temp = v;
480  for (size_t i = 0; i < v.size(); ++i)
481  v[i] = temp[static_cast<size_t>(indeces[i])];
482 }
483 namespace
484 {
485  template<class T> struct index_cmp
486  {
487  explicit index_cmp(const T _arr) : arr(_arr) {}
488  bool operator()(const size_t a, const size_t b) const
489  {
490  return arr[a] < arr[b];
491  }
492  private:
493  const T arr;
494  };
495 }
500 template<class T> void sort_index(const vector<T> & arr, vector<int>& res)
501 {
502  res.resize(arr.size());
503  for (size_t i = 0; i < res.size(); ++i)
504  res[i] = static_cast<int>(i);
505  sort(res.begin(), res.end(), index_cmp<vector<T> >(arr));
506 }
507 
512 template<class T> void sort_index(const vector<T> & arr, vector<size_t>& res)
513 {
514  res.resize(arr.size());
515  for (size_t i = 0; i < res.size(); ++i)
516  res[i] = i;
517  sort(res.begin(), res.end(), index_cmp<vector<T> >(arr));
518 }
519 
520 
525 template<class T> vector<size_t> sort_index(const vector<T> & arr)
526 {
527  vector<size_t> res(arr.size());
528  for (size_t i = 0; i < res.size(); ++i)
529  res[i] = i;
530  sort(res.begin(), res.end(), index_cmp<vector<T> >(arr));
531  return res;
532 }
533 
534 namespace
535 {
536  template <class RAIter, class Compare>
537  class PairComp
538  {
539  public:
540  Compare comp;
541  explicit PairComp(Compare comp_) : comp(comp_) {}
542  bool operator() (const std::pair<size_t, RAIter>& a,
543  const std::pair<size_t, RAIter>& b) const {
544  return comp(*a.second, *b.second);
545  }
546  };
547 }
548 
555 template <class RAIter, class Compare>
556 void sort_index(RAIter iterBegin, RAIter iterEnd, Compare comp,
557  std::vector<size_t>& indexes)
558 {
559 
560  std::vector< std::pair<size_t, RAIter> > pv;
561  pv.reserve(iterEnd - iterBegin);
562 
563  RAIter iter;
564  size_t k;
565  for (iter = iterBegin, k = 0; iter != iterEnd; iter++, k++) {
566  pv.push_back(std::pair<int, RAIter>(k, iter));
567  }
568  PairComp<RAIter, Compare> compy(comp);
569  std::sort(pv.begin(), pv.end(), compy);
570 
571  indexes.resize(pv.size());
572  for (size_t i = 0; i < pv.size(); ++i)
573  indexes[i] = pv[i].first;
574 }
575 
581 template<class T> vector<T> join(vector<T> const& v1,
582  vector<T> const& v2)
583 {
584  if (v1.empty() && v2.empty())
585  return vector<T>();
586  vector<T> res(v1.size() + v2.size());
587  if (!v1.empty())
588  copy(v1.begin(), v1.end(), res.begin());
589  if (!v2.empty())
590  copy(v2.begin(), v2.end(), res.begin() + static_cast<int>(v1.size()));
591  return res;
592 }
593 
595 template<class T> class BinaryOperation
596 {
597 public:
598 
604  virtual T operator()(T const& t1, T const& t2) const = 0;
605 
606  virtual ~BinaryOperation(void) {}
607 };
608 
615 template<class T> vector<T> binary_unite(vector<T> const& v1,
616  vector<T> const& v2,
617  BinaryOperation<T> const& bin_op)
618 {
619  assert(v1.size() == v2.size());
620 
621  vector<T> res(v1.size());
622  for (size_t i = 0; i < v1.size(); ++i)
623  res[i] = bin_op(v1[i], v2[i]);
624  return res;
625 }
626 
628 template<class T> class UnaryOperation
629 {
630 public:
631 
636  virtual T operator()(T const& t) const = 0;
637 
638  virtual ~UnaryOperation(void) {}
639 };
640 
646 template<class T> vector<T> apply_to_each_term(vector<T> const& v,
647  UnaryOperation<T> const& un_op)
648 {
649  vector<T> res(v.size());
650  for (size_t i = 0; i < v.size(); ++i)
651  res[i] = un_op(v[i]);
652  return res;
653 }
654 
660 template<class T> T pair_member(const std::pair<T, T>& p, int index)
661 {
662  assert((0 == index) || (1 == index));
663  return 0 == index ? p.first : p.second;
664 }
665 
671 template<class T> void set_pair_member(std::pair<T, T>& p, int index, const T& val)
672 {
673  assert((0 == index) || (1 == index));
674  if (0 == index)
675  p.first = val;
676  else
677  p.second = val;
678 }
679 
684 template<class T, class S> vector<T> list_static_cast(const vector<S>& source)
685 {
686  vector<T> res(source.size());
687  for (size_t i = 0; i < res.size(); ++i)
688  res[i] = static_cast<T>(source[i]);
689  return res;
690 }
691 
696 template<class T> void insert_all_to_back(vector<T>& subject, const vector<T>& addendum)
697 {
698  if (!addendum.empty())
699  subject.insert(subject.end(), addendum.begin(), addendum.end());
700 }
708 template<class Iter, class T>
709 Iter binary_find(Iter begin, Iter end, T val)
710 {
711  // Finds the lower bound in at most log(last - first) + 1 comparisons
712  Iter i = std::lower_bound(begin, end, val);
713 
714  if (i != end && !(val < *i))
715  return i; // found
716  else
717  return end; // not found
718 }
719 
726 template<class S, class T> typename vector<T>::const_reference safe_retrieve
727 (vector<T> const& data, vector<S> const& keys, const S& key)
728 {
729  assert(data.size() == keys.size());
730  typename vector<S>::const_iterator it = binary_find(keys.begin(), keys.end(), key);
731  assert(it != keys.end());
732  size_t index = static_cast<size_t>(it - keys.begin());
733  return data.at(index);
734 }
735 
742 template<class S, class T> typename vector<T>::reference safe_retrieve
743 (vector<T> &data, vector<S> const& keys, const S& key)
744 {
745  assert(data.size() == keys.size());
746  typename vector<S>::const_iterator it = binary_find(keys.begin(), keys.end(), key);
747  assert(it != keys.end());
748  return data[static_cast<size_t>(it - keys.begin())];
749 }
750 
756 template<class S, class T> const T& safe_retrieve
757 (const boost::container::flat_map<S, T>& m,
758  const S& s)
759 {
760  typename boost::container::flat_map<S, T>::const_iterator it =
761  m.find(s);
762  assert(it != m.end());
763  return it->second;
764 }
770 template<class T> vector<vector<T> > CombineVectors(vector<vector<vector<T> > > const& data)
771 {
772  size_t counter = 0;
773  size_t out_size = data.size();
774  for (size_t i = 0; i < out_size; ++i)
775  counter += data[i].size();
776  vector<vector<T> > res(counter);
777  counter = 0;
778  for (size_t i = 0; i < out_size; ++i)
779  {
780  for (size_t j = 0; j < data[i].size(); ++j)
781  {
782  res[counter] = data[i][j];
783  ++counter;
784  }
785  }
786  return res;
787 }
788 
794 template<class T> vector<T> CombineVectors(vector<vector<T> > const& data)
795 {
796  vector<T> res;
797  for (size_t i = 0; i < data.size(); ++i)
798  res.insert(res.end(), data[i].begin(), data[i].end());
799  return res;
800 }
801 
807 template<class S, class T> T& safe_retrieve
808 (boost::container::flat_map<S, T>& m,
809  const S& s)
810 {
811  typename boost::container::flat_map<S, T>::iterator it =
812  m.find(s);
813  assert(it != m.end());
814  return it->second;
815 }
816 
821 double fastsqrt(double x);
822 
823 #endif // UTILS_HPP
vector< T > unique(vector< T > const &v)
Returns a vector containing only unique elements.
Definition: utils.hpp:376
vector< T > VectorValues(vector< T > const &v, vector< int > const &index)
Returns only the values with indeces in index.
Definition: utils.hpp:326
vector< T > list_static_cast(const vector< S > &source)
Performs type casting for an entire vector.
Definition: utils.hpp:684
void sort_index(const vector< T > &arr, vector< int > &res)
Returns the indeces of a sort.
Definition: utils.hpp:500
void RemoveVector(vector< T > &v, vector< int > &indeces)
Removes the elements in v given by indeces.
Definition: utils.hpp:275
vector< vector< T > > CombineVectors(vector< vector< vector< T > > > const &data)
Reduces the dimension of the input vector.
Definition: utils.hpp:770
Container for error reports.
int IndexInVector(vector< T > const &vec, T val)
Returns the index of val in the vector.
Definition: utils.hpp:464
BinaryOperation Binary operator.
Definition: utils.hpp:595
void set_pair_member(std::pair< T, T > &p, int index, const T &val)
Sets a member of std::pair.
Definition: utils.hpp:671
vector< T > apply_to_each_term(vector< T > const &v, UnaryOperation< T > const &un_op)
Applies an unary operator to all terms in a std::vector.
Definition: utils.hpp:646
double max(vector< double > const &v)
returns the maximal term in a vector
Definition: utils.cpp:52
vector< T > binary_unite(vector< T > const &v1, vector< T > const &v2, BinaryOperation< T > const &bin_op)
Applies a binary operation on every pair of values from two vectors.
Definition: utils.hpp:615
vector< T > join(vector< T > const &v1, vector< T > const &v2)
Concatenates two vectors.
Definition: utils.hpp:581
T LinearInterpolation(const vector< T > &x, const vector< T > &y, T xi)
Linear Interpolation.
Definition: utils.hpp:197
double fastsqrt(double x)
Fast approximate sqrt.
Definition: utils.cpp:11
vector< double > linspace(double xl, double xh, int n)
Uniformly spaced array (like the matlab function with the same name)
Definition: utils.cpp:26
T pair_member(const std::pair< T, T > &p, int index)
Selects a member of std::pair.
Definition: utils.hpp:660
void RemoveVal(vector< T > &vec, T val)
Removes the first occurence of val inside a vector.
Definition: utils.hpp:431
void ReArrangeVector(vector< T > &v, vector< int > const &indeces)
Rearranges the vector according to the indeces.
Definition: utils.hpp:477
void insert_all_to_back(vector< T > &subject, const vector< T > &addendum)
Inserts all elements from one vector to the end of another.
Definition: utils.hpp:696
vector< T >::const_reference safe_retrieve(vector< T > const &data, vector< S > const &keys, const S &key)
Checks for existence and retrieves entry from flat map.
Definition: utils.hpp:727
double min(vector< double > const &v)
Returns the minimal term in a vector.
Definition: utils.cpp:44
vector< double > arange(double x_min, double x_max, double dx)
Uniformly spaced array (line numpy function with the same name)
Definition: utils.cpp:35
vector< int > unique_index(vector< T > const &v)
Returns a vector containing only indeces of unique elements.
Definition: utils.hpp:397
bool InVector(vector< T > const &vec, T val)
checks if val is in the vector
Definition: utils.hpp:449
bool is_nan(double x)
Checks whether a number is a nan.
Definition: utils.cpp:19
Abstract class for an unary operation.
Definition: utils.hpp:628
T BiLinearInterpolation(const vector< T > &x, const vector< T > &y, const std::vector< std::vector< T > > &z, T xi, T yi)
BiLinear Interpolation.
Definition: utils.hpp:137
T VectorSum(vector< T > const &v)
Returns the sum of the vector.
Definition: utils.hpp:361
Iter binary_find(Iter begin, Iter end, T val)
Binary search that return iterator of found object or end if not found.
Definition: utils.hpp:709
vector< T > RemoveList(vector< T > const &v, vector< T > const &list)
Returns only elements from vector v which are not in vector list, assumes list is sorted...
Definition: utils.hpp:416
A class for storing error and debug information.