GNU Radio Manual and C++ API Reference  3.7.14.0
The Free & Open Software Radio Ecosystem
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
math.h
Go to the documentation of this file.
1 /* -*- c++ -*- */
2 /*
3  * Copyright 2003,2005,2008,2013 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 namespace gr {
35 
36 static inline bool is_power_of_2(long x) { return x != 0 && (x & (x - 1)) == 0; }
37 
38 /*!
39  * \brief Fast arc tangent using table lookup and linear interpolation
40  * \ingroup misc
41  *
42  * \param y component of input vector
43  * \param x component of input vector
44  * \returns float angle angle of vector (x, y) in radians
45  *
46  * This function calculates the angle of the vector (x,y) based on a
47  * table lookup and linear interpolation. The table uses a 256 point
48  * table covering -45 to +45 degrees and uses symmetry to determine
49  * the final angle value in the range of -180 to 180 degrees. Note
50  * that this function uses the small angle approximation for values
51  * close to zero. This routine calculates the arc tangent with an
52  * average error of +/- 0.045 degrees.
53  */
54 GR_RUNTIME_API float fast_atan2f(float y, float x);
55 
56 static inline float fast_atan2f(gr_complex z) { return fast_atan2f(z.imag(), z.real()); }
57 
58 /* This bounds x by +/- clip without a branch */
59 static inline float branchless_clip(float x, float clip)
60 {
61  float x1 = fabsf(x + clip);
62  float x2 = fabsf(x - clip);
63  x1 -= x2;
64  return 0.5 * x1;
65 }
66 
67 static inline float clip(float x, float clip)
68 {
69  float y = x;
70  if (x > clip)
71  y = clip;
72  else if (x < -clip)
73  y = -clip;
74  return y;
75 }
76 
77 // Slicer Functions
78 static inline unsigned int binary_slicer(float x)
79 {
80  if (x >= 0)
81  return 1;
82  else
83  return 0;
84 }
85 
86 static inline unsigned int quad_45deg_slicer(float r, float i)
87 {
88  unsigned int ret = 0;
89  if ((r >= 0) && (i >= 0))
90  ret = 0;
91  else if ((r < 0) && (i >= 0))
92  ret = 1;
93  else if ((r < 0) && (i < 0))
94  ret = 2;
95  else
96  ret = 3;
97  return ret;
98 }
99 
100 static inline unsigned int quad_0deg_slicer(float r, float i)
101 {
102  unsigned int ret = 0;
103  if (fabsf(r) > fabsf(i)) {
104  if (r > 0)
105  ret = 0;
106  else
107  ret = 2;
108  } else {
109  if (i > 0)
110  ret = 1;
111  else
112  ret = 3;
113  }
114 
115  return ret;
116 }
117 
118 static inline unsigned int quad_45deg_slicer(gr_complex x)
119 {
120  return quad_45deg_slicer(x.real(), x.imag());
121 }
122 
123 static inline unsigned int quad_0deg_slicer(gr_complex x)
124 {
125  return quad_0deg_slicer(x.real(), x.imag());
126 }
127 
128 // Branchless Slicer Functions
129 static inline unsigned int branchless_binary_slicer(float x) { return (x >= 0); }
130 
131 static inline unsigned int branchless_quad_0deg_slicer(float r, float i)
132 {
133  unsigned int ret = 0;
134  ret = (fabsf(r) > fabsf(i)) * (((r < 0) << 0x1)); // either 0 (00) or 2 (10)
135  ret |= (fabsf(i) > fabsf(r)) * (((i < 0) << 0x1) | 0x1); // either 1 (01) or 3 (11)
136 
137  return ret;
138 }
139 
140 static inline unsigned int branchless_quad_0deg_slicer(gr_complex x)
141 {
142  return branchless_quad_0deg_slicer(x.real(), x.imag());
143 }
144 
145 static inline unsigned int branchless_quad_45deg_slicer(float r, float i)
146 {
147  char ret = (r <= 0);
148  ret |= ((i <= 0) << 1);
149  return (ret ^ ((ret & 0x2) >> 0x1));
150 }
151 
152 static inline unsigned int branchless_quad_45deg_slicer(gr_complex x)
153 {
154  return branchless_quad_45deg_slicer(x.real(), x.imag());
155 }
156 
157 /*!
158  * \param x any value
159  * \param pow2 must be a power of 2
160  * \returns \p x rounded down to a multiple of \p pow2.
161  */
162 static inline size_t p2_round_down(size_t x, size_t pow2) { return x & -pow2; }
163 
164 /*!
165  * \param x any value
166  * \param pow2 must be a power of 2
167  * \returns \p x rounded up to a multiple of \p pow2.
168  */
169 static inline size_t p2_round_up(size_t x, size_t pow2)
170 {
171  return p2_round_down(x + pow2 - 1, pow2);
172 }
173 
174 /*!
175  * \param x any value
176  * \param pow2 must be a power of 2
177  * \returns \p x modulo \p pow2.
178  */
179 static inline size_t p2_modulo(size_t x, size_t pow2) { return x & (pow2 - 1); }
180 
181 /*!
182  * \param x any value
183  * \param pow2 must be a power of 2
184  * \returns \p pow2 - (\p x modulo \p pow2).
185  */
186 static inline size_t p2_modulo_neg(size_t x, size_t pow2)
187 {
188  return pow2 - p2_modulo(x, pow2);
189 }
190 
191 } /* namespace gr */
192 
193 #endif /* _GR_MATH_H_ */
static unsigned int branchless_quad_45deg_slicer(float r, float i)
Definition: math.h:145
static unsigned int quad_45deg_slicer(float r, float i)
Definition: math.h:86
static size_t p2_modulo_neg(size_t x, size_t pow2)
Definition: math.h:186
static size_t p2_round_down(size_t x, size_t pow2)
Definition: math.h:162
static unsigned int binary_slicer(float x)
Definition: math.h:78
static size_t p2_round_up(size_t x, size_t pow2)
Definition: math.h:169
#define GR_RUNTIME_API
Definition: gnuradio-runtime/include/gnuradio/api.h:30
static bool is_power_of_2(long x)
Definition: math.h:36
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:179
static float branchless_clip(float x, float clip)
Definition: math.h:59
static unsigned int branchless_quad_0deg_slicer(float r, float i)
Definition: math.h:131
static unsigned int quad_0deg_slicer(float r, float i)
Definition: math.h:100
static unsigned int branchless_binary_slicer(float x)
Definition: math.h:129
static float clip(float x, float clip)
Definition: math.h:67