Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Filter window calculation illegal calculation. #1348

Closed
cor-mt opened this issue Jun 27, 2017 · 5 comments
Closed

Filter window calculation illegal calculation. #1348

cor-mt opened this issue Jun 27, 2017 · 5 comments

Comments

@cor-mt
Copy link

cor-mt commented Jun 27, 2017

This bug get triggered on an "AMD FX(tm)-8150 Eight-Core Processor" when gnuradio is compiled with CFLAGS="-march=native -O2".

In window.cc line 265, with i == ntaps - 1 gives temp = 1.0000000000000000002 that cause sqrt (0) witch return "-nan" on the next line for the last value of the vector. This value get used for the gain calculation in the low_pass filter and thus screwing all the rest of the calculations.

@marcusmueller
Copy link
Member

Thanks for documenting/reporting this here 👍

For future readers: http://lists.gnu.org/archive/html/discuss-gnuradio/2017-06/msg00277.html

@marcusmueller
Copy link
Member

Just to be clear: this is a serious bug in the way we do floating point math, and I (hopefully) have a patch coming up. We need to be vigilant, though – this is most likely not the only mistake of this type.

@marcusmueller
Copy link
Member

diff --git a/gr-fft/lib/window.cc b/gr-fft/lib/window.cc
index 126b28978..e80d469e9 100644
--- a/gr-fft/lib/window.cc
+++ b/gr-fft/lib/window.cc
@@ -30,9 +30,10 @@
 namespace gr {
   namespace fft {
 
-#define IzeroEPSILON 1E-21               /* Max error acceptable in Izero */
+#define BESSEL_EPSILON 1E-21               /* Max error acceptable in bessel_i_zero */
 
-    static double Izero(double x)
+    /*! \brief Iterative first kind Bessel function approximation */
+    static double bessel_i_zero(double x)
     {
       double sum, u, halfx, temp;
       int n;
@@ -45,7 +46,7 @@ namespace gr {
         temp *= temp;
         u *= temp;
         sum += u;
-      } while (u >= IzeroEPSILON*sum);
+      } while (u >= BESSEL_EPSILON*sum);
       return(sum);
     }
 
@@ -257,13 +258,17 @@ namespace gr {
 
       std::vector<float> taps(ntaps);
 
-      double IBeta = 1.0/Izero(beta);
+      double bessel_i_beta = 1.0/bessel_i_zero(beta);
       double inm1 = 1.0/((double)(ntaps-1));
       double temp;
 
-      for(int i = 0; i < ntaps; i++) {
+      /* dragging taps[0] out of the loop, because ((double)(-1))*((double)(-1))
+      might be 1.0 + epsilon and then we get sqrt() of something < 0, i.e. NaN.
+      https://github.com/gnuradio/gnuradio/issues/1348 */
+      taps[0] = bessel_i_zero(0) * bessel_i_beta;
+      for(int i = 1; i < ntaps; i++) {
         temp = 2*i*inm1 - 1;
-        taps[i] = Izero(beta*sqrt(1.0-temp*temp)) * IBeta;
+        taps[i] = bessel_i_zero(beta*sqrt(1.0-temp*temp)) * bessel_i_beta;
       }
       return taps;
     }

marcusmueller added a commit to marcusmueller/gnuradio that referenced this issue Jun 27, 2017
gnuradio#1348

We were doing floating point math wrong.
marcusmueller added a commit to marcusmueller/gnuradio that referenced this issue Jun 27, 2017
gnuradio#1348

We were doing floating point math wrong.
marcusmueller added a commit to marcusmueller/gnuradio that referenced this issue Jun 27, 2017
Mustn't do sqrt(1 - (1.0+epsilon)**2);
marcusmueller added a commit to marcusmueller/gnuradio that referenced this issue Jun 27, 2017
gnuradio#1348

sqrt(x<0) yields NaN; to avoid a situation where a variable would be
close to, but not necessarily exactly +-1, extracted the relevant
floating point corner cases from the loop.
@noc0lour
Copy link
Member

Is this fixed now (: ?

@mbr0wn
Copy link
Member

mbr0wn commented Jul 7, 2017

This was fixed in #1349. Closing.

@mbr0wn mbr0wn closed this as completed Jul 7, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants