isce3  0.1.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Pages
Utilities.h
1 //-*- C++ -*_
2 //-*- coding: utf-8 -*-
3 //
4 // Authors: Bryan Riel, Joshua Cohen
5 // Copyright 2017-2018
6 
7 #pragma once
8 
9 #include <algorithm>
10 #include <iostream>
11 #include <iterator>
12 #include <limits>
13 #include <sstream>
14 #include <string>
15 #include <vector>
16 #include <valarray>
17 #include <complex>
18 
19 // Macro wrappers to check vector lengths
20 // (adds calling function and variable name information to the exception)
21 #define checkVecLen(v,l) isce3::core::checkVecLenDebug(v,l,#v,__PRETTY_FUNCTION__)
22 #define check2dVecLen(v,l,w) isce3::core::check2dVecLenDebug(v,l,w,#v,__PRETTY_FUNCTION__)
23 
24 namespace isce3 { namespace core {
25 
30  template <typename T>
31  inline void checkVecLenDebug(const std::vector<T> &vec, size_t len, const char *vec_name,
32  const char *parent_func) {
33  if (vec.size() != len) {
34  std::string errstr = "In '" + std::string(parent_func) + "': Vector '" +
35  std::string(vec_name) + "' has size " +
36  std::to_string(vec.size()) + ", expected size " +
37  std::to_string(len) + ".";
38  throw std::invalid_argument(errstr);
39  }
40  }
41 
42  // Same as above but for 2D vectors
43  template <typename T>
44  inline void check2dVecLenDebug(const std::vector<std::vector<T>> &vec,
45  size_t len, size_t width, const char *vec_name,
46  const char *parent_func) {
47  if ((vec.size() != len) && (vec[0].size() != width)) {
48  std::string errstr = "In '" + std::string(parent_func) + "': Vector '" +
49  std::string(vec_name) + "' has size (" +
50  std::to_string(vec.size()) + " x " +
51  std::to_string(vec[0].size()) + "), expected size (" +
52  std::to_string(len) + " x " + std::to_string(width) + ").";
53  throw std::invalid_argument(errstr);
54  }
55  }
56 
61  template <typename T>
62  inline std::vector<T> arange(T low, T high, T increment) {
63  // Instantiate the vector
64  std::vector<T> data;
65  // Set the first value
66  T current = low;
67  // Loop over the increments and add to vector
68  while (current < high) {
69  data.push_back(current);
70  current += increment;
71  }
72  // done
73  return data;
74  }
75 
80  template <typename T>
81  inline std::vector<T> linspace(T low, T high, std::size_t number) {
82  // Instantiate the vector
83  std::vector<T> data;
84  // Compute the increment
85  T increment = (high - low) / (number - 1);
86  // Handle cases where number in (0, 1)
87  if (number == 0) {
88  return data;
89  }
90  if (number == 1) {
91  data.push_back(low);
92  return data;
93  }
94  // Loop over the increments and add to vector
95  for (std::size_t i = 0; i < number - 1; ++i) {
96  data.push_back(low + i * increment);
97  }
98  // Add the last element
99  data.push_back(high);
100  // done
101  return data;
102  }
103 
108  template <typename T>
109  inline void linspace(T low, T high, std::vector<T> & data) {
110  // Compute the increment
111  int number = data.size();
112  T increment = (high - low) / (number - 1);
113  // Handle cases where number in (0, 1)
114  if (number == 0) {
115  return;
116  }
117  if (number == 1) {
118  data[0] = low;
119  return;
120  }
121  // Loop over the increments and add to vector
122  for (std::size_t i = 0; i < number; ++i) {
123  data[i] = low + i * increment;
124  }
125  // done
126  }
127 
132  template <typename T>
133  inline void linspace(T low, T high, std::valarray<T> & data) {
134  // Compute the increment
135  int number = data.size();
136  T increment = (high - low) / (number - 1);
137  // Handle cases where number in (0, 1)
138  if (number == 0) {
139  return;
140  }
141  if (number == 1) {
142  data[0] = low;
143  return;
144  }
145  // Loop over the increments and add to vector
146  for (std::size_t i = 0; i < number; ++i) {
147  data[i] = low + i * increment;
148  }
149  // done
150  }
151 
157  template <typename T>
158  inline std::vector<T> logspace(T first, T last, std::size_t number, T base=10) {
159  // Instantiate the vector
160  std::vector<T> data;
161  // Compute the increment of the powers
162  T increment = (last - first) / (number - 1);
163  // Handle cases where number in (0, 1)
164  if (number == 0) {
165  return data;
166  }
167  if (number == 1) {
168  data.push_back(pow(base, first));
169  return data;
170  }
171  // Loop over the increments and add to vector
172  for (std::size_t i = 0; i < number - 1; ++i) {
173  T value = pow(base, first + i * increment);
174  data.push_back(value);
175  }
176  // Add the last element
177  data.push_back(pow(base, last));
178  // done
179  return data;
180  }
181 
185  template <typename T>
186  inline std::vector<T> stringToVector(const std::string & str) {
187  // Make a stream
188  std::stringstream stream(str);
189  // Parse string
190  T number;
191  std::vector<T> vec;
192  while (stream >> number) {
193  vec.push_back(number);
194  }
195  // done
196  return vec;
197  }
198 
202  template <typename T>
203  inline std::string vectorToString(const std::vector<T> & vec) {
204  // Initialize stream
205  std::stringstream stream;
206  // Print values
207  std::copy(vec.begin(), vec.end(), std::ostream_iterator<T>(stream, " "));
208  // done
209  return stream.str();
210  }
211 
216  std::string stringFromVRT(const char * filename, int bandNum=1);
217 
224  template <typename T>
225  inline bool
226  compareFloatingPoint(T first, T second) {
227  const T scale = std::max({static_cast<T>(1.0), std::abs(first), std::abs(second)});
228  return std::abs(first - second) <= std::numeric_limits<T>::epsilon() * scale;
229  }
230 
235  template <typename T>
236  inline bool
237  compareComplex(std::complex<T> first, std::complex<T> second) {
238  return compareFloatingPoint(first.real(), second.real())
239  && compareFloatingPoint(first.imag(), second.imag());
240  }
241 
246  template <typename T>
247  inline std::valarray<bool>
248  makeMask(const std::valarray<std::complex<T>> & v, std::complex<T> noDataValue) {
249  std::valarray<bool> mask(v.size());
250  for (size_t i = 0; i < v.size(); ++i) {
251  if (compareComplex(v[i], noDataValue)) {
252  mask[i] = false;
253  } else {
254  mask[i] = true;
255  }
256  }
257  return mask;
258  }
259 
264  template <typename T>
265  inline std::valarray<bool>
266  makeMask(const std::valarray<T> & v, T noDataValue) {
267  std::valarray<bool> mask(v.size());
268  for (size_t i = 0; i < v.size(); ++i) {
269  if (compareFloatingPoint(v[i], noDataValue)) {
270  mask[i] = false;
271  } else {
272  mask[i] = true;
273  }
274  }
275  return mask;
276  }
277 
279  inline void insertionSort(std::valarray<double> & a,
280  std::valarray<double> & b,
281  std::valarray<double> & c) {
282  for (int i = 1; i < a.size(); ++i) {
283  int j = i - 1;
284  const double tempa = a[i];
285  const double tempb = b[i];
286  const double tempc = c[i];
287  while (j >= 0 && a[j] > tempa) {
288  a[j+1] = a[j];
289  b[j+1] = b[j];
290  c[j+1] = c[j];
291  j = j - 1;
292  }
293  a[j+1] = tempa;
294  b[j+1] = tempb;
295  c[j+1] = tempc;
296  }
297  }
298 
300  inline void insertionSort(std::valarray<double> & a,
301  std::valarray<double> & b) {
302  for (int i = 1; i < a.size(); ++i) {
303  int j = i - 1;
304  const double tempa = a[i];
305  const double tempb = b[i];
306  while (j >= 0 && a[j] > tempa) {
307  a[j+1] = a[j];
308  b[j+1] = b[j];
309  j = j - 1;
310  }
311  a[j+1] = tempa;
312  b[j+1] = tempb;
313  }
314  }
315 
317  inline int binarySearch(const std::valarray<double> & array, double value) {
318 
319  // Do the binary search
320  int left = 0;
321  int right = array.size() - 1;
322  int index;
323  while (left <= right) {
324  const int middle = static_cast<int>(std::round(0.5 * (left + right)));
325  if (left == (right - 1)) {
326  index = left;
327  return index;
328  }
329  if (array[middle] <= value) {
330  left = middle;
331  } else if (array[middle] > value) {
332  right = middle;
333  }
334  }
335  index = left;
336  return index;
337  }
338 
340  template<class T>
341  inline const T & clamp(const T & x, const T & lower, const T & upper) {
342  return std::min(upper, std::max(x, lower));
343  }
344 
345 }}
bool compareComplex(std::complex< T > first, std::complex< T > second)
Tolerance test for real and imaginary components for scalar value.
Definition: Utilities.h:237
void checkVecLenDebug(const std::vector< T > &vec, size_t len, const char *vec_name, const char *parent_func)
Inline function for input checking on vector lengths (primarily to check to see if 3D vector has the ...
Definition: Utilities.h:31
std::vector< T > linspace(T low, T high, std::size_t number)
Function to return a Matlab/Python style linspace vector.
Definition: Utilities.h:81
std::vector< T > stringToVector(const std::string &str)
Parse a space-separated string into a vector.
Definition: Utilities.h:186
const T & clamp(const T &x, const T &lower, const T &upper)
Clip a number between an upper and lower range (implements std::clamp for older GCC) ...
Definition: Utilities.h:341
std::string vectorToString(const std::vector< T > &vec)
Generate a string of space-separated values from a vector.
Definition: Utilities.h:203
bool compareFloatingPoint(T first, T second)
Combined absolute and relative tolerance test.
Definition: Utilities.h:226
std::valarray< bool > makeMask(const std::valarray< std::complex< T >> &v, std::complex< T > noDataValue)
making a boolean mask for an array based on noDataValue
Definition: Utilities.h:248
std::vector< T > arange(T low, T high, T increment)
Function to return a Python style arange vector.
Definition: Utilities.h:62
void insertionSort(std::valarray< double > &a, std::valarray< double > &b, std::valarray< double > &c)
Sort arrays a, b, c by the values in array a.
Definition: Utilities.h:279
std::vector< T > logspace(T first, T last, std::size_t number, T base=10)
Function to return a Matlab/Python style logspace vector.
Definition: Utilities.h:158
std::string stringFromVRT(const char *filename, int bandNum=1)
Read metadata from a VRT file and return an std::string.
Definition: Utilities.cpp:5
int binarySearch(const std::valarray< double > &array, double value)
Searches array for index closest to provided value.
Definition: Utilities.h:317

Generated for ISCE3.0 by doxygen 1.8.5.