eDSP  0.0.1
A cross-platform DSP library written in C++.
numeric.hpp
Go to the documentation of this file.
1 /*
2  * eDSP, A cross-platform Digital Signal Processing library written in modern C++.
3  * Copyright (C) 2018 Mohammed Boujemaoui Boulaghmoudi, All rights reserved.
4  *
5  * This program is free software: you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License as published by the Free
7  * Software Foundation, either version 3 of the License, or (at your option)
8  * any later version.
9  *
10  * This program is distributed in the hope that it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13  * more details.
14  *
15  * You should have received a copy of the GNU General Public License along width
16  * this program. If not, see <http://www.gnu.org/licenses/>
17 
18  * File: numeric.hpp
19  * Date: 04/10/18
20  * Author: Mohammed Boujemaoui Boulaghmoudi
21  */
22 
23 #ifndef EDSP_NUMERIC_HPP
24 #define EDSP_NUMERIC_HPP
25 
26 #include <cmath>
27 #include <cstdint>
28 #include <complex>
29 #include <random>
30 
31 namespace edsp { inline namespace math {
32 
38  template <typename T>
39  constexpr bool is_negative(T x) {
40  return x < 0;
41  }
42 
48  template <typename T>
49  constexpr bool is_odd(T x) {
50  return (x % 2) == 1;
51  }
52 
58  template <typename T>
59  constexpr bool is_even(T x) {
60  return !is_odd(x);
61  }
62 
68  template <typename T>
69  constexpr bool is_power_two(T x) {
70  const auto tmp = static_cast<std::int32_t>(x);
71  return tmp != 0 && !(tmp & (tmp - 1));
72  }
73 
79  template <typename T>
80  constexpr bool is_denormal(T x) {
81  return std::fpclassify(x) == FP_SUBNORMAL;
82  }
83 
89  template <typename T>
90  constexpr bool is_normal(T x) {
91  return std::fpclassify(x) == FP_NORMAL;
92  }
93 
99  template <typename T>
100  constexpr bool is_zero(T x) {
101  return std::fpclassify(x) == FP_ZERO;
102  }
103 
109  template <typename T>
110  constexpr bool is_nan(T x) noexcept {
111  return std::isnan(x);
112  }
113 
119  template <typename T>
120  constexpr bool is_inf(T x) {
121  return std::fpclassify(x) == FP_INFINITE;
122  }
123 
129  template <typename T>
130  constexpr bool is_prime(T x) {
131  auto n = static_cast<std::uint64_t>(x);
132  if (n <= 1)
133  return 0;
134  else if (n <= 3)
135  return 1;
136  else if (!(n & 1))
137  return 0;
138  else if (!(n % 3))
139  return 0;
140  std::uint64_t r = 5;
141  while (r * r <= n) {
142  if ((n % r) == 0 || (n % (r + 2)) == 0)
143  return 0;
144  r += 6;
145  }
146  return false;
147  }
148 
154  template <typename T>
155  constexpr T sign(T x) noexcept {
156  return is_negative(x) ? static_cast<T>(-1) : static_cast<T>(1);
157  }
158 
164  template <typename T>
165  constexpr T next_power_two(T x) {
166  if (is_negative(x)) {
167  return 0;
168  } else if (is_power_two(x)) {
169  return x;
170  } else {
171  auto _x = static_cast<int32_t>(x);
172  --_x;
173  _x |= _x >> 1;
174  _x |= _x >> 2;
175  _x |= _x >> 4;
176  _x |= _x >> 8;
177  _x |= _x >> 16;
178  return static_cast<T>(_x + 1);
179  }
180  }
181 
187  template <typename T>
188  constexpr T square(T x) {
189  return x * x;
190  }
191 
197  template <typename T>
198  constexpr T fract(T x) {
199  return x - std::floor(x);
200  }
201 
207  template <typename T>
208  constexpr T inv(T x) {
209  return static_cast<T>(1) / x;
210  }
211 
217  template <typename T>
218  constexpr T half(T x) {
219  return 0.5 * x;
220  }
221 
230  template <typename T>
231  inline typename std::enable_if<std::is_floating_point<T>::value, T>::type rand(T min, T max) {
232  std::random_device rd;
233  std::mt19937 eng(rd());
234  std::uniform_real_distribution<T> distribution(min, max);
235  return distribution(eng);
236  }
237 
243  template <typename T>
244  inline typename std::enable_if<std::is_floating_point<T>::value, T>::type rand() {
245  std::random_device rd;
246  std::mt19937 eng(rd());
247  std::uniform_real_distribution<T> distribution(std::numeric_limits<T>::min(), std::numeric_limits<T>::max());
248  return distribution(eng);
249  }
250 
259  template <typename T>
260  inline typename std::enable_if<std::is_integral<T>::value, T>::type rand(T min, T max) {
261  std::random_device rd;
262  std::mt19937 eng(rd());
263  std::uniform_int_distribution<T> distribution(min, max);
264  return distribution(eng);
265  }
266 
272  template <typename T>
273  inline typename std::enable_if<std::is_integral<T>::value, T>::type rand() {
274  std::random_device rd;
275  std::mt19937 eng(rd());
276  std::uniform_int_distribution<T> distribution(std::numeric_limits<T>::min(), std::numeric_limits<T>::max());
277  return distribution(eng);
278  }
279 
280  enum distances {
284  };
285 
286 
287  namespace internal {
288 
289  template <distances d>
290  struct distance {};
291 
292  template <>
293  struct distance<distances::manhattan> {
294  template <typename T>
295  constexpr T operator()(T x, T y) noexcept {
296  return x - y;
297  }
298  };
299 
300  template <>
301  struct distance<distances::euclidean> {
302  template <typename T>
303  constexpr T operator()(T x, T y) noexcept {
304  return math::square(x - y);
305  }
306  };
307 
308 
309  template <>
310  struct distance<distances::logarithmic> {
311  template <typename T>
312  constexpr T operator()(T x, T y) noexcept {
313  return std::log(std::abs(x) / std::abs(y));
314  }
315  };
316  }
317 
318 
327  template <distances d, typename T>
328  constexpr T distance(T x, T y) noexcept {
329  return internal::distance<d>{}(x, y);
330  }
331 
332 
333 
334 }} // namespace edsp::math
335 
336 #endif //EDSP_NUMERIC_HPP
constexpr meta::value_type_t< ForwardIt > max(ForwardIt first, ForwardIt last)
Computes the maximum value of the range [first, last)
Definition: max.hpp:38
constexpr T half(T x)
Computes the half value of the input number.
Definition: numeric.hpp:218
constexpr bool is_even(T x)
Determines if the number is even.
Definition: numeric.hpp:59
constexpr bool is_denormal(T x)
Determines if the number is denormal floating-point.
Definition: numeric.hpp:80
constexpr auto is_inf(const std::complex< T > &z) noexcept
Determines if the given real or imaginary part of the complex number is .
Definition: complex.hpp:100
distances
Definition: numeric.hpp:280
constexpr void floor(InputIt first, InputIt last, OutputIt d_first)
For each element in the range [first, last) computes the largest integer value not greater than the e...
Definition: floor.hpp:40
constexpr bool is_power_two(T x)
Determines if the number is power of two.
Definition: numeric.hpp:69
constexpr T next_power_two(T x)
Computes the closest next higher power of 2 of the input number.
Definition: numeric.hpp:165
constexpr bool is_normal(T x)
Determines if the number is normal floating-point.
Definition: numeric.hpp:90
constexpr T inv(T x)
Computes the inverse value of the input number.
Definition: numeric.hpp:208
std::enable_if< std::is_floating_point< T >::value, T >::type rand(T min, T max)
Computes a random number in the range [min, max].
Definition: numeric.hpp:231
constexpr bool is_odd(T x)
Determines if the number is odd.
Definition: numeric.hpp:49
constexpr T distance(T x, T y) noexcept
Computes the distance between x and y.
Definition: numeric.hpp:328
Definition: numeric.hpp:281
constexpr bool is_zero(T x)
Determines if the number is zero.
Definition: numeric.hpp:100
constexpr T square(T x)
Computes the square value of the input number.
Definition: numeric.hpp:188
Definition: numeric.hpp:283
constexpr bool is_negative(T x)
Determines if the number is negative.
Definition: numeric.hpp:39
constexpr auto is_nan(const std::complex< T > &z) noexcept
Determines if the given real or imaginary part of the complex number is a not-a-number (NaN) value...
Definition: complex.hpp:90
constexpr meta::value_type_t< ForwardIt > min(ForwardIt first, ForwardIt last)
Computes the minimum value of the range [first, last)
Definition: min.hpp:38
constexpr T fract(T x)
Computes the fractional part of the input number.
Definition: numeric.hpp:198
Definition: numeric.hpp:282
constexpr T sign(T x) noexcept
Determines the sign of the input number.
Definition: numeric.hpp:155
Definition: amplifier.hpp:29
constexpr bool is_prime(T x)
Determines if the number is prime.
Definition: numeric.hpp:130