isce3 0.25.0
Loading...
Searching...
No Matches
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 <chrono>
11#include <iostream>
12#include <iterator>
13#include <limits>
14#include <sstream>
15#include <string>
16#include <vector>
17#include <valarray>
18#include <complex>
19
20// Macro wrappers to check vector lengths
21// (adds calling function and variable name information to the exception)
22#define checkVecLen(v,l) isce3::core::checkVecLenDebug(v,l,#v,__PRETTY_FUNCTION__)
23#define check2dVecLen(v,l,w) isce3::core::check2dVecLenDebug(v,l,w,#v,__PRETTY_FUNCTION__)
24
25namespace isce3 { namespace core {
26
29 inline uint64_t getTimeStampMillisec() {
30 using namespace std::chrono;
31 return duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
32 }
33
36 inline std::string getTempString(const std::string& suffix) {
37 if (suffix.length() == 0) {
38 return "tmp_" + std::to_string(getTimeStampMillisec());
39 }
40 return "tmp_" + suffix + "_" + std::to_string(getTimeStampMillisec());
41 }
42
43
48 template <typename T>
49 inline void checkVecLenDebug(const std::vector<T> &vec, size_t len, const char *vec_name,
50 const char *parent_func) {
51 if (vec.size() != len) {
52 std::string errstr = "In '" + std::string(parent_func) + "': Vector '" +
53 std::string(vec_name) + "' has size " +
54 std::to_string(vec.size()) + ", expected size " +
55 std::to_string(len) + ".";
56 throw std::invalid_argument(errstr);
57 }
58 }
59
60 // Same as above but for 2D vectors
61 template <typename T>
62 inline void check2dVecLenDebug(const std::vector<std::vector<T>> &vec,
63 size_t len, size_t width, const char *vec_name,
64 const char *parent_func) {
65 if ((vec.size() != len) && (vec[0].size() != width)) {
66 std::string errstr = "In '" + std::string(parent_func) + "': Vector '" +
67 std::string(vec_name) + "' has size (" +
68 std::to_string(vec.size()) + " x " +
69 std::to_string(vec[0].size()) + "), expected size (" +
70 std::to_string(len) + " x " + std::to_string(width) + ").";
71 throw std::invalid_argument(errstr);
72 }
73 }
74
79 template <typename T>
80 inline std::vector<T> arange(T low, T high, T increment) {
81 // Instantiate the vector
82 std::vector<T> data;
83 // Set the first value
84 T current = low;
85 // Loop over the increments and add to vector
86 while (current < high) {
87 data.push_back(current);
88 current += increment;
89 }
90 // done
91 return data;
92 }
93
98 template <typename T>
99 inline std::vector<T> linspace(T low, T high, std::size_t number) {
100 // Instantiate the vector
101 std::vector<T> data;
102 // Compute the increment
103 T increment = (high - low) / (number - 1);
104 // Handle cases where number in (0, 1)
105 if (number == 0) {
106 return data;
107 }
108 if (number == 1) {
109 data.push_back(low);
110 return data;
111 }
112 // Loop over the increments and add to vector
113 for (std::size_t i = 0; i < number - 1; ++i) {
114 data.push_back(low + i * increment);
115 }
116 // Add the last element
117 data.push_back(high);
118 // done
119 return data;
120 }
121
126 template <typename T>
127 inline void linspace(T low, T high, std::vector<T> & data) {
128 // Compute the increment
129 int number = data.size();
130 T increment = (high - low) / (number - 1);
131 // Handle cases where number in (0, 1)
132 if (number == 0) {
133 return;
134 }
135 if (number == 1) {
136 data[0] = low;
137 return;
138 }
139 // Loop over the increments and add to vector
140 for (std::size_t i = 0; i < number; ++i) {
141 data[i] = low + i * increment;
142 }
143 // done
144 }
145
150 template <typename T>
151 inline void linspace(T low, T high, std::valarray<T> & data) {
152 // Compute the increment
153 int number = data.size();
154 T increment = (high - low) / (number - 1);
155 // Handle cases where number in (0, 1)
156 if (number == 0) {
157 return;
158 }
159 if (number == 1) {
160 data[0] = low;
161 return;
162 }
163 // Loop over the increments and add to vector
164 for (std::size_t i = 0; i < number; ++i) {
165 data[i] = low + i * increment;
166 }
167 // done
168 }
169
175 template <typename T>
176 inline std::vector<T> logspace(T first, T last, std::size_t number, T base=10) {
177 // Instantiate the vector
178 std::vector<T> data;
179 // Compute the increment of the powers
180 T increment = (last - first) / (number - 1);
181 // Handle cases where number in (0, 1)
182 if (number == 0) {
183 return data;
184 }
185 if (number == 1) {
186 data.push_back(pow(base, first));
187 return data;
188 }
189 // Loop over the increments and add to vector
190 for (std::size_t i = 0; i < number - 1; ++i) {
191 T value = pow(base, first + i * increment);
192 data.push_back(value);
193 }
194 // Add the last element
195 data.push_back(pow(base, last));
196 // done
197 return data;
198 }
199
203 template <typename T>
204 inline std::vector<T> stringToVector(const std::string & str) {
205 // Make a stream
206 std::stringstream stream(str);
207 // Parse string
208 T number;
209 std::vector<T> vec;
210 while (stream >> number) {
211 vec.push_back(number);
212 }
213 // done
214 return vec;
215 }
216
220 template <typename T>
221 inline std::string vectorToString(const std::vector<T> & vec) {
222 // Initialize stream
223 std::stringstream stream;
224 // Print values
225 std::copy(vec.begin(), vec.end(), std::ostream_iterator<T>(stream, " "));
226 // done
227 return stream.str();
228 }
229
235 template <typename T>
236 inline bool
237 compareFloatingPoint(T first, T second) {
238 const T scale = std::max({static_cast<T>(1.0), std::abs(first), std::abs(second)});
239 return std::abs(first - second) <= std::numeric_limits<T>::epsilon() * scale;
240 }
241
246 template <typename T>
247 inline bool
248 compareComplex(std::complex<T> first, std::complex<T> second) {
249 return compareFloatingPoint(first.real(), second.real())
250 && compareFloatingPoint(first.imag(), second.imag());
251 }
252
257 template <typename T>
258 inline std::valarray<bool>
259 makeMask(const std::valarray<std::complex<T>> & v, std::complex<T> noDataValue) {
260 std::valarray<bool> mask(v.size());
261 for (size_t i = 0; i < v.size(); ++i) {
262 if (compareComplex(v[i], noDataValue)) {
263 mask[i] = false;
264 } else {
265 mask[i] = true;
266 }
267 }
268 return mask;
269 }
270
275 template <typename T>
276 inline std::valarray<bool>
277 makeMask(const std::valarray<T> & v, T noDataValue) {
278 std::valarray<bool> mask(v.size());
279 for (size_t i = 0; i < v.size(); ++i) {
280 if (compareFloatingPoint(v[i], noDataValue)) {
281 mask[i] = false;
282 } else {
283 mask[i] = true;
284 }
285 }
286 return mask;
287 }
288
292 inline void insertionSort(std::valarray<double> & a,
293 std::valarray<double> & b,
294 std::valarray<double> & c) {
295 for (int i = 1; i < a.size(); ++i) {
296 int j = i - 1;
297 const double tempa = a[i];
298 const double tempb = b[i];
299 const double tempc = c[i];
300 while (j >= 0 && a[j] > tempa) {
301 a[j+1] = a[j];
302 b[j+1] = b[j];
303 c[j+1] = c[j];
304 j = j - 1;
305 }
306 a[j+1] = tempa;
307 b[j+1] = tempb;
308 c[j+1] = tempc;
309 }
310 }
311
315 inline void insertionSort(std::valarray<double> & a,
316 std::valarray<double> & b,
317 std::valarray<short> & c) {
318 for (int i = 1; i < a.size(); ++i) {
319 int j = i - 1;
320 const double tempa = a[i];
321 const double tempb = b[i];
322 const short tempc = c[i];
323 while (j >= 0 && a[j] > tempa) {
324 a[j+1] = a[j];
325 b[j+1] = b[j];
326 c[j+1] = c[j];
327 j = j - 1;
328 }
329 a[j+1] = tempa;
330 b[j+1] = tempb;
331 c[j+1] = tempc;
332 }
333 }
334
336 inline int binarySearch(const std::valarray<double> & array, double value) {
337
338 // Do the binary search
339 int left = 0;
340 int right = array.size() - 1;
341 int index;
342 while (left <= right) {
343 const int middle = static_cast<int>(std::round(0.5 * (left + right)));
344 if (left == (right - 1)) {
345 index = left;
346 return index;
347 }
348 if (array[middle] <= value) {
349 left = middle;
350 } else if (array[middle] > value) {
351 right = middle;
352 }
353 }
354 index = left;
355 return index;
356 }
357
359 template<class T>
360 inline const T & clamp(const T & x, const T & lower, const T & upper) {
361 return std::min(upper, std::max(x, lower));
362 }
363
364}}
base interpolator is an abstract base class
Definition BinarySearchFunc.cpp:5

Generated for ISCE3.0 by doxygen 1.13.2.