GNU Radio Manual and C++ API Reference 3.7.14.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 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
34namespace gr {
35
36static 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 */
54GR_RUNTIME_API float fast_atan2f(float y, float x);
55
56static inline float fast_atan2f(gr_complex z) { return fast_atan2f(z.imag(), z.real()); }
57
58/* This bounds x by +/- clip without a branch */
59static 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
67static 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
78static inline unsigned int binary_slicer(float x)
79{
80 if (x >= 0)
81 return 1;
82 else
83 return 0;
84}
85
86static 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
100static 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
118static inline unsigned int quad_45deg_slicer(gr_complex x)
119{
120 return quad_45deg_slicer(x.real(), x.imag());
121}
122
123static 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
129static inline unsigned int branchless_binary_slicer(float x) { return (x >= 0); }
130
131static 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
140static inline unsigned int branchless_quad_0deg_slicer(gr_complex x)
141{
142 return branchless_quad_0deg_slicer(x.real(), x.imag());
143}
144
145static 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
152static 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 */
162static 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 */
169static 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 */
179static 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 */
186static 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_ */
#define GR_RUNTIME_API
Definition: gnuradio-runtime/include/gnuradio/api.h:30
std::complex< float > gr_complex
Definition: gr_complex.h:27
GR_RUNTIME_API float fast_atan2f(float y, float x)
Fast arc tangent using table lookup and linear interpolation.
Include this header to use the message passing features.
Definition: basic_block.h:45
static unsigned int binary_slicer(float x)
Definition: math.h:78
static unsigned int branchless_quad_45deg_slicer(float r, float i)
Definition: math.h:145
static unsigned int quad_0deg_slicer(float r, float i)
Definition: math.h:100
static size_t p2_round_up(size_t x, size_t pow2)
Definition: math.h:169
static unsigned int quad_45deg_slicer(float r, float i)
Definition: math.h:86
static float clip(float x, float clip)
Definition: math.h:67
static size_t p2_round_down(size_t x, size_t pow2)
Definition: math.h:162
static unsigned int branchless_quad_0deg_slicer(float r, float i)
Definition: math.h:131
static size_t p2_modulo_neg(size_t x, size_t pow2)
Definition: math.h:186
static float branchless_clip(float x, float clip)
Definition: math.h:59
static unsigned int branchless_binary_slicer(float x)
Definition: math.h:129
static bool is_power_of_2(long x)
Definition: math.h:36
static size_t p2_modulo(size_t x, size_t pow2)
Definition: math.h:179