GNU Radio 3.5.3.2 C++ API
gr_math.h
Go to the documentation of this file.
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_core_api.h>
00031 #include <gr_complex.h>
00032 
00033 static inline bool
00034 gr_is_power_of_2(long x)
00035 {
00036   return x != 0 && (x & (x-1)) == 0;
00037 }
00038 
00039 /*!
00040  * \brief Fast arc tangent using table lookup and linear interpolation
00041  * \ingroup misc
00042  *
00043  * \param y component of input vector
00044  * \param x component of input vector
00045  * \returns float angle angle of vector (x, y) in radians
00046  *
00047  * This function calculates the angle of the vector (x,y) based on a
00048  * table lookup and linear interpolation. The table uses a 256 point
00049  * table covering -45 to +45 degrees and uses symetry to determine the
00050  * final angle value in the range of -180 to 180 degrees. Note that
00051  * this function uses the small angle approximation for values close
00052  * to zero. This routine calculates the arc tangent with an average
00053  * error of +/- 0.045 degrees.
00054  */
00055 GR_CORE_API float gr_fast_atan2f(float y, float x);
00056 
00057 static inline float gr_fast_atan2f(gr_complex z) 
00058 { 
00059   return gr_fast_atan2f(z.imag(), z.real()); 
00060 }
00061 
00062 /* This bounds x by +/- clip without a branch */
00063 static inline float gr_branchless_clip(float x, float clip)
00064 {
00065   float x1 = fabsf(x+clip);
00066   float x2 = fabsf(x-clip);
00067   x1 -= x2;
00068   return 0.5*x1;
00069 }
00070 
00071 static inline float gr_clip(float x, float clip)
00072 {
00073   float y = x;
00074   if(x > clip)
00075     y = clip;
00076   else if(x < -clip)
00077     y = -clip;
00078   return y;
00079 }
00080 
00081 // Slicer Functions
00082 static inline unsigned int gr_binary_slicer(float x)
00083 {
00084   if(x >= 0)
00085     return 1;
00086   else
00087     return 0;
00088 }
00089 
00090 static inline unsigned int gr_quad_45deg_slicer(float r, float i)
00091 {
00092   unsigned int ret = 0;
00093   if((r >= 0) && (i >= 0))
00094     ret = 0;
00095   else if((r < 0) && (i >= 0))
00096     ret = 1;
00097   else if((r < 0) && (i < 0))
00098     ret = 2;
00099   else 
00100     ret = 3;
00101   return ret;
00102 }
00103 
00104 static inline unsigned int gr_quad_0deg_slicer(float r, float i)
00105 {
00106   unsigned int ret = 0;
00107   if(fabsf(r) > fabsf(i)) {
00108     if(r > 0)
00109       ret = 0;
00110     else
00111       ret = 2;
00112   }
00113   else {
00114     if(i > 0)
00115       ret = 1;
00116     else
00117       ret = 3;
00118   }
00119 
00120   return ret;
00121 }
00122 
00123 static inline unsigned int gr_quad_45deg_slicer(gr_complex x)
00124 {
00125   return gr_quad_45deg_slicer(x.real(), x.imag());
00126 }
00127 
00128 static inline unsigned int gr_quad_0deg_slicer(gr_complex x)
00129 {
00130   return gr_quad_0deg_slicer(x.real(), x.imag());
00131 }
00132 
00133 // Branchless Slicer Functions
00134 static inline unsigned int gr_branchless_binary_slicer(float x)
00135 {
00136   return (x >= 0);
00137 }
00138 
00139 static inline unsigned int gr_branchless_quad_0deg_slicer(float r, float i)
00140 {
00141   unsigned int ret = 0;
00142   ret =  (fabsf(r) > fabsf(i)) * (((r < 0) << 0x1));       // either 0 (00) or 2 (10)
00143   ret |= (fabsf(i) > fabsf(r)) * (((i < 0) << 0x1) | 0x1); // either 1 (01) or 3 (11)
00144 
00145   return ret;
00146 }
00147 
00148 static inline unsigned int gr_branchless_quad_0deg_slicer(gr_complex x)
00149 {
00150   return gr_branchless_quad_0deg_slicer(x.real(), x.imag());
00151 }
00152 
00153 static inline unsigned int gr_branchless_quad_45deg_slicer(float r, float i)
00154 {
00155   char ret = (r <= 0);
00156   ret |= ((i <= 0) << 1);
00157   return (ret ^ ((ret & 0x2) >> 0x1));
00158 }
00159 
00160 static inline unsigned int gr_branchless_quad_45deg_slicer(gr_complex x)
00161 {
00162   return gr_branchless_quad_45deg_slicer(x.real(), x.imag());
00163 }
00164 
00165 /*!
00166  * \param x any value
00167  * \param pow2 must be a power of 2
00168  * \returns \p x rounded down to a multiple of \p pow2.
00169  */
00170 static inline size_t
00171 gr_p2_round_down(size_t x, size_t pow2)
00172 {
00173   return x & -pow2;
00174 }
00175 
00176 /*!
00177  * \param x any value
00178  * \param pow2 must be a power of 2
00179  * \returns \p x rounded up to a multiple of \p pow2.
00180  */
00181 static inline size_t
00182 gr_p2_round_up(size_t x, size_t pow2)
00183 {
00184   return gr_p2_round_down(x + pow2 - 1, pow2);
00185 }
00186 
00187 /*!
00188  * \param x any value
00189  * \param pow2 must be a power of 2
00190  * \returns \p x modulo \p pow2.
00191  */
00192 static inline size_t
00193 gr_p2_modulo(size_t x, size_t pow2)
00194 {
00195   return x & (pow2 - 1);
00196 }
00197 
00198 /*!
00199  * \param x any value
00200  * \param pow2 must be a power of 2
00201  * \returns \p pow2 - (\p x modulo \p pow2).
00202  */
00203 static inline size_t
00204 gr_p2_modulo_neg(size_t x, size_t pow2)
00205 {
00206   return pow2 - gr_p2_modulo(x, pow2);
00207 }
00208 
00209 #endif /* _GR_MATH_H_ */