* Bug #13866 fixed - There were some issues with FFTW3 library. 25/16525/1
Vincent COUVERT [Thu, 28 May 2015 14:48:09 +0000 (16:48 +0200)]
This bug was already fixed in YaSp branch: https://codereview.scilab.org/#/c/16244/
For more information, see: http://www.fftw.org/doc/New_002darray-Execute-Functions.html#New_002darray-Execute-Functions

Change-Id: Ia93a5cdf179ca1648f2db319f6d5db25673532a6

scilab/CHANGES_5.5.X
scilab/modules/fftw/src/c/fftw_utilities.c
scilab/modules/fftw/tests/nonreg_tests/bug_13866.dia.ref [new file with mode: 0644]
scilab/modules/fftw/tests/nonreg_tests/bug_13866.tst [new file with mode: 0644]

index ca682f7..8a07333 100644 (file)
@@ -8,6 +8,8 @@ Scilab Bug Fixes
 
 * Bug #13854 fixed - On some operating systems, SciNotes did not initialize a new document at startup.
 
+* Bug #13866 fixed - There were some issues with FFTW3 library.
+
 * Bug #13881 fixed - datatipRemoveAll did not work.
 
 
index 2a9f5e0..4dbfa95 100644 (file)
@@ -102,7 +102,7 @@ int FreeFFTWPlan(FFTW_Plan_struct *Sci_Plan)
         FREE(Sci_Plan->gdim.howmany_dims);
         Sci_Plan->gdim.howmany_dims = NULL;
     }
-    return(1);
+    return (1);
 }
 /*--------------------------------------------------------------------------*/
 /* Return a valid plan ptr.
@@ -143,102 +143,96 @@ fftw_plan GetFFTWPlan(enum Plan_Type type, guru_dim_struct *gdim,
         Sci_Plan = &Sci_Forward_Plan;
     }
 
-    if ( (!(CheckGuruDims(&(Sci_Plan->gdim), gdim))) ||
-            (!CheckKindArray(Sci_Plan->kind, kind, gdim->rank)) ||
-            (Sci_Plan->flags != cur_fftw_flags) ||
-            (Sci_Plan->plan_type != type))
+    /* plan must be changed */
+    FreeFFTWPlan(Sci_Plan);
+
+    Sci_Plan->plan_type = type;
+    if (gdim->rank != 0)
     {
-        /* plan must be changed */
-        FreeFFTWPlan(Sci_Plan);
+        Sci_Plan->gdim.rank = gdim->rank;
+        if ((Sci_Plan->gdim.dims = (fftw_iodim *) MALLOC(sizeof(fftw_iodim) * (gdim->rank))) == NULL)
+        {
+            *errflag = 1;
+            return (NULL);
+        }
+        for (i = 0; i < gdim->rank; i++)
+        {
+            Sci_Plan->gdim.dims[i].n  = gdim->dims[i].n;
+            Sci_Plan->gdim.dims[i].is = gdim->dims[i].is;
+            Sci_Plan->gdim.dims[i].os = gdim->dims[i].os;
+        }
 
-        Sci_Plan->plan_type = type;
-        if (gdim->rank != 0)
+        if (kind != NULL)
         {
-            Sci_Plan->gdim.rank = gdim->rank;
-            if ((Sci_Plan->gdim.dims = (fftw_iodim *) MALLOC(sizeof(fftw_iodim) * (gdim->rank))) == NULL)
+            if ((Sci_Plan->kind = (fftw_r2r_kind *) MALLOC(sizeof(fftw_r2r_kind) * (gdim->rank))) == NULL)
             {
                 *errflag = 1;
-                return(NULL);
+                return (NULL);
             }
             for (i = 0; i < gdim->rank; i++)
             {
-                Sci_Plan->gdim.dims[i].n  = gdim->dims[i].n;
-                Sci_Plan->gdim.dims[i].is = gdim->dims[i].is;
-                Sci_Plan->gdim.dims[i].os = gdim->dims[i].os;
-            }
-
-            if (kind != NULL)
-            {
-                if ((Sci_Plan->kind = (fftw_r2r_kind *) MALLOC(sizeof(fftw_r2r_kind) * (gdim->rank))) == NULL)
-                {
-                    *errflag = 1;
-                    return(NULL);
-                }
-                for (i = 0; i < gdim->rank; i++)
-                {
-                    Sci_Plan->kind[i]  = kind[i];
-                }
+                Sci_Plan->kind[i]  = kind[i];
             }
         }
-        if (gdim->howmany_rank != 0)
+    }
+    if (gdim->howmany_rank != 0)
+    {
+        Sci_Plan->gdim.howmany_rank = gdim->howmany_rank;
+        if ((Sci_Plan->gdim.howmany_dims = (fftw_iodim *) MALLOC(sizeof(fftw_iodim) * (gdim->howmany_rank))) == NULL)
         {
-            Sci_Plan->gdim.howmany_rank = gdim->howmany_rank;
-            if ((Sci_Plan->gdim.howmany_dims = (fftw_iodim *) MALLOC(sizeof(fftw_iodim) * (gdim->howmany_rank))) == NULL)
-            {
-                FREE(Sci_Plan->gdim.dims);
-                *errflag = 1;
-                return(NULL);
-            }
-            for (i = 0; i < gdim->howmany_rank; i++)
-            {
-                Sci_Plan->gdim.howmany_dims[i].n  = gdim->howmany_dims[i].n;
-                Sci_Plan->gdim.howmany_dims[i].is = gdim->howmany_dims[i].is;
-                Sci_Plan->gdim.howmany_dims[i].os = gdim->howmany_dims[i].os;
-            }
+            FREE(Sci_Plan->gdim.dims);
+            *errflag = 1;
+            return (NULL);
         }
-
-        Sci_Plan->flags = cur_fftw_flags;
-
-        switch (type)
+        for (i = 0; i < gdim->howmany_rank; i++)
         {
-            case C2C_PLAN:
-                Sci_Plan->p = call_fftw_plan_guru_split_dft(Sci_Plan->gdim.rank,
-                              Sci_Plan->gdim.dims,
-                              Sci_Plan->gdim.howmany_rank,
-                              Sci_Plan->gdim.howmany_dims,
-                              ri, ii, ro, io,
-                              Sci_Plan->flags);
-                break;
-            case C2R_PLAN:
-                Sci_Plan->p = call_fftw_plan_guru_split_dft_c2r(Sci_Plan->gdim.rank,
-                              Sci_Plan->gdim.dims,
-                              Sci_Plan->gdim.howmany_rank,
-                              Sci_Plan->gdim.howmany_dims,
-                              ri, ii, ro, flags);
-                break;
-            case R2C_PLAN:
-                Sci_Plan->p = call_fftw_plan_guru_split_dft_r2c(Sci_Plan->gdim.rank,
-                              Sci_Plan->gdim.dims,
-                              Sci_Plan->gdim.howmany_rank,
-                              Sci_Plan->gdim.howmany_dims,
-                              ri, ro, io, flags);
-
-                break;
-            case R2R_PLAN:
-                Sci_Plan->p = call_fftw_plan_guru_split_dft_r2r(Sci_Plan->gdim.rank,
-                              Sci_Plan->gdim.dims,
-                              Sci_Plan->gdim.howmany_rank,
-                              Sci_Plan->gdim.howmany_dims,
-                              ri, ro, kind, flags);
-                break;
+            Sci_Plan->gdim.howmany_dims[i].n  = gdim->howmany_dims[i].n;
+            Sci_Plan->gdim.howmany_dims[i].is = gdim->howmany_dims[i].is;
+            Sci_Plan->gdim.howmany_dims[i].os = gdim->howmany_dims[i].os;
         }
+    }
+
+    Sci_Plan->flags = cur_fftw_flags;
+
+    switch (type)
+    {
+        case C2C_PLAN:
+            Sci_Plan->p = call_fftw_plan_guru_split_dft(Sci_Plan->gdim.rank,
+                          Sci_Plan->gdim.dims,
+                          Sci_Plan->gdim.howmany_rank,
+                          Sci_Plan->gdim.howmany_dims,
+                          ri, ii, ro, io,
+                          Sci_Plan->flags);
+            break;
+        case C2R_PLAN:
+            Sci_Plan->p = call_fftw_plan_guru_split_dft_c2r(Sci_Plan->gdim.rank,
+                          Sci_Plan->gdim.dims,
+                          Sci_Plan->gdim.howmany_rank,
+                          Sci_Plan->gdim.howmany_dims,
+                          ri, ii, ro, flags);
+            break;
+        case R2C_PLAN:
+            Sci_Plan->p = call_fftw_plan_guru_split_dft_r2c(Sci_Plan->gdim.rank,
+                          Sci_Plan->gdim.dims,
+                          Sci_Plan->gdim.howmany_rank,
+                          Sci_Plan->gdim.howmany_dims,
+                          ri, ro, io, flags);
 
+            break;
+        case R2R_PLAN:
+            Sci_Plan->p = call_fftw_plan_guru_split_dft_r2r(Sci_Plan->gdim.rank,
+                          Sci_Plan->gdim.dims,
+                          Sci_Plan->gdim.howmany_rank,
+                          Sci_Plan->gdim.howmany_dims,
+                          ri, ro, kind, flags);
+            break;
     }
+
     if (Sci_Plan->p == NULL)
     {
         *errflag = 2;
     }
-    return(Sci_Plan->p);
+    return (Sci_Plan->p);
 }
 /*--------------------------------------------------------------------------*/
 /* Check if two guru_dim structures are equal
@@ -260,37 +254,37 @@ int CheckGuruDims(guru_dim_struct *gdim1, guru_dim_struct *gdim2)
         {
             if (gdim1->dims[i].n  != gdim2->dims[i].n)
             {
-                return(0);
+                return (0);
             }
             if (gdim1->dims[i].is != gdim2->dims[i].is)
             {
-                return(0);
+                return (0);
             }
             if (gdim1->dims[i].os != gdim2->dims[i].os)
             {
-                return(0);
+                return (0);
             }
         }
         for (i = 0; i < gdim1->howmany_rank; i++)
         {
             if (gdim1->howmany_dims[i].n  != gdim2->howmany_dims[i].n)
             {
-                return(0);
+                return (0);
             }
             if (gdim1->howmany_dims[i].is != gdim2->howmany_dims[i].is)
             {
-                return(0);
+                return (0);
             }
             if (gdim1->howmany_dims[i].os != gdim2->howmany_dims[i].os)
             {
-                return(0);
+                return (0);
             }
         }
-        return(1);
+        return (1);
     }
     else
     {
-        return(0);
+        return (0);
     }
 }
 /*--------------------------------------------------------------------------*/
@@ -308,17 +302,17 @@ int CheckKindArray(fftw_r2r_kind *kind1, fftw_r2r_kind *kind2, int rank)
     int i;
     if ((kind1 == NULL) && (kind2 == NULL))
     {
-        return(1);
+        return (1);
     }
 
     for (i = 0; i < rank; i++)
     {
         if (kind1[i]  != kind2[i])
         {
-            return(0);
+            return (0);
         }
     }
-    return(1);
+    return (1);
 }
 /*--------------------------------------------------------------------------*/
 /* call different fftw_execute_split_dft_xxx procedures according to type input
diff --git a/scilab/modules/fftw/tests/nonreg_tests/bug_13866.dia.ref b/scilab/modules/fftw/tests/nonreg_tests/bug_13866.dia.ref
new file mode 100644 (file)
index 0000000..1024288
--- /dev/null
@@ -0,0 +1,49 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2015 - Scilab Enterprises - Vincent COUVERT
+//
+//  This file is distributed under the same license as the Scilab package.
+// =============================================================================
+//
+// <-- CLI SHELL MODE -->
+//
+// <-- Non-regression test for bug 13866 -->
+//
+// <-- Bugzilla URL -->
+// http://bugzilla.scilab.org/13866
+//
+// <-- Short Description -->
+// weird behaviour of fft(real(S))
+s=zeros(100,1);
+s(4)=1;
+S=fft(s,-1);
+CC=cos(2*%pi*[0:99]'*3/100);
+CS=-sin(2*%pi*[0:99]'*3/100);
+assert_checkalmostequal(real(S), CC, [], 10*%eps);
+// With fresh plan creation
+fft([1;0;0],-1); // Force the creation of a new plan at next line
+rs=fft(real(S),-1);
+is=fft(imag(S),-1);
+assert_checkalmostequal(real(rs), real(fft(CC,-1)), [], 100*%eps);
+rs2=fft(real(S),-1,dim=100,incr=1); // dim + incr forced
+assert_checkequal(real(rs), real(rs2));
+assert_checkalmostequal(imag(is), imag(fft(CS,-1)), [], 100*%eps);
+// Without fresh plan creation (1)
+fft(eye(100,1),-1); // Plan with same size => no new plan creation at next line
+rs=fft(real(S),-1);
+is=fft(imag(S),-1);
+assert_checkalmostequal(real(rs), real(fft(CC,-1)), [], 100*%eps);
+rs2=fft(real(S),-1,dim=100,incr=1); // dim + incr forced
+assert_checkequal(real(rs), real(rs2));
+assert_checkalmostequal(imag(is), imag(fft(CS,-1)), [], 100*%eps);
+// Without fresh plan creation (2)
+rs=fft(real(S),-1);
+is=fft(imag(S),-1);
+assert_checkalmostequal(real(rs), real(fft(CC,-1)), [], 100*%eps);
+rs2=fft(real(S),-1,dim=100,incr=1); // dim + incr forced
+assert_checkequal(real(rs), real(rs2));
+assert_checkalmostequal(imag(is), imag(fft(CS,-1)), [], 100*%eps);
+// convol test
+t=rand(1,100);
+r=convol(eye(50,1)',t);
+assert_checkalmostequal(t(1:10),r(1:10), [], 100*%eps);
diff --git a/scilab/modules/fftw/tests/nonreg_tests/bug_13866.tst b/scilab/modules/fftw/tests/nonreg_tests/bug_13866.tst
new file mode 100644 (file)
index 0000000..84857c7
--- /dev/null
@@ -0,0 +1,65 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2015 - Scilab Enterprises - Vincent COUVERT
+//
+//  This file is distributed under the same license as the Scilab package.
+// =============================================================================
+//
+// <-- CLI SHELL MODE -->
+//
+// <-- Non-regression test for bug 13866 -->
+//
+// <-- Bugzilla URL -->
+// http://bugzilla.scilab.org/13866
+//
+// <-- Short Description -->
+// weird behaviour of fft(real(S))
+
+s=zeros(100,1);
+s(4)=1;
+S=fft(s,-1);
+CC=cos(2*%pi*[0:99]'*3/100);
+CS=-sin(2*%pi*[0:99]'*3/100);
+assert_checkalmostequal(real(S), CC, [], 10*%eps);
+
+// With fresh plan creation
+fft([1;0;0],-1); // Force the creation of a new plan at next line
+rs=fft(real(S),-1);
+is=fft(imag(S),-1);
+
+assert_checkalmostequal(real(rs), real(fft(CC,-1)), [], 100*%eps);
+
+rs2=fft(real(S),-1,dim=100,incr=1); // dim + incr forced
+assert_checkequal(real(rs), real(rs2));
+
+assert_checkalmostequal(imag(is), imag(fft(CS,-1)), [], 100*%eps);
+
+
+// Without fresh plan creation (1)
+fft(eye(100,1),-1); // Plan with same size => no new plan creation at next line
+rs=fft(real(S),-1);
+is=fft(imag(S),-1);
+
+assert_checkalmostequal(real(rs), real(fft(CC,-1)), [], 100*%eps);
+
+rs2=fft(real(S),-1,dim=100,incr=1); // dim + incr forced
+assert_checkequal(real(rs), real(rs2));
+
+assert_checkalmostequal(imag(is), imag(fft(CS,-1)), [], 100*%eps);
+
+
+// Without fresh plan creation (2)
+rs=fft(real(S),-1);
+is=fft(imag(S),-1);
+
+assert_checkalmostequal(real(rs), real(fft(CC,-1)), [], 100*%eps);
+
+rs2=fft(real(S),-1,dim=100,incr=1); // dim + incr forced
+assert_checkequal(real(rs), real(rs2));
+
+assert_checkalmostequal(imag(is), imag(fft(CS,-1)), [], 100*%eps);
+
+// convol test
+t=rand(1,100);
+r=convol(eye(50,1)',t);
+assert_checkalmostequal(t(1:10),r(1:10), [], 100*%eps);
\ No newline at end of file