3 * Copyright 2003,2005,2008 Free Software Foundation, Inc.
5 * This file is part of GNU Radio
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)
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.
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.
24 * mathematical odds and ends.
30 #include <gr_complex.h>
33 gr_is_power_of_2(long x)
35 return x != 0 && (x & (x-1)) == 0;
38 long gr_gcd (long m, long n);
40 // returns a non-zero value if value is "not-a-number" (NaN), and 0 otherwise
41 int gr_isnan (double value);
43 // returns a non-zero value if the value of x has its sign bit set.
45 // This is not the same as `x < 0.0', because IEEE 754 floating point
46 // allows zero to be signed. The comparison `-0.0 < 0.0' is false, but
47 // `gr_signbit (-0.0)' will return a nonzero value.
49 int gr_signbit (double x);
52 * \brief Fast arc tangent using table lookup and linear interpolation
55 * \param y component of input vector
56 * \param x component of input vector
57 * \returns float angle angle of vector (x, y) in radians
59 * This function calculates the angle of the vector (x,y) based on a
60 * table lookup and linear interpolation. The table uses a 256 point
61 * table covering -45 to +45 degrees and uses symetry to determine the
62 * final angle value in the range of -180 to 180 degrees. Note that
63 * this function uses the small angle approximation for values close
64 * to zero. This routine calculates the arc tangent with an average
65 * error of +/- 0.045 degrees.
67 float gr_fast_atan2f(float y, float x);
69 static inline float gr_fast_atan2f(gr_complex z)
71 return gr_fast_atan2f(z.imag(), z.real());
74 /* This bounds x by +/- clip without a branch */
75 static inline float gr_branchless_clip(float x, float clip)
77 float x1 = fabsf(x+clip);
78 float x2 = fabsf(x-clip);
83 static inline float gr_clip(float x, float clip)
94 static inline unsigned int gr_binary_slicer(float x)
102 static inline unsigned int gr_quad_45deg_slicer(float r, float i)
104 unsigned int ret = 0;
105 if((r >= 0) && (i >= 0))
107 else if((r < 0) && (i >= 0))
109 else if((r < 0) && (i < 0))
116 static inline unsigned int gr_quad_0deg_slicer(float r, float i)
118 unsigned int ret = 0;
119 if(fabsf(r) > fabsf(i)) {
135 static inline unsigned int gr_quad_45deg_slicer(gr_complex x)
137 return gr_quad_45deg_slicer(x.real(), x.imag());
140 static inline unsigned int gr_quad_0deg_slicer(gr_complex x)
142 return gr_quad_0deg_slicer(x.real(), x.imag());
145 // Branchless Slicer Functions
146 static inline unsigned int gr_branchless_binary_slicer(float x)
151 static inline unsigned int gr_branchless_quad_0deg_slicer(float r, float i)
153 unsigned int ret = 0;
154 ret = (fabsf(r) > fabsf(i)) * (((r < 0) << 0x1)); // either 0 (00) or 2 (10)
155 ret |= (fabsf(i) > fabsf(r)) * (((i < 0) << 0x1) | 0x1); // either 1 (01) or 3 (11)
160 static inline unsigned int gr_branchless_quad_0deg_slicer(gr_complex x)
162 return gr_branchless_quad_0deg_slicer(x.real(), x.imag());
165 static inline unsigned int gr_branchless_quad_45deg_slicer(float r, float i)
168 ret |= ((i <= 0) << 1);
169 return (ret ^ ((ret & 0x2) >> 0x1));
172 static inline unsigned int gr_branchless_quad_45deg_slicer(gr_complex x)
174 return gr_branchless_quad_45deg_slicer(x.real(), x.imag());
179 * \param pow2 must be a power of 2
180 * \returns \p x rounded down to a multiple of \p pow2.
183 gr_p2_round_down(size_t x, size_t pow2)
190 * \param pow2 must be a power of 2
191 * \returns \p x rounded up to a multiple of \p pow2.
194 gr_p2_round_up(size_t x, size_t pow2)
196 return gr_p2_round_down(x + pow2 - 1, pow2);
201 * \param pow2 must be a power of 2
202 * \returns \p x modulo \p pow2.
205 gr_p2_modulo(size_t x, size_t pow2)
207 return x & (pow2 - 1);
212 * \param pow2 must be a power of 2
213 * \returns \p pow2 - (\p x modulo \p pow2).
216 gr_p2_modulo_neg(size_t x, size_t pow2)
218 return pow2 - gr_p2_modulo(x, pow2);
221 #endif /* _GR_MATH_H_ */