GNU Radio Manual and C++ API Reference  3.8.1.0
The Free & Open Software Radio Ecosystem
math.h
Go to the documentation of this file.
1 /* -*- c++ -*- */
2 /*
3  * Copyright 2003,2005,2008,2013,2018 Free Software Foundation, Inc.
4  *
5  * This file is part of GNU Radio
6  *
7  * GNU Radio is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3, or (at your option)
10  * any later version.
11  *
12  * GNU Radio is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with GNU Radio; see the file COPYING. If not, write to
19  * the Free Software Foundation, Inc., 51 Franklin Street,
20  * Boston, MA 02110-1301, USA.
21  */
22 
23 /*
24  * mathematical odds and ends.
25  */
26 
27 #ifndef _GR_MATH_H_
28 #define _GR_MATH_H_
29 
30 #include <gnuradio/api.h>
31 #include <gnuradio/gr_complex.h>
32 #include <cmath>
33 
34 /*
35  * \brief Define commonly used mathematical constants
36  * \ingroup misc
37  *
38  * Mathematical constants are neither defined in the C standard
39  * nor the C++ standard. For -std=c{++}11 M_LOG2E and M_SQRT2 won't
40  * compile. GR_M_PI actually works with C++ but is defined here for the sake
41  * of consistency.
42  */
43 #define GR_M_LOG2E 1.4426950408889634074 /* log_2 e */
44 #define GR_M_PI 3.14159265358979323846 /* pi */
45 #define GR_M_PI_4 0.78539816339744830961566084582 /* pi/4 */
46 #define GR_M_TWOPI (2 * GR_M_PI) /* 2*pi */
47 #define GR_M_SQRT2 1.41421356237309504880 /* sqrt(2) */
48 
49 
50 namespace gr {
51 
52 static inline bool is_power_of_2(long x) { return x != 0 && (x & (x - 1)) == 0; }
53 
54 /*!
55  * \brief Fast arc tangent using table lookup and linear interpolation
56  * \ingroup misc
57  *
58  * \param y component of input vector
59  * \param x component of input vector
60  * \returns float angle angle of vector (x, y) in radians
61  *
62  * This function calculates the angle of the vector (x,y) based on a
63  * table lookup and linear interpolation. The table uses a 256 point
64  * table covering -45 to +45 degrees and uses symmetry to determine
65  * the final angle value in the range of -180 to 180 degrees. Note
66  * that this function uses the small angle approximation for values
67  * close to zero. This routine calculates the arc tangent with an
68  * average error of +/- 0.045 degrees.
69  */
70 GR_RUNTIME_API float fast_atan2f(float y, float x);
71 
72 static inline float fast_atan2f(gr_complex z) { return fast_atan2f(z.imag(), z.real()); }
73 
74 /* This bounds x by +/- clip without a branch */
75 static inline float branchless_clip(float x, float clip)
76 {
77  float x1 = fabsf(x + clip);
78  float x2 = fabsf(x - clip);
79  x1 -= x2;
80  return 0.5 * x1;
81 }
82 
83 static inline float clip(float x, float clip)
84 {
85  float y = x;
86  if (x > clip)
87  y = clip;
88  else if (x < -clip)
89  y = -clip;
90  return y;
91 }
92 
93 // Slicer Functions
94 static inline unsigned int binary_slicer(float x)
95 {
96  if (x >= 0)
97  return 1;
98  else
99  return 0;
100 }
101 
102 static inline unsigned int quad_45deg_slicer(float r, float i)
103 {
104  unsigned int ret = 0;
105  if ((r >= 0) && (i >= 0))
106  ret = 0;
107  else if ((r < 0) && (i >= 0))
108  ret = 1;
109  else if ((r < 0) && (i < 0))
110  ret = 2;
111  else
112  ret = 3;
113  return ret;
114 }
115 
116 static inline unsigned int quad_0deg_slicer(float r, float i)
117 {
118  unsigned int ret = 0;
119  if (fabsf(r) > fabsf(i)) {
120  if (r > 0)
121  ret = 0;
122  else
123  ret = 2;
124  } else {
125  if (i > 0)
126  ret = 1;
127  else
128  ret = 3;
129  }
130 
131  return ret;
132 }
133 
134 static inline unsigned int quad_45deg_slicer(gr_complex x)
135 {
136  return quad_45deg_slicer(x.real(), x.imag());
137 }
138 
139 static inline unsigned int quad_0deg_slicer(gr_complex x)
140 {
141  return quad_0deg_slicer(x.real(), x.imag());
142 }
143 
144 // Branchless Slicer Functions
145 static inline unsigned int branchless_binary_slicer(float x) { return (x >= 0); }
146 
147 static inline unsigned int branchless_quad_0deg_slicer(float r, float i)
148 {
149  unsigned int ret = 0;
150  ret = (fabsf(r) > fabsf(i)) * (((r < 0) << 0x1)); // either 0 (00) or 2 (10)
151  ret |= (fabsf(i) > fabsf(r)) * (((i < 0) << 0x1) | 0x1); // either 1 (01) or 3 (11)
152 
153  return ret;
154 }
155 
156 static inline unsigned int branchless_quad_0deg_slicer(gr_complex x)
157 {
158  return branchless_quad_0deg_slicer(x.real(), x.imag());
159 }
160 
161 static inline unsigned int branchless_quad_45deg_slicer(float r, float i)
162 {
163  char ret = (r <= 0);
164  ret |= ((i <= 0) << 1);
165  return (ret ^ ((ret & 0x2) >> 0x1));
166 }
167 
168 static inline unsigned int branchless_quad_45deg_slicer(gr_complex x)
169 {
170  return branchless_quad_45deg_slicer(x.real(), x.imag());
171 }
172 
173 /*!
174  * \param x any value
175  * \param pow2 must be a power of 2
176  * \returns \p x rounded down to a multiple of \p pow2.
177  */
178 static inline size_t p2_round_down(size_t x, size_t pow2) { return x & -pow2; }
179 
180 /*!
181  * \param x any value
182  * \param pow2 must be a power of 2
183  * \returns \p x rounded up to a multiple of \p pow2.
184  */
185 static inline size_t p2_round_up(size_t x, size_t pow2)
186 {
187  return p2_round_down(x + pow2 - 1, pow2);
188 }
189 
190 /*!
191  * \param x any value
192  * \param pow2 must be a power of 2
193  * \returns \p x modulo \p pow2.
194  */
195 static inline size_t p2_modulo(size_t x, size_t pow2) { return x & (pow2 - 1); }
196 
197 /*!
198  * \param x any value
199  * \param pow2 must be a power of 2
200  * \returns \p pow2 - (\p x modulo \p pow2).
201  */
202 static inline size_t p2_modulo_neg(size_t x, size_t pow2)
203 {
204  return pow2 - p2_modulo(x, pow2);
205 }
206 
207 } /* namespace gr */
208 
209 #endif /* _GR_MATH_H_ */
static unsigned int branchless_quad_45deg_slicer(float r, float i)
Definition: math.h:161
static unsigned int quad_45deg_slicer(float r, float i)
Definition: math.h:102
static size_t p2_modulo_neg(size_t x, size_t pow2)
Definition: math.h:202
static size_t p2_round_down(size_t x, size_t pow2)
Definition: math.h:178
static unsigned int binary_slicer(float x)
Definition: math.h:94
static size_t p2_round_up(size_t x, size_t pow2)
Definition: math.h:185
#define GR_RUNTIME_API
Definition: gnuradio-runtime/include/gnuradio/api.h:30
static bool is_power_of_2(long x)
Definition: math.h:52
GR_RUNTIME_API float fast_atan2f(float y, float x)
Fast arc tangent using table lookup and linear interpolation.
std::complex< float > gr_complex
Definition: gr_complex.h:27
static size_t p2_modulo(size_t x, size_t pow2)
Definition: math.h:195
GNU Radio logging wrapper for log4cpp library (C++ port of log4j)
Definition: basic_block.h:43
static float branchless_clip(float x, float clip)
Definition: math.h:75
static unsigned int branchless_quad_0deg_slicer(float r, float i)
Definition: math.h:147
static unsigned int quad_0deg_slicer(float r, float i)
Definition: math.h:116
static unsigned int branchless_binary_slicer(float x)
Definition: math.h:145
static float clip(float x, float clip)
Definition: math.h:83