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