GNU Radio 3.3.0 C++ API
|
00001 /* -*- c++ -*- */ 00002 /* 00003 * Copyright 2003,2005,2008 Free Software Foundation, Inc. 00004 * 00005 * This file is part of GNU Radio 00006 * 00007 * GNU Radio is free software; you can redistribute it and/or modify 00008 * it under the terms of the GNU General Public License as published by 00009 * the Free Software Foundation; either version 3, or (at your option) 00010 * any later version. 00011 * 00012 * GNU Radio is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU General Public License 00018 * along with GNU Radio; see the file COPYING. If not, write to 00019 * the Free Software Foundation, Inc., 51 Franklin Street, 00020 * Boston, MA 02110-1301, USA. 00021 */ 00022 00023 /* 00024 * mathematical odds and ends. 00025 */ 00026 00027 #ifndef _GR_MATH_H_ 00028 #define _GR_MATH_H_ 00029 00030 #include <gr_complex.h> 00031 00032 static inline bool 00033 gr_is_power_of_2(long x) 00034 { 00035 return x != 0 && (x & (x-1)) == 0; 00036 } 00037 00038 long gr_gcd (long m, long n); 00039 00040 // returns a non-zero value if value is "not-a-number" (NaN), and 0 otherwise 00041 int gr_isnan (double value); 00042 00043 // returns a non-zero value if the value of x has its sign bit set. 00044 // 00045 // This is not the same as `x < 0.0', because IEEE 754 floating point 00046 // allows zero to be signed. The comparison `-0.0 < 0.0' is false, but 00047 // `gr_signbit (-0.0)' will return a nonzero value. 00048 00049 int gr_signbit (double x); 00050 00051 /*! 00052 * \brief Fast arc tangent using table lookup and linear interpolation 00053 * \ingroup misc 00054 * 00055 * \param y component of input vector 00056 * \param x component of input vector 00057 * \returns float angle angle of vector (x, y) in radians 00058 * 00059 * This function calculates the angle of the vector (x,y) based on a 00060 * table lookup and linear interpolation. The table uses a 256 point 00061 * table covering -45 to +45 degrees and uses symetry to determine the 00062 * final angle value in the range of -180 to 180 degrees. Note that 00063 * this function uses the small angle approximation for values close 00064 * to zero. This routine calculates the arc tangent with an average 00065 * error of +/- 0.045 degrees. 00066 */ 00067 float gr_fast_atan2f(float y, float x); 00068 00069 static inline float gr_fast_atan2f(gr_complex z) 00070 { 00071 return gr_fast_atan2f(z.imag(), z.real()); 00072 } 00073 00074 /* This bounds x by +/- clip without a branch */ 00075 static inline float gr_branchless_clip(float x, float clip) 00076 { 00077 float x1 = fabsf(x+clip); 00078 float x2 = fabsf(x-clip); 00079 x1 -= x2; 00080 return 0.5*x1; 00081 } 00082 00083 static inline float gr_clip(float x, float clip) 00084 { 00085 float y = x; 00086 if(x > clip) 00087 y = clip; 00088 else if(x < -clip) 00089 y = -clip; 00090 return y; 00091 } 00092 00093 // Slicer Functions 00094 static inline unsigned int gr_binary_slicer(float x) 00095 { 00096 if(x >= 0) 00097 return 1; 00098 else 00099 return 0; 00100 } 00101 00102 static inline unsigned int gr_quad_45deg_slicer(float r, float i) 00103 { 00104 unsigned int ret = 0; 00105 if((r >= 0) && (i >= 0)) 00106 ret = 0; 00107 else if((r < 0) && (i >= 0)) 00108 ret = 1; 00109 else if((r < 0) && (i < 0)) 00110 ret = 2; 00111 else 00112 ret = 3; 00113 return ret; 00114 } 00115 00116 static inline unsigned int gr_quad_0deg_slicer(float r, float i) 00117 { 00118 unsigned int ret = 0; 00119 if(fabsf(r) > fabsf(i)) { 00120 if(r > 0) 00121 ret = 0; 00122 else 00123 ret = 2; 00124 } 00125 else { 00126 if(i > 0) 00127 ret = 1; 00128 else 00129 ret = 3; 00130 } 00131 00132 return ret; 00133 } 00134 00135 static inline unsigned int gr_quad_45deg_slicer(gr_complex x) 00136 { 00137 return gr_quad_45deg_slicer(x.real(), x.imag()); 00138 } 00139 00140 static inline unsigned int gr_quad_0deg_slicer(gr_complex x) 00141 { 00142 return gr_quad_0deg_slicer(x.real(), x.imag()); 00143 } 00144 00145 // Branchless Slicer Functions 00146 static inline unsigned int gr_branchless_binary_slicer(float x) 00147 { 00148 return (x >= 0); 00149 } 00150 00151 static inline unsigned int gr_branchless_quad_0deg_slicer(float r, float i) 00152 { 00153 unsigned int ret = 0; 00154 ret = (fabsf(r) > fabsf(i)) * (((r < 0) << 0x1)); // either 0 (00) or 2 (10) 00155 ret |= (fabsf(i) > fabsf(r)) * (((i < 0) << 0x1) | 0x1); // either 1 (01) or 3 (11) 00156 00157 return ret; 00158 } 00159 00160 static inline unsigned int gr_branchless_quad_0deg_slicer(gr_complex x) 00161 { 00162 return gr_branchless_quad_0deg_slicer(x.real(), x.imag()); 00163 } 00164 00165 static inline unsigned int gr_branchless_quad_45deg_slicer(float r, float i) 00166 { 00167 char ret = (r <= 0); 00168 ret |= ((i <= 0) << 1); 00169 return (ret ^ ((ret & 0x2) >> 0x1)); 00170 } 00171 00172 static inline unsigned int gr_branchless_quad_45deg_slicer(gr_complex x) 00173 { 00174 return gr_branchless_quad_45deg_slicer(x.real(), x.imag()); 00175 } 00176 00177 /*! 00178 * \param x any value 00179 * \param pow2 must be a power of 2 00180 * \returns \p x rounded down to a multiple of \p pow2. 00181 */ 00182 static inline size_t 00183 gr_p2_round_down(size_t x, size_t pow2) 00184 { 00185 return x & -pow2; 00186 } 00187 00188 /*! 00189 * \param x any value 00190 * \param pow2 must be a power of 2 00191 * \returns \p x rounded up to a multiple of \p pow2. 00192 */ 00193 static inline size_t 00194 gr_p2_round_up(size_t x, size_t pow2) 00195 { 00196 return gr_p2_round_down(x + pow2 - 1, pow2); 00197 } 00198 00199 /*! 00200 * \param x any value 00201 * \param pow2 must be a power of 2 00202 * \returns \p x modulo \p pow2. 00203 */ 00204 static inline size_t 00205 gr_p2_modulo(size_t x, size_t pow2) 00206 { 00207 return x & (pow2 - 1); 00208 } 00209 00210 /*! 00211 * \param x any value 00212 * \param pow2 must be a power of 2 00213 * \returns \p pow2 - (\p x modulo \p pow2). 00214 */ 00215 static inline size_t 00216 gr_p2_modulo_neg(size_t x, size_t pow2) 00217 { 00218 return pow2 - gr_p2_modulo(x, pow2); 00219 } 00220 00221 #endif /* _GR_MATH_H_ */