improved fft function based on fftw, taking data symmetry into account, hard coded... 80/6880/15
steer [Wed, 4 Apr 2012 12:26:28 +0000 (14:26 +0200)]
Change-Id: I952a61144d605082637c9373f46ab41e71709ebd

50 files changed:
SEP/INDEX
SEP/SEP_084_fft_improvments.odt [new file with mode: 0644]
scilab/CHANGES_5.4.X
scilab/modules/fftw/fftw.vcxproj
scilab/modules/fftw/help/en_US/fftw.xml [deleted file]
scilab/modules/fftw/help/en_US/fftw_flags.xml
scilab/modules/fftw/help/en_US/fftw_forget_wisdom.xml
scilab/modules/fftw/help/en_US/get_fftw_wisdom.xml
scilab/modules/fftw/help/en_US/set_fftw_wisdom.xml
scilab/modules/fftw/help/fr_FR/fftw.xml [deleted file]
scilab/modules/fftw/help/fr_FR/fftw_flags.xml
scilab/modules/fftw/help/fr_FR/fftw_forget_wisdom.xml
scilab/modules/fftw/help/fr_FR/get_fftw_wisdom.xml
scilab/modules/fftw/help/fr_FR/set_fftw_wisdom.xml
scilab/modules/fftw/sci_gateway/c/sci_disposefftwlibrary.c
scilab/modules/fftw/sci_gateway/c/sci_fftw.c
scilab/modules/fftw/sci_gateway/c/sci_fftw_flags.c
scilab/modules/fftw/sci_gateway/c/sci_fftw_forget_wisdom.c
scilab/modules/fftw/sci_gateway/c/sci_fftwlibraryisloaded.c
scilab/modules/fftw/sci_gateway/c/sci_get_fftw_wisdom.c
scilab/modules/fftw/sci_gateway/c/sci_set_fftw_wisdom.c
scilab/modules/fftw/src/c/DllmainFttw.c
scilab/modules/fftw/src/c/callfftw.c
scilab/modules/fftw/src/c/callfftw.h
scilab/modules/fftw/src/c/fftw3.h
scilab/modules/fftw/src/c/fftw_utilities.c
scilab/modules/fftw/src/c/fftw_utilities.h
scilab/modules/fftw/src/c/fftwlibname.c
scilab/modules/fftw/src/c/fftwlibname.h
scilab/modules/fftw/src/c/with_fftw.c
scilab/modules/fftw/tests/unit_tests/fftw.dia.ref [deleted file]
scilab/modules/fftw/tests/unit_tests/fftw.tst [deleted file]
scilab/modules/fftw/tests/unit_tests/fftw_flag.dia.ref
scilab/modules/fftw/tests/unit_tests/fftw_flag.tst
scilab/modules/fftw/tests/unit_tests/fftw_part1.dia.ref [new file with mode: 0644]
scilab/modules/fftw/tests/unit_tests/fftw_part1.tst [new file with mode: 0644]
scilab/modules/fftw/tests/unit_tests/fftw_part2.dia.ref [new file with mode: 0644]
scilab/modules/fftw/tests/unit_tests/fftw_part2.tst [new file with mode: 0644]
scilab/modules/fftw/tests/unit_tests/fftw_part3.dia.ref [new file with mode: 0644]
scilab/modules/fftw/tests/unit_tests/fftw_part3.tst [new file with mode: 0644]
scilab/modules/fftw/tests/unit_tests/fftw_part4.dia.ref [new file with mode: 0644]
scilab/modules/fftw/tests/unit_tests/fftw_part4.tst [new file with mode: 0644]
scilab/modules/fftw/tests/unit_tests/fftw_part5.dia.ref [new file with mode: 0644]
scilab/modules/fftw/tests/unit_tests/fftw_part5.tst [new file with mode: 0644]
scilab/modules/fftw/tests/unit_tests/setget_fftw_wisdom.dia.ref
scilab/modules/fftw/tests/unit_tests/setget_fftw_wisdom.tst
scilab/modules/overloading/macros/%hm_fft.sci [deleted file]
scilab/modules/signal_processing/help/en_US/fft.xml
scilab/modules/signal_processing/help/fr_FR/fft.xml
scilab/modules/signal_processing/macros/ifft.sci

index fd5c4b5..f84f2dd 100644 (file)
--- a/SEP/INDEX
+++ b/SEP/INDEX
@@ -77,4 +77,7 @@ SEP #077: atomsQuit function
 SEP #078: nthroot function
 SEP #079: arma2ss function
 SEP #080: xcorr & xcov functions
-SEP #081: new argument for test_run to generate a xunit report
\ No newline at end of file
+SEP #081: new argument for test_run to generate a xunit report
+SEP #082: eigs function
+SEP #083: example_run function
+SEP #084: fft improvements
\ No newline at end of file
diff --git a/SEP/SEP_084_fft_improvments.odt b/SEP/SEP_084_fft_improvments.odt
new file mode 100644 (file)
index 0000000..b348a7d
Binary files /dev/null and b/SEP/SEP_084_fft_improvments.odt differ
index d4d6767..a22054b 100644 (file)
@@ -42,6 +42,13 @@ Documentation
     - genetic algorithms. See bug #11514.
 
 
+Signal Processing
+=================
+
+* Updated and improved fft function based on fftw (See SEP#84):
+    - taking data symmetry into account,
+    - hard coded multivariate fft.
+
 
 Compilation
 ===========
@@ -645,6 +652,7 @@ CACSD & Signal Processing
 
 * Bug #11340 fixed - bode, gainplot, nyquist and plzr without arguments did not show an example.
 
+
 ATOMS
 =======
 
index 6d77311..a5937cf 100644 (file)
@@ -90,6 +90,7 @@ lib /DEF:"$(ProjectDir)Elementary_functions_f_Import.def" /SUBSYSTEM:WINDOWS /MA
     </PreLinkEvent>
     <Link>
       <AdditionalDependencies>core.lib;scilab_windows.lib;elementary_functions_f.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>../../bin/blasplus.lib;scilab_windows.lib;core.lib;elementary_functions_f.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <OutputFile>$(SolutionDir)bin\$(ProjectName).dll</OutputFile>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <SubSystem>Windows</SubSystem>
@@ -119,6 +120,7 @@ lib /DEF:"$(ProjectDir)Elementary_functions_f_Import.def" /SUBSYSTEM:WINDOWS /MA
     </PreLinkEvent>
     <Link>
       <AdditionalDependencies>core.lib;scilab_windows.lib;elementary_functions_f.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>../../bin/blasplus.lib;scilab_windows.lib;core.lib;elementary_functions_f.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <OutputFile>$(SolutionDir)bin\$(ProjectName).dll</OutputFile>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <SubSystem>Windows</SubSystem>
@@ -149,6 +151,7 @@ lib /DEF:"$(ProjectDir)Elementary_functions_f_Import.def" /SUBSYSTEM:WINDOWS /MA
     </PreLinkEvent>
     <Link>
       <AdditionalDependencies>core.lib;scilab_windows.lib;elementary_functions_f.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>../../bin/blasplus.lib;scilab_windows.lib;core.lib;elementary_functions_f.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <OutputFile>$(SolutionDir)bin\$(ProjectName).dll</OutputFile>
       <GenerateDebugInformation>false</GenerateDebugInformation>
       <SubSystem>Windows</SubSystem>
@@ -184,6 +187,7 @@ lib /DEF:"$(ProjectDir)Elementary_functions_f_Import.def" /SUBSYSTEM:WINDOWS /MA
     </PreLinkEvent>
     <Link>
       <AdditionalDependencies>core.lib;scilab_windows.lib;elementary_functions_f.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>../../bin/blasplus.lib;scilab_windows.lib;core.lib;elementary_functions_f.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <OutputFile>$(SolutionDir)bin\$(ProjectName).dll</OutputFile>
       <GenerateDebugInformation>false</GenerateDebugInformation>
       <SubSystem>Windows</SubSystem>
diff --git a/scilab/modules/fftw/help/en_US/fftw.xml b/scilab/modules/fftw/help/en_US/fftw.xml
deleted file mode 100644 (file)
index c3ae17f..0000000
+++ /dev/null
@@ -1,129 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
- * Copyright (C) 2007 - INRIA
- * 
- * This file must be used under the terms of the CeCILL.
- * This source file is licensed as described in the file COPYING, which
- * you should have received as part of this distribution.  The terms
- * are also available at    
- * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
- *
- -->
-<refentry xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svg="http://www.w3.org/2000/svg" xmlns:ns3="http://www.w3.org/1999/xhtml" xmlns:mml="http://www.w3.org/1998/Math/MathML" xmlns:db="http://docbook.org/ns/docbook" version="5.0-subset Scilab" xml:id="fftw" xml:lang="en">
-  <refnamediv>
-    <refname>fftw</refname>
-    <refpurpose>Fast fourier transform based on the fftw library</refpurpose>
-  </refnamediv>
-  <refsynopsisdiv>
-    <title>Calling Sequence</title>
-    <synopsis>[y]=fftw(x)
-      [y]=fftw(x,sign)
-      [y]=fftw(x,sign,dim,incr)
-      [y]=fftw(x,sign,[dim1 dim2 ...dimN],[incr1 incr2 ...incrN])
-    </synopsis>
-  </refsynopsisdiv>
-  <refsection>
-    <title>Arguments</title>
-    <variablelist>
-      <varlistentry>
-        <term>y,x</term>
-        <listitem>
-          <para>matrix/vector of real/complex data. Input/output data to be
-            transformed.
-          </para>
-        </listitem>
-      </varlistentry>
-      <varlistentry>
-        <term>sign</term>
-        <listitem>
-          <para>Integer. 1 or -1. Set direct or inverse transform.</para>
-        </listitem>
-      </varlistentry>
-      <varlistentry>
-        <term>dim</term>
-        <listitem>
-          <para>integer. Set the dimension (the length) of the
-            transform.
-          </para>
-        </listitem>
-      </varlistentry>
-      <varlistentry>
-        <term>incr</term>
-        <listitem>
-          <para>integer. Set the stride (the span) of the transform.</para>
-        </listitem>
-      </varlistentry>
-    </variablelist>
-  </refsection>
-  <refsection>
-    <title>Description</title>
-    <para>This function realizes direct/inverse Discrete Fourier Transform
-      (DFT) with the help of the FFTW library.
-    </para>
-    <para>One can compute vector, 2D, M-D transform with this function.</para>
-    <para>
-      For more details of fftw syntax see <link linkend="fft">fft</link> scilab function.
-    </para>
-    <para>
-      For more details about FFTW library see FFTW Web site : <ulink url="http://www.fftw.org">http://www.fftw.org</ulink>
-    </para>
-    <para>Remark: fftw function automatically stores his last parameters in
-      memory to re-use it in a second time.
-    </para>
-    <para>This improves greatly the time computation when consecutives
-      calls (with same parameters) are performed.
-    </para>
-  </refsection>
-  <refsection>
-    <title>Examples</title>
-    <programlisting role="example"><![CDATA[ 
-//simple vector direct transform
-a = rand(50,1)+%i*rand(50,1);
-y = fftw(a);
-y = fftw(a,-1);
-//inverse transform
-b = fftw(y,1);
-
-//2D transform
-a = rand(512,512)+%i*rand(512,512);
-y = fftw(a);
-
-//M-D transform -old calling sequence-
-a = rand(120,1);
-y = a;
-dim=[5 6 4];incr=[1 5 30];
-for i=1:3
-  y = fftw(y,-1,dim(i),incr(i));
-end
-
-//M-D transform -new calling sequence-
-//More efficient than old
-y = fftw(a,-1,[5 6 4],[1 5 30]);
-b = fftw(y,1,[5 6 4],[1 5 30]);
- ]]></programlisting>
-  </refsection>
-  <refsection role="see also">
-    <title>See Also</title>
-    <simplelist type="inline">
-      <member>
-        <link linkend="fftw_flags">fftw_flags</link>
-      </member>
-      <member>
-        <link linkend="get_fftw_wisdom">get_fftw_wisdom</link>
-      </member>
-      <member>
-        <link linkend="set_fftw_wisdom">set_fftw_wisdom</link>
-      </member>
-      <member>
-        <link linkend="fftw_forget_wisdom">fftw_forget_wisdom</link>
-      </member>
-    </simplelist>
-  </refsection>
-  <refsection>
-    <title>Bibliography</title>
-    <para>
-      Matteo Frigo and Steven G. Johnson, "FFTW Documentation" <ulink url="http://www.fftw.org/#documentation">http://www.fftw.org/#documentation</ulink>
-    </para>
-  </refsection>
-</refentry>
index 031080b..5869013 100644 (file)
  * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
  *
  -->
-<refentry xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svg="http://www.w3.org/2000/svg" xmlns:ns4="http://www.w3.org/1999/xhtml" xmlns:mml="http://www.w3.org/1998/Math/MathML" xmlns:db="http://docbook.org/ns/docbook" version="5.0-subset Scilab" xml:id="fftw_flags" xml:lang="en">
+<refentry xmlns="http://docbook.org/ns/docbook" 
+          xmlns:xlink="http://www.w3.org/1999/xlink" 
+          xmlns:svg="http://www.w3.org/2000/svg" 
+          xmlns:ns4="http://www.w3.org/1999/xhtml" 
+          xmlns:mml="http://www.w3.org/1998/Math/MathML" 
+          xmlns:db="http://docbook.org/ns/docbook" 
+          version="5.0-subset Scilab" xml:id="fftw_flags" xml:lang="en">
   <refnamediv>
     <refname>fftw_flags</refname>
-    <refpurpose>set computation method of fast fourier transform of the fftw
-      function
+    <refpurpose>set method for fft planner algorithm selection
     </refpurpose>
   </refnamediv>
   <refsynopsisdiv>
     <title>Calling Sequence</title>
-    <synopsis>[a,[S]]=fftw_flags([x1;x2;...])</synopsis>
+    <synopsis>[a,[S]]=fftw_flags(flag)</synopsis>
   </refsynopsisdiv>
   <refsection>
     <title>Arguments</title>
     <variablelist>
       <varlistentry>
-        <term>[x1;x2;...]</term>
+        <term>flag</term>
         <listitem>
-          <para>Matrix of string or integers. Entry to switch the method of
-            fft computation for fftw.
+          <para>
+            a string or an integer. Specifies the planner
+            algorithm. See below.
           </para>
         </listitem>
       </varlistentry>
       <varlistentry>
         <term>a</term>
         <listitem>
-          <para>Integer. Give the current value of the flag of the fftw
-            function.
+          <para>an integer. The planner code. See below.
           </para>
         </listitem>
       </varlistentry>
       <varlistentry>
         <term>S</term>
         <listitem>
-          <para>String matrix. Give the string value of the fftw flag.</para>
+          <para>a character string. The planner name.</para>
         </listitem>
       </varlistentry>
     </variablelist>
   <refsection>
     <title>Description</title>
     <para>
-      This function enables the change of the <literal>unsigned
-        flags
-      </literal>
-      parameter of the
-      <literal>fftw_plan_guru_split_dft</literal> function that is used in <link linkend="fftw">fftw</link> function. 
+      This function enables the selection of the algorithm used to
+      determine the fftw planner algorithm. The planner is used to
+      determine an efficient way to compute the fft.
     </para>
-    <para>Default value is FFTW_ESTIMATE</para>
+    <para>
+      Warning: the default value "FFTW_MEASURE" gives
+      quite efficient plans. Try to change it only if the fft efficiency is
+      really important and you have a lot of simmilar calls to do.
+    </para>
+   
     <para>Accepted entries are :</para>
     <itemizedlist>
       <listitem>
-        <para>FFTW_MEASURE or 0</para>
-      </listitem>
-      <listitem>
-        <para>FFTW_DESTROY_INPUT or 1</para>
-      </listitem>
-      <listitem>
-        <para>FFTW_UNALIGNED or 2</para>
-      </listitem>
-      <listitem>
-        <para>FFTW_CONSERVE_MEMORY or 4</para>
-      </listitem>
-      <listitem>
-        <para>FFTW_EXHAUSTIVE or 8</para>
-      </listitem>
-      <listitem>
-        <para>FFTW_PRESERVE_INPUT or 16</para>
+        <para>FFTW_ESTIMATE or 64. Specifies that, instead of actual
+        measurements of different algorithms, a simple heuristic is
+        used to pick a (probably sub-optimal) plan quickly. With this
+        flag, the input/output arrays are not overwritten during
+        planning. It is the defailt value</para>
       </listitem>
       <listitem>
-        <para>FFTW_PATIENT or 32</para>
+        <para>"FFTW_MEASURE" or 0. tells FFTW to find an optimized
+        plan by actually computing several FFTs and measuring their
+        execution time. Depending on your machine, this can take some
+        time (often a few seconds). 
+        planning option.</para>
       </listitem>
       <listitem>
-        <para>FFTW_ESTIMATE or 64</para>
+        <para>FFTW_PATIENT or 32. It is like "FFTW_MEASURE", but
+        considers a wider range of algorithms and often produces a
+        “more optimal” plan (especially for large transforms), but at
+        the expense of several times longer planning time (especially
+        for large transforms). </para>
       </listitem>
+    
       <listitem>
-        <para>FFTW_ESTIMATE_PATIENT or 128</para>
+        <para>FFTW_EXHAUSTIVE or 8. It is like "FFTW_PATIENT", but
+        considers an even wider range of algorithms, including many
+        that we think are unlikely to be fast, to produce the most
+        optimal plan but with a substantially increased planning
+        time. </para>
       </listitem>
-      <listitem>
-        <para>FFTW_BELIEVE_PCOST or 256</para>
-      </listitem>
-      <listitem>
-        <para>FFTW_NO_DFT_R2HC or 512</para>
-      </listitem>
-      <listitem>
-        <para>FFTW_NO_NONTHREADED or 1024</para>
-      </listitem>
-      <listitem>
-        <para>FFTW_NO_BUFFERING or 2048</para>
-      </listitem>
-      <listitem>
-        <para>FFTW_NO_INDIRECT_OP or 4096</para>
-      </listitem>
-      <listitem>
-        <para>FFTW_ALLOW_LARGE_GENERIC or 8192</para>
-      </listitem>
-      <listitem>
-        <para>FFTW_NO_RANK_SPLITS or 16384</para>
-      </listitem>
-      <listitem>
-        <para>FFTW_NO_VRANK_SPLITS or 32768</para>
-      </listitem>
-      <listitem>
-        <para>FFTW_NO_VRECURSE or 65536</para>
-      </listitem>
-      <listitem>
-        <para>FFTW_NO_SIMD or 131072</para>
-      </listitem>
-      <listitem>
-        <para>FFTW_NO_SLOW or 262144</para>
-      </listitem>
-      <listitem>
-        <para>FFTW_NO_FIXED_RADIX_LARGE_N or 524288</para>
-      </listitem>
-      <listitem>
-        <para>FFTW_ALLOW_PRUNING or 1048576</para>
-      </listitem>
-    </itemizedlist>
-    <para>Rmk : when using FFTW_MEASURE/FFTW_PATIENT/FFTW_EXHAUSTIVE you must
+   </itemizedlist>
+    
+
+    <para>Remark : when using FFTW_MEASURE/FFTW_PATIENT/FFTW_EXHAUSTIVE you must
       call two times fftw. (first call for initialisation, second and others
       calls for computation)
     </para>
   <refsection>
     <title>Examples</title>
     <programlisting role="example"><![CDATA[ 
-//return the integer value of the flag
-fftw_flags()
-
-//change flags
-fftw_flags(["FFTW_MEASURE";"FFTW_CONSERVE_MEMORY"]);
+A=rand(1,2^9+2^15+2^17);
+fftw_forget_wisdom();
+fftw_flags("FFTW_ESTIMATE");
+timer();y=fft(A);timer()//first call determines the plan
+timer();y=fft(A);timer() //subsequent similar calls
+fftw_flags("FFTW_MEASURE");
+fftw_forget_wisdom();
+timer();y=fft(A);timer()//first call determines the plan
+timer();y=fft(A);timer() //subsequent similar calls
 
-//change flags and display current value of fftw flags (both integer and strings)
-[a,S]=fftw_flags("FFTW_PATIENT")
  ]]></programlisting>
   </refsection>
   <refsection role="see also">
     <title>See Also</title>
     <simplelist type="inline">
       <member>
-        <link linkend="fftw">fftw</link>
+        <link linkend="fft">fft</link>
+      </member>
+      <member>
+        <link linkend="set_fftw_wisdom">set_fftw_wisdom</link>
+      </member>
+     <member>
+        <link linkend="get_fftw_wisdom">get_fftw_wisdom</link>
+      </member>
+      <member>
+        <link linkend="fftw_forget_wisdom">fftw_forget_wisdom</link>
       </member>
     </simplelist>
   </refsection>
index 4179512..155f2eb 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!--
  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
- * Copyright (C) 2007 - INRIA
+ * Copyright (C) 2007 - Allan Layec - INRIA
  * 
  * This file must be used under the terms of the CeCILL.
  * This source file is licensed as described in the file COPYING, which
  * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
  *
  -->
-<refentry xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svg="http://www.w3.org/2000/svg" xmlns:mml="http://www.w3.org/1998/Math/MathML" xmlns:db="http://docbook.org/ns/docbook" version="5.0-subset Scilab" xml:lang="en" xml:id="fftw_forget_wisdom">
+<refentry xmlns="http://docbook.org/ns/docbook" 
+          xmlns:xlink="http://www.w3.org/1999/xlink" 
+          xmlns:svg="http://www.w3.org/2000/svg" 
+          xmlns:mml="http://www.w3.org/1998/Math/MathML" 
+          xmlns:db="http://docbook.org/ns/docbook" 
+          version="5.0-subset Scilab" xml:lang="en" xml:id="fftw_forget_wisdom">
   <refnamediv>
     <refname>fftw_forget_wisdom</refname>
     <refpurpose>Reset fftw wisdom</refpurpose>
     </para>
   </refsection>
   <refsection>
+    <title>Caveat</title>
+     <para> 
+       This function do nothing  in Scilab versions which use
+       the MKL intel library (Scilab official versions for windows in particular).
+     </para>
+ </refsection>
+
+  <refsection>
     <title>Examples</title>
     <programlisting role="example"><![CDATA[ 
 //return fftw wisdom
@@ -40,9 +53,6 @@ fftw_forget_wisdom();
     <title>See Also</title>
     <simplelist type="inline">
       <member>
-        <link linkend="fftw">fftw</link>
-      </member>
-      <member>
         <link linkend="get_fftw_wisdom">get_fftw_wisdom</link>
       </member>
       <member>
index d34aad4..1b3b264 100644 (file)
@@ -1,7 +1,8 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!--
  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
- * Copyright (C) 2007 - INRIA
+ * Copyright (C) 2007 - Allan Layec - INRIA
+ * Copyright (C) 2012 - Serge Steer - INRIA
  * 
  * This file must be used under the terms of the CeCILL.
  * This source file is licensed as described in the file COPYING, which
  * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
  *
  -->
-<refentry xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svg="http://www.w3.org/2000/svg" xmlns:mml="http://www.w3.org/1998/Math/MathML" xmlns:db="http://docbook.org/ns/docbook" version="5.0-subset Scilab" xml:lang="en" xml:id="get_fftw_wisdom">
+<refentry xmlns="http://docbook.org/ns/docbook" 
+          xmlns:xlink="http://www.w3.org/1999/xlink" 
+          xmlns:svg="http://www.w3.org/2000/svg" 
+          xmlns:mml="http://www.w3.org/1998/Math/MathML" 
+          xmlns:db="http://docbook.org/ns/docbook"
+          version="5.0-subset Scilab" xml:lang="en" xml:id="get_fftw_wisdom">
   <refnamediv>
     <refname>get_fftw_wisdom</refname>
     <refpurpose>return fftw wisdom</refpurpose>
     </variablelist>
   </refsection>
   <refsection>
+    <title>Caveat</title>
+     <para> 
+       This function is not implemented in Scilab versions which use
+       the MKL intel library (Scilab official versions for windows in particular).
+     </para>
+ </refsection>
+  <refsection>
     <title>Description</title>
     <para>
-      This function return the fftw wisdom in a string matrix.
+      This function return the fftw wisdom in a string matrix.  Using
+      <literal>get_fftw_wisdom</literal> and
+      <literal>set_fftw_wisdom</literal> allows to optimize fft
+      efficiency if many calls have to be done on with same data sizes
+      and same options for the <link linkend="fft">fft</link> function.
     </para>
   </refsection>
   <refsection>
     <title>Examples</title>
     <programlisting role="example"><![CDATA[ 
-//return fftw wisdom
-txt=get_fftw_wisdom();
-//set fftw wisdom
-set_fftw_wisdom(txt);
-//reset fftw wisdom
-fftw_forget_wisdom();
+sample_rate=1000;
+t = 0:1/sample_rate:40;
+N=size(t,'*'); //number of samples
+s=sin(2*%pi*50*t)+sin(2*%pi*70*t+%pi/4)+grand(1,N,'nor',0,1);
+fftw_forget_wisdom();  
+timer();y=fft(s);t1=timer() //first call
+timer();y=fft(s);t2=timer()  //second call uses preserved wisdom
+t1/t2
+wisdom1=get_fftw_wisdom(); //preserve current wisdom
+//realize a different fft
+A = zeros(256,256);
+A(5:24,13:17) = 1;
+X = fft(A);
+
+//Create a new signal with same size as s
+s1=sin(2*%pi*10*t)+sin(2*%pi*7*t+%pi/4)+5*grand(1,N,'nor',0,1);
+//restore preserved wisdom
+set_fftw_wisdom(wisdom1);
+timer();y=fft(s);t3=timer()
+t3/t2
+
  ]]></programlisting>
   </refsection>
   <refsection role="see also">
     <title>See Also</title>
     <simplelist type="inline">
       <member>
-        <link linkend="fftw">fftw</link>
+        <link linkend="fft">fft</link>
       </member>
+
       <member>
         <link linkend="set_fftw_wisdom">set_fftw_wisdom</link>
       </member>
index 1137f1c..c117d53 100644 (file)
@@ -1,7 +1,8 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!--
  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
- * Copyright (C) 2007 - INRIA
+ * Copyright (C) 2007 - Allan Layec - INRIA
+ * Copyright (C) 2012 - Serge Steer - INRIA
  * 
  * This file must be used under the terms of the CeCILL.
  * This source file is licensed as described in the file COPYING, which
  * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
  *
  -->
-<refentry xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svg="http://www.w3.org/2000/svg" xmlns:mml="http://www.w3.org/1998/Math/MathML" xmlns:db="http://docbook.org/ns/docbook" version="5.0-subset Scilab" xml:lang="en" xml:id="set_fftw_wisdom">
+<refentry xmlns="http://docbook.org/ns/docbook" 
+          xmlns:xlink="http://www.w3.org/1999/xlink" 
+          xmlns:svg="http://www.w3.org/2000/svg" 
+          xmlns:mml="http://www.w3.org/1998/Math/MathML" 
+          xmlns:db="http://docbook.org/ns/docbook" 
+          version="5.0-subset Scilab" xml:lang="en" xml:id="set_fftw_wisdom">
   <refnamediv>
     <refname>set_fftw_wisdom</refname>
     <refpurpose>set fftw wisdom</refpurpose>
     </variablelist>
   </refsection>
   <refsection>
+    <title>Caveat</title>
+     <para> 
+       This function is not implemented in Scilab versions which use
+       the MKL intel library (Scilab official versions for windows in particular).
+     </para>
+ </refsection>
+  <refsection>
     <title>Description</title>
     <para>
-      This function set the fftw wisdom with a string matrix.
+      This function set the fftw wisdom with a string matrix.Using
+      <literal>get_fftw_wisdom</literal> and
+      <literal>set_fftw_wisdom</literal> allows to optimize fft
+      efficiency if many calls have to be done on with same data sizes
+      and same options for the <link linkend="fft">fft</link> function.
     </para>
   </refsection>
   <refsection>
     <title>Examples</title>
     <programlisting role="example"><![CDATA[ 
-//return fftw wisdom
-txt=get_fftw_wisdom();
-//set fftw wisdom
-set_fftw_wisdom(txt);
-//reset fftw wisdom
-fftw_forget_wisdom();
+sample_rate=1000;
+t = 0:1/sample_rate:40;
+N=size(t,'*'); //number of samples
+s=sin(2*%pi*50*t)+sin(2*%pi*70*t+%pi/4)+grand(1,N,'nor',0,1);
+fftw_forget_wisdom();  
+timer();y=fft(s);t1=timer() //first call
+timer();y=fft(s);t2=timer()  //second call uses preserved wisdom
+t1/t2
+wisdom1=get_fftw_wisdom(); //preserve current wisdom
+//realize a different fft
+A = zeros(256,256);
+A(5:24,13:17) = 1;
+X = fft(A);
+
+//Create a new signal with same size as s
+s1=sin(2*%pi*10*t)+sin(2*%pi*7*t+%pi/4)+5*grand(1,N,'nor',0,1);
+//restore preserved wisdom
+set_fftw_wisdom(wisdom1);
+timer();y=fft(s);t3=timer()
+t3/t2
  ]]></programlisting>
   </refsection>
   <refsection role="see also">
     <title>See Also</title>
     <simplelist type="inline">
       <member>
-        <link linkend="fftw">fftw</link>
-      </member>
-      <member>
         <link linkend="get_fftw_wisdom">get_fftw_wisdom</link>
       </member>
       <member>
diff --git a/scilab/modules/fftw/help/fr_FR/fftw.xml b/scilab/modules/fftw/help/fr_FR/fftw.xml
deleted file mode 100644 (file)
index a60ef84..0000000
+++ /dev/null
@@ -1,126 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<refentry xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svg="http://www.w3.org/2000/svg" xmlns:ns4="http://www.w3.org/1999/xhtml" xmlns:mml="http://www.w3.org/1998/Math/MathML" xmlns:db="http://docbook.org/ns/docbook" version="5.0-subset Scilab" xml:id="fftw" xml:lang="fr">
-  <refnamediv>
-    <refname>fftw</refname>
-    <refpurpose>transformée de Fourier rapide qui utilise la bibliothèque
-      FFTW
-    </refpurpose>
-  </refnamediv>
-  <refsynopsisdiv>
-    <title>Séquence d'appel</title>
-    <synopsis>[y]=fftw(x)
-      [y]=fftw(x,sign)
-      [y]=fftw(x,sign,dim,incr)
-      [y]=fftw(x,sign,[dim1 dim2 ...dimN],[incr1 incr2 ...incrN])
-    </synopsis>
-  </refsynopsisdiv>
-  <refsection>
-    <title>Paramètres</title>
-    <variablelist>
-      <varlistentry>
-        <term>y,x</term>
-        <listitem>
-          <para>matrice/vecteur de donnée réelle ou complexe. Données
-            d'entrée/sortie.
-          </para>
-        </listitem>
-      </varlistentry>
-      <varlistentry>
-        <term>sign</term>
-        <listitem>
-          <para>entier. 1 ou -1. Choix du type de transformée (inverse ou
-            directe).
-          </para>
-        </listitem>
-      </varlistentry>
-      <varlistentry>
-        <term>dim</term>
-        <listitem>
-          <para>entier. Donne la dimension (la longueur) de la
-            transformée.
-          </para>
-        </listitem>
-      </varlistentry>
-      <varlistentry>
-        <term>incr</term>
-        <listitem>
-          <para>entier. Donne l'entrelacement (l'écart entre les données
-            consécutives) de la transformée.
-          </para>
-        </listitem>
-      </varlistentry>
-    </variablelist>
-  </refsection>
-  <refsection>
-    <title>Description</title>
-    <para>Cette fonction réalise une Transformée de Fourier Discrete (TFD)
-      inverse ou directe au moyen de la bibliothèque FFTW.
-    </para>
-    <para>Elle permet le calcul de transformée vectorielle, 2D et M-D.</para>
-    <para>Pour plus de détails concernant la syntaxe de l'appel à fftw,
-      consultez la fonction <link linkend="fft">fft</link> de scilab.
-    </para>
-    <para>Pour plus de détails concernant la bibliothèque FFTW, consultez le site
-      web <ulink url="http://www.fftw.org">http://www.fftw.org</ulink>.
-    </para>
-    <para>Rmq : La fonction fftw enregistre automatiquement les dernières
-      paramètres utilisés lors d'un appel pour les ré-utiliser une seconde
-      fois.
-    </para>
-    <para>Cela permet une amélioration significative du temps de calcul
-      lorsque la fonction fftw est appelée consécutivement avec les mêmes
-      paramètres.
-    </para>
-  </refsection>
-  <refsection>
-    <title>Exemples</title>
-    <programlisting role="example"><![CDATA[ 
-//transformée 1D
-a = rand(50,1)+%i*rand(50,1);
-y = fftw(a);
-y = fftw(a,-1);
-//transformée inverse
-b = fftw(y,1);
-
-//transformée 2D
-a = rand(512,512)+%i*rand(512,512);
-y = fftw(a);
-
-//transformée M-D -ancienne séquence d'appel-
-a = rand(120,1);
-y = a;
-dim=[5 6 4];incr=[1 5 30];
-for i=1:3
-  y = fftw(y,-1,dim(i),incr(i));
-end
-
-//transformée M-D transform -nouvelle séquence d'appel-
-//plus performante que l'ancienne
-y = fftw(a,-1,[5 6 4],[1 5 30]);
-b = fftw(y,1,[5 6 4],[1 5 30]);
- ]]></programlisting>
-  </refsection>
-  <refsection role="see also">
-    <title>Voir aussi</title>
-    <simplelist type="inline">
-      <member>
-        <link linkend="fftw_flags">fftw_flags</link>
-      </member>
-      <member>
-        <link linkend="get_fftw_wisdom">get_fftw_wisdom</link>
-      </member>
-      <member>
-        <link linkend="set_fftw_wisdom">set_fftw_wisdom</link>
-      </member>
-      <member>
-        <link linkend="fftw_forget_wisdom">fftw_forget_wisdom</link>
-      </member>
-    </simplelist>
-  </refsection>
-  <refsection>
-    <title>Bibliographie</title>
-    <para>
-      Matteo Frigo and Steven G. Johnson, "FFTW Documentation" <ulink url="http://www.fftw.org/#documentation">http://www.fftw.org/#documentation</ulink>
-    </para>
-  </refsection>
-</refentry>
index 6586bd9..8306a42 100644 (file)
@@ -1,32 +1,52 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<refentry xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svg="http://www.w3.org/2000/svg" xmlns:mml="http://www.w3.org/1998/Math/MathML" xmlns:db="http://docbook.org/ns/docbook" version="5.0-subset Scilab" xml:lang="fr" xml:id="fftw_flags">
+<!--
+ * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+ * Copyright (C) 2007 - INRIA
+ * 
+ * This file must be used under the terms of the CeCILL.
+ * This source file is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution.  The terms
+ * are also available at    
+ * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
+ *
+ -->
+<refentry xmlns="http://docbook.org/ns/docbook" 
+          xmlns:xlink="http://www.w3.org/1999/xlink" 
+          xmlns:svg="http://www.w3.org/2000/svg" 
+          xmlns:mml="http://www.w3.org/1998/Math/MathML" 
+          xmlns:db="http://docbook.org/ns/docbook" 
+          version="5.0-subset Scilab" xml:lang="fr" xml:id="fftw_flags">
   <refnamediv>
     <refname>fftw_flags</refname>
-    <refpurpose>choix de la méthode de calcul pour la fonction fftw</refpurpose>
+    <refpurpose>choix de la méthode pour la sélection de l'algorithme
+    de planification pour la fft</refpurpose>
   </refnamediv>
   <refsynopsisdiv>
     <title>Séquence d'appel</title>
-    <synopsis>[a,[S]]=fftw_flags([x1;x2;...])</synopsis>
+    <synopsis>[a,[S]]=fftw_flags(flag)</synopsis>
   </refsynopsisdiv>
   <refsection>
     <title>Paramètres</title>
     <variablelist>
       <varlistentry>
-        <term>[x1;x2;...]</term>
+        <term>flag</term>
         <listitem>
-          <para>Matrice de chaînes de caractères ou bien d'entiers. Sert à sélectionner la méthode de calcul de la fonction fftw.</para>
+          <para>une chaîne de caractères ou bien un entier. Sert à
+          spécifier l'algorithme de planification. Voir ci-dessous.</para>
         </listitem>
       </varlistentry>
       <varlistentry>
         <term>a</term>
         <listitem>
-          <para>Entier. Donne sous forme d'entier la méthode courante utilisée par la fonction fftw.</para>
+          <para>un entier. Code de l'algorithme de planification.Voir
+          ci-dessous.</para>
         </listitem>
       </varlistentry>
       <varlistentry>
         <term>S</term>
         <listitem>
-          <para>Matrice de chaînes de caractères. Donne sous forme de chaînes de caractères la méthode utilisée par fftw.</para>
+          <para>une chaîne de caractères. Le nom de l'algorithme de
+          planification.</para>
         </listitem>
       </varlistentry>
     </variablelist>
   <refsection>
     <title>Description</title>
     <para>
-      Cette fonction permet de sélectionner le paramètre <literal>unsigned flags</literal> de la fonction <literal>fftw_plan_guru_split_dft</literal>
-      qui est utilisée dans l'interface scilab de la fonction fftw. La valeur par défault est FFTW_ESTIMATE.
+      Cette fonction permet la sélection de l'algorithme utilisé pour
+      déterminer l'algorithme de planification de fftw. Le
+      planificateur est utilisé pour déterminer un moyen efficace pour
+      calculer la fft.
+    </para>
+    <para>
+      Attention: la valeur par défaut "FFTW_MEASURE" donne le plus
+      souvent de bonnes performances. N'essayez d'autres choix que si
+      la performance est cruciale et que vous avez beaucoup d'appels
+      du même type que faire.
     </para>
     <para>
       Les entrées possibles sont :
     </para>
     <itemizedlist>
       <listitem>
-        <para>FFTW_MEASURE or 0</para>
-      </listitem>
-      <listitem>
-        <para>FFTW_DESTROY_INPUT or 1</para>
-      </listitem>
-      <listitem>
-        <para>FFTW_UNALIGNED or 2</para>
-      </listitem>
-      <listitem>
-        <para>FFTW_CONSERVE_MEMORY or 4</para>
-      </listitem>
-      <listitem>
-        <para>FFTW_EXHAUSTIVE or 8</para>
-      </listitem>
-      <listitem>
-        <para>FFTW_PRESERVE_INPUT or 16</para>
-      </listitem>
-      <listitem>
-        <para>FFTW_PATIENT or 32</para>
-      </listitem>
-      <listitem>
-        <para>FFTW_ESTIMATE or 64</para>
-      </listitem>
-      <listitem>
-        <para>FFTW_ESTIMATE_PATIENT or 128</para>
-      </listitem>
-      <listitem>
-        <para>FFTW_BELIEVE_PCOST or 256</para>
-      </listitem>
-      <listitem>
-        <para>FFTW_NO_DFT_R2HC or 512</para>
+        <para>FFTW_ESTIMATE ou 64. Selectionne une heuristique simple et
+        peu couteuse pour choisir un plan (probablement
+        sous-optimal). C'est la valeur par défaut.</para>
       </listitem>
       <listitem>
-        <para>FFTW_NO_NONTHREADED or 1024</para>
+        <para>FFTW_MEASURE ou 0.  Selectionne une méthode consistant a
+        éffectuer plusieurs calcul de fft avec des planifications
+        différentes, à mesurer leur temps d'exécution et de choisir la
+        meilleur planification. En fonction de votre machine, cela
+        peut prendre un certain le temps (souvent quelques
+        secondes).</para>
       </listitem>
       <listitem>
-        <para>FFTW_NO_BUFFERING or 2048</para>
+        <para>FFTW_PATIENT ou 32. Similaire à "FFTW_MEASURE", mais
+        considère un plus large éventail d'algorithmes et produit
+        souvent un plan plus efficace (en particulier pour les
+        transformations importantes), par contre le cout de la
+        détermination du plan peut être largement supérieur (en
+        particulier pour les transformations importantes).</para>
       </listitem>
+     
       <listitem>
-        <para>FFTW_NO_INDIRECT_OP or 4096</para>
-      </listitem>
-      <listitem>
-        <para>FFTW_ALLOW_LARGE_GENERIC or 8192</para>
-      </listitem>
-      <listitem>
-        <para>FFTW_NO_RANK_SPLITS or 16384</para>
-      </listitem>
-      <listitem>
-        <para>FFTW_NO_VRANK_SPLITS or 32768</para>
-      </listitem>
-      <listitem>
-        <para>FFTW_NO_VRECURSE or 65536</para>
-      </listitem>
-      <listitem>
-        <para>FFTW_NO_SIMD or 131072</para>
-      </listitem>
-      <listitem>
-        <para>FFTW_NO_SLOW or 262144</para>
-      </listitem>
-      <listitem>
-        <para>FFTW_NO_FIXED_RADIX_LARGE_N or 524288</para>
-      </listitem>
-      <listitem>
-        <para>FFTW_ALLOW_PRUNING or 1048576</para>
+        <para>FFTW_EXHAUSTIVE or 8. C'est comme "FFTW_PATIENT", mais
+        considère une gamme encore plus large d'algorithmes, visant a
+        trouver le plan optimal , mais avec un temps de planification
+        sensiblement augmenté. </para>
       </listitem>
+    
     </itemizedlist>
     <para>
-      Rmq : Lors de l'utilisation des méthodes FFTW_MEASURE/FFTW_PATIENT/FFTW_EXHAUSTIVE la fonction fftw doit être appélée au moins deux fois.
-      (le premier appel est pour l'initalisation, le second et les autres pour le calcul)
+      Remarque : Lors de l'utilisation des méthodes
+      FFTW_MEASURE/FFTW_PATIENT/FFTW_EXHAUSTIVE la fonction fftw doit
+      être appélée au moins deux fois.  (le premier appel est pour
+      l'initalisation, le second et les autres pour le calcul)
     </para>
   </refsection>
   <refsection>
     <title>Exemples</title>
     <programlisting role="example"><![CDATA[ 
-//retourne sous forme entière la valeur du flag
-fftw_flags()
+A=rand(1,2^9+2^15+2^17);
+fftw_forget_wisdom();
+fftw_flags("FFTW_ESTIMATE");
+timer();y=fft(A);timer()//premier appel, détermine le plan
+timer();y=fft(A);timer() //appels similaires suivants
+fftw_flags("FFTW_MEASURE");
+fftw_forget_wisdom();
+timer();y=fft(A);timer()//premier appel, détermine le plan
+timer();y=fft(A);timer() //appels similaires suivants
 
-//changement de méthode
-fftw_flags(["FFTW_MEASURE";"FFTW_CONSERVE_MEMORY"]);
-
-//changement de méthode de affichage des flags (sous forme d'entiers et de chaînes)
-[a,S]=fftw_flags("FFTW_PATIENT")
  ]]></programlisting>
   </refsection>
   <refsection role="see also">
     <title>Voir aussi</title>
     <simplelist type="inline">
+    <member>
+        <link linkend="fft">fft</link>
+      </member>
+      <member>
+        <link linkend="set_fftw_wisdom">set_fftw_wisdom</link>
+      </member>
+     <member>
+        <link linkend="get_fftw_wisdom">get_fftw_wisdom</link>
+      </member>
       <member>
-        <link linkend="fftw">fftw</link>
+        <link linkend="fftw_forget_wisdom">fftw_forget_wisdom</link>
       </member>
-    </simplelist>
+     </simplelist>
   </refsection>
 </refentry>
index 4ed64e8..75a2e32 100644 (file)
@@ -1,5 +1,21 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<refentry xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svg="http://www.w3.org/2000/svg" xmlns:mml="http://www.w3.org/1998/Math/MathML" xmlns:db="http://docbook.org/ns/docbook" version="5.0-subset Scilab" xml:lang="fr" xml:id="fftw_forget_wisdom">
+<!--
+ * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+ * Copyright (C) 2007 - Allan Layec - INRIA
+ * 
+ * This file must be used under the terms of the CeCILL.
+ * This source file is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution.  The terms
+ * are also available at    
+ * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
+ *
+ -->
+<refentry xmlns="http://docbook.org/ns/docbook"
+          xmlns:xlink="http://www.w3.org/1999/xlink" 
+          xmlns:svg="http://www.w3.org/2000/svg" 
+          xmlns:mml="http://www.w3.org/1998/Math/MathML" 
+          xmlns:db="http://docbook.org/ns/docbook" 
+          version="5.0-subset Scilab" xml:lang="fr" xml:id="fftw_forget_wisdom">
   <refnamediv>
     <refname>fftw_forget_wisdom</refname>
     <refpurpose>Re-initialise le wisdom fftw</refpurpose>
@@ -9,6 +25,15 @@
     <synopsis>fftw_forget_wisdom()</synopsis>
   </refsynopsisdiv>
   <refsection>
+    <title>Attention</title>
+     <para> 
+       Cette fonction n'est pas implémentée lorsque Scilab utilise la
+       bibliuthèque MKL d'Intel (c'est en particulier le cas des
+       binaires Windows officiels).
+     </para>
+ </refsection>
+
+  <refsection>
     <title>Description</title>
     <para>
       Cette fonction re-initialise le wisdom fftw.
@@ -29,9 +54,6 @@ fftw_forget_wisdom();
     <title>Voir aussi</title>
     <simplelist type="inline">
       <member>
-        <link linkend="fftw">fftw</link>
-      </member>
-      <member>
         <link linkend="get_fftw_wisdom">get_fftw_wisdom</link>
       </member>
       <member>
index 26ef540..95cc3a0 100644 (file)
@@ -1,5 +1,22 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<refentry xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svg="http://www.w3.org/2000/svg" xmlns:mml="http://www.w3.org/1998/Math/MathML" xmlns:db="http://docbook.org/ns/docbook" version="5.0-subset Scilab" xml:lang="fr" xml:id="get_fftw_wisdom">
+<!--
+ * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+ * Copyright (C) 2007 - Allan Layec - INRIA
+ * Copyright (C) 2012 - Serge Steer - INRIA
+ * 
+ * This file must be used under the terms of the CeCILL.
+ * This source file is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution.  The terms
+ * are also available at    
+ * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
+ *
+ -->
+<refentry xmlns="http://docbook.org/ns/docbook" 
+          xmlns:xlink="http://www.w3.org/1999/xlink" 
+          xmlns:svg="http://www.w3.org/2000/svg" 
+          xmlns:mml="http://www.w3.org/1998/Math/MathML" 
+          xmlns:db="http://docbook.org/ns/docbook" 
+          version="5.0-subset Scilab" xml:lang="fr" xml:id="get_fftw_wisdom">
   <refnamediv>
     <refname>get_fftw_wisdom</refname>
     <refpurpose>retourne le wisdom fftw</refpurpose>
       <varlistentry>
         <term>txt</term>
         <listitem>
-          <para>Matrice de chaîne de caractères contenant le wisdom fftw.</para>
+          <para>Matrice de chaîne de caractères contenant le wisdom courant de fftw.</para>
         </listitem>
       </varlistentry>
     </variablelist>
   </refsection>
   <refsection>
+    <title>Attention</title>
+     <para> 
+       Cette fonction n'est pas implémentée lorsque Scilab utilise la
+       bibliuthèque MKL d'Intel (c'est en particulier le cas des
+       binaires Windows officiels).
+     </para>
+ </refsection>
+  <refsection>
     <title>Description</title>
     <para>
-      Cette fonction retourne le wisdom fftw sous la forme d'une chaîne de caractère.
+      Cette fonction retourne le wisdom fftw sous la forme d'une
+      chaîne de caractère. L'utilisation de
+      <literal>get_fftw_wisdom</literal> et de
+      <literal>set_fftw_wisdom</literal> permet d'optimiser
+      l'efficaité de la fft si de nombreux appels doivent être
+      effectués sur des tailles de données identiques et pour les
+      mêmes options de la fonction <link linkend="fft">fft</link>.
     </para>
   </refsection>
   <refsection>
     <title>Exemples</title>
     <programlisting role="example"><![CDATA[ 
-//return fftw wisdom
-txt=get_fftw_wisdom();
-//set fftw wisdom
-set_fftw_wisdom(txt);
-//reset fftw wisdom
-fftw_forget_wisdom();
+sample_rate=1000;
+t = 0:1/sample_rate:40;
+N=size(t,'*'); //number of samples
+s=sin(2*%pi*50*t)+sin(2*%pi*70*t+%pi/4)+grand(1,N,'nor',0,1);
+fftw_forget_wisdom();  
+timer();y=fft(s);t1=timer() //premier appel
+timer();y=fft(s);t2=timer()  //second appel similaire utilise le wisdom courant
+t1/t2
+wisdom1=get_fftw_wisdom(); //préserve le  wisdom courant
+//une fft différente
+A = zeros(256,256);
+A(5:24,13:17) = 1;
+X = fft(A);
+
+//un nouveau signal avec la même taille que s
+s1=sin(2*%pi*10*t)+sin(2*%pi*7*t+%pi/4)+5*grand(1,N,'nor',0,1);
+//reinstallation du wisdom 
+set_fftw_wisdom(wisdom1);
+timer();y=fft(s);t3=timer()
+t3/t2
+
  ]]></programlisting>
   </refsection>
   <refsection role="see also">
     <title>Voir aussi</title>
     <simplelist type="inline">
       <member>
-        <link linkend="fftw">fftw</link>
+        <link linkend="fft">fft</link>
       </member>
       <member>
         <link linkend="set_fftw_wisdom">set_fftw_wisdom</link>
index 69b9641..b91ed29 100644 (file)
@@ -1,5 +1,22 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<refentry xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svg="http://www.w3.org/2000/svg" xmlns:mml="http://www.w3.org/1998/Math/MathML" xmlns:db="http://docbook.org/ns/docbook" version="5.0-subset Scilab" xml:lang="fr" xml:id="set_fftw_wisdom">
+<!--
+ * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+ * Copyright (C) 2007 - Allan Layec - INRIA
+ * Copyright (C) 2012 - Serge Steer - INRIA
+ * 
+ * This file must be used under the terms of the CeCILL.
+ * This source file is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution.  The terms
+ * are also available at    
+ * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
+ *
+ -->
+<refentry xmlns="http://docbook.org/ns/docbook" 
+          xmlns:xlink="http://www.w3.org/1999/xlink" 
+          xmlns:svg="http://www.w3.org/2000/svg" 
+          xmlns:mml="http://www.w3.org/1998/Math/MathML" 
+          xmlns:db="http://docbook.org/ns/docbook" 
+          version="5.0-subset Scilab" xml:lang="fr" xml:id="set_fftw_wisdom">
   <refnamediv>
     <refname>set_fftw_wisdom</refname>
     <refpurpose>charge un wisdom fftw</refpurpose>
       </varlistentry>
     </variablelist>
   </refsection>
+<refsection>
+    <title>Attention</title>
+     <para> 
+       Cette fonction n'est pas implémentée lorsque Scilab utilise la
+       bibliuthèque MKL d'Intel (c'est en particulier le cas des
+       binaires Windows officiels).
+     </para>
+ </refsection>
   <refsection>
     <title>Description</title>
     <para>
-      Cette fonction charge un wisdom fftw contenue dans une chaîne de caractères.
+      Cette fonction charge un wisdom fftw contenue dans une chaîne de
+      caractères. L'utilisation de <literal>get_fftw_wisdom</literal>
+      et de <literal>set_fftw_wisdom</literal> permet d'optimiser
+      l'efficaité de la fft si de nombreux appels doivent être
+      effectués sur des tailles de données identiques et pour les
+      mêmes options de la fonction <link linkend="fft">fft</link>.
     </para>
   </refsection>
   <refsection>
     <title>Exemples</title>
     <programlisting role="example"><![CDATA[ 
-//return fftw wisdom
-txt=get_fftw_wisdom();
-//set fftw wisdom
-set_fftw_wisdom(txt);
-//reset fftw wisdom
-fftw_forget_wisdom();
+sample_rate=1000;
+t = 0:1/sample_rate:40;
+N=size(t,'*'); //number of samples
+s=sin(2*%pi*50*t)+sin(2*%pi*70*t+%pi/4)+grand(1,N,'nor',0,1);
+fftw_forget_wisdom();  
+timer();y=fft(s);t1=timer() //first call
+timer();y=fft(s);t2=timer()  //second call uses preserved wisdom
+t1/t2
+wisdom1=get_fftw_wisdom(); //preserve current wisdom
+//realize a different fft
+A = zeros(256,256);
+A(5:24,13:17) = 1;
+X = fft(A);
+
+//Create a new signal with same size as s
+s1=sin(2*%pi*10*t)+sin(2*%pi*7*t+%pi/4)+5*grand(1,N,'nor',0,1);
+//restore preserved wisdom
+set_fftw_wisdom(wisdom1);
+timer();y=fft(s);t3=timer()
+t3/t2
+
  ]]></programlisting>
   </refsection>
   <refsection role="see also">
     <title>Voir aussi</title>
     <simplelist type="inline">
       <member>
-        <link linkend="fftw">fftw</link>
+        <link linkend="fft">fft</link>
       </member>
       <member>
         <link linkend="get_fftw_wisdom">get_fftw_wisdom</link>
index d4dc669..68ccbca 100644 (file)
@@ -1,11 +1,11 @@
 /*
  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
  * Copyright (C) 2006 - INRIA - Allan CORNET
- * 
+ *
  * This file must be used under the terms of the CeCILL.
  * This source file is licensed as described in the file COPYING, which
  * you should have received as part of this distribution.  The terms
- * are also available at    
+ * are also available at
  * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
  *
  */
 #include "callfftw.h"
 #include "gw_fftw.h"
 #include "stack-c.h"
-/*--------------------------------------------------------------------------*/ 
+/*--------------------------------------------------------------------------*/
 int sci_disposefftwlibrary(char *fname,unsigned long fname_len)
 {
-       static int l1,n1;
+  static int l1,n1;
 
-       n1=1;
-       if ( DisposeFFTWLibrary() )
-       {
-               CreateVar(Rhs+1,MATRIX_OF_BOOLEAN_DATATYPE, &n1,&n1,&l1);
-               *istk(l1)=(int)(TRUE);
-       }
-       else
-       {
-               CreateVar(Rhs+1,MATRIX_OF_BOOLEAN_DATATYPE, &n1,&n1,&l1);
-               *istk(l1)=(int)(FALSE);
-       }
+  n1=1;
+  if ( DisposeFFTWLibrary() )
+    {
+      CreateVar(Rhs+1,MATRIX_OF_BOOLEAN_DATATYPE, &n1,&n1,&l1);
+      *istk(l1)=(int)(TRUE);
+    }
+  else
+    {
+      CreateVar(Rhs+1,MATRIX_OF_BOOLEAN_DATATYPE, &n1,&n1,&l1);
+      *istk(l1)=(int)(FALSE);
+    }
 
-       LhsVar(1)=Rhs+1;
-       PutLhsVar();
+  LhsVar(1)=Rhs+1;
+  PutLhsVar();
 
-       return(0);
+  return(0);
 }
-/*--------------------------------------------------------------------------*/ 
+/*--------------------------------------------------------------------------*/
index 7fc7be3..ce3a663 100644 (file)
  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
  * Copyright (C) 2006/2007 - INRIA - Alan LAYEC
  * Copyright (C) 2007 - INRIA - Allan CORNET
- * 
+ * Copyright (C) 2012 - DIGITEO - Allan CORNET
+ * Copyright (C) 2012 - INRIA - Serge STEER
+ *
  * This file must be used under the terms of the CeCILL.
  * This source file is licensed as described in the file COPYING, which
  * you should have received as part of this distribution.  The terms
- * are also available at    
+ * are also available at
  * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
  *
  */
-
+/*--------------------------------------------------------------------------*/
+#include "stack-c.h"
 #include "fftw_utilities.h"
 #include "callfftw.h"
 #include "MALLOC.h"
 #include "gw_fftw.h"
+#include "api_scilab.h"
 #include "localization.h"
 #include "Scierror.h"
+#include "BOOL.h"
+/*--------------------------------------------------------------------------*/
+enum Scaling {
+  Divide = -1,
+  None = 0,
+  Multiply = 1,
+};
+/*--------------------------------------------------------------------------*/
+extern void C2F(dscal)(int *n,double *da,double *dx,int *incx); /* blas routine */
+extern void C2F(dset)(int *n,double *da,double *dx,int *incx); /* blas routine */
 /*--------------------------------------------------------------------------*/
-extern unsigned cur_fftw_flags;
+static int getArrayOfDouble(void* pvApiCtx, int *piAddr, int *ndims, int **dims, double **Ar, double **Ai);
+static SciErr allocArrayOfDouble(void* _pvCtx, int _iVar, int ndims, int *dims, double **Ar);
+static SciErr allocComplexArrayOfDouble(void* _pvCtx, int _iVar, int ndims, int *dims, double **Ar, double **Ai);
+static SciErr getScalarIntArg(void* _pvCtx, int _iVar, char *fname, int *value);
+static SciErr getVectorIntArg(void* _pvCtx, int _iVar, char *fname, int *pndims, int **pDim);
+static BOOL isHyperMatrixMlist(void* _pvCtx, int *piAddressVar);
+static int sci_fft_gen(char *fname, int ndimsA, int *dimsA, double *Ar,  double *Ai, int isn, int iopt, guru_dim_struct gdim);
+static int sci_fft_2args(char *fname, int ndimsA, int *dimsA, double *Ar,  double *Ai, int isn, int iopt);
+static int sci_fft_3args(char *fname, int ndimsA, int *dimsA, double *Ar,  double *Ai, int isn, int iopt);
+static int sci_fft_4args(char *fname, int ndimsA, int *dimsA, double *Ar,  double *Ai, int isn, int iopt);
 /*--------------------------------------------------------------------------*/
 
+int WITHMKL=0;
 /* fftw function.
-*
-* Scilab Calling sequence :
-*   -->fftw(a,sign,dim,incr);
-*
-* Input : rhs(1) : a scilab double complex or real
-*                  vector (row or column)/matrix
-*
-*         rhs(2) : a scilab double or integer
-*                  scalar (-1 or 1) giving the sign
-*                  in the exponential component
-*
-*         rhs(3) : a scilab double or integer
-*                  vector (row or column) of dimension
-*                  of the Fast Fourier Transform to perform
-*
-*         rhs(4) : a scilab double or integer
-*                  scalar...
-*
-* Output : a scilab double complex or real
-*          vector(row or column)/matrix that
-*          gives the result of the transform.
-*
-*/
-int sci_fftw(char *fname,unsigned long fname_len)
+ *
+ * Scilab Calling sequence :
+ *   fftw(A [,option])
+ *   fftw(A,sign [,option])
+ *   fftw(A,sel,sign [,option])
+ *   fftw(A,sign,dim,incr [,option])
+ *
+ * Input : A : a scilab double complex or real vector, matrix or hypermatrix
+ *
+ *         sign : a scilab double or integer scalar (-1 or 1): the sign
+ *                  in the exponential component
+ *
+ *         sel : a scilab double or integer vector, the selection of dimensions
+
+ *         dim : a scilab double or integer vector: the dimensions
+ *                  of the Fast Fourier Transform to perform
+ *
+ *         incr : a scilab double or integer vector: the increments
+ *                  of the Fast Fourier Transform to perform
+ *
+ * Output : a scilab double complex or real array with same shape as A that
+ *          gives the result of the transform.
+ *
+ */
+                     int sci_fftw(char *fname,unsigned long fname_len)
 {
-  /* declaration of variables to store scilab parameters address */
-  static int lr1 = 0,li1 = 0,it1 = 0,m1 = 0, n1 = 0; /* Rhs(1) */
+  SciErr sciErr;
+  int *piAddr = NULL;
+  char *option = NULL;
+  int iopt = 0; /* automatic r2c or c2r transform use decision */
+  int rhs = Rhs;
+  int iTypeOne = 0;
 
-  static int it2 = 0,m2 = 0,n2 = 0;   /* Rhs(2) */
+  int ndimsA = 0;
+  int *dimsA = NULL;
+  double *Ar = NULL,*Ai = NULL;
 
-  static int it3 = 0,m3 = 0,n3 = 0;           /* Rhs(3) */
-  int mn3 = 0;
+  int isn = FFTW_FORWARD;
+  WITHMKL=withMKL();
+  /****************************************
+   * Basic constraints on rhs arguments  *
+   ****************************************/
 
-  static int it4 = 0,m4 = 0,n4 = 0;           /* Rhs(4) */
-  int mn4 = 0;
+  /* check min/max lhs/rhs arguments of scilab function */
+  CheckRhs(1, 5);
+  CheckLhs(1, 1);
 
-  int *header = NULL;
+  sciErr = getVarAddressFromPosition(pvApiCtx, 1, &piAddr);
+  if(sciErr.iErr) {
+    printError(&sciErr, 0);
+    Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, 1);
+    return 0;
+  }
 
-  double         *ptr_d  = NULL;
-  char           *ptr_c  = NULL;
-  unsigned char  *ptr_uc = NULL;
-  short          *ptr_s  = NULL;
-  unsigned short *ptr_us = NULL;
-  int            *ptr_i  = NULL;
-  unsigned int   *ptr_ui = NULL;
+  sciErr = getVarType(pvApiCtx, piAddr, &iTypeOne);
+  if(sciErr.iErr) {
+    printError(&sciErr, 0);
+    Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, 1);
+    return 0;
+  }
 
-  /* specific declaration for FFTW library variable */
-  fftw_plan p;
-  guru_dim_struct gdim;
+  if ((iTypeOne == sci_list) ||
+      (iTypeOne == sci_tlist)) {
+    OverLoad(1);
+    return 0;
+  }
 
-  /* input/output address for transform variables */
-  double *ri = NULL,*ii = NULL,*ro = NULL,*io = NULL;
-  double *ptr = NULL;
+  if (iTypeOne == sci_mlist) {
+    /* We allow overload for not hypermatrix type */
+    if (!isHyperMatrixMlist(pvApiCtx, piAddr)) {
+      OverLoad(1);
+      return 0;
+    }
+  }
+
+  /* checking if last argument is a potential option argument (character string) */
+  sciErr = getVarAddressFromPosition(pvApiCtx, Rhs, &piAddr);
+  if(sciErr.iErr) {
+    printError(&sciErr, 0);
+    Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, Rhs);
+    return 0;
+  }
+
+  if (isStringType(pvApiCtx, piAddr)) { /*  fftw(...,option); */
+    if(isScalar(pvApiCtx, piAddr)) {
+      if (getAllocatedSingleString(pvApiCtx, piAddr, &option)==0) {
+        if (strcmp("symmetric", option) == 0)  iopt=1; /*user assumes symmetry */
+        else if (strcmp("nonsymmetric", option) == 0) iopt=2; /*user claims full transform */
+        else {
+          Scierror(999,_("%s: Wrong value for input argument #%d: '%s' or '%s' expected.\n"),
+                   fname, Rhs, "\"symmetric\"", "\"nonsymmetric\"");
+          freeAllocatedSingleString(option);
+          option = NULL;
+          return 0;
+        }
+        freeAllocatedSingleString(option);
+        option = NULL;
+        rhs=Rhs-1;
+      }
+      else {
+        Scierror(999,_("%s: Wrong value for input argument #%d: '%s' or '%s' expected.\n"),
+                 fname, Rhs, "\"full\", \"same\"","\"valid\"");
+        return 0;
+      }
+    }
+  }
+
+
+  /********************  Checking if isn is given  ************************************************/
+  if (rhs==1) {  /*only one rhs argument: forward fft*/
+    isn=FFTW_FORWARD;/* default value */
+  }
+  else { /*get isn out of second argument*/
+    sciErr = getScalarIntArg(pvApiCtx, 2,fname, &isn);
+    if(sciErr.iErr) {
+      Scierror(sciErr.iErr, getErrorMessage(sciErr));
+      return 0;
+    }
+    /* check value of second rhs argument */
+    if ((isn !=  FFTW_FORWARD) && (isn !=  FFTW_BACKWARD)) {
+      Scierror(53,_("%s: Wrong value for input argument #%d: %d or %d expected.\n"),
+               fname,2,FFTW_FORWARD,FFTW_BACKWARD);
+      return(0);
+    }
+  }
+
+  /********************  getting the array A      ************************************************/
+  getVarAddressFromPosition(pvApiCtx, 1, &piAddr);
+  if (!getArrayOfDouble(pvApiCtx, piAddr, &ndimsA, &dimsA, &Ar, &Ai)) {
+    Scierror(999,_("%s: Wrong type for argument %d: Array of floating point numbers expected.\n"),
+             fname, 1);
+    return 0;
+  }
+
+
+  /********************  Select proper method     ************************************************/
+  if (rhs<3) {
+    /* fftw(A ,sign [,option])*/
+    sci_fft_2args(fname, ndimsA, dimsA, Ar, Ai,isn,iopt);
+  }
+  else if (rhs==3) {
+    /* fftw(A ,sign ,sel [,option])*/
+    sci_fft_3args(fname, ndimsA, dimsA, Ar, Ai,isn,iopt);
+  }
+  else if (rhs==4) {
+    /* fftw(A ,sign ,dim,incr [option])*/
+    sci_fft_4args(fname, ndimsA, dimsA, Ar, Ai,isn,iopt);
+  }
+
+  return 0;
+}
+
+/*--------------------------------------------------------------------------*/
+int getArrayOfDouble(void* _pvCtx, int *piAddr, int *ndims, int **dims, double **Ar, double **Ai)
+{
+  SciErr sciErr;
+  int *piAddrChild = NULL;
+  int *piOffset = NULL;
+  int *piData = NULL;
+  int nItems = 0;
+  int iRows = 0;
+  int iCols = 0;
+  int iType = 0;
+
+  sciErr = getVarType(_pvCtx, piAddr, &iType);
+  if (iType == sci_matrix) {
+    *ndims=2;
+    *dims=&(piAddr[1]);
+    if(isVarComplex(_pvCtx, piAddr)) {
+      getComplexMatrixOfDouble(_pvCtx, piAddr, &iRows, &iCols, Ar, Ai);
+    }
+    else {
+      getMatrixOfDouble(_pvCtx, piAddr, &iRows, &iCols, Ar);
+      *Ai=NULL;
+    }
+    return 1;
+  }
+  else if(iType == sci_mlist) {
+    sciErr = getListItemNumber(_pvCtx, piAddr, &nItems);
+    if (nItems != 3) return 0;
+    /*Check if first item is ["hm","dims","entries"] */
+    sciErr = getListItemAddress(_pvCtx, piAddr, 1, &piAddrChild);
+    sciErr = getVarType(_pvCtx, piAddrChild, &iType);
+    if (iType != sci_strings) return 0;
+    sciErr = getVarDimension(_pvCtx, piAddrChild, &iRows, &iCols);
+    if (iRows*iCols != 3) return 0;
+    /* Check if first entry of the first item is "hm" */
+    piOffset = piAddrChild+4;
+    if (piOffset[1]-piOffset[0] != 2)  return 0;
+    piData = piOffset + iRows * iCols + 1;
+    if (piData[0]!=17||piData[1]!=22) return 0; /* check "hm" */
+    /* Get second item dims */
+    sciErr = getListItemAddress(_pvCtx, piAddr, 2, &piAddrChild);
+    sciErr = getVarType(_pvCtx, piAddrChild,&iType);
+    if (iType != sci_ints) return 0;
+    sciErr = getMatrixOfInteger32(_pvCtx, piAddrChild, &iRows, &iCols, dims);
+    if(sciErr.iErr)  return 0;
+    *ndims=iRows*iCols;
+    /* Get thirds item entries */
+    sciErr = getListItemAddress(_pvCtx, piAddr, 3, &piAddrChild);
+    sciErr = getVarType(_pvCtx, piAddrChild,&iType);
+    if (iType != sci_matrix) return 0;
+    if(isVarComplex(_pvCtx, piAddrChild)) {
+      getComplexMatrixOfDouble(_pvCtx, piAddrChild, &iRows, &iCols, Ar, Ai);
+    }
+    else {
+      getMatrixOfDouble(_pvCtx, piAddrChild, &iRows, &iCols, Ar);
+      *Ai=NULL;
+    }
+    return 1;
+  }
+  else {
+    return 0;
+  }
+}
+
+SciErr allocComplexArrayOfDouble(void* _pvCtx, int _iVar, int ndims, int *dims, double **Ar, double **Ai)
+{
+  SciErr sciErr;
+  int *piAddr= NULL;
+
+  if (ndims==2) {
+    sciErr = allocComplexMatrixOfDouble( _pvCtx,_iVar, dims[0], dims[1], Ar,Ai);
+    if (sciErr.iErr) return sciErr;
+  }
+  else {
+    int i = 0;
+    int n = 1;
+    const char * hmType[]={"hm","dims","entries"};
+
+    for (i=0;i<ndims;i++)   n *= dims[i];
+
+    sciErr = createMList(_pvCtx, _iVar, 3, &piAddr);
+    if (sciErr.iErr) return sciErr;
+
+    sciErr = createMatrixOfStringInList(_pvCtx, _iVar, piAddr, 1, 1, 3, hmType);
+    if (sciErr.iErr) return sciErr;
+    sciErr = createMatrixOfInteger32InList(_pvCtx, _iVar, piAddr, 2, 1, ndims, dims);
+    if (sciErr.iErr) return sciErr;
+
+    sciErr = allocComplexMatrixOfDoubleInList(_pvCtx, _iVar, piAddr, 3, n, 1, Ar, Ai);
+    if (sciErr.iErr) return sciErr;
+  }
+  return sciErr;
+}
+
+SciErr allocArrayOfDouble(void* _pvCtx, int _iVar,  int ndims, int *dims, double **Ar)
+{
+  SciErr sciErr;
+  int *piAddr      = NULL;
+
+
+  if (ndims==2) {
+    sciErr = allocMatrixOfDouble( _pvCtx,_iVar, dims[0], dims[1], Ar);
+    if (sciErr.iErr) return sciErr;
+  }
+  else {
+    int i = 0;
+    int n = 1;
+    const char * hmType[]={"hm","dims","entries"};
+
+    for (i=0;i<ndims;i++) n *= dims[i];
 
-  /* local counter variable */
-  int i = 0,j = 0,k = 0;
+    sciErr = createMList(_pvCtx,  _iVar, 3, &piAddr);
+    if (sciErr.iErr) return sciErr;
+    sciErr = createMatrixOfStringInList(_pvCtx, _iVar, piAddr, 1, 1, 3, hmType);
+    if (sciErr.iErr) return sciErr;
+    sciErr = createMatrixOfInteger32InList(_pvCtx, _iVar, piAddr, 2, 1, ndims, dims);
+    if (sciErr.iErr) return sciErr;
+
+    sciErr = allocMatrixOfDoubleInList(_pvCtx, _iVar, piAddr, 3, n, 1, Ar);
+    if (sciErr.iErr) return sciErr;
+  }
+  return sciErr;
+}
+
+SciErr getScalarIntArg(void* _pvCtx, int _iVar, char *fname, int *value)
+{
+  SciErr sciErr;
+  int *piAddr = NULL;
+  int iType = 0;
+  int iPrec = 0;
+  double t_d=0.0;
+  char t_c=0;
+  unsigned char t_uc=0;
+  short t_s=0;
+  unsigned short t_us=0;
+  int t_i=0;
+  unsigned int  t_ui=0;
+  sciErr.iErr = 0; sciErr.iMsgCount = 0;
+
+  sciErr = getVarAddressFromPosition(_pvCtx, _iVar, &piAddr);
+  if(sciErr.iErr) {
+    addErrorMessage(&sciErr,API_ERROR_GET_STRING,  _("%s: Can not read input argument #%d.\n"),fname,_iVar);
+    return sciErr;
+  }
+
+  //check type
+  sciErr = getVarType(_pvCtx, piAddr, &iType);
+  if(sciErr.iErr) {
+    addErrorMessage(&sciErr,API_ERROR_GET_INT,  _("%s: Can not read input argument #%d.\n"),fname,_iVar);
+    return sciErr;
+  }
+
+  if(!isScalar(_pvCtx, piAddr)) {
+    addErrorMessage(&sciErr,API_ERROR_GET_INT, _("%s: Wrong size for input argument #%d: A scalar expected.\n"), fname, _iVar);
+    return sciErr;
+  }
+
+  if(iType == sci_matrix) {
+    getScalarDouble(_pvCtx, piAddr, &t_d);
+    *value=(int)t_d;
+  }
+  else if (iType == sci_ints) {
+    sciErr = getMatrixOfIntegerPrecision(_pvCtx, piAddr, &iPrec);
+    if(sciErr.iErr) {
+      addErrorMessage(&sciErr,API_ERROR_GET_INT,_("%s: Can not read input argument #%d.\n"), fname, _iVar);
+      return sciErr;
+    }
+
+    switch(iPrec) {
+    case SCI_INT8 : {
+      getScalarInteger8(_pvCtx, piAddr, &t_c);
+      *value= (int)t_c;
+    }
+    case SCI_INT16 : {
+      getScalarInteger16(_pvCtx, piAddr, &t_s);
+      *value= (int)t_s;
+    }
+    case SCI_INT32 : {
+      getScalarInteger32(_pvCtx, piAddr, &t_i);
+      *value= (int)t_i;
+    }
+    case SCI_UINT8 : {
+      getScalarUnsignedInteger8(_pvCtx, piAddr, &t_uc);
+      *value= (int)t_uc;
+    }
+    case SCI_UINT16 : {
+      getScalarUnsignedInteger16(_pvCtx, piAddr, &t_us);
+      *value= (int)t_us;
+    }
+    case SCI_UINT32 : {
+      getScalarUnsignedInteger32(_pvCtx, piAddr, &t_ui);
+      *value= (int)t_ui;
+    }
+    }
+  }
+  else {
+    addErrorMessage(&sciErr,API_ERROR_GET_INT,
+                    _("%s: Wrong type for argument %d: An integer or a floating point number expected.\n"),
+                    fname, _iVar);
+    return sciErr;
+  }
+  return sciErr;
+}
+
+SciErr getVectorIntArg(void* _pvCtx, int _iVar, char *fname,int *pndims, int **pDim)
+{
+  SciErr sciErr;
+  int *piAddr = NULL;
+  int iType = 0;
+  int iPrec = 0;
+  int mDim = 0;
+  int nDim = 0;
+  int *Dim=NULL;
+  int ndims=0;
+
+  double* p_d=NULL;
+  char* p_c=NULL;
+  unsigned char* p_uc=NULL;
+  short* p_s=NULL;
+  unsigned short* p_us=NULL;
+  int* p_i=NULL;
+  unsigned int*  p_ui=NULL;
+  int i = 0;
+
+  sciErr.iErr = 0; sciErr.iMsgCount = 0;
+
+  getVarAddressFromPosition(_pvCtx, _iVar, &piAddr);
+
+  //check type
+  getVarType(_pvCtx, piAddr, &iType);
+
+  if (isVarMatrixType(_pvCtx, piAddr) == 0) {
+    addErrorMessage(&sciErr,API_ERROR_GET_INT, _("%s: Wrong type for input argument #%d.\n"), fname, _iVar);
+    return sciErr;
+  }
+
+  getVarDimension(_pvCtx, piAddr, &mDim, &nDim);
+
+  ndims = mDim * nDim;
+  *pndims=ndims;
+  if (ndims <= 0) {
+    addErrorMessage(&sciErr,API_ERROR_GET_INT,
+                    _("%s: Wrong size for input argument #%d.\n"), fname, _iVar);
+    return sciErr;
+  }
+  if ((Dim=(int *)MALLOC(ndims*sizeof(int)))==NULL) {
+    addErrorMessage(&sciErr,API_ERROR_GET_INT,
+                    _("%s: Cannot allocate more memory.\n"), fname);
+    return sciErr;
+  }
+  *pDim=Dim;
+  if(iType == sci_matrix) {
+    sciErr = getMatrixOfDouble(_pvCtx, piAddr, &mDim, &nDim, &p_d);
+    for (i=0;i<ndims;i++)  Dim[i] = (int)(p_d[i]);
+  }
+  else if (iType == sci_ints) {
+    getMatrixOfIntegerPrecision(_pvCtx, piAddr, &iPrec);
+    switch(iPrec) {
+    case SCI_INT8 :
+      getMatrixOfInteger8(_pvCtx, piAddr, &mDim, &nDim, &p_c);
+      for (i=0;i<ndims;i++) Dim[i]  = (int)(p_c[i]);
+      break;
+    case SCI_INT16 :
+      getMatrixOfInteger16(_pvCtx, piAddr, &mDim, &nDim, &p_s);
+      for (i=0;i<ndims;i++) Dim[i]  = (int)(p_s[i]);
+      break;
+    case SCI_INT32 :
+      getMatrixOfInteger32(_pvCtx, piAddr, &mDim, &nDim, &p_i);
+      for (i=0;i<ndims;i++)  Dim[i]  = (int)(p_i[i]);
+      break;
+    case SCI_UINT8 :
+      getMatrixOfUnsignedInteger8(_pvCtx, piAddr, &mDim, &nDim, &p_uc);
+      for (i=0;i<ndims;i++) Dim[i]  = (int)(p_uc[i]);
+      break;
+    case SCI_UINT16 :
+      getMatrixOfUnsignedInteger16(_pvCtx, piAddr, &mDim, &nDim, &p_us);
+      for (i=0;i<ndims;i++) Dim[i]  = (int) p_us[i];
+      break;
+    case SCI_UINT32 :
+      getMatrixOfUnsignedInteger32(_pvCtx, piAddr, &mDim, &nDim, &p_ui);
+      for (i=0;i<ndims;i++) Dim[i]  = (int)(p_ui[i]);
+      break;
+    }
+  }
+  else {
+    FREE(Dim);
+    Dim=NULL;
+    addErrorMessage(&sciErr,API_ERROR_GET_INT,
+                    _("%s: Wrong type for argument %d: An array of floating point or integer numbers expected.\n"), fname, _iVar);
+    return sciErr;
+  }
+  return sciErr;
+}
+
+int sci_fft_2args(char *fname, int ndimsA, int *dimsA, double *Ar,  double *Ai, int isn, int iopt)
+{
+  /*FFTW specific library variable */
+  guru_dim_struct gdim={0,NULL,0,NULL};
 
   /* local variable */
-  int isn = 0,vect = 0;
-  int *n = NULL,*nspn = NULL;
-  int n_and_nspn_allocated = FALSE;
-  double zero=0.0;
-  int iType1 = -1;
+  int ndims = 0; /* number of non singleton dimensions */
+  int first_nonsingleton = -1;
+  int i = 0,j = 0;
+  int prd = 1;
 
-  /****************************************
-   * Basic constraints on rhs arguments  *
-   ****************************************/
+  /* ignore singleton dimensions */
+  first_nonsingleton = -1;
+  ndims = 0;
+  for (i=0;i<ndimsA;i++) {
+    if (dimsA[i]>1) {
+      ndims++;
+      if (first_nonsingleton<0) first_nonsingleton = i;
+    }
+  }
 
-  /* check min/max lhs/rhs arguments of scilab funcion */
-  CheckRhs(1,4);
-  CheckLhs(1,1);
+  /* void or scalar input gives void output or scalar*/
+  if (ndims ==0 ) {
+    LhsVar(1) =  1;
+    PutLhsVar();
+    return(0);
+  }
 
-  iType1 = VarType(1);
+  gdim.rank=ndims;
+  if ((gdim.dims=(fftw_iodim *)MALLOC(sizeof(fftw_iodim)*gdim.rank))==NULL) {
+    Scierror(999,_("%s: Cannot allocate more memory.\n"),fname);
+    goto ERR;
+  }
 
-  if ((iType1 == sci_list) ||
-      (iType1 == sci_tlist) ||
-      (iType1 == sci_mlist))
-  {
-      OverLoad(1);
-      return 0;
+  j = 0;
+  prd = 1;
+  for (i=(first_nonsingleton);i<ndimsA;i++) {
+    if (dimsA[i]>1) {
+      gdim.dims[j].n = dimsA[i];
+      gdim.dims[j].is = prd;
+      gdim.dims[j].os = prd;
+      prd *= dimsA[i];
+      j++;
+    }
   }
+  gdim.howmany_rank=0;
+  gdim.howmany_dims=NULL;
 
-  /* 3 rhs not allowed */
-  if (Rhs == 3) 
-    {
-      Scierror(39,_("%s: Wrong number of input arguments: %d not expected.\n"),fname,3);
-      return(0);
+
+  if (!sci_fft_gen(fname, ndimsA, dimsA,  Ar,  Ai, isn,iopt,gdim))  goto ERR;
+
+
+  /***********************************
+   * Return results in lhs argument *
+   ***********************************/
+
+  PutLhsVar();
+ ERR:
+  FREE(gdim.dims);
+  FREE(gdim.howmany_dims);
+  return(0);
+}
+
+
+int  sci_fft_3args(char *fname, int ndimsA, int *dimsA, double *Ar,  double *Ai, int isn, int iopt)
+{
+  /* API variables */
+  SciErr sciErr;
+  int *piAddr = NULL;
+
+  int *Sel=NULL;
+  int rank=0;
+
+  /*FFTW specific library variable */
+  guru_dim_struct gdim={0,NULL,0,NULL};
+   /* local variable */
+  int ndims = 0;
+  int first_nonsingleton = -1;
+  int ih = 0;
+  int pd = 1; /* used to store prod(Dims(1:sel(k-1)))*/
+  int pds = 1; /* used to store prod(Dims(sel(k-1):sel(k)))*/
+  int i = 0,j = 0;
+
+  /* ignore singleton dimensions */
+  first_nonsingleton = -1;
+  ndims = 0;
+  for (i=0;i<ndimsA;i++) {
+    if (dimsA[i]>1) {
+      ndims++;
+      if (first_nonsingleton<0) first_nonsingleton = i;
     }
+  }
 
-  /* retrieve address of input variable to transform */
-  GetRhsCVar(1,MATRIX_OF_DOUBLE_DATATYPE, &it1, &m1, &n1, &lr1, &li1);
+  /* void or scalar input gives void output or scalar*/
+  if (ndims ==0 ) {
+    LhsVar(1) =  1;
+    PutLhsVar();
+    return(0);
+  }
 
-  /* void input gives void output */
-  if ((m1<1)|(n1<1)) 
-    {
-      LhsVar(1) =  1;
-      PutLhsVar();
-      return(0);
+
+  /******************** get and check third argument (sel) ****************************************/
+  getVarAddressFromPosition(pvApiCtx, 3, &piAddr);
+  if (isVarMatrixType(pvApiCtx, piAddr) == 0) {
+    Scierror(999, _("%s: Wrong type for input argument #%d.\n"), fname, 3);
+    goto ERR;
+  }
+  sciErr = getVectorIntArg(pvApiCtx, 3,fname, &rank,&Sel);
+  if(sciErr.iErr) {
+    Scierror(sciErr.iErr, getErrorMessage(sciErr));
+    goto ERR;
+  }
+  /* size of Sel must be less than ndimsA */
+  if (rank<=0||rank>=ndimsA) {
+    Scierror(999,_("%s: Wrong size for input argument #%d: Must be between %d and %d.\n"),fname,3,1,ndimsA-1);
+    goto ERR;
+  }
+  /* check values of Sel[i] */
+  for (i=0;i<rank;i++) {
+    if (Sel[i]<=0) {
+      Scierror(999,_("%s: Wrong values for input argument #%d:Positive integers expected.\n"),fname,3);
+      goto ERR;
     }
+    if (Sel[i]>ndimsA) {
+      Scierror(999,_("%s: Wrong values for input argument #%d: Elements must be less than %d.\n"),fname,3,ndimsA);
+      goto ERR;
+    }
+    if (i>0&&Sel[i]<=Sel[i-1]) {
+      Scierror(999,_("%s: Wrong values for input argument #%d: Elements must be in increasing order.\n"),fname,3);
+      goto ERR;
+    }
+  }
+
+  /* Create  gdim struct */
+  gdim.rank=rank;
+  if ((gdim.dims=(fftw_iodim *)MALLOC(sizeof(fftw_iodim)*gdim.rank))==NULL) {
+    Scierror(999,_("%s: Cannot allocate more memory.\n"),fname);
+    goto ERR;
+  }
+
+  pd = 1; /* used to store prod(Dims(1:sel(k-1)))*/
+  pds = 1; /* used to store prod(Dims(sel(k-1):sel(k)))*/
+  j = 0;
+  for (i=0;i<ndimsA;i++) {
+    if (j>=gdim.rank) break;
+    if (Sel[j]==i+1) {
+      gdim.dims[j].n = dimsA[i];
+      gdim.dims[j].is = pd;
+      gdim.dims[j].os = pd;
+      j++;
+    }
+    pd *= dimsA[i];
+  }
+  /* Compute howmany_rank based on jumps in the Sel sequence */
+  gdim.howmany_rank=0;
+  if ((Sel[0]!=1)&&(Sel[0]!=ndimsA)) gdim.howmany_rank++;
+
+  for (i=1;i<=rank-1;i++)
+    if (Sel[i] != Sel[i-1]+1) gdim.howmany_rank++;
+
+  if ((Sel[rank-1] != ndimsA)||(rank==1)) gdim.howmany_rank++;
 
-  /******************************************
-   * Advanced constraints on rhs arguments *
-   * Get value of rhs arguments            *
-   ******************************************/
-
-  /*only one rhs argument*/
-  /*forward fft*/
-  if (Rhs==1) 
-    {
-      /* sign of the exp. component */
-      isn=-1;
-    }
-  /* two or four rhs arguments case */
-  else 
-    {
-      /* Get dim/type of Rhs(2) */
-      header = GetData(2);
-      m2  = header[1];
-      n2  = header[2];
-      it2 = header[3];
-      
-      /* */
-      CheckDims(2,m2,n2,1,1);
-      
-      /* look at for type of Rhs(2) */
-      if (VarType(2)==sci_ints) { /* int */
-       /* */
-       switch (it2) /* Types defines in stack-c.h */
-         {
-         case I_CHAR   : ptr_c=IC_CHAR(&header[4]);
-           isn=(int) ptr_c[0];
-           break;
-         case I_INT16  : ptr_s=IC_INT16(&header[4]);
-           isn=(int) ptr_s[0];
-           break;
-         case I_INT32  : ptr_i=IC_INT32(&header[4]);
-           isn=(int) ptr_i[0];
-           break;
-         case I_UCHAR  : ptr_uc=IC_UCHAR(&header[4]);
-           isn=(int) ptr_uc[0];
-           break;
-         case I_UINT16 : ptr_us=IC_UINT16(&header[4]);
-           isn=(int) ptr_us[0];
-           break;
-         case I_UINT32 : ptr_ui=IC_UINT32(&header[4]);
-           isn=(int) ptr_ui[0];
-           break;
-         }
+  /* Fill the howmany_dims struct */
+  if (gdim.howmany_rank>0) {
+    /* it must be the case */
+    if ((gdim.howmany_dims=(fftw_iodim *)MALLOC(gdim.howmany_rank*sizeof(fftw_iodim)))==NULL) {
+      Scierror(999,_("%s: Cannot allocate more memory.\n"),fname);
+      goto ERR;
+    }
+    pd = 1;
+    for (j=1;j<=(Sel[0]-1);j++) pd *=dimsA[j-1];/*prod(Dims(1:(sel(1)-1)))*/
+    ih = 0;
+    if ((Sel[0]!=1)&&(Sel[0]!=ndimsA)) {
+      /* First seleted dimension */
+      gdim.howmany_dims[ih].is = 1;
+      gdim.howmany_dims[ih].os = 1;
+      gdim.howmany_dims[ih].n = pd;
+      ih++;
+    }
+    pd *= dimsA[Sel[0]-1];/*prod(Dims(1:sel(1)))*/
+    for (i=2;i<=rank;i++) {
+      /* intermediate selected dimensions */
+      if (Sel[i-1]!=Sel[i-2]+1) {
+        pds = 1;
+        for (j=(Sel[i-2]+1);j<=(Sel[i-1]-1);j++) pds *= dimsA[j-1]; /*prod(Dims(sel(i-1)+1:(sel(i)-1)))*/
+        gdim.howmany_dims[ih].is = pd;
+        gdim.howmany_dims[ih].os = pd;
+        gdim.howmany_dims[ih].n = pds;
+        ih++;
       }
-      else if (VarType(2)==sci_matrix)
-       { /* double */
-         ptr_d=(double *)(&header[4]);
-         isn=(int)ptr_d[0];
-       }
-      /* if is not int/double then error message */
-      else 
-       {
-         Scierror(53,_("%s: Wrong type for input argument #%d: A Real or Complex expected.\n"),fname,2);
-         return(0);
-       }
-      
-      /* check value of second rhs argument */
-      if ((isn!=1)&&(isn!=-1)) 
-       {
-         Scierror(53,_("%s: Wrong values for input argument #%d.\n"), fname,2);
-         return(0);
-       }
-      
-      /* four rhs arguments */
-      if (Rhs==4) 
-       {
-         /* Get dim/type of Rhs(3) */
-         header = GetData(3);
-         m3  = header[1];
-         n3  = header[2];
-         it3 = header[3];
-         
-         /* look at for type of Rhs(3) */
-         if ((VarType(3)!=sci_ints)&&(VarType(3)!=sci_matrix)) 
-           {
-             Scierror(53,_("%s: Wrong type for input argument #%d: N-dimensional array expected.\n"),fname,3);
-             return(0);
-           }
-         
-         /* */
-         mn3=m3*n3;
-         
-         /* check dims */
-         if (m3*n3==0) 
-           {
-             Scierror(999,_("%s: Wrong size for input argument #%d.\n"),fname,3);
-             return(0);
-           }
-         
-         /* Get dim/type of Rhs(4) */
-         header = GetData(4);
-         m4  = header[1];
-         n4  = header[2];
-         it4 = header[3];
-         
-         /* look at for type of Rhs(4) */
-         if ((VarType(4)!=sci_ints)&&(VarType(4)!=sci_matrix)) 
-           { 
-             /* int */
-             Scierror(53,_("%s: Wrong type for input argument #%d: int matrix expected.\n"),fname,3);
-             return(0);
-           }
-         
-         /* */
-         mn4=m4*n4;
-         
-         /* check dims */
-         if (m4*n4 == 0) 
-           {
-             Scierror(999,_("%s: Wrong size for input argument #%d.\n"), fname,4);
-             return(0);
-           }
-         
-         /* cross variable size checking */
-         if (mn4 != mn3) 
-           {
-             Scierror(999,_("%s: Incompatible input arguments '#%d and '#%d': Same sizes expected.\n"),fname,3,4);
-             return(0);
-           }
-         
-         /* alloc n/nspn with MALLOC */
-         if ((n=(int *)MALLOC(mn4*sizeof(int)))==NULL) 
-           {
-             Scierror(999,_("%s: No more memory.\n"),fname);
-             return(0);
-           }
-         
-         if ((nspn=(int *)MALLOC(mn4*sizeof(int)))==NULL) 
-           {
-             Scierror(999,_("%s: No more memory.\n"),fname);
-             FREE(n);
-             return(0);
-           }
-         else
-           {
-             n_and_nspn_allocated = TRUE;
-           }
-
-         /* n    <- Rhs(3) */
-         /* nspn <- Rhs(4) */
-         /* check values   */
-         for (i=0;i<mn3;i++) 
-           {
-             /* Rhs(3) */
-             header = GetData(3);
-             
-             switch (VarType(3))
-               {
-                 /* double */
-               case 1 :
-                 {
-                   ptr_d=(double *)(&header[4]);
-                   n[i]=(int)ptr_d[i];
-                   break;
-                 }
-                 /* int */
-               case 8 :
-                 {
-                   switch (it3)
-                     {
-                     case I_CHAR:
-                       ptr_c = IC_CHAR(&header[4]);
-                       n[i]  = (int) ptr_c[i];
-                       break;
-                       
-                     case I_INT16:
-                       ptr_s = IC_INT16(&header[4]);
-                       n[i]  = (int) ptr_s[i];
-                       break;
-                       
-                     case I_INT32:
-                       ptr_i = IC_INT32(&header[4]);
-                       n[i]  = (int) ptr_i[i];
-                       break;
-                       
-                     case I_UCHAR:
-                       ptr_uc = IC_UCHAR(&header[4]);
-                       n[i]   = (int) ptr_uc[i];
-                       break;
-                       
-                     case I_UINT16:
-                       ptr_us = IC_UINT16(&header[4]);
-                       n[i]   = (int) ptr_us[i];
-                       break;
-                       
-                     case I_UINT32: 
-                       ptr_ui = IC_UINT32(&header[4]);
-                       n[i]   = (int) ptr_ui[i];
-                       break;
-                     }
-                   break;
-                 }
-               }
-             /* check value of n[i] */
-             if (n[i]<=0) 
-               {
-                 Scierror(999,_("%s: Wrong values for input argument #%d: Non-negative integers expected.\n"),fname,3);
-                 if (n_and_nspn_allocated)
-                   {
-                     FREE(n);FREE(nspn);
-                   }
-                 return(0);
-                 break;
-               }
-             
-             /* Rhs(4) */
-             header = GetData(4);
-             
-             switch (VarType(4))
-               {
-                 /* double */
-               case 1:
-                 {
-                   ptr_d   = (double *)(&header[4]);
-                   nspn[i] = (int)ptr_d[i];
-                   break;
-                 }
-                 /* int */
-               case 8:
-                 {
-                   switch (it4)
-                     {
-                     case I_CHAR:
-                       ptr_c   = IC_CHAR(&header[4]);
-                       nspn[i] = (int) ptr_c[i];
-                       break;
-                     case I_INT16:
-                       ptr_s   = IC_INT16(&header[4]);
-                       nspn[i] = (int) ptr_s[i];
-                       break;
-                     case I_INT32:
-                       ptr_i   = IC_INT32(&header[4]);
-                       nspn[i] = (int) ptr_i[i];
-                       break;
-                     case I_UCHAR:
-                       ptr_uc  = IC_UCHAR(&header[4]);
-                       nspn[i] = (int) ptr_uc[i];
-                       break;
-                     case I_UINT16: 
-                       ptr_us  = IC_UINT16(&header[4]);
-                       nspn[i] = (int) ptr_us[i];
-                       break;
-                     case I_UINT32:
-                       ptr_ui  = IC_UINT32(&header[4]);
-                       nspn[i] = (int) ptr_ui[i];
-                       break;
-                     }
-                   break;
-                 }
-               }
-             /* check value of nspn[i] */
-             if (nspn[i]<=0) 
-               {
-                 Scierror(999,_("%s: Wrong values for input argument #%d: Non-negative integers expected.\n"),fname,4);
-                 if (n_and_nspn_allocated)
-                   {
-                     FREE(n);
-                     FREE(nspn);
-                   }
-                 return(0);
-                 break;
-               }
-           }
-       }
-    }
-  
-  /*********************************************
-   * Set address of input/ouput array for fftw *
-   *********************************************/
-  
-  if (it1==1) /* complex data */
-    {
-      /* set input array address */
-      ri=stk(lr1);
-      ii=stk(li1);
-    }
-  else if (it1==0) /* real data */
-    {
-      /* set input array address */
-      CreateCVar(1,MATRIX_OF_DOUBLE_DATATYPE, (i=1,&i), &m1, &n1, &lr1,&li1);
-      
-      ri=stk(lr1);
-      ii=stk(li1);
-      
-      /* set all elements of imaginary parts to 0 */
-      C2F(dset)((i=m1*n1,&i), &zero, ii, (k=1,&k));
-    }
-
-  /* set output array address */
-  ro=ri;
-  io=ii;
-  
-  /* reverse address of input/output array
-   * if it is a backward fft
-   */
-  if (isn==1) 
-    {
-      /* reverse input */
-      ptr=ri;
-      ri=ii;
-      ii=ptr;
-      
-      /* reverse output */
-      ptr=ro;
-      ro=io;
-      io=ptr;
-    }
-  
-  /**********************************
-   * Set arguments needed for fftw *
-   **********************************/
-  
-  /* check if it is one column or row vector */
-  vect = 0;
-  if ((m1==1)|(n1==1)) vect = 1;
-  
-  /* vector transform */
-  if ((vect)&&(Rhs<=2)) 
-    {
-      /* set arguments of fftw_plan_guru_split_dft */
-      gdim.rank=1;
-      if ((gdim.dims=(fftw_iodim *)MALLOC(sizeof(fftw_iodim)))==NULL) 
-       {
-         Scierror(999,_("%s: No more memory.\n"),fname);
-         if (n_and_nspn_allocated)
-           {
-             FREE(n);
-             FREE(nspn);
-           }
-         return(0);
-       }
-      
-      gdim.dims[0].n = m1*n1;
-      gdim.dims[0].is = 1;
-      gdim.dims[0].os = 1;
-      
-      gdim.howmany_rank=0;
-      gdim.howmany_dims=NULL;
-    }
-  else
-    {
-      /* 2D fft */
-      if (Rhs<=2) 
-       {
-         /* set arguments of fftw_plan_guru_split_dft */
-         gdim.rank=2;
-         if ((gdim.dims=(fftw_iodim *)MALLOC(sizeof(fftw_iodim)*gdim.rank))==NULL) 
-           {
-             Scierror(999,_("%s: No more memory.\n"), fname);
-             if (n_and_nspn_allocated)
-               {
-                 FREE(n);
-                 FREE(nspn);
-               }
-             return(0);
-           }
-         
-         gdim.dims[0].n = m1;
-         gdim.dims[0].is = 1;
-         gdim.dims[0].os = 1;
-
-         gdim.dims[1].n = n1;
-         gdim.dims[1].is = m1;
-         gdim.dims[1].os = m1;
-         
-         gdim.howmany_rank=0;
-         gdim.howmany_dims=NULL;
-       }
-      /* multidimensional fft */
-      else if (Rhs==4) 
-       {
-         /* size 1x1 for Rhs(3)/Rhs(4) */
-         if (mn3==1) 
-           {
-             /* **This is a special case**
-              * all is made in the following block.
-              * compatibility with scilab fft function.
-              */
-             
-             /* set arguments of fftw_plan_guru_split_dft */
-             gdim.rank = 1;
-             if ((gdim.dims=(fftw_iodim *)MALLOC(sizeof(fftw_iodim)))==NULL) 
-               {
-                 Scierror(999,_("%s: No more memory.\n"),fname);
-                 if (n_and_nspn_allocated)
-                   {
-                     FREE(n);
-                     FREE(nspn);
-                   }
-                 return(0);
-               }
-             
-             gdim.dims[0].n = n[0];
-             gdim.dims[0].is = nspn[0];
-             gdim.dims[0].os = nspn[0];
-             
-             gdim.howmany_rank = 1;
-             if ((gdim.howmany_dims=(fftw_iodim *)MALLOC(sizeof(fftw_iodim)))==NULL) 
-               {
-                 Scierror(999,_("%s: No more memory.\n"), fname);
-                 if (n_and_nspn_allocated)
-                   {
-                     FREE(n);
-                     FREE(nspn);
-                   }
-                 return(0);
-               }
-             
-             /* find number of transforms to compute */
-             gdim.howmany_dims[0].n = 0;
-             j = (n[0]-1)*nspn[0];
-
-             while(j<((m1*n1)-(nspn[0]-1))) 
-               {
-                 gdim.howmany_dims[0].n++;
-                 j += nspn[0]*n[0];
-               }
-
-             if (j<=((m1*n1)-(nspn[0]-1)))
-               k = j+nspn[0];
-             else
-               k = j-nspn[0]*n[0]+nspn[0];
-             
-             gdim.howmany_dims[0].is = n[0]*nspn[0];
-             gdim.howmany_dims[0].os = n[0]*nspn[0];
-             
-             if ((p = GetFFTWPlan(&gdim,
-                                  ri, ii, ro, io,
-                                  cur_fftw_flags,isn)) == NULL)
-               {
-                 Scierror(999,_("%s: No more memory.\n"), fname);
-                 FREE(gdim.dims);
-                 FREE(gdim.howmany_dims);
-                 if (n_and_nspn_allocated)
-                   {
-                     FREE(n);
-                     FREE(nspn);
-                   }
-                 return(0);
-               }
-             else 
-               {
-                 if (isn==1) 
-                   { /* backward */
-                     double ak;
-                     
-                     ak=1/((double)(n[0]));
-                     
-                     /* must find a BLAS/calelm function to do that */
-                     for(i=0;i<k;i++) 
-                       {
-                         ri[i]=ri[i]*ak;
-                         ii[i]=ii[i]*ak;
-                       }
-                   }
-                 
-                 /* */
-                 for(i=0;i<nspn[0];i++)
-                   call_fftw_execute_split_dft(p,&ri[i],&ii[i],&ro[i],&io[i]);
-                 
-                 /* */
-                 FREE(gdim.dims);
-                 FREE(gdim.howmany_dims);
-                 if (n_and_nspn_allocated)
-                   {
-                     FREE(n);
-                     FREE(nspn);
-                   }
-                 
-                 LhsVar(1) = 1;
-                 PutLhsVar();
-                 
-                 return(0);
-               }
-           }
-         else /* size mxn Rhs(3)/Rhs(4)  */
-           {
-             /* set arguments of fftw_plan_guru_split_dft */
-             gdim.rank=mn3;
-             if ((gdim.dims=(fftw_iodim *)MALLOC(sizeof(fftw_iodim)*gdim.rank))==NULL) 
-               {
-                 Scierror(999,_("%s: No more memory.\n"),fname);
-                 if (n_and_nspn_allocated)
-                   {
-                     FREE(n);
-                     FREE(nspn);
-                   }
-                 return(0);
-               }
-             
-             /* */
-             for(j=0;j<gdim.rank;j++) 
-               {
-                 gdim.dims[j].n = n[j];
-                 gdim.dims[j].is = nspn[j];
-                 gdim.dims[j].os = nspn[j];
-               }
-             
-             gdim.howmany_rank=0;
-             gdim.howmany_dims=NULL;
-           }
-       }
-    }
-
-  /*****************
-   * Get fftw plan *
-   *****************/
-  
-  /* call GetFFTWPlan */
-  if ((p = GetFFTWPlan(&gdim,
-                       ri, ii, ro, io,
-                       cur_fftw_flags,isn)) == NULL) 
-    {
-      Scierror(999,_("%s: No more memory.\n"),fname);
-      FREE(gdim.dims);
-      FREE(gdim.howmany_dims);
-      if (n_and_nspn_allocated)
-       {
-         FREE(n);
-         FREE(nspn);
-       }
-      return(0);
+      pd *= pds*dimsA[Sel[i-1]-1]; /*prod(Dims(1:sel(i)))*/
+    }
+
+    if (Sel[rank-1]!=ndimsA) {
+      /* last selected dimension*/
+      pds = 1;
+      for (j=(Sel[rank-1]+1);j<=ndimsA;j++) pds *= dimsA[j-1]; /*prod(Dims(sel(i-1)+1:(sel(i)-1)))*/
+      gdim.howmany_dims[ih].is = pd;
+      gdim.howmany_dims[ih].os = pd;
+      gdim.howmany_dims[ih].n = pds;
+      ih++;
     }
-  
-  /* */
+    else if (rank==1) {
+      /* the only selected dimension is the last one */
+      gdim.howmany_dims[ih].is = 1;
+      gdim.howmany_dims[ih].os = 1;
+      gdim.howmany_dims[ih].n = pd/dimsA[Sel[0]-1];
+      ih++;
+    }
+  }
+
+  if (!sci_fft_gen(fname, ndimsA, dimsA, Ar,  Ai, isn,iopt,gdim))  goto ERR;
+  /***********************************
+   * Return results in lhs argument *
+   ***********************************/
+
+  PutLhsVar();
+ ERR:
   FREE(gdim.dims);
   FREE(gdim.howmany_dims);
-  
-  /***************
-   * Compute fft *
-   ***************/
-  
-  if (isn==1)
-    { /* backward */
-      /* */
-      double ak;
-      
-      if (Rhs==4) 
-       {
-         ak = 1;
-         for(i=0;i<mn3;i++) ak=ak*1/((double)(n[i]));
-         if (n_and_nspn_allocated)
-           {
-             FREE(n);
-             FREE(nspn);
-             n_and_nspn_allocated = FALSE;
-           }
-       }
-      else 
-       {
-         ak = 1/((double)(m1*n1));
-       }
-      
-      /* must find a BLAS/calelm function to do that */
-      for(i=0;i<m1*n1;i++) 
-       {
-         ri[i]=ri[i]*ak;
-         ii[i]=ii[i]*ak;
-       }
-    }
-  
-  /* execute FFTW plan */
-  call_fftw_execute_split_dft(p,ri,ii,ro,io);
+  return(0);
+}
+
+int sci_fft_4args(char *fname, int ndimsA, int *dimsA, double *Ar,  double *Ai, int isn, int iopt)
+{
+  /* API variables */
+  SciErr sciErr;
+  int *piAddr = NULL;
+
+  /* Input  array variables */
+  int *Dim1 = NULL;
+  int ndims = 0;
+  int *Incr = NULL;
+  int nincr = 0;
+
+  /*FFTW specific library variable */
+  guru_dim_struct gdim={0,NULL,0,NULL};
+  /* input/output address for transform variables */
 
-  if (n_and_nspn_allocated)
-  {
-      FREE(n);
-      FREE(nspn);
+  /* local variable */
+  int *Dim = NULL,*Sel = NULL;
+  int pd = 1;
+  int pds = 1;
+  int nd = 0;
+  int rank = 0;
+  int i = 0,j = 0,k = 0, lA = 1;
+
+  for (i=0;i<ndimsA;i++) {
+    lA *= dimsA[i];
   }
 
+  /* void or scalar input gives void output or scalar*/
+  if (lA <= 1 ) {
+    LhsVar(1) =  1;
+    PutLhsVar();
+    return(0);
+  }
+
+  /******************** get and check third argument (dim) ****************************************/
+  getVarAddressFromPosition(pvApiCtx, 3, &piAddr);
+  if (isVarMatrixType(pvApiCtx, piAddr) == 0) {
+    Scierror(999, _("%s: Wrong type for input argument #%d.\n"), fname, 3);
+    goto ERR;
+  }
+  sciErr = getVectorIntArg(pvApiCtx, 3,fname, &ndims,&Dim1);
+  if(sciErr.iErr) {
+    Scierror(sciErr.iErr, getErrorMessage(sciErr));
+    goto ERR;
+  }
+  /* check values of Dim1[i} */
+  pd = 1;
+  for (i=0;i<ndims;i++) {
+    if (Dim1[i] <= 1) {
+      Scierror(999,_("%s: Wrong values for input argument #%d: Elements must be greater than %d.\n"),fname,3,1);
+      goto ERR;
+    }
+    pd *= Dim1[i];
+  }
+  if ( pd>lA) {
+    Scierror(999,_("%s: Wrong values for input argument #%d: Must be less than %d.\n"),fname,3,lA);
+    goto ERR;
+  }
+  if (lA%pd) {
+    Scierror(999,_("%s: Wrong values for input argument #%d: Must be a divisor of %d.\n"),fname,3,lA);
+    goto ERR;
+  }
+  /******************** get and check fourth argument (incr) ****************************************/
+  sciErr = getVectorIntArg(pvApiCtx, 4,fname, &nincr,&Incr);
+  if(sciErr.iErr) {
+    Scierror(sciErr.iErr, getErrorMessage(sciErr));
+    goto ERR;
+  }
+  if (nincr!=ndims) {
+    Scierror(999,_("%s: Incompatible input arguments #%d and #%d: Same sizes expected.\n"),fname,3,4);
+    goto ERR;
+  }
+
+  /* check values of Incr[i] */
+  if (Incr[0]<=0) {
+    Scierror(999,_("%s: Wrong values for input argument #%d: Positive integers expected.\n"),fname,4);
+    goto ERR;
+  }
+  for (i=0;i<ndims;i++) {
+    if (lA%Incr[i]) {
+      Scierror(999,_("%s: Wrong values for input argument #%d: Elements must be divisors of %d.\n"),fname,3,lA);
+      goto ERR;
+    }
+    if (i>0&&(Incr[i]<=Incr[i-1])) {
+      Scierror(999,_("%s: Wrong values for input argument #%d: Elements must be in increasing ""order.\n"),fname,4);
+      goto ERR;
+    }
+  }
+  if ((Dim=(int *)MALLOC((2*ndims+1)*sizeof(int)))==NULL) {
+    Scierror(999,_("%s: Cannot allocate more memory.\n"),fname);
+    goto ERR;
+  }
+  if ((Sel=(int *)MALLOC((ndims)*sizeof(int)))==NULL) {
+    Scierror(999,_("%s: Cannot allocate more memory.\n"),fname);
+    goto ERR;
+  }
+
+
+  /*Transform  Dim1 and Incr into Dim and Sel and check validity*/
+
+  nd = 0;
+  pd = 1;
+  if (Incr[0] != 1) {
+    Dim[nd++] = Incr[0];
+    pd *= Incr[0];
+  }
+  Dim[nd++] = Dim1[0];
+  pd *= Dim1[0];
+  Sel[0] = nd;
+
+  for (k=1;k<ndims;k++) {
+    if (Incr[k]%pd != 0) {
+      Scierror(999,_("%s: Incompatible input arguments #%d and #%d.\n"),fname,3,4);
+      goto ERR;
+    }
+    if (Incr[k] != pd) {
+      Dim[nd++] = (int)(Incr[k]/pd);
+      pd = Incr[k];
+    }
+    Dim[nd++] = Dim1[k];
+    pd *= Dim1[k];
+    Sel[k] = nd;
+  }
+  if (pd<lA) {
+    if (lA%pd != 0) {
+      Scierror(999,_("%s: Incompatible input arguments #%d and #%d.\n"),fname,3,4);
+      goto ERR;
+    }
+    Dim[nd++] = (int)(lA/pd);
+  }
+
+  rank = ndims;
+  ndims = nd;
+
+  /* now one  same algorithm than sci_fft_3args applies */
+  /* Create  gdim struct */
+  gdim.rank=rank;
+  if ((gdim.dims=(fftw_iodim *)MALLOC(sizeof(fftw_iodim)*gdim.rank))==NULL) {
+    Scierror(999,_("%s: Cannot allocate more memory.\n"),fname);
+    goto ERR;
+  }
+
+  pd = 1; /* used to store prod(Dims(1:sel(k-1)))*/
+  pds = 1; /* used to store prod(Dims(sel(k-1):sel(k)))*/
+  j = 0;
+  for (i=0;i<ndims;i++) {
+    if (j>=gdim.rank) break;
+    if (Sel[j]==i+1) {
+      gdim.dims[j].n = Dim[i];
+      gdim.dims[j].is = pd;
+      gdim.dims[j].os = pd;
+      j++;
+    }
+    pd *= Dim[i];
+  }
+  /* Compute howmany_rank based on jumps in the Sel sequence */
+  gdim.howmany_rank=0;
+  if ((Sel[0]!=1)&&(Sel[0]!=ndims)) gdim.howmany_rank++;
+
+  for (i=1;i<=rank-1;i++) {
+    if (Sel[i]!=Sel[i-1]+1) gdim.howmany_rank++;
+  }
+  if ((Sel[rank-1]!=ndims)||(rank==1)) gdim.howmany_rank++;
+  /* Fill the howmany_dims struct */
+  if (gdim.howmany_rank>0) {
+    /* it must be the case */
+    int ih = 0;
+
+    if ((gdim.howmany_dims=(fftw_iodim *)MALLOC(gdim.howmany_rank*sizeof(fftw_iodim)))==NULL) {
+      Scierror(999,_("%s: Cannot allocate more memory.\n"),fname);
+      goto ERR;
+    }
+    pd = 1;
+    for (j=1;j<=(Sel[0]-1);j++) pd *=Dim[j-1];/*prod(Dims(1:(sel(1)-1)))*/
+    ih = 0;
+    if ((Sel[0]!=1)&&(Sel[0]!=ndims)) {
+      /* First seleted dimension */
+      gdim.howmany_dims[ih].is = 1;
+      gdim.howmany_dims[ih].os = 1;
+      gdim.howmany_dims[ih].n = pd;
+      ih++;
+    }
+    pd *= Dim[Sel[0]-1];/*prod(Dims(1:sel(1)))*/
+    for (i=2;i<=rank;i++) {
+      /* intermediate selected dimensions */
+      if (Sel[i-1]!=Sel[i-2]+1) {
+        pds = 1;
+        for (j=(Sel[i-2]+1);j<=(Sel[i-1]-1);j++) pds *= Dim[j-1]; /*prod(Dims(sel(i-1)+1:(sel(i)-1)))*/
+        gdim.howmany_dims[ih].is = pd;
+        gdim.howmany_dims[ih].os = pd;
+        gdim.howmany_dims[ih].n = pds;
+        ih++;
+      }
+      pd *= pds*Dim[Sel[i-1]-1]; /*prod(Dims(1:sel(i)))*/
+    }
+
+    if (Sel[rank-1]!=ndims) {
+      /* last selected dimension*/
+      pds = 1;
+      for (j=(Sel[rank-1]+1);j<=ndims;j++) pds *= Dim[j-1]; /*prod(Dims(sel(i-1)+1:(sel(i)-1)))*/
+      gdim.howmany_dims[ih].is = pd;
+      gdim.howmany_dims[ih].os = pd;
+      gdim.howmany_dims[ih].n = pds;
+      ih++;
+    }
+    else if (rank==1) { /* the only selected dimension is the last one */
+      gdim.howmany_dims[ih].is = 1;
+      gdim.howmany_dims[ih].os = 1;
+      gdim.howmany_dims[ih].n = pd/Dim[Sel[0]-1];
+      ih++;
+    }
+  }
+  if (!sci_fft_gen(fname, ndimsA, dimsA, Ar,  Ai, isn,iopt,gdim))  goto ERR;
+
   /***********************************
    * Return results in lhs argument *
    ***********************************/
-  
-  LhsVar(1) = 1;
-  PutLhsVar();  
 
+  PutLhsVar();
+ ERR:
+  FREE(Dim1);
+  FREE(Incr);
+  FREE(Dim);
+  FREE(Sel);
+  FREE(gdim.dims);
+  FREE(gdim.howmany_dims);
+  return(0);
+}
+/*--------------------------------------------------------------------------*/
+BOOL isHyperMatrixMlist(void* _pvCtx, int *piAddressVar)
+{
+  char **fields = NULL;
+  SciErr sciErr;
+  int iType = 0;
+  int m = 0, n = 0;
+
+  if (piAddressVar == NULL) {
+    return FALSE;
+  }
+
+  sciErr = getVarType(_pvCtx, piAddressVar, &iType);
+  if (sciErr.iErr) {
+    return FALSE;
+  }
+
+  if (iType == sci_mlist) {
+    int* piAddrChild  = NULL;
+    int iItem   = 0;
+
+    sciErr = getListItemNumber(pvApiCtx, piAddressVar, &iItem);
+    if(sciErr.iErr) {
+      return FALSE;
+    }
+
+    sciErr = getListItemAddress(pvApiCtx, piAddressVar, 1, &piAddrChild);
+    if(sciErr.iErr) {
+      return FALSE;
+    }
+
+    if (!isStringType(_pvCtx, piAddrChild)) {
+      return FALSE;
+    }
+
+    if (getAllocatedMatrixOfString(_pvCtx, piAddrChild, &m, &n , &fields) == 0) {
+      if (strcmp(fields[0], "hm") != 0) {
+        freeAllocatedMatrixOfString(m, n, fields);
+        fields = NULL;
+        return FALSE;
+      }
+      freeAllocatedMatrixOfString(m, n, fields);
+      fields = NULL;
+    }
+    else {
+      return FALSE;
+    }
+    return TRUE;
+  }
+  return FALSE;
+}
+/*--------------------------------------------------------------------------*/
+int sci_fft_gen(char *fname, int ndimsA, int *dimsA, double *Ar,  double *Ai, int isn, int iopt, guru_dim_struct gdim)
+{
+  /* API variables */
+  SciErr sciErr;
+
+  /* Input  array variables */
+  int  isrealA = (Ai==NULL), issymA = 1, lA = 1;
+  /*for MKL*/
+  int isrealA_save=isrealA ;
+
+  /*FFTW specific library variable */
+  enum Scaling scale = None;
+  enum Plan_Type type;
+  fftw_plan p;
+
+  /* input/output address for transform variables */
+  double *ri = NULL,*ii = NULL,*ro = NULL,*io = NULL;
+
+
+  /* local variable */
+  int one = 1;
+  int i = 0;
+
+
+  for (i=0;i<ndimsA;i++) {
+    lA *= dimsA[i];
+  }
+
+
+  if (iopt==0) {
+    /* automatically selected algorithm*/
+    issymA =  check_array_symmetry(Ar,Ai, gdim);
+    if (issymA<0 ) {
+      Scierror(999,_("%s: Cannot allocate more memory.\n"),fname);
+      goto ERR;
+    }
+  }
+
+  else if (iopt==1) {
+    issymA = 1; /* user forces symmetry */
+  }
+  else {
+    issymA = 0;
+  }
+  LhsVar(1) = 1; /* assume inplace transform*/
+
+  if (WITHMKL) {
+    double dzero=0.0;
+    if (isrealA) {
+      /*MKL does not implement the r2c nor r2r guru split methods, make A complex */
+      if (issymA) {
+        /* result will be real, the imaginary part of A can be allocated alone */
+        sciErr = allocMatrixOfDouble(pvApiCtx, Rhs + 1, 1, lA, &Ai);
+        if(sciErr.iErr) {
+          Scierror(999,_("%s: Cannot allocate more memory.\n"),fname);
+          goto ERR;
+        }
+        C2F(dset)(&lA,&dzero,Ai,&one);
+      }
+      else {
+        /* result will be complex, realloc A for inplace computation */
+        sciErr = allocComplexArrayOfDouble(pvApiCtx, Rhs + 1, ndimsA,dimsA, &ri, &Ai);
+        if(sciErr.iErr) {
+          Scierror(999,_("%s: Cannot allocate more memory.\n"),fname);
+          goto ERR;
+        }
+        C2F(dcopy)(&lA,Ar,&one,ri,&one);
+        Ar=ri;
+        C2F(dset)(&lA,&dzero,Ai,&one);
+        LhsVar(1) = Rhs + 1;
+        isrealA=0;
+      }
+    }
+  }
+
+  if (!isrealA&&issymA){ /* A is complex but result is real */
+    /* result will be complex, realloc real part of A for real part inplace computation */
+    sciErr = allocArrayOfDouble(pvApiCtx, Rhs + 1, ndimsA,dimsA, &ri);
+    if(sciErr.iErr) {
+      Scierror(999,_("%s: Cannot allocate more memory.\n"),fname);
+      goto ERR;
+    }
+    C2F(dcopy)(&lA,Ar,&one,ri,&one);Ar=ri;
+    LhsVar(1) = Rhs + 1;
+  }
+
+  /* Set pointers on real and imaginary part of the input */
+  ri=Ar;
+  ii=Ai;
+
+  scale = None; /*no scaling needed */
+  if (isn== FFTW_BACKWARD) scale=Divide;
+  if (isrealA) {
+    /*A is real */
+    if (issymA) {
+      /*r2r =  isrealA &&  issymA*/
+      /* there is no general plan able to compute r2r transform so it is tranformed into
+         a R2c plan. The computed imaginary part will be zero*/
+      sciErr = allocMatrixOfDouble(pvApiCtx, Rhs + 1, 1, lA,  &io);
+      if(sciErr.iErr) {
+        Scierror(999,_("%s: Cannot allocate more memory.\n"),fname);
+        goto ERR;
+      }
+      type=R2C_PLAN;
+      ro=Ar;
+    }
+    else {
+      /*r2c =  isrealA && ~issymA;*/
+      /* transform cannot be done in place */
+      sciErr = allocComplexArrayOfDouble(pvApiCtx, Rhs + 1, ndimsA,dimsA, &ro, &io);
+      if(sciErr.iErr) {
+        Scierror(999,_("%s: Cannot allocate more memory.\n"),fname);
+        goto ERR;
+      }
+      LhsVar(1) = Rhs + 1;
+      type=R2C_PLAN; /* fftw_plan_guru_split_dft_r2c plans for an FFTW_FORWARD transform*/
+      if (isn== FFTW_BACKWARD) {
+        /*transform problem into a FORWARD fft*/
+        /*ifft(A)=conj(fft(A/N)) cas vect*/
+        /* pre traitement A must be  divided by N cas vect*/
+        /* post treatment result must conjugated */
+      }
+    }
+  }
+  else {
+    /* A is complex */
+    if (!WITHMKL&&issymA) { /*result is real*/
+      /*c2r =  ~isrealA &&  issymA*/
+      ro = ri;
+      io = NULL;
+
+      type=C2R_PLAN; /*fftw_plan_guru_split_dft_c2r plans for an FFTW_BACKWARD transform*/
+      if (isn== FFTW_FORWARD) {
+        /*transform problem into a BACKWARD fft : fft(A)=ifft(conj(A))*/
+        double minusone=-1.0;
+         C2F(dscal)(&lA,&minusone,ii,&one);
+      }
+    }
+    else {
+      /*c2c =  ~isrealA && ~issymA;*/
+      /* use inplace transform*/
+      type=C2C_PLAN; /*  fftw_plan_guru_split_dft plans for an FFTW_FORWARD transform*/
+      if (isn== FFTW_BACKWARD) {
+        /*transform problem into a FORWARD fft*/
+        /* ifft(A) = %i*conj(fft(%i*conj(A)/N) */
+        /* reverse input */
+        ri=Ai;
+        ii=Ar;
+        /* reverse output */
+        ro=Ai;
+        io=Ar;
+      }
+      else {
+        ro=ri;
+        io=ii;
+      }
+    }
+  }
+  /* Set Plan */
+  p = GetFFTWPlan(type, &gdim, ri, ii, ro, io, getCurrentFftwFlags(), isn);
+  if (p == NULL) {
+    Scierror(999,_("%s:Plan, No more memory.\n"),fname);
+    goto ERR;
+  }
+  /* pre-treatment */
+  if (scale != None) {
+    double ak = 1.0;
+    for(i=0;i<gdim.rank;i++) ak=ak*((double)(gdim.dims[i].n));
+    if (scale== Divide) ak=1.0/ak;
+    C2F(dscal)(&lA,&ak,ri,&one);
+    if (isrealA==0) C2F(dscal)(&lA,&ak,ii,&one);
+  }
+  /* execute FFTW plan */
+  ExecuteFFTWPlan(type, p, ri, ii, ro, io);
+  /* Post treatment */
+  switch (type) {
+  case R2R_PLAN:
+    if (complete_array(ro,NULL, gdim)==-1) {
+      Scierror(999,_("%s: Cannot allocate more memory.\n"),fname);
+      goto ERR;
+    }
+    break;
+  case C2R_PLAN:
+    break;
+  case R2C_PLAN:
+    if (issymA) {
+      /*R2C has been used to solve an r2r problem*/
+      if (complete_array(ro,NULL, gdim)==-1) {
+        Scierror(999,_("%s: Cannot allocate more memory.\n"),fname);
+        goto ERR;
+      }
+    }
+    else {
+      if (complete_array(ro,io, gdim)==-1) {
+        Scierror(999,_("%s: Cannot allocate more memory.\n"),fname);
+        goto ERR;
+      }
+      if (isn== FFTW_BACKWARD) {
+        /*conjugate result */
+        double ak = -1.0;
+        C2F(dscal)(&lA,&ak,io,&one);
+      }
+    }
+    break;
+  case C2C_PLAN:
+    if (WITHMKL&&isrealA_save) {
+      if (isn==FFTW_FORWARD) {
+        if (complete_array(ro,io, gdim)==-1) {
+          Scierror(999,_("%s: Cannot allocate more memory.\n"),fname);
+          goto ERR;
+        }
+      }
+      else {
+        if (complete_array(io,ro, gdim)==-1) {
+          Scierror(999,_("%s: Cannot allocate more memory.\n"),fname);
+          goto ERR;
+        }
+      }
+    }
+    break;
+  }
+
+  return(1);
+ ERR:
   return(0);
 }
-/*--------------------------------------------------------------------------*/ 
index dc042a5..f5f785f 100644 (file)
@@ -2,14 +2,16 @@
  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
  * Copyright (C) 2006/2007 - INRIA - Alan LAYEC
  * Copyright (C) 2007 - INRIA - Allan CORNET
- * 
+ * Copyright (C) 2012 - DIGITEO - Allan CORNET
+ *
  * This file must be used under the terms of the CeCILL.
  * This source file is licensed as described in the file COPYING, which
  * you should have received as part of this distribution.  The terms
- * are also available at    
+ * are also available at
  * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
  *
  */
+/*--------------------------------------------------------------------------*/
 #include <string.h>
 #include "fftw_utilities.h"
 #include "MALLOC.h"
 #include "localization.h"
 #include "freeArrayOfString.h"
 #include "Scierror.h"
+#include "stack-c.h"
 #ifdef _MSC_VER
 #include "strdup_windows.h"
 #endif
 /*--------------------------------------------------------------------------*/
-extern unsigned cur_fftw_flags;
-/*--------------------------------------------------------------------------*/
 /* fftw_flags function.
-*
-* Scilab Calling sequence :
-*   -->[a,b]=fftw_flags();
-* or
-*   -->[a,b]=fftw_flags(S);
-*
-*  a is an int scalar. (the int value of
-*                            the flag parameter of fftw)
-*  b is a string matrix.(the string values of
-*                             the flag parameter of fftw)
-*  S is a string matrix or an int or a double scalar
-*  given the value(s) of the fftw flag parameter.
-*
-*  This function gives and set the flag parameter of fftw
-*  when creating a new plan.
-*  This should be done before calling fftw function.
-*  (default is FFTW_ESTIMATE)
-*/
-int sci_fftw_flags(char *fname,unsigned long fname_len)
+ *
+ * Scilab Calling sequence :
+ *   -->[a,b]=fftw_flags();
+ * or
+ *   -->[a,b]=fftw_flags(S);
+ *
+ *  a is an int scalar. (the int value of
+ *                            the flag parameter of fftw)
+ *  b is a string matrix.(the string values of
+ *                             the flag parameter of fftw)
+ *  S is a string matrix or an int or a double scalar
+ *  given the value(s) of the fftw flag parameter.
+ *
+ *  This function gives and set the flag parameter of fftw
+ *  when creating a new plan.
+ *  This should be done before calling fftw function.
+ *  (default is FFTW_ESTIMATE)
+ */
+/*--------------------------------------------------------------------------*/
+int sci_fftw_flags(char *fname, unsigned long fname_len)
 {
-       /* declaration of variables to store scilab parameters address */
-       static int l1 = 0, m1 = 0, n1 = 0;
-       SciIntMat M1;
-       char **Str1 = NULL;
-
-       static int l2 = 0, m2 = 0, n2 = 0;
-
-       char **Str3 = NULL;
-
-       /* please update me ! */
-       static int nb_flag = 22;
-       static char *Str[]= {/* documented flags */
-                       "FFTW_MEASURE",
-                       "FFTW_DESTROY_INPUT",
-                       "FFTW_UNALIGNED",
-                       "FFTW_CONSERVE_MEMORY",
-                       "FFTW_EXHAUSTIVE",
-                       "FFTW_PRESERVE_INPUT",
-                       "FFTW_PATIENT",
-                       "FFTW_ESTIMATE",
-
-                       /* undocumented beyond-guru flags */
-                       "FFTW_ESTIMATE_PATIENT",
-                       "FFTW_BELIEVE_PCOST",
-                       "FFTW_NO_DFT_R2HC",
-                       "FFTW_NO_NONTHREADED",
-                       "FFTW_NO_BUFFERING",
-                       "FFTW_NO_INDIRECT_OP",
-                       "FFTW_ALLOW_LARGE_GENERIC",
-                       "FFTW_NO_RANK_SPLITS",
-                       "FFTW_NO_VRANK_SPLITS",
-                       "FFTW_NO_VRECURSE",
-                       "FFTW_NO_SIMD",
-                       "FFTW_NO_SLOW",
-                       "FFTW_NO_FIXED_RADIX_LARGE_N",
-                       "FFTW_ALLOW_PRUNING"};
-
-       static unsigned flagt[]= {/* documented flags */
-                            FFTW_MEASURE,
-                            FFTW_DESTROY_INPUT,
-                            FFTW_UNALIGNED,
-                            FFTW_CONSERVE_MEMORY,
-                            FFTW_EXHAUSTIVE,
-                            FFTW_PRESERVE_INPUT,
-                            FFTW_PATIENT,
-                            FFTW_ESTIMATE,
-
-                            /* undocumented beyond-guru flags */
-                            FFTW_ESTIMATE_PATIENT,
-                            FFTW_BELIEVE_PCOST,
-                            FFTW_NO_DFT_R2HC,
-                            FFTW_NO_NONTHREADED,
-                            FFTW_NO_BUFFERING,
-                            FFTW_NO_INDIRECT_OP,
-                            FFTW_ALLOW_LARGE_GENERIC,
-                            FFTW_NO_RANK_SPLITS,
-                            FFTW_NO_VRANK_SPLITS,
-                            FFTW_NO_VRECURSE,
-                            FFTW_NO_SIMD,
-                            FFTW_NO_SLOW,
-                            FFTW_NO_FIXED_RADIX_LARGE_N,
-                            FFTW_ALLOW_PRUNING};
-       unsigned flagv = 0;
-
-       int i = 0,j = 0;
-
-       CheckRhs(0,1);
-
-       if (Rhs==0) 
-       {
-               // nothing
-       }
-       else 
-       {
-               switch(VarType(1)){
-                       case sci_ints:
-
-                       /* int */
-                       GetRhsVar(1,MATRIX_OF_VARIABLE_SIZE_INTEGER_DATATYPE, &m1, &n1, &M1);
-                       CheckDims(1,m1,n1,1,1);
-                       cur_fftw_flags = ((int *)M1.D)[0];
-                       break;
-                       case sci_matrix:
-                               /* double */
-                               GetRhsVar(1,MATRIX_OF_DOUBLE_DATATYPE, &m1, &n1, &l1);
-                               CheckDims(1,m1,n1,1,1);
-                               cur_fftw_flags = (int)*stk(l1);
-                               break;
-                       case sci_strings:
-                               /* string */
-                               GetRhsVar(1,MATRIX_OF_STRING_DATATYPE,&m1,&n1,&Str1);
-                               for (j=0;j<m1*n1;j++) 
-                                       {
-                                               for (i=0;i<nb_flag;i++) 
-                                                       {
-                                                               if (strcmp(Str1[j],Str[i])==0) break;
-                                                       }
-
-                                               if (i == nb_flag) 
-                                                       {
-                                                               freeArrayOfString(Str1,m1*n1);
-                                                               Scierror(999,_("%s: Wrong values for input argument #%d: FFTW flag expected.\n"),fname,1); 
-                                                               return(0);
-                                                       }
-                                               else 
-                                                       {
-                                                               if (i>0) flagv = ( flagv | (1U << (i-1)) );
-                                                       }
-                                       }
-                               cur_fftw_flags = flagv;
-                               freeArrayOfString(Str1,m1*n1);
-                               break;
-                       default:
-                               Scierror(53,_("%s: Wrong type for input argument #%d.\n"),fname,1);
-                               return(0);
-               }
-       }
-
-       /* return value of Sci_Plan.flags in position 2 */
-       m2 = 1;
-       n2 = m2;
-       l2 = I_INT32;
-       CreateVar(Rhs+2,MATRIX_OF_VARIABLE_SIZE_INTEGER_DATATYPE,&m2,&n2,&l2);
-       *istk(l2)=(int) cur_fftw_flags;
-
-       /*Test for only FFTW_MEASURE*/
-       if (cur_fftw_flags == 0) 
-       {
-               j = 1;
-               if ((Str3 = (char **)MALLOC(sizeof(char *))) == NULL) 
-               {
-                       Scierror(999,_("%s: No more memory.\n"),fname);
-                       return(0);
-               }
-
-               Str3[0] = strdup(Str[0]);
-               if (Str3[0] == NULL) 
-               {
-                       Scierror(999,_("%s: No more memory.\n"),fname);
-                       return(0);
-               }
-       }
-       else 
-       {
-               j = 0;
-               for (i = 1;i < nb_flag; i++) 
-               {
-                       if((cur_fftw_flags&flagt[i])==flagt[i]) 
-                       {
-                               j++;
-                               if (Str3) Str3 = (char **)REALLOC(Str3,sizeof(char *)*j);
-                               else Str3 = (char **)MALLOC(sizeof(char *)*j);
-
-                               if ( Str3 == NULL) 
-                               {
-                                       Scierror(999,_("%s: No more memory.\n"),fname);
-                                       return(0);
-                               }
-
-                               Str3[j-1] = strdup(Str[i]);
-                               if (Str3[j-1] == NULL) 
-                               {
-                                       freeArrayOfString(Str3,j);
-                                       Scierror(999,_("%s: No more memory.\n"),fname);
-                                       return(0);
-                               }
-                       }
-               }
-       }
-
-       n1=1;
-       CreateVarFromPtr( Rhs+3,MATRIX_OF_STRING_DATATYPE, &j, &n1, Str3);
-       freeArrayOfString(Str3,j);
-
-       LhsVar(1)=Rhs+2;
-       LhsVar(2)=Rhs+3;
-       PutLhsVar();
-       return(0);
+  /* declaration of variables to store scilab parameters address */
+  static int l1 = 0, m1 = 0, n1 = 0;
+  SciIntMat M1;
+  char **Str1 = NULL;
+
+  static int l2 = 0, m2 = 0, n2 = 0;
+
+  char **Str3 = NULL;
+
+  /* please update me ! */
+  static int nb_flag = 22;
+  static char *Str[] =
+    {
+      /* documented flags */
+      "FFTW_MEASURE",
+      "FFTW_DESTROY_INPUT",
+      "FFTW_UNALIGNED",
+      "FFTW_CONSERVE_MEMORY",
+      "FFTW_EXHAUSTIVE",
+      "FFTW_PRESERVE_INPUT",
+      "FFTW_PATIENT",
+      "FFTW_ESTIMATE",
+
+      /* undocumented beyond-guru flags */
+      "FFTW_ESTIMATE_PATIENT",
+      "FFTW_BELIEVE_PCOST",
+      "FFTW_NO_DFT_R2HC",
+      "FFTW_NO_NONTHREADED",
+      "FFTW_NO_BUFFERING",
+      "FFTW_NO_INDIRECT_OP",
+      "FFTW_ALLOW_LARGE_GENERIC",
+      "FFTW_NO_RANK_SPLITS",
+      "FFTW_NO_VRANK_SPLITS",
+      "FFTW_NO_VRECURSE",
+      "FFTW_NO_SIMD",
+      "FFTW_NO_SLOW",
+      "FFTW_NO_FIXED_RADIX_LARGE_N",
+      "FFTW_ALLOW_PRUNING"
+    };
+
+  static unsigned flagt[] =
+    {
+      /* documented flags */
+      FFTW_MEASURE,
+      FFTW_DESTROY_INPUT,
+      FFTW_UNALIGNED,
+      FFTW_CONSERVE_MEMORY,
+      FFTW_EXHAUSTIVE,
+      FFTW_PRESERVE_INPUT,
+      FFTW_PATIENT,
+      FFTW_ESTIMATE,
+
+      /* undocumented beyond-guru flags */
+      FFTW_ESTIMATE_PATIENT,
+      FFTW_BELIEVE_PCOST,
+      FFTW_NO_DFT_R2HC,
+      FFTW_NO_NONTHREADED,
+      FFTW_NO_BUFFERING,
+      FFTW_NO_INDIRECT_OP,
+      FFTW_ALLOW_LARGE_GENERIC,
+      FFTW_NO_RANK_SPLITS,
+      FFTW_NO_VRANK_SPLITS,
+      FFTW_NO_VRECURSE,
+      FFTW_NO_SIMD,
+      FFTW_NO_SLOW,
+      FFTW_NO_FIXED_RADIX_LARGE_N,
+      FFTW_ALLOW_PRUNING
+    };
+
+  unsigned flagv = 0;
+
+  int i = 0, j = 0;
+
+  CheckRhs(0, 1);
+
+  if (Rhs == 0)
+    {
+      // nothing
+    }
+  else
+    {
+      switch(VarType(1))
+        {
+        case sci_ints:
+
+          /* int */
+          GetRhsVar(1, MATRIX_OF_VARIABLE_SIZE_INTEGER_DATATYPE, &m1, &n1, &M1);
+          CheckDims(1, m1, n1, 1, 1);
+          setCurrentFftwFlags(((int *)M1.D)[0]);
+          break;
+        case sci_matrix:
+          /* double */
+          GetRhsVar(1, MATRIX_OF_DOUBLE_DATATYPE, &m1, &n1, &l1);
+          CheckDims(1, m1, n1, 1, 1);
+          setCurrentFftwFlags((int)*stk(l1));
+          break;
+        case sci_strings:
+          /* string */
+          GetRhsVar(1, MATRIX_OF_STRING_DATATYPE, &m1, &n1, &Str1);
+          for (j = 0; j < m1 * n1; j++)
+            {
+              for (i = 0; i < nb_flag; i++)
+                {
+                  if (strcmp(Str1[j], Str[i]) == 0) break;
+                }
+
+              if (i == nb_flag)
+                {
+                  freeArrayOfString(Str1, m1 * n1);
+                  Scierror(999, _("%s: Wrong values for input argument #%d: FFTW flag expected.\n"), fname, 1);
+                  return 0;
+                }
+              else
+                {
+                  if (i > 0)
+                    {
+                      flagv = ( flagv | (1U << (i - 1)) );
+                    }
+                }
+            }
+          setCurrentFftwFlags(flagv);
+          freeArrayOfString(Str1, m1 * n1);
+          break;
+
+        default:
+          Scierror(53, _("%s: Wrong type for input argument #%d.\n"), fname, 1);
+          return 0;
+        }
+    }
+
+  /* return value of Sci_Plan.flags in position 2 */
+  m2 = 1;
+  n2 = m2;
+  l2 = I_INT32;
+  CreateVar(Rhs + 2, MATRIX_OF_VARIABLE_SIZE_INTEGER_DATATYPE, &m2, &n2, &l2);
+  *istk(l2) = (int) getCurrentFftwFlags();
+
+  /*Test for only FFTW_MEASURE*/
+  if (getCurrentFftwFlags() == 0)
+    {
+      j = 1;
+      if ((Str3 = (char **)MALLOC(sizeof(char *))) == NULL)
+        {
+          Scierror(999, _("%s: No more memory.\n"), fname);
+          return 0;
+        }
+
+      Str3[0] = strdup(Str[0]);
+      if (Str3[0] == NULL)
+        {
+          Scierror(999, _("%s: No more memory.\n"), fname);
+          return 0;
+        }
+    }
+  else
+    {
+      j = 0;
+      for (i = 1;i < nb_flag; i++)
+        {
+          if((getCurrentFftwFlags() & flagt[i]) == flagt[i])
+            {
+              j++;
+              if (Str3)
+                {
+                  Str3 = (char **)REALLOC(Str3,sizeof(char *) * j);
+                }
+              else
+                {
+                  Str3 = (char **)MALLOC(sizeof(char *) * j);
+                }
+
+              if ( Str3 == NULL)
+                {
+                  Scierror(999, _("%s: No more memory.\n"), fname);
+                  return 0;
+                }
+
+              Str3[j - 1] = strdup(Str[i]);
+              if (Str3[j - 1] == NULL)
+                {
+                  freeArrayOfString(Str3, j);
+                  Scierror(999, _("%s: No more memory.\n"), fname);
+                  return 0;
+                }
+            }
+        }
+    }
+
+  n1 = 1;
+  CreateVarFromPtr(Rhs + 3, MATRIX_OF_STRING_DATATYPE, &j, &n1, Str3);
+  freeArrayOfString(Str3, j);
+
+  LhsVar(1) = Rhs + 2;
+  LhsVar(2) = Rhs + 3;
+  PutLhsVar();
+  return 0;
 }
-/*--------------------------------------------------------------------------*/ 
+/*--------------------------------------------------------------------------*/
index 96f7d23..870db04 100644 (file)
@@ -2,24 +2,21 @@
  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
  * Copyright (C) 2007 - INRIA - Alan LAYEC
  * Copyright (C) 2007 - INRIA - Allan CORNET
- * 
+ *
  * This file must be used under the terms of the CeCILL.
  * This source file is licensed as described in the file COPYING, which
  * you should have received as part of this distribution.  The terms
- * are also available at    
+ * are also available at
  * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
  *
  */
 
+#include "stack-c.h"
 #include "fftw_utilities.h"
 #include "callfftw.h"
 #include "MALLOC.h"
 #include "gw_fftw.h"
 /*--------------------------------------------------------------------------*/
-extern FFTW_Plan_struct Sci_Forward_Plan;
-extern FFTW_Plan_struct Sci_Backward_Plan;
-/*--------------------------------------------------------------------------*/
-
 /* Reset fftw wisdom
  *
  * Scilab Calling sequence :
@@ -30,17 +27,18 @@ extern FFTW_Plan_struct Sci_Backward_Plan;
  * Output : Nothing
  *
  */
+/*--------------------------------------------------------------------------*/
 int sci_fftw_forget_wisdom(char *fname,unsigned long fname_len)
 {
- CheckRhs(0,0);
+  CheckRhs(0,0);
 
- FreeFFTWPlan(&Sci_Backward_Plan);
- FreeFFTWPlan(&Sci_Forward_Plan);
+  FreeFFTWPlan(getSci_Backward_Plan());
+  FreeFFTWPlan(getSci_Forward_Plan());
 
- call_fftw_forget_wisdom();
+  call_fftw_forget_wisdom();
 
- PutLhsVar();
+  PutLhsVar();
 
- return(0);
+  return(0);
 }
 /*--------------------------------------------------------------------------*/
index 30dbad2..cf5ac83 100644 (file)
@@ -1,37 +1,37 @@
 /*
  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
  * Copyright (C) 2006 - INRIA - Allan CORNET
- * 
+ *
  * This file must be used under the terms of the CeCILL.
  * This source file is licensed as described in the file COPYING, which
  * you should have received as part of this distribution.  The terms
- * are also available at    
+ * are also available at
  * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
  *
  */
 #include "callfftw.h"
 #include "gw_fftw.h"
 #include "stack-c.h"
-/*--------------------------------------------------------------------------*/ 
+/*--------------------------------------------------------------------------*/
 int sci_fftwlibraryisloaded(char *fname,unsigned long fname_len)
 {
-       static int l1,n1;
+  static int l1,n1;
 
-       n1=1;
-       if ( IsLoadedFFTW() )
-       {
-               CreateVar(Rhs+1,MATRIX_OF_BOOLEAN_DATATYPE, &n1,&n1,&l1);
-               *istk(l1)=(int)(TRUE);
-       }
-       else
-       {
-               CreateVar(Rhs+1,MATRIX_OF_BOOLEAN_DATATYPE, &n1,&n1,&l1);
-               *istk(l1)=(int)(FALSE);
-       }
+  n1=1;
+  if ( IsLoadedFFTW() )
+    {
+      CreateVar(Rhs+1,MATRIX_OF_BOOLEAN_DATATYPE, &n1,&n1,&l1);
+      *istk(l1)=(int)(TRUE);
+    }
+  else
+    {
+      CreateVar(Rhs+1,MATRIX_OF_BOOLEAN_DATATYPE, &n1,&n1,&l1);
+      *istk(l1)=(int)(FALSE);
+    }
 
-       LhsVar(1)=Rhs+1;
-       PutLhsVar();
+  LhsVar(1)=Rhs+1;
+  PutLhsVar();
 
-       return(0);
+  return(0);
 }
-/*--------------------------------------------------------------------------*/ 
+/*--------------------------------------------------------------------------*/
index e3c92e6..708f51a 100644 (file)
@@ -10,8 +10,7 @@
  * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
  *
  */
-
-
+/*--------------------------------------------------------------------------*/
 #include "callfftw.h"
 #include "stack-c.h"
 #include "MALLOC.h"
@@ -20,7 +19,6 @@
 #include "freeArrayOfString.h"
 #include "Scierror.h"
 /*--------------------------------------------------------------------------*/
-
 /* Return text of fftw wisdom
  *
  * Scilab Calling sequence :
  */
 int sci_get_fftw_wisdom(char *fname,unsigned long fname_len)
 {
-       int n1 = 0,i = 0,j = 0;
-       char *Str = NULL;
-       char **Str1 = NULL;
-
-       CheckRhs(0,0);
-       CheckLhs(0,1);
-
-       Str = call_fftw_export_wisdom_to_string();
-
-       n1 = 0; j = 0;
-       if (Str)
-       {
-               for(i = 0; i < (int)strlen(Str); i++) 
-               {
-                       if (Str[i] == '\n') 
-                       {
-                               int len = 0;
-                               int k = 0;
-
-                               n1++;
-
-                               if (Str1) Str1 = (char **)REALLOC(Str1,sizeof(char *)*n1);
-                               else Str1 = (char **)MALLOC(sizeof(char *)*n1);
-
-                               if (Str1 == NULL) 
-                               {
-                                       Scierror(999,_("%s: No more memory.\n"),fname);
-                                       if (Str) {FREE(Str); Str = NULL;}
-                                       return(0);
-                               }
-                               len = i-j;
-                               if ((Str1[n1-1] = (char *)MALLOC(sizeof(char)*(len+1))) == NULL) 
-                               {
-                                       freeArrayOfString(Str1,n1-1);
-                                       if (Str) {FREE(Str); Str = NULL;}
-                                       Scierror(999,_("%s: No more memory.\n"),fname);
-                                       return(0);
-                               }
-
-                               for(k = 0; k < len;k++) 
-                               {
-                                       Str1[n1-1][k] = Str[k+j];
-                               }
-                               Str1[n1-1][len] = '\0';
-                               j = i+1;
-                       }
-               }
-       }
-
-       n1++;
-
-       if (Str1) Str1 = (char **)REALLOC(Str1,sizeof(char *)*n1);
-       else Str1 = (char **)MALLOC(sizeof(char *)*n1);
-
-       if (Str1 == NULL) 
-       {
-               Scierror(999,_("%s: No more memory.\n"),fname);
-               if (Str) {FREE(Str); Str = NULL;}
-               return(0);
-       }
-       if ((Str1[n1-1] = (char *)MALLOC(sizeof(char))) == NULL) 
-       {
-               freeArrayOfString(Str1,n1-1);
-               if (Str) {FREE(Str); Str = NULL;}
-               Scierror(999,_("%s: No more memory.\n"),fname);
-               return(0);
-       }
-       Str1[n1-1][0] = '\0';
-
-       CreateVarFromPtr(Rhs+1,MATRIX_OF_STRING_DATATYPE, &n1, (j=1,&j), Str1);
-
-       freeArrayOfString(Str1,n1);
-       if (Str) {FREE(Str); Str = NULL;}
-
-    LhsVar(1) = Rhs+1;
-    PutLhsVar();
-
-       return(0);
+  int n1 = 0,i = 0,j = 0;
+  char *Str = NULL;
+  char **Str1 = NULL;
+
+  CheckRhs(0,0);
+  CheckLhs(0,1);
+
+  if ((Str = call_fftw_export_wisdom_to_string())==NULL) {
+    Scierror(999,_("%s: MKL fftw library does not implement wisdom functions yet.\n"), fname);
+    return 0;
+  };
+
+  n1 = 0; j = 0;
+  if (Str)
+    {
+      for(i = 0; i < (int)strlen(Str); i++)
+        {
+          if (Str[i] == '\n')
+            {
+              int len = 0;
+              int k = 0;
+
+              n1++;
+
+              if (Str1)
+                {
+                  Str1 = (char **)REALLOC(Str1,sizeof(char *)*n1);
+                }
+              else
+                {
+                  Str1 = (char **)MALLOC(sizeof(char *)*n1);
+                }
+
+              if (Str1 == NULL)
+                {
+                  Scierror(999,_("%s: No more memory.\n"), fname);
+                  if (Str)
+                    {
+                      FREE(Str);
+                      Str = NULL;
+                    }
+                  return(0);
+                }
+
+              len = i - j;
+
+              if ((Str1[n1 - 1] = (char *)MALLOC(sizeof(char)*(len+1))) == NULL)
+                {
+                  freeArrayOfString(Str1, n1 - 1);
+                  if (Str)
+                    {
+                      FREE(Str);
+                      Str = NULL;
+                    }
+                  Scierror(999,_("%s: No more memory.\n"),fname);
+                  return(0);
+                }
+
+              for(k = 0; k < len;k++)
+                {
+                  Str1[n1 - 1][k] = Str[k + j];
+                }
+              Str1[n1 - 1][len] = '\0';
+              j = i + 1;
+            }
+        }
+    }
+
+  n1++;
+
+  if (Str1)
+    {
+      Str1 = (char **)REALLOC(Str1,sizeof(char *)*n1);
+    }
+  else
+    {
+      Str1 = (char **)MALLOC(sizeof(char *)*n1);
+    }
+
+  if (Str1 == NULL)
+    {
+      Scierror(999,_("%s: No more memory.\n"),fname);
+      if (Str)
+        {
+          FREE(Str);
+          Str = NULL;
+        }
+      return(0);
+    }
+
+  if ((Str1[n1-1] = (char *)MALLOC(sizeof(char))) == NULL)
+    {
+      freeArrayOfString(Str1, n1 - 1);
+      if (Str)
+        {
+          FREE(Str);
+          Str = NULL;
+        }
+      Scierror(999, _("%s: No more memory.\n"), fname);
+      return(0);
+    }
+  Str1[n1 - 1][0] = '\0';
+
+  CreateVarFromPtr(Rhs + 1, MATRIX_OF_STRING_DATATYPE, &n1, (j=1,&j), Str1);
+
+  freeArrayOfString(Str1,n1);
+  if (Str)
+    {
+      FREE(Str);
+      Str = NULL;
+    }
+
+  LhsVar(1) = Rhs + 1;
+  PutLhsVar();
+
+  return(0);
 }
 /*--------------------------------------------------------------------------*/
index e27a46b..7d7eb79 100644 (file)
  */
 int sci_set_fftw_wisdom(char *fname,unsigned long fname_len)
 {
-       CheckRhs(1,1);
 
-       if (VarType(1)==sci_strings) 
-       {
-               char **Str1 = NULL;
-               char *Str = NULL;
-               int m1 = 0, n1 = 0;
-               int len = 0, k = 0;
-               int j = 0;
+  if(withMKL()) {
+    Scierror(999,_("%s: MKL fftw library does not implement wisdom functions yet.\n"), fname);
+    return 0;
+  }
 
-               GetRhsVar(1,MATRIX_OF_STRING_DATATYPE,&m1,&n1,&Str1);
-               
-               for (j = 0; j < m1*n1; j++) 
-               {
-                       int i = 0;
+  CheckRhs(1,1);
 
-                       len += (int)strlen(Str1[j])+1;
+  if (VarType(1)==sci_strings)
+    {
+      char **Str1 = NULL;
+      char *Str = NULL;
+      int m1 = 0, n1 = 0;
+      int len = 0, k = 0;
+      int j = 0;
 
-                       if (Str) Str = (char *)REALLOC(Str,sizeof(char)*(len));
-                       else Str = (char *)MALLOC(sizeof(char)*(len));
+      GetRhsVar(1,MATRIX_OF_STRING_DATATYPE,&m1,&n1,&Str1);
 
-                       if (Str == NULL) 
-                       {
-                               freeArrayOfString(Str1,m1*n1);
-                               Scierror(999,_("%s: No more memory.\n"),fname);
-                               return(0);
-                       }
+      for (j = 0; j < m1*n1; j++)
+        {
+          int i = 0;
 
-                       for (i = 0; i < (int)strlen(Str1[j]); i++) 
-                       {
-                               Str[k+i] = Str1[j][i];
-                       }
-                       Str[k+strlen(Str1[j])] = '\n';
-                       k += (int)strlen(Str1[j])+1;
-               }
-               Str[k-1] = '\0';
+          len += (int)strlen(Str1[j])+1;
 
-               freeArrayOfString(Str1,m1*n1);
-  
-               if(!(call_fftw_import_wisdom_from_string(Str))) 
-               {
-                       FREE(Str); Str = NULL;
-                       Scierror(999,_("%s: An error occurred: %s\n"),fname,_("FFTW can't read wisdom."));
-                       return(0);
-               }
-               FREE(Str); Str = NULL;
-       }
-       else 
-       {
-               Scierror(999,_("%s: Wrong type for input argument #%d: A string expected.\n"),fname,1);
-               return(0);
-       }
+          if (Str) Str = (char *)REALLOC(Str,sizeof(char)*(len));
+          else Str = (char *)MALLOC(sizeof(char)*(len));
 
-       LhsVar(1)= 0;
-       PutLhsVar();
-       return(0);
+          if (Str == NULL)
+            {
+              freeArrayOfString(Str1,m1*n1);
+              Scierror(999,_("%s: Cannot allocate more memory.\n"),fname);
+              return(0);
+            }
+
+          for (i = 0; i < (int)strlen(Str1[j]); i++)
+            {
+              Str[k+i] = Str1[j][i];
+            }
+          Str[k+strlen(Str1[j])] = '\n';
+          k += (int)strlen(Str1[j])+1;
+        }
+      Str[k-1] = '\0';
+
+      freeArrayOfString(Str1,m1*n1);
+
+      if(!(call_fftw_import_wisdom_from_string(Str)))
+        {
+          FREE(Str); Str = NULL;
+          Scierror(999,_("%s: Wrong value for input argument #%d: a valid wisdom expected.\n"),fname,1);
+          return(0);
+        }
+      FREE(Str); Str = NULL;
+    }
+  else
+    {
+      Scierror(999,_("%s: Wrong type for input argument #%d: A string expected.\n"),fname,1);
+      return(0);
+    }
+
+  LhsVar(1)= 0;
+  PutLhsVar();
+  return(0);
 }
 /*--------------------------------------------------------------------------*/
index be2250e..095ebd0 100644 (file)
@@ -1,21 +1,21 @@
 /*
  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
  * Copyright (C) 2006 - INRIA - Allan CORNET
- * 
+ *
  * This file must be used under the terms of the CeCILL.
  * This source file is licensed as described in the file COPYING, which
  * you should have received as part of this distribution.  The terms
- * are also available at    
+ * are also available at
  * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
  *
  */
-#include <windows.h> 
-/*--------------------------------------------------------------------------*/ 
+#include <windows.h>
+/*--------------------------------------------------------------------------*/
 #pragma comment(lib,"../../bin/libintl.lib")
-/*--------------------------------------------------------------------------*/ 
+/*--------------------------------------------------------------------------*/
 int WINAPI DllMain (HINSTANCE hInstance , DWORD reason, PVOID pvReserved)
 {
-  switch (reason) 
+  switch (reason)
     {
     case DLL_PROCESS_ATTACH:
       break;
@@ -28,5 +28,5 @@ int WINAPI DllMain (HINSTANCE hInstance , DWORD reason, PVOID pvReserved)
     }
   return 1;
 }
-/*--------------------------------------------------------------------------*/ 
+/*--------------------------------------------------------------------------*/
 
index 33b2f20..351db1e 100644 (file)
@@ -1,14 +1,15 @@
 /*
- * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
- * Copyright (C) 2006 - INRIA - Allan CORNET
- * 
- * This file must be used under the terms of the CeCILL.
- * This source file is licensed as described in the file COPYING, which
- * you should have received as part of this distribution.  The terms
- * are also available at    
- * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
- *
- */
+* Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+* Copyright (C) 2006 - INRIA - Allan CORNET
+* Copyright (C) 2012 - INRIA - Serge STEER
+*
+* This file must be used under the terms of the CeCILL.
+* This source file is licensed as described in the file COPYING, which
+* you should have received as part of this distribution.  The terms
+* are also available at
+* http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
+*
+*/
 #include "callfftw.h"
 /*--------------------------------------------------------------------------*/
 #include "dynamiclibrary.h"
 #include "MALLOC.h"
 #include "charEncoding.h"
 /*--------------------------------------------------------------------------*/
-typedef void (*PROC_FFTW_EXECUTE_SPLIT_DFT) (const fftw_plan p, double *ri, double *ii, double *ro, double *io);
+typedef void (*PROC_FFTW_EXECUTE_SPLIT_DFT)     (const fftw_plan p, double *ri, double *ii, double *ro, double *io);
+typedef void (*PROC_FFTW_EXECUTE_SPLIT_DFT_C2R) (const fftw_plan p, double *ri, double *ii, double *ro);
+typedef void (*PROC_FFTW_EXECUTE_SPLIT_DFT_R2C) (const fftw_plan p, double *ri,             double *ro, double *io);
+typedef void (*PROC_FFTW_EXECUTE_SPLIT_DFT_R2R) (const fftw_plan p, double *ri,             double *ro);
 typedef fftw_plan (*PROC_FFTW_PLAN_GURU_SPLIT_DFT) (int rank, const fftw_iodim *dims, int howmany_rank, const fftw_iodim *howmany_dims, double *ri, double *ii, double *ro, double *io, unsigned flags);
+typedef fftw_plan (*PROC_FFTW_PLAN_GURU_SPLIT_DFT_C2R) (int rank, const fftw_iodim *dims, int howmany_rank, const fftw_iodim *howmany_dims, double *ri, double *ii, double *ro, unsigned flags);
+typedef fftw_plan (*PROC_FFTW_PLAN_GURU_SPLIT_DFT_R2C) (int rank, const fftw_iodim *dims, int howmany_rank, const fftw_iodim *howmany_dims, double *ri, double *ro, double *io, unsigned flags);
+typedef fftw_plan (*PROC_FFTW_PLAN_GURU_SPLIT_DFT_R2R) (int rank, const fftw_iodim *dims, int howmany_rank, const fftw_iodim *howmany_dims, double *ri, double *ro, fftw_r2r_kind *kind, unsigned flags);
 typedef void (*PROC_FFTW_DESTROY_PLAN) (fftw_plan p);
-
 typedef char *(*PROC_FFTW_EXPORT_WISDOM_TO_STRING) (void);
 typedef int (*PROC_FFTW_IMPORT_WISDOM_FROM_STRING) (const char *input_string);
 typedef void (*PROC_FFTW_FORGET_WISDOM) (void);
 /*--------------------------------------------------------------------------*/
-static DynLibHandle hinstLib = NULL; 
-static PROC_FFTW_EXECUTE_SPLIT_DFT MY_FFTW_EXECUTE_SPLIT_DFT=NULL;
-static PROC_FFTW_PLAN_GURU_SPLIT_DFT MY_FFTW_PLAN_GURU_SPLIT_DFT=NULL;
-static PROC_FFTW_DESTROY_PLAN MY_FFTW_DESTROY_PLAN=NULL;
-
-static PROC_FFTW_EXPORT_WISDOM_TO_STRING MY_FFTW_EXPORT_WISDOM_TO_STRING=NULL;
-static PROC_FFTW_IMPORT_WISDOM_FROM_STRING MY_FFTW_IMPORT_WISDOM_FROM_STRING=NULL;
+static DynLibHandle hinstLib = NULL;
+static PROC_FFTW_EXECUTE_SPLIT_DFT       MY_FFTW_EXECUTE_SPLIT_DFT       = NULL;
+static PROC_FFTW_EXECUTE_SPLIT_DFT_C2R   MY_FFTW_EXECUTE_SPLIT_DFT_C2R   = NULL;
+static PROC_FFTW_EXECUTE_SPLIT_DFT_R2C   MY_FFTW_EXECUTE_SPLIT_DFT_R2C   = NULL;
+static PROC_FFTW_EXECUTE_SPLIT_DFT_R2R   MY_FFTW_EXECUTE_SPLIT_DFT_R2R   = NULL;
+static PROC_FFTW_PLAN_GURU_SPLIT_DFT     MY_FFTW_PLAN_GURU_SPLIT_DFT     = NULL;
+static PROC_FFTW_PLAN_GURU_SPLIT_DFT_C2R MY_FFTW_PLAN_GURU_SPLIT_DFT_C2R = NULL;
+static PROC_FFTW_PLAN_GURU_SPLIT_DFT_R2C MY_FFTW_PLAN_GURU_SPLIT_DFT_R2C = NULL;
+static PROC_FFTW_PLAN_GURU_SPLIT_DFT_R2R MY_FFTW_PLAN_GURU_SPLIT_DFT_R2R = NULL;
+static PROC_FFTW_DESTROY_PLAN            MY_FFTW_DESTROY_PLAN            = NULL;
+static PROC_FFTW_EXPORT_WISDOM_TO_STRING MY_FFTW_EXPORT_WISDOM_TO_STRING = NULL;
+static PROC_FFTW_IMPORT_WISDOM_FROM_STRING MY_FFTW_IMPORT_WISDOM_FROM_STRING = NULL;
 static PROC_FFTW_FORGET_WISDOM MY_FFTW_FORGET_WISDOM=NULL;
 /*--------------------------------------------------------------------------*/
 BOOL IsLoadedFFTW(void)
 {
-       if ( (MY_FFTW_EXECUTE_SPLIT_DFT) && (MY_FFTW_PLAN_GURU_SPLIT_DFT) && (MY_FFTW_DESTROY_PLAN) &&\
-             (MY_FFTW_EXPORT_WISDOM_TO_STRING) && (MY_FFTW_IMPORT_WISDOM_FROM_STRING) &&\
-             (MY_FFTW_FORGET_WISDOM) ) return TRUE;
-       return FALSE;
+    if ( (MY_FFTW_EXECUTE_SPLIT_DFT)       && (MY_FFTW_EXECUTE_SPLIT_DFT_C2R)     &&
+        (MY_FFTW_EXECUTE_SPLIT_DFT_R2C)   && (MY_FFTW_EXECUTE_SPLIT_DFT_R2R)     &&
+        (MY_FFTW_PLAN_GURU_SPLIT_DFT)     && (MY_FFTW_PLAN_GURU_SPLIT_DFT_C2R)   &&
+        (MY_FFTW_PLAN_GURU_SPLIT_DFT_R2C) && (MY_FFTW_PLAN_GURU_SPLIT_DFT_R2R)   &&
+        (MY_FFTW_DESTROY_PLAN)            &&
+        (MY_FFTW_EXPORT_WISDOM_TO_STRING) && (MY_FFTW_IMPORT_WISDOM_FROM_STRING) &&
+        (MY_FFTW_FORGET_WISDOM) ) return TRUE;
+    return FALSE;
 }
 /*--------------------------------------------------------------------------*/
 BOOL LoadFFTWLibrary(char *libraryname)
 {
-       if (libraryname == NULL) return FALSE;
-
-       if (hinstLib == NULL)
-       {
-               #ifdef _MSC_VER
-               {
-                       wchar_t * wclibraryname = to_wide_string(libraryname);
-                       if (wclibraryname)
-                       {
-                               hinstLib = LoadDynLibraryW(wclibraryname); 
-                               FREE(wclibraryname);
-                               wclibraryname = NULL;
-                       }
-               }
-               #else
-               hinstLib = LoadDynLibrary(libraryname);
-               #endif
-               MY_FFTW_EXECUTE_SPLIT_DFT=NULL;
-               MY_FFTW_PLAN_GURU_SPLIT_DFT=NULL;
-               MY_FFTW_DESTROY_PLAN=NULL;
-
-               MY_FFTW_EXPORT_WISDOM_TO_STRING=NULL;
-               MY_FFTW_IMPORT_WISDOM_FROM_STRING=NULL;
-               MY_FFTW_FORGET_WISDOM=NULL;
-
-               MY_FFTW_EXECUTE_SPLIT_DFT = (PROC_FFTW_EXECUTE_SPLIT_DFT) GetDynLibFuncPtr(hinstLib,"fftw_execute_split_dft");
-               MY_FFTW_PLAN_GURU_SPLIT_DFT = (PROC_FFTW_PLAN_GURU_SPLIT_DFT) GetDynLibFuncPtr(hinstLib,"fftw_plan_guru_split_dft");
-               MY_FFTW_DESTROY_PLAN = (PROC_FFTW_DESTROY_PLAN) GetDynLibFuncPtr(hinstLib,"fftw_destroy_plan");
-
-               MY_FFTW_EXPORT_WISDOM_TO_STRING = (PROC_FFTW_EXPORT_WISDOM_TO_STRING) GetDynLibFuncPtr(hinstLib,"fftw_export_wisdom_to_string");
-               MY_FFTW_IMPORT_WISDOM_FROM_STRING = (PROC_FFTW_IMPORT_WISDOM_FROM_STRING) GetDynLibFuncPtr(hinstLib, "fftw_import_wisdom_from_string");
-               MY_FFTW_FORGET_WISDOM = (PROC_FFTW_FORGET_WISDOM) GetDynLibFuncPtr(hinstLib,"fftw_forget_wisdom");
-       }
-
-       if ( MY_FFTW_EXECUTE_SPLIT_DFT && MY_FFTW_PLAN_GURU_SPLIT_DFT && MY_FFTW_DESTROY_PLAN &&\
-             MY_FFTW_EXPORT_WISDOM_TO_STRING && MY_FFTW_IMPORT_WISDOM_FROM_STRING &&\
-             MY_FFTW_FORGET_WISDOM )
-       {
-               return TRUE;
-       }
-       return FALSE;
+
+    if (libraryname == NULL) return FALSE;
+    if (hinstLib == NULL) {
+#ifdef _MSC_VER
+        {
+            wchar_t * wclibraryname = to_wide_string(libraryname);
+            if (wclibraryname)
+            {
+                hinstLib = LoadDynLibraryW(wclibraryname);
+                FREE(wclibraryname);
+                wclibraryname = NULL;
+            }
+        }
+#else
+        hinstLib = LoadDynLibrary(libraryname);
+#endif
+        MY_FFTW_EXECUTE_SPLIT_DFT        = NULL;
+        MY_FFTW_EXECUTE_SPLIT_DFT_C2R    = NULL;
+        MY_FFTW_EXECUTE_SPLIT_DFT_R2C    = NULL;
+        MY_FFTW_EXECUTE_SPLIT_DFT_R2R    = NULL;
+
+        MY_FFTW_PLAN_GURU_SPLIT_DFT      = NULL;
+        MY_FFTW_PLAN_GURU_SPLIT_DFT_C2R  = NULL;
+        MY_FFTW_PLAN_GURU_SPLIT_DFT_R2C  = NULL;
+        MY_FFTW_PLAN_GURU_SPLIT_DFT_R2R  = NULL;
+
+        MY_FFTW_DESTROY_PLAN             = NULL;
+
+        MY_FFTW_EXPORT_WISDOM_TO_STRING  = NULL;
+        MY_FFTW_IMPORT_WISDOM_FROM_STRING= NULL;
+        MY_FFTW_FORGET_WISDOM            = NULL;
+
+        MY_FFTW_EXECUTE_SPLIT_DFT     = (PROC_FFTW_EXECUTE_SPLIT_DFT)     GetDynLibFuncPtr(hinstLib,"fftw_execute_split_dft");
+        MY_FFTW_EXECUTE_SPLIT_DFT_C2R = (PROC_FFTW_EXECUTE_SPLIT_DFT_C2R) GetDynLibFuncPtr(hinstLib,"fftw_execute_split_dft_c2r");
+        MY_FFTW_EXECUTE_SPLIT_DFT_R2C = (PROC_FFTW_EXECUTE_SPLIT_DFT_R2C) GetDynLibFuncPtr(hinstLib,"fftw_execute_split_dft_r2c");
+        MY_FFTW_EXECUTE_SPLIT_DFT_R2R = (PROC_FFTW_EXECUTE_SPLIT_DFT_R2R) GetDynLibFuncPtr(hinstLib,"fftw_execute_r2r");
+
+        MY_FFTW_PLAN_GURU_SPLIT_DFT     = (PROC_FFTW_PLAN_GURU_SPLIT_DFT)     GetDynLibFuncPtr(hinstLib,"fftw_plan_guru_split_dft");
+        MY_FFTW_PLAN_GURU_SPLIT_DFT_C2R = (PROC_FFTW_PLAN_GURU_SPLIT_DFT_C2R) GetDynLibFuncPtr(hinstLib,"fftw_plan_guru_split_dft_c2r");
+        MY_FFTW_PLAN_GURU_SPLIT_DFT_R2C = (PROC_FFTW_PLAN_GURU_SPLIT_DFT_R2C) GetDynLibFuncPtr(hinstLib,"fftw_plan_guru_split_dft_r2c");
+        MY_FFTW_PLAN_GURU_SPLIT_DFT_R2R = (PROC_FFTW_PLAN_GURU_SPLIT_DFT_R2R) GetDynLibFuncPtr(hinstLib,"fftw_plan_guru_r2r");
+
+
+        MY_FFTW_DESTROY_PLAN = (PROC_FFTW_DESTROY_PLAN) GetDynLibFuncPtr(hinstLib,"fftw_destroy_plan");
+
+        MY_FFTW_EXPORT_WISDOM_TO_STRING   = (PROC_FFTW_EXPORT_WISDOM_TO_STRING)   GetDynLibFuncPtr(hinstLib,"fftw_export_wisdom_to_string");
+        MY_FFTW_IMPORT_WISDOM_FROM_STRING = (PROC_FFTW_IMPORT_WISDOM_FROM_STRING) GetDynLibFuncPtr(hinstLib, "fftw_import_wisdom_from_string");
+        MY_FFTW_FORGET_WISDOM             = (PROC_FFTW_FORGET_WISDOM) GetDynLibFuncPtr(hinstLib,"fftw_forget_wisdom");
+    }
+
+    if ( MY_FFTW_EXECUTE_SPLIT_DFT       && MY_FFTW_EXECUTE_SPLIT_DFT_C2R   &&
+        MY_FFTW_EXECUTE_SPLIT_DFT_R2C   && MY_FFTW_EXECUTE_SPLIT_DFT_R2R   &&
+        MY_FFTW_PLAN_GURU_SPLIT_DFT     && MY_FFTW_PLAN_GURU_SPLIT_DFT_C2R &&
+        MY_FFTW_PLAN_GURU_SPLIT_DFT_R2C && MY_FFTW_PLAN_GURU_SPLIT_DFT_R2R &&
+        MY_FFTW_DESTROY_PLAN            &&
+        MY_FFTW_EXPORT_WISDOM_TO_STRING && MY_FFTW_IMPORT_WISDOM_FROM_STRING &&
+        MY_FFTW_FORGET_WISDOM )
+    {
+        return TRUE;
+    }
+    return FALSE;
 }
 /*--------------------------------------------------------------------------*/
 BOOL DisposeFFTWLibrary(void)
 {
-       BOOL fFreeResult;
-
-       if (hinstLib)
-       {
-               fFreeResult = FreeDynLibrary(hinstLib); 
-               hinstLib=NULL;
-       }
-       
-       if (MY_FFTW_EXECUTE_SPLIT_DFT) MY_FFTW_EXECUTE_SPLIT_DFT=NULL;
-       if (MY_FFTW_PLAN_GURU_SPLIT_DFT) MY_FFTW_PLAN_GURU_SPLIT_DFT=NULL;
-       if (MY_FFTW_DESTROY_PLAN) MY_FFTW_DESTROY_PLAN=NULL;
-
-        if (MY_FFTW_EXPORT_WISDOM_TO_STRING) MY_FFTW_EXPORT_WISDOM_TO_STRING=NULL;
-        if (MY_FFTW_IMPORT_WISDOM_FROM_STRING) MY_FFTW_IMPORT_WISDOM_FROM_STRING=NULL;
-        if (MY_FFTW_FORGET_WISDOM) MY_FFTW_FORGET_WISDOM=NULL;
-
-       if ( !MY_FFTW_EXECUTE_SPLIT_DFT && !MY_FFTW_PLAN_GURU_SPLIT_DFT && !MY_FFTW_DESTROY_PLAN &&\
-             !MY_FFTW_EXPORT_WISDOM_TO_STRING && !MY_FFTW_IMPORT_WISDOM_FROM_STRING &&\
-             !MY_FFTW_FORGET_WISDOM )
-       {
-               return TRUE;
-       }
-
-       return FALSE;
+    BOOL fFreeResult;
+
+    if (hinstLib)
+    {
+        fFreeResult = FreeDynLibrary(hinstLib);
+        hinstLib = NULL;
+    }
+
+    if (MY_FFTW_EXECUTE_SPLIT_DFT) MY_FFTW_EXECUTE_SPLIT_DFT = NULL;
+    if (MY_FFTW_EXECUTE_SPLIT_DFT_C2R) MY_FFTW_EXECUTE_SPLIT_DFT_C2R = NULL;
+    if (MY_FFTW_EXECUTE_SPLIT_DFT_R2C) MY_FFTW_EXECUTE_SPLIT_DFT_R2C = NULL;
+    if (MY_FFTW_EXECUTE_SPLIT_DFT_R2R) MY_FFTW_EXECUTE_SPLIT_DFT_R2R = NULL;
+
+    if (MY_FFTW_PLAN_GURU_SPLIT_DFT) MY_FFTW_PLAN_GURU_SPLIT_DFT = NULL;
+    if (MY_FFTW_PLAN_GURU_SPLIT_DFT_C2R) MY_FFTW_PLAN_GURU_SPLIT_DFT_C2R = NULL;
+    if (MY_FFTW_PLAN_GURU_SPLIT_DFT_R2C) MY_FFTW_PLAN_GURU_SPLIT_DFT_R2C = NULL;
+    if (MY_FFTW_PLAN_GURU_SPLIT_DFT_R2R) MY_FFTW_PLAN_GURU_SPLIT_DFT_R2R = NULL;
+
+    if (MY_FFTW_DESTROY_PLAN) MY_FFTW_DESTROY_PLAN = NULL;
+
+    if (MY_FFTW_EXPORT_WISDOM_TO_STRING) MY_FFTW_EXPORT_WISDOM_TO_STRING     = NULL;
+    if (MY_FFTW_IMPORT_WISDOM_FROM_STRING) MY_FFTW_IMPORT_WISDOM_FROM_STRING = NULL;
+    if (MY_FFTW_FORGET_WISDOM) MY_FFTW_FORGET_WISDOM                         = NULL;
+
+    if ( !MY_FFTW_EXECUTE_SPLIT_DFT       && !MY_FFTW_EXECUTE_SPLIT_DFT_C2R     &&
+        !MY_FFTW_EXECUTE_SPLIT_DFT_R2C   && !MY_FFTW_EXECUTE_SPLIT_DFT_R2R     &&
+        !MY_FFTW_PLAN_GURU_SPLIT_DFT     && !MY_FFTW_PLAN_GURU_SPLIT_DFT_C2R   &&
+        !MY_FFTW_PLAN_GURU_SPLIT_DFT_R2C && !MY_FFTW_PLAN_GURU_SPLIT_DFT_R2R   &&
+        !MY_FFTW_DESTROY_PLAN            &&
+        !MY_FFTW_EXPORT_WISDOM_TO_STRING && !MY_FFTW_IMPORT_WISDOM_FROM_STRING &&
+        !MY_FFTW_FORGET_WISDOM )
+    {
+        return TRUE;
+    }
+
+    return FALSE;
+}
+/*--------------------------------------------------------------------------*/
+void call_fftw_execute_split_dft (const fftw_plan p, double *ri, double *ii, double *ro, double *io)
+{
+    if (MY_FFTW_EXECUTE_SPLIT_DFT)
+    {
+        (MY_FFTW_EXECUTE_SPLIT_DFT)(p, ri, ii, ro, io);
+    }
+}
+/*--------------------------------------------------------------------------*/
+void call_fftw_execute_split_dft_c2r (const fftw_plan p, double *ri, double *ii, double *ro)
+{
+    if (MY_FFTW_EXECUTE_SPLIT_DFT_C2R)
+    {
+        (MY_FFTW_EXECUTE_SPLIT_DFT_C2R)(p, ri, ii, ro);
+    }
 }
 /*--------------------------------------------------------------------------*/
-void call_fftw_execute_split_dft (const fftw_plan p, double *ri, double *ii, double *ro, double *io) 
+void call_fftw_execute_split_dft_r2c (const fftw_plan p, double *ri, double *ro, double *io)
 {
-       if (MY_FFTW_EXECUTE_SPLIT_DFT)
-       {
-               (MY_FFTW_EXECUTE_SPLIT_DFT)(p,ri,ii,ro,io);
-       }
+    if (MY_FFTW_EXECUTE_SPLIT_DFT_R2C)
+    {
+        (MY_FFTW_EXECUTE_SPLIT_DFT_R2C)(p, ri, ro, io);
+    }
 }
 /*--------------------------------------------------------------------------*/
-fftw_plan call_fftw_plan_guru_split_dft (int rank, const fftw_iodim *dims, int howmany_rank, const fftw_iodim *howmany_dims, double *ri, double *ii, double *ro, double *io, unsigned flags) 
+void call_fftw_execute_split_dft_r2r (const fftw_plan p, double *ri, double *ro)
 {
-       if (MY_FFTW_PLAN_GURU_SPLIT_DFT)
-       {
-               return (fftw_plan)(MY_FFTW_PLAN_GURU_SPLIT_DFT)(rank,dims,howmany_rank,howmany_dims,ri,ii,ro,io,flags);
-       }
-       else return NULL;
+    if (MY_FFTW_EXECUTE_SPLIT_DFT_R2R)
+    {
+        (MY_FFTW_EXECUTE_SPLIT_DFT_R2R)(p, ri, ro);
+    }
 }
 /*--------------------------------------------------------------------------*/
-void call_fftw_destroy_plan (fftw_plan p) 
+fftw_plan call_fftw_plan_guru_split_dft (int rank, const fftw_iodim *dims, int howmany_rank, const fftw_iodim *howmany_dims, double *ri, double *ii, double *ro, double *io, unsigned flags)
+{
+    if (MY_FFTW_PLAN_GURU_SPLIT_DFT)
+    {
+        return (fftw_plan)(MY_FFTW_PLAN_GURU_SPLIT_DFT)(rank, dims, howmany_rank, howmany_dims, ri, ii, ro, io, flags);
+    }
+    else return NULL;
+}
+/*--------------------------------------------------------------------------*/
+fftw_plan call_fftw_plan_guru_split_dft_c2r (int rank, const fftw_iodim *dims, int howmany_rank, const fftw_iodim *howmany_dims, double *ri, double *ii, double *ro,  unsigned flags)
+{
+    if (MY_FFTW_PLAN_GURU_SPLIT_DFT_C2R)
+    {
+        return (fftw_plan)(MY_FFTW_PLAN_GURU_SPLIT_DFT_C2R)(rank, dims, howmany_rank, howmany_dims, ri, ii, ro, flags);
+    }
+    else return NULL;
+}
+/*--------------------------------------------------------------------------*/
+fftw_plan call_fftw_plan_guru_split_dft_r2c (int rank, const fftw_iodim *dims, int howmany_rank, const fftw_iodim *howmany_dims, double *ri, double *ro, double *io, unsigned flags)
+{
+    if (MY_FFTW_PLAN_GURU_SPLIT_DFT_R2C)
+    {
+        return (fftw_plan)(MY_FFTW_PLAN_GURU_SPLIT_DFT_R2C)(rank, dims, howmany_rank, howmany_dims, ri, ro, io, flags);
+    }
+    else return NULL;
+}
+/*--------------------------------------------------------------------------*/
+fftw_plan call_fftw_plan_guru_split_dft_r2r (int rank, const fftw_iodim *dims, int howmany_rank, const fftw_iodim *howmany_dims, double *ri, double *ro, fftw_r2r_kind *kind, unsigned flags)
+{
+    if (MY_FFTW_PLAN_GURU_SPLIT_DFT_R2R)
+    {
+        return (fftw_plan)(MY_FFTW_PLAN_GURU_SPLIT_DFT_R2R)(rank, dims, howmany_rank, howmany_dims, ri, ro, kind, flags);
+    }
+    else return NULL;
+}
+
+/*--------------------------------------------------------------------------*/
+void call_fftw_destroy_plan (fftw_plan p)
 {
-       if (MY_FFTW_DESTROY_PLAN)
-       {
-               (MY_FFTW_DESTROY_PLAN)(p);
-       }
+    if (MY_FFTW_DESTROY_PLAN)
+    {
+        (MY_FFTW_DESTROY_PLAN)(p);
+    }
 }
 /*--------------------------------------------------------------------------*/
 char *call_fftw_export_wisdom_to_string (void)
 {
-       if (MY_FFTW_EXPORT_WISDOM_TO_STRING)
-       {
-               return (char *)(MY_FFTW_EXPORT_WISDOM_TO_STRING)();
-       }
-       return NULL;
+    if (MY_FFTW_EXPORT_WISDOM_TO_STRING)
+    {
+        return (char *)(MY_FFTW_EXPORT_WISDOM_TO_STRING)();
+    }
+    return NULL;
 }
 /*--------------------------------------------------------------------------*/
 int call_fftw_import_wisdom_from_string (const char *input_string)
 {
-       if (MY_FFTW_IMPORT_WISDOM_FROM_STRING)
-       {
-               return (int)(MY_FFTW_IMPORT_WISDOM_FROM_STRING)(input_string);
-       }
-       return 0;
+    if (MY_FFTW_IMPORT_WISDOM_FROM_STRING)
+    {
+        return (int)(MY_FFTW_IMPORT_WISDOM_FROM_STRING)(input_string);
+    }
+    return 0;
 }
 /*--------------------------------------------------------------------------*/
 void call_fftw_forget_wisdom (void)
 {
-       if (MY_FFTW_FORGET_WISDOM)
-       {
-               (MY_FFTW_FORGET_WISDOM)();
-       }
+    if (MY_FFTW_FORGET_WISDOM)
+    {
+        (MY_FFTW_FORGET_WISDOM)();
+    }
 }
 /*--------------------------------------------------------------------------*/
index 008b61f..a2205ca 100644 (file)
@@ -1,11 +1,12 @@
 /*
  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
  * Copyright (C) 2006 - INRIA - Allan CORNET
- * 
+ * Copyright (C) 2012 - INRIA - Serge STEER
+ *
  * This file must be used under the terms of the CeCILL.
  * This source file is licensed as described in the file COPYING, which
  * you should have received as part of this distribution.  The terms
- * are also available at    
+ * are also available at
  * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
  *
  */
@@ -22,11 +23,23 @@ BOOL LoadFFTWLibrary(char *libraryname);
 /*--------------------------------------------------------------------------*/
 BOOL DisposeFFTWLibrary(void);
 /*--------------------------------------------------------------------------*/
-void call_fftw_execute_split_dft (const fftw_plan p, double *ri, double *ii, double *ro, double *io); 
+void call_fftw_execute_split_dft (const fftw_plan p, double *ri, double *ii, double *ro, double *io);
+/*--------------------------------------------------------------------------*/
+void call_fftw_execute_split_dft_c2r (const fftw_plan p, double *ri, double *ii, double *ro);
+/*--------------------------------------------------------------------------*/
+void call_fftw_execute_split_dft_r2c (const fftw_plan p, double *ri, double *ro, double *io);
+/*--------------------------------------------------------------------------*/
+void call_fftw_execute_split_dft_r2r (const fftw_plan p, double *ri, double *ro);
 /*--------------------------------------------------------------------------*/
 fftw_plan call_fftw_plan_guru_split_dft (int rank, const fftw_iodim *dims, int howmany_rank, const fftw_iodim *howmany_dims, double *ri, double *ii, double *ro, double *io, unsigned flags) ;
 /*--------------------------------------------------------------------------*/
-void call_fftw_destroy_plan (fftw_plan p); 
+fftw_plan call_fftw_plan_guru_split_dft_c2r (int rank, const fftw_iodim *dims, int howmany_rank, const fftw_iodim *howmany_dims, double *ri, double *ii, double *ro,  unsigned flags);
+/*--------------------------------------------------------------------------*/
+fftw_plan call_fftw_plan_guru_split_dft_r2c (int rank, const fftw_iodim *dims, int howmany_rank, const fftw_iodim *howmany_dims, double *ri, double *ro, double *io, unsigned flags);
+/*--------------------------------------------------------------------------*/
+fftw_plan call_fftw_plan_guru_split_dft_r2r (int rank, const fftw_iodim *dims, int howmany_rank, const fftw_iodim *howmany_dims, double *ri, double *ro, fftw_r2r_kind *kind, unsigned flags);
+/*--------------------------------------------------------------------------*/
+void call_fftw_destroy_plan (fftw_plan p);
 /*--------------------------------------------------------------------------*/
 char *call_fftw_export_wisdom_to_string (void);
 /*--------------------------------------------------------------------------*/
@@ -34,5 +47,8 @@ int call_fftw_import_wisdom_from_string (const char *input_string);
 /*--------------------------------------------------------------------------*/
 void call_fftw_forget_wisdom (void);
 /*--------------------------------------------------------------------------*/
+int withMKL(void);
+/*--------------------------------------------------------------------------*/
+
 #endif /* __CALLFFTW_H__ */
 /*--------------------------------------------------------------------------*/
index 3050fca..0efab75 100644 (file)
@@ -4,7 +4,7 @@
  *
  * The following statement of license applies *only* to this header file,
  * and *not* to the other files distributed with FFTW or derived therefrom:
- * 
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -84,9 +84,9 @@ extern "C"
 #if defined(FFTW_DLL) && (defined(_WIN32) || defined(__WIN32__))
    /* annoying Windows syntax for shared-library declarations */
 #  if defined(COMPILING_FFTW) /* defined in api.h when compiling FFTW */
-#    define FFTW_EXTERN extern __declspec(dllexport) 
+#    define FFTW_EXTERN extern __declspec(dllexport)
 #  else /* user is calling FFTW; import symbol */
-#    define FFTW_EXTERN extern __declspec(dllimport) 
+#    define FFTW_EXTERN extern __declspec(dllimport)
 #  endif
 #else
 #  define FFTW_EXTERN extern
@@ -107,7 +107,7 @@ struct fftw_iodim_do_not_use_me {
 /*
   huge second-order macro that defines prototypes for all API
   functions.  We expand this macro for each supported precision
+
   X: name-mangling macro
   R: real data type
   C: complex data type
index 9169fad..d656f8f 100644 (file)
@@ -2,36 +2,68 @@
  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
  * Copyright (C) 2006-2007 - INRIA - Alan LAYEC
  * Copyright (C) 2007 - INRIA - Allan CORNET
- * 
+ * Copyright (C) 2012 - INRIA - Serge STEER
+ *
  * This file must be used under the terms of the CeCILL.
  * This source file is licensed as described in the file COPYING, which
  * you should have received as part of this distribution.  The terms
- * are also available at    
+ * are also available at
  * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
  *
  */
 #include "fftw_utilities.h"
 #include "MALLOC.h"
 #include "callfftw.h"
-/*--------------------------------------------------------------------------*/ 
+#include <math.h>
+int check_1D_symmetry(double *Ar,double *Ai, int nA, int iA);
+int check_2D_symmetry(double *Ar,double *Ai, int mA, int iA, int nA, int jA);
+int check_ND_symmetry(double *Ar,double *Ai, int ndims, int *dims, int *incr);
+
+void complete_1D_array(double *Ar, double *Ai,int nA, int iA);
+void complete_2D_array(double *Ar, double *Ai,int mA, int iA, int nA, int jA);
+int complete_ND_array(double *Ar, double *Ai, int ndims, int *dims, int *incr);
+
+/*--------------------------------------------------------------------------*/
 /* definition of structures to store parameters
  * of FFTW planners - set here default value -
  */
 FFTW_Plan_struct Sci_Forward_Plan =
-{
-  NULL,            /* fftw_plan p              */
-  {0,NULL,0,NULL}, /* guru_dim_struct gdim     */
-  FFTW_ESTIMATE    /* unsigned flags           */
-};
+  {
+    0,               /* int plan_type            */
+    NULL,            /* fftw_plan p              */
+    {0,NULL,0,NULL}, /* guru_dim_struct gdim     */
+    FFTW_ESTIMATE    /* unsigned flags           */
+  };
 
 FFTW_Plan_struct Sci_Backward_Plan =
+  {
+    0,                /* int plan_type            */
+    NULL,             /* fftw_plan p              */
+    {0,NULL,0,NULL},  /* guru_dim_struct gdim     */
+    FFTW_ESTIMATE     /* unsigned flags           */
+  };
+/*--------------------------------------------------------------------------*/
+FFTW_Plan_struct *getSci_Backward_Plan(void)
 {
-  NULL,             /* fftw_plan p              */
-  {0,NULL,0,NULL},  /* guru_dim_struct gdim     */
-  FFTW_ESTIMATE     /* unsigned flags           */
-};
-
-unsigned cur_fftw_flags=FFTW_ESTIMATE;
+  return &Sci_Backward_Plan;
+}
+/*--------------------------------------------------------------------------*/
+FFTW_Plan_struct *getSci_Forward_Plan(void)
+{
+  return &Sci_Forward_Plan;
+}
+/*--------------------------------------------------------------------------*/
+unsigned cur_fftw_flags = FFTW_ESTIMATE;
+/*--------------------------------------------------------------------------*/
+unsigned int getCurrentFftwFlags(void)
+{
+  return cur_fftw_flags;
+}
+/*--------------------------------------------------------------------------*/
+void setCurrentFftwFlags(unsigned int newFftwFlags)
+{
+  cur_fftw_flags = newFftwFlags;
+}
 /*--------------------------------------------------------------------------*/
 /* Free a FFTW_Plan_struct
  *
@@ -64,7 +96,7 @@ int FreeFFTWPlan(FFTW_Plan_struct *Sci_Plan)
  * the given input parameters follows an already stored
  * set of parameters.
  * If found then return an already stored plan ptr.
- * If not found, then returns 
+ * If not found, then returns
  * a new set of parameters (and a new plan)
  * with fftw_plan_guru_split_dft
  * and store it in Sci_xx_Plan structures
@@ -78,58 +110,112 @@ int FreeFFTWPlan(FFTW_Plan_struct *Sci_Plan)
  *
  *
  */
-fftw_plan GetFFTWPlan(guru_dim_struct *gdim,
+fftw_plan GetFFTWPlan(enum Plan_Type type, guru_dim_struct *gdim,
                       double *ri, double *ii,
                       double *ro, double *io,
                       unsigned flags, int isn)
 {
   FFTW_Plan_struct *Sci_Plan;
-  int i;
+  int i=0;
+  fftw_r2r_kind *kind = NULL;
 
   if (isn==-1) Sci_Plan = &Sci_Backward_Plan;
   else Sci_Plan = &Sci_Forward_Plan;
 
   if ( (!(CheckGuruDims(&(Sci_Plan->gdim), gdim))) ||
-       (Sci_Plan->flags != cur_fftw_flags) ) {
+       (Sci_Plan->flags != cur_fftw_flags)||
+       (Sci_Plan->plan_type != type))
+    { /* plan must be changed */
+      FreeFFTWPlan(Sci_Plan);
 
-    FreeFFTWPlan(Sci_Plan);
+      Sci_Plan->plan_type = type;
+      if (gdim->rank != 0)
+        {
+          Sci_Plan->gdim.rank = gdim->rank;
+          if ((Sci_Plan->gdim.dims = (fftw_iodim *) MALLOC(sizeof(fftw_iodim)*(gdim->rank)))==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 (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)
+            {
+              FREE(Sci_Plan->gdim.dims);
+              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;
+            }
+        }
 
-    if (gdim->rank != 0) {
-      Sci_Plan->gdim.rank = gdim->rank;
-      if ((Sci_Plan->gdim.dims = \
-              (fftw_iodim *)MALLOC(sizeof(fftw_iodim)*gdim->rank))==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;
-      }
-    }
+      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);
 
-    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) {
-       FREE(Sci_Plan->gdim.dims);
-       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;
-      }
-    }
+          break;
+        case R2R_PLAN:
+          if ((kind=(fftw_r2r_kind *)MALLOC(sizeof(fftw_r2r_kind)*Sci_Plan->gdim.rank))==NULL)
+            {
+              return(NULL);
+            }
+          for (i=0;i<Sci_Plan->gdim.rank;i++)
+            {
+              kind[i]=FFTW_REDFT00;
+              if  ((Sci_Plan->gdim.dims[i].n)%2 == 0)
+                {
+                  /*even */
+                  /*   kind[i]=(isn==-1)?FFTW_RODFT10:FFTW_RODFT01; */
+                  //kind[i]=FFTW_R2HC;
+                  kind[i]=FFTW_REDFT00;
+                }
+              else
+                {
+                  /*odd*/
+                  kind[i]=FFTW_REDFT00;
+                }
+            }
+          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);
+          FREE(kind);
+          break;
+        }
 
-    Sci_Plan->flags = cur_fftw_flags;
-
-    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);
-  }
+    }
   return(Sci_Plan->p);
 }
 /*--------------------------------------------------------------------------*/
@@ -146,19 +232,923 @@ int CheckGuruDims(guru_dim_struct *gdim1, guru_dim_struct *gdim2)
   int i;
 
   if( (gdim1->rank==gdim2->rank) &&
-      (gdim1->howmany_rank==gdim2->howmany_rank)) {
-    for(i=0;i<gdim1->rank;i++) {
-      if (gdim1->dims[i].n  != gdim2->dims[i].n)  return(0);
-      if (gdim1->dims[i].is != gdim2->dims[i].is) return(0);
-      if (gdim1->dims[i].os != gdim2->dims[i].os) return(0);
-    }
-    for(i=0;i<gdim1->howmany_rank;i++) {
-      if (gdim1->howmany_dims[i].n  != gdim2->howmany_dims[i].n)  return(0);
-      if (gdim1->howmany_dims[i].is != gdim2->howmany_dims[i].is) return(0);
-      if (gdim1->howmany_dims[i].os != gdim2->howmany_dims[i].os) return(0);
-    }
-    return(1);
-  }
+      (gdim1->howmany_rank==gdim2->howmany_rank))
+    {
+      for(i=0;i<gdim1->rank;i++)
+        {
+          if (gdim1->dims[i].n  != gdim2->dims[i].n)  return(0);
+          if (gdim1->dims[i].is != gdim2->dims[i].is) return(0);
+          if (gdim1->dims[i].os != gdim2->dims[i].os) return(0);
+        }
+      for(i=0;i<gdim1->howmany_rank;i++)
+        {
+          if (gdim1->howmany_dims[i].n  != gdim2->howmany_dims[i].n)  return(0);
+          if (gdim1->howmany_dims[i].is != gdim2->howmany_dims[i].is) return(0);
+          if (gdim1->howmany_dims[i].os != gdim2->howmany_dims[i].os) return(0);
+        }
+      return(1);
+    }
   else return(0);
 }
 /*--------------------------------------------------------------------------*/
+/* call different fftw_execute_split_dft_xxx procedures according to type input
+ *
+ * Input :  Plan_Type type
+ *          fftw_plan p
+ *          double *ri
+ *          double *ii
+ * Output : double *ro
+ *          double *io
+ */
+void ExecuteFFTWPlan(enum Plan_Type type, const fftw_plan p, double *ri, double *ii,double *ro, double *io)
+{
+  switch (type)
+    {
+    case C2C_PLAN:
+      call_fftw_execute_split_dft(p,ri,ii,ro,io);
+      break;
+    case C2R_PLAN:
+      call_fftw_execute_split_dft_c2r(p,ri,ii,ro);
+      break;
+    case R2C_PLAN:
+      call_fftw_execute_split_dft_r2c(p,ri,ro,io);
+      break;
+    case R2R_PLAN:
+      call_fftw_execute_split_dft_r2r(p,ri,ro);
+      break;
+    }
+}
+/*--------------------------------------------------------------------------*/
+int is_real(double *Ar,double *Ai, int ndims, int *dims)
+{
+  double zero=0.0;
+  int t = 1;
+  int i = 0;
+  int lA = 1;
+
+
+  for (i=0;i<ndims;i++)
+    {
+      lA = lA *dims[i];
+    }
+
+  /*Check if A is real*/
+  if (Ai != NULL)
+    {
+      for (i=0;i<lA;i++)
+        {
+          if (Ai[i] != zero)
+            {
+              t = 0;
+              break;
+            }
+        }
+    }
+  return t;
+}
+
+/*--------------------------------------------------------------------------
+ * Check if a 1D array A  is "symmetric" or hermitian symmetric for fft.
+ * A==conj(A([1 $:-1:2]))
+ * Ar : pointer on real part array
+ * Ai : pointer on imaginary part array or NULL
+ * nA : number of elements
+ * iA : increment between 2 consecutive element of the array
+ */
+
+int check_1D_symmetry(double *Ar,double *Ai, int nA, int iA)
+{
+  int i = 0;
+  int nas2 = (int)(nA/2);
+  double zero = 0.0;
+  //Checking real part
+  if ( nA % 2 == 0)
+    {
+      /* A length is even */
+      for (i=1;i<nas2;i++)
+        {
+          if (Ar[iA*i] != Ar[iA*(nA-i)]) return 0;
+        }
+    }
+  else
+    { /* A length is odd */
+      for (i=1;i<=nas2;i++)
+        {
+          if (Ar[iA*i] != Ar[iA*(nA-i)])  return 0;
+        }
+    }
+  if (Ai==NULL) return 1;
+  //Checking imaginary part
+  if ( nA % 2 == 0)
+    {
+      /* A length is even */
+      if (Ai[0] != zero|| Ai[iA*(nA/2)] != zero) return 0;
+      for (i=1;i<nas2;i++)
+        {
+          if (Ai[iA*i] != -Ai[iA*(nA-i)]) return 0;
+        }
+    }
+  else
+    { /* A length is odd */
+      if (Ai[0] != zero) return 0;
+      for (i=1;i<=nas2;i++)
+        {
+          if (Ai[iA*i] != -Ai[iA*(nA-i)]) return 0;
+        }
+    }
+  return 1;
+}
+/*--------------------------------------------------------------------------
+ * Check if a 2D array A  is "symmetric" or hermitian symmetric for fft.
+ * A==conj(A([1 $:-1:2],[1 $:-1:2])
+ * Ar : pointer on real part array
+ * Ai : pointer on imaginary part array or NULL
+ * mA : number of rows
+ * nA : number of columns
+ * iA : increment between 2 consecutive element of a row
+ * jA : increment between 2 consecutive element of a column
+ */
+
+int check_2D_symmetry(double *Ar,double *Ai, int mA, int iA, int nA, int jA)
+{
+  int l1 = 0;
+  int l2 = 0;
+  int k = 0;
+  int l = 0;
+  int nAs2 = (int)(nA/2)+1;/* A VERIFIER */
+
+  /* Check first column */
+  if (!check_1D_symmetry(Ar,Ai,mA,iA))  return 0;
+  /* Check first row */
+  if (!check_1D_symmetry(Ar,Ai,nA,jA))  return 0;
+
+  /* Check A(2:$,2:$) block */
+  if (Ai==NULL)
+    {
+      for (k=1;k<nAs2;k++)
+        {
+          l1 = jA*k + iA ;
+          l2 = jA*(nA-k)+iA*(mA-1);
+          for (l=1;l<mA;l++)
+            {
+              if (Ar[l1] != Ar[l2]) return 0;
+              l1 += iA;
+              l2 -= iA;
+            }
+        }
+    }
+  else
+    {
+      for (k=1;k<nAs2;k++)
+        {
+          l1 = jA*k + iA ;
+          l2 = jA*(nA-k)+iA*(mA-1);
+          for (l=1;l<mA;l++)
+            {
+              if ((Ar[l1] != Ar[l2])||(Ai[l1] != -Ai[l2])) return 0;
+              l1 += iA;
+              l2 -= iA;
+            }
+        }
+    }
+  return 1;
+}
+
+/*--------------------------------------------------------------------------
+ * Check if a N-D array A  is "symmetric" or hermitian symmetric for fft
+ * A==conj(A([1 $:-1:2],...,[1 $:-1:2])
+ * Ar : pointer on real part array
+ * Ai : pointer on imaginary part array or NULL
+ * mA : number of rows
+ * nA : number of columns
+ * iA : increment between 2 consecutive element of a row
+ * jA : increment between 2 consecutive element of a column
+ */
+
+int check_ND_symmetry(double *Ar,double *Ai, int ndims, int *dims, int *incr)
+{
+  int i = 0, j = 0, l = 0;
+  int r = 0;
+  int l1 = 0;/* current 1-D index in array*/
+  int l2 = 0;/* associated symmetric value 1-D index */
+  int *temp = NULL;
+  int *dims1 = NULL;
+  int *incr1 = NULL;
+  int nSub = 0, nSubs2 = 0;
+  int k = 0, step = 0;
+
+  if (ndims==2)
+    {
+      r=check_2D_symmetry(Ar,Ai,dims[0],incr[0],dims[1],incr[1]);
+      return r;
+    }
+  else if  (ndims==1)
+    {
+      r=check_1D_symmetry(Ar,Ai,dims[0],incr[0]);
+      return r;
+    }
+
+  if  ((temp =  (int *)MALLOC(sizeof(int)*(2*ndims)))==NULL) return -1;
+  dims1 = temp;
+  incr1 = temp + ndims;
+
+  for (i=0;i<ndims;i++)
+    {
+      /* remove current dimension and increment out of  dims ans incr */
+      l=0;
+      for   (j =0;j<ndims;j++)
+        {
+          if (j!=i)
+            {
+              dims1[l]=dims[j];
+              incr1[l]=incr[j];
+              l++;
+            }
+        }
+      r=check_ND_symmetry(Ar,Ai, ndims-1, dims1,incr1);
+      if (r != 1)
+        {
+          dims1 = NULL;
+          incr1 = NULL;
+          FREE(temp);
+          return r;
+        }
+    }
+
+  /* check bloc A(2:$,....,2:$)*/
+  /*A(2,...,2) index*/
+  l1 = 0;
+  for (i =0;i<ndims;i++) l1 += incr[i];
+  /*A($,...,$) index*/
+  l2 = 0;
+  for (i =0;i<ndims;i++) l2 += (dims[i]-1)*incr[i];
+
+
+  /* cumprod(size(A(2:$,....,2:$)))*/
+  incr1[0]=dims[0]-1;
+  for (i =1;i<(ndims-1);i++) incr1[i] = incr1[i-1]*(dims[i]-1) ;
+  /* steps*/
+  dims1[0]=(dims[0]-2)*incr[0];
+  for (i =1;i<(ndims-1);i++) dims1[i]=dims1[i-1]+(dims[i]-2)*incr[i];
+
+  /*  A(2:$,....,2:$) block number of elements*/
+  nSub=1;
+  for (i =0;i<ndims;i++) nSub *= (dims[i]-1);
+
+  nSubs2=(int)(nSub/2);
+
+
+  k = 0;
+  if (Ai == NULL)
+    {
+      /* Real case */
+      for (i=0;i<nSubs2;i++)
+        {
+
+          if (Ar[l1] != Ar[l2]) return 0;
+          step=incr[0];
+          for (j=ndims-2;j>=0;j--)
+            {
+              if ((i+1)%incr1[j]==0)
+                {
+                  step = -dims1[j]+incr[j+1] ;
+                  break;
+                }
+            }
+          l1 += step;
+          l2 -= step;
+        }
+    }
+  else {  /* Complex case */
+    for (i=0;i<nSubs2;i++)
+      {
+        if (Ar[l1] != Ar[l2]||Ai[l1] != -Ai[l2]) return 0;
+        step=incr[0];
+        for (j=ndims-2;j>=0;j--)
+          {
+            if ((i+1)%incr1[j]==0)
+              {
+                step = -dims1[j]+incr[j+1] ;
+                break;
+              }
+          }
+        l1 += step;
+        l2 -= step;
+      }
+  }
+  dims1 = NULL;
+  incr1 = NULL;
+  FREE(temp);
+  return 1;
+}
+
+
+
+int check_array_symmetry(double *Ar,double *Ai, guru_dim_struct gdim)
+{
+  int ndims=gdim.rank;
+  int * dims=NULL;
+  int * incr=NULL;
+  int r = -1;
+  int i = 0, j = 0, k = 0;
+
+  if (gdim.howmany_rank==0)
+    {
+      switch (gdim.rank)
+        {
+        case 1:
+          return check_1D_symmetry(Ar,Ai,gdim.dims[0].n,gdim.dims[0].is);
+        case 2:
+          return check_2D_symmetry(Ar,Ai,gdim.dims[0].n,gdim.dims[0].is,gdim.dims[1].n,gdim.dims[1].is);
+        default: /*general N-D case*/
+          if ((dims=(int *)MALLOC(sizeof(int)*gdim.rank))==NULL) return -1;
+          if ((incr=(int *)MALLOC(sizeof(int)*gdim.rank))==NULL)
+            {
+              FREE(dims);
+              return -1;
+            }
+          for (i=0;i<ndims;i++)
+            {
+              dims[i]=gdim.dims[i].n;
+              incr[i]=gdim.dims[i].is;
+            }
+          r=check_ND_symmetry(Ar,Ai,ndims,dims,incr);
+          FREE(dims);
+          FREE(incr);
+          return r;
+        }
+    }
+  else
+    {
+      int m = 0;
+      int p = 1;
+      int *dims1 = NULL;
+      int *incr1 = NULL;
+      int ir = 0;
+
+      if ((dims1=(int *)MALLOC(sizeof(int)*gdim.howmany_rank))==NULL) return -1;
+      dims1[0]=gdim.howmany_dims[0].n;
+      for (i=1;i<gdim.howmany_rank;i++) dims1[i]=dims1[i-1]*gdim.howmany_dims[i].n;
+      m= dims1[gdim.howmany_rank-1];
+
+      if ((incr1=(int *)MALLOC(sizeof(int)*gdim.howmany_rank))==NULL)
+        {
+          FREE(dims1);
+          return -1;
+        }
+      p=1;
+      for (i=0;i<gdim.howmany_rank;i++)
+        {
+          p +=(gdim.howmany_dims[i].n-1)*gdim.howmany_dims[i].is;
+          incr1[i]=p;
+        }
+      switch (gdim.rank)
+        {
+        case 1:
+          if (Ai == NULL)
+            {
+              /* multiple 1D fft */
+              for (ir=0;ir<gdim.howmany_rank;ir++)
+                {
+                  j = 0;
+                  for (i=1;i<=m;i++)
+                    {
+                      if ((r=check_1D_symmetry(Ar+j,NULL,gdim.dims[0].n,gdim.dims[0].is)) !=1 ) return r;
+                      j += gdim.howmany_dims[0].is;
+                      for (k=gdim.howmany_rank-2;k>=0;k--)
+                        {
+                          if (i%dims1[k]==0)
+                            {
+                              j += -incr1[k]+gdim.howmany_dims[k+1].is;
+                              break;
+                            }
+                        }
+                    }
+                }
+            }
+          else
+            {
+              for (ir=0;ir<gdim.howmany_rank;ir++)
+                {
+                  j = 0;
+                  for (i=1;i<=m;i++)
+                    {
+                      if ((r=check_1D_symmetry(Ar+j,Ai+j,gdim.dims[0].n,gdim.dims[0].is)) !=1 ) return r;
+                      j += gdim.howmany_dims[0].is;
+                      for (k=gdim.howmany_rank-2;k>=0;k--)
+                        {
+                          if (i%dims1[k]==0)
+                            {
+                              j += -incr1[k]+gdim.howmany_dims[k+1].is;
+                              break;
+                            }
+                        }
+                    }
+                }
+            }
+          FREE(dims1);
+          return 1;
+        case 2:  /* multiple 2D fft */
+          if (Ai == NULL)
+            {
+              for (ir=0;ir<gdim.howmany_rank;ir++)
+                {
+                  j = 0;
+                  for (i=1;i<=m;i++)
+                    {
+                      if ((r=check_2D_symmetry(Ar+j,NULL,gdim.dims[0].n,gdim.dims[0].is,
+                                               gdim.dims[1].n,gdim.dims[1].is)) !=1 ) return r;
+                      j += gdim.howmany_dims[0].is;
+
+                      for (k=gdim.howmany_rank-2;k>=0;k--)
+                        {
+                          if (i%dims1[k]==0)
+                            {
+                              j += -incr1[k]+gdim.howmany_dims[k+1].is;
+                              break;
+                            }
+                        }
+                    }
+                }
+            }
+          else {
+            for (ir=0;ir<gdim.howmany_rank;ir++)
+              {
+                j = 0;
+                for (i=1;i<=m;i++)
+                  {
+                    if ((r=check_2D_symmetry(Ar+j,Ai+j,gdim.dims[0].n,gdim.dims[0].is,
+                                             gdim.dims[1].n,gdim.dims[1].is)) !=1 ) return r;
+                    j += gdim.howmany_dims[0].is;
+                    for (k=gdim.howmany_rank-2;k>=0;k--)
+                      {
+                        if (i%dims1[k]==0)
+                          {
+                            j += -incr1[k]+gdim.howmany_dims[k+1].is;
+                            break;
+                          }
+                      }
+                  }
+              }
+          }
+          FREE(dims1);
+          FREE(incr1);
+          return 1;
+        default: /*general N-D case*/
+          if ((dims=(int *)MALLOC(sizeof(int)*gdim.rank))==NULL) return -1;
+          if ((incr=(int *)MALLOC(sizeof(int)*gdim.rank))==NULL)
+            {
+              FREE(dims);
+              return -1;
+            }
+          for (i=0;i<ndims;i++)
+            {
+              dims[i]=gdim.dims[i].n;
+              incr[i]=gdim.dims[i].is;
+            }
+          for (ir=0;ir<gdim.howmany_rank;ir++)
+            {
+              j = 0;
+              for (i=1;i<=m;i++)
+                {
+                  if (Ai == NULL)
+                    r=check_ND_symmetry(Ar+j,NULL,ndims,dims,incr);
+                  else
+                    r=check_ND_symmetry(Ar+j,Ai+j,ndims,dims,incr);
+                  if (r<=0)
+                    {
+                      FREE(dims);
+                      FREE(incr);
+                      FREE(dims1);
+                      return r;
+                    }
+                  j += gdim.howmany_dims[0].is;
+                  for (k=gdim.howmany_rank-2;k>=0;k--)
+                    {
+                      if (i%dims1[k]==0)
+                        {
+                          j += -incr1[k]+gdim.howmany_dims[k+1].is;
+                          break;
+                        }
+                    }
+                }
+            }
+          FREE(dims);
+          FREE(incr);
+          FREE(dims1);
+          return 1;
+        }
+    }
+  return 1;
+}
+/*--------------------------------------------------------------------------
+ * "symmetrizing" a vector A of length nA modifying the second half part of the vector
+ * nA even: A=[a0 A1 conj(A1($:-1:1))]
+ * nA odd : A=[a0 A1 am conj(A1($:-1:1))]
+ */
+
+void complete_1D_array(double *Ar, double *Ai, int nA, int iA)
+{
+  if (nA>2)
+    {
+      int nAs2 = (int)(nA/2);
+      int n = (nA%2 == 0)?nAs2-1:nAs2;
+      int l1 = iA; /* ignore first element */
+      int l2 = (nA-1)*iA;
+      int i = 0;
+      if (Ai == NULL)
+        {
+          for (i=0;i<n;i++)
+            {
+              Ar[l2]=Ar[l1];
+              l1 += iA;
+              l2 -= iA;
+            }
+        }
+      else
+        { 
+          for (i=0;i<n;i++)
+            {
+              Ar[l2]=Ar[l1];
+              Ai[l2]=-Ai[l1];
+              l1 += iA;
+              l2 -= iA;
+            }
+        }
+    }
+}
+
+/*--------------------------------------------------------------------------
+ * "symmetrizing" a mA x nA array modifying the second half part of the columns
+ * nA even: A=[a11 A12 conj(A12($:-1:1))
+ *             A21 A22 conj(A22($:-1:1,$:-1:1))]
+ *
+ * nA odd : A=[a11 A12 am  conj(A12($:-1:1))
+ A21 A22 A2m conj(A22($:-1:1,$:-1:1))]]
+*/
+
+void complete_2D_array(double *Ar, double *Ai,int mA, int iA, int nA, int jA)
+{
+  if (nA>2)
+    {
+      int n = (nA%2 == 0)?(int)(nA/2)-1:(int)(nA/2);
+      int i = 0, j = 0; /* loop variables */
+      int l1 = jA+iA; /* the index of the first element of the A22 block A(2,2)*/
+      int l2 = (mA-1)*iA+(nA-1)*jA; /* the index of the last element of the A22 block A(mA,nA)*/
+      int step = 0;
+      /* first column  */
+      /*could not be useful because fftw only skip half of the rightmost dimension but it may be not exactly symmetric */
+
+      complete_1D_array(Ar, Ai, mA, iA);
+
+      /* first row */
+      complete_1D_array(Ar, Ai,nA, jA);
+
+      /* A22 block */
+      if (Ai==NULL)
+        {
+          for (j=0;j<n;j++)
+            {
+              for (i=1;i<mA;i++)
+                {
+                  Ar[l2]=Ar[l1];
+                  l1 += iA;
+                  l2 -= iA;
+                }
+              step = -(mA-1)*iA+jA;
+              l1 += step;
+              l2 -= step;
+            }
+        }
+      else
+        {
+          for (j=0;j<n;j++)
+            {
+              for (i=1;i<mA;i++)
+                {
+                  Ar[l2]=Ar[l1];
+                  Ai[l2]=-Ai[l1];
+                  l1 += iA;
+                  l2 -= iA;
+                }
+              step = -(mA-1)*iA+jA;
+              l1 += step;
+              l2 -= step;
+            }
+        }
+    }
+}
+
+int complete_ND_array(double *Ar, double *Ai, int ndims, int *dims, int *incr)
+{
+  int i = 0, j = 0, l = 0;
+  int r = 0;
+  int l1 = 0;/* current 1-D index in array*/
+  int l2 = 0;/* associated symmetric value 1-D index */
+
+  int *temp = NULL;
+  int *dims1 = NULL;
+  int *incr1 = NULL;
+  int nSub = 0, nSubs2 = 0, k = 0, step = 0;
+
+  if (ndims==2)
+    {
+      complete_2D_array(Ar,Ai,dims[0],incr[0],dims[1],incr[1]);
+      return 0;
+    }
+  else if (ndims==1)
+    {
+      complete_1D_array(Ar,Ai,dims[0],incr[0]);
+      return 0;
+    }
+  if  ((temp =  (int *)MALLOC(sizeof(int)*(2*ndims)))==NULL) return -1;
+  dims1=temp;incr1=temp+ndims;
+
+  for (i =0;i<ndims;i++) {
+    /* remove current dimension and increment out of  dims ans incr */
+    l=0;
+    for   (j =0;j<ndims;j++)
+      {
+        if (j!=i)
+          {
+            dims1[l]=dims[j];
+            incr1[l]=incr[j];
+            l++;
+          }
+      }
+    r=complete_ND_array(Ar,Ai, ndims-1, dims1,incr1);
+    if (r<0)
+      {
+        dims1 = NULL;
+        incr1 = NULL;
+        FREE(temp);
+        return r;
+      }
+  }
+
+  /* check bloc A(2:$,....,2:$)*/
+  l1 = 0;
+  for (i =0;i<ndims;i++) l1 += incr[i];
+  /*A($,...,$) index*/
+  l2 = 0;
+  for (i =0;i<ndims;i++) l2 += (dims[i]-1)*incr[i];
+
+
+  /* cumprod(size(A(2:$,....,2:$)))*/
+  incr1[0]=dims[0]-1;
+  for (i =1;i<(ndims-1);i++) incr1[i] = incr1[i-1]*(dims[i]-1) ;
+  /* steps*/
+  dims1[0]=(dims[0]-2)*incr[0];
+  for (i =1;i<(ndims-1);i++) dims1[i]=dims1[i-1]+(dims[i]-2)*incr[i];
+
+  /*  A(2:$,....,2:$) block number of elements*/
+  nSub=1;
+  for (i =0;i<ndims;i++) nSub *= (dims[i]-1);
+
+  nSubs2=(int)(nSub/2);
+  k = 0;
+  if (Ai == 0)
+    {
+      /* Real case */
+      for (i=0;i<nSubs2;i++)
+        {
+          Ar[l2] = Ar[l1];
+          step=incr[0];
+          for (j=ndims-2;j>=0;j--)
+            {
+              if ((i+1)%incr1[j]==0)
+                {
+                  step = -dims1[j]+incr[j+1] ;
+                  break;
+                }
+            }
+          l1 += step;
+          l2 -= step;
+        }
+    }
+  else {  /* Complex case */
+    for (i=0;i<nSubs2;i++)
+      {
+        Ar[l2] = Ar[l1];
+        Ai[l2] = -Ai[l1];
+        step=incr[0];
+        for (j=ndims-2;j>=0;j--)
+          {
+            if ((i+1)%incr1[j]==0)
+              {
+                step = -dims1[j]+incr[j+1] ;
+                break;
+              }
+          }
+        l1 += step;
+        l2 -= step;
+      }
+  }
+  dims1 = NULL;
+  incr1 = NULL;
+  FREE(temp);
+  return 1;
+}
+
+int complete_array(double *Ar,double *Ai, guru_dim_struct gdim)
+{
+  int ndims=gdim.rank;
+  int * dims=NULL;
+  int * incr=NULL;
+  int r = -1;
+  int i = 0, j = 0, k = 0;
+  if (gdim.howmany_rank==0)
+    {
+      switch (gdim.rank)
+        {
+        case 1:
+          complete_1D_array(Ar,Ai,gdim.dims[0].n,gdim.dims[0].is);
+          return 0;
+        case 2:
+          complete_2D_array(Ar,Ai,gdim.dims[0].n,gdim.dims[0].is,gdim.dims[1].n,gdim.dims[1].is);
+          return 0;
+        default: /*general N-D case*/
+          if ((dims=(int *)MALLOC(sizeof(int)*gdim.rank))==NULL) return -1;
+          if ((incr=(int *)MALLOC(sizeof(int)*gdim.rank))==NULL)
+            {
+              FREE(dims);
+              return -1;
+            }
+          for (i=0;i<ndims;i++)
+            {
+              dims[i]=gdim.dims[i].n;
+              incr[i]=gdim.dims[i].is;
+            }
+          r=complete_ND_array(Ar,Ai,ndims,dims,incr);
+          FREE(dims);
+          FREE(incr);
+          return r;
+        }
+    }
+  else
+    {
+      int m = 0;
+      int p = 1;
+      int *dims1 = NULL;
+      int *incr1 = NULL;
+      int ir = 0;
+      int hrank = gdim.howmany_rank;
+
+      if ((dims1=(int *)MALLOC(sizeof(int)*hrank))==NULL) return -1;
+      dims1[0]=gdim.howmany_dims[0].n;
+      for (i=1;i<hrank;i++) dims1[i]=dims1[i-1]*gdim.howmany_dims[i].n;
+      m = dims1[gdim.howmany_rank-1];
+
+      if ((incr1=(int *)MALLOC(sizeof(int)*hrank))==NULL)
+        {
+          FREE(dims1);
+          return -1;
+        }
+      p=1;
+      for (i=0;i<hrank;i++)
+        {
+          p +=(gdim.howmany_dims[i].n-1)*gdim.howmany_dims[i].is;
+          incr1[i]=p;
+        }
+
+      switch (gdim.rank)
+        {
+        case 1: /* multiple 1D fft */
+          if (Ai == NULL)
+            {
+              for (ir=0;ir<hrank;ir++)
+                {
+                  j = 0;
+                  for (i=1; i<=m; i++)
+                    {
+                      complete_1D_array(Ar+j,NULL,gdim.dims[0].n,gdim.dims[0].is);
+                      j += gdim.howmany_dims[0].is;
+                      for (k=hrank-2; k>=0; k--)
+                        {
+                          if (i%dims1[k]==0)
+                            {
+                              j += -incr1[k]+gdim.howmany_dims[k+1].is;
+                              break;
+                            }
+                        }
+                    }
+                }
+            }
+          else
+            {
+              for (ir=0;ir<hrank;ir++)
+                {
+                  j = 0;
+                  for (i=1; i<=m; i++)
+                    {
+                      complete_1D_array(Ar+j,Ai+j,gdim.dims[0].n,gdim.dims[0].is);
+                      j += gdim.howmany_dims[0].is;
+                      for (k=hrank-2;k>=0;k--)
+                        {
+                          if (i%dims1[k]==0)
+                            {
+                              j += -incr1[k]+gdim.howmany_dims[k+1].is;
+                              break;
+                            }
+                        }
+                    }
+                }
+            }
+          FREE(dims1);
+          return 0;
+        case 2: /* multiple 2D fft */
+          if (Ai == NULL) {
+            j = 0;
+            for (i=1; i<=m; i++)
+              {
+                complete_2D_array(Ar+j,NULL,gdim.dims[0].n,gdim.dims[0].is, gdim.dims[1].n,gdim.dims[1].is);
+                j += gdim.howmany_dims[0].is;
+                for (k=hrank-2; k>=0; k--)
+                  {
+                    if (i%dims1[k]==0)
+                      {
+                        j += -incr1[k]+gdim.howmany_dims[k+1].is;
+                        break;
+                      }
+                  }
+              }
+          }
+          else {
+            j = 0;
+            for (i=1; i<=m; i++)
+              {
+                complete_2D_array(Ar+j,Ai+j,gdim.dims[0].n,gdim.dims[0].is, gdim.dims[1].n,gdim.dims[1].is);
+
+                j += gdim.howmany_dims[0].is;
+                for (k=hrank-2; k>=0; k--)
+                  {
+                    if (i%dims1[k]==0)
+                      {
+                        j += -incr1[k]+gdim.howmany_dims[k+1].is;
+                        break;
+                      }
+                  }
+              }
+          }
+          FREE(dims1);
+          return 0;
+        default:  /* multiple ND fft */
+          if ((dims=(int *)MALLOC(sizeof(int)*gdim.rank))==NULL) return -1;
+          if ((incr=(int *)MALLOC(sizeof(int)*gdim.rank))==NULL)
+            {
+              FREE(dims);
+              FREE(dims1);
+              return -1;
+            }
+          for (i=0;i<ndims;i++)
+            {
+              dims[i]=gdim.dims[i].n;
+              incr[i]=gdim.dims[i].is;
+            }
+          for (ir=0;ir<hrank;ir++)
+            {
+              j = 0;
+              for (i=1;i<=m;i++)
+                {
+                  if (Ai == NULL)
+                    r=complete_ND_array(Ar+j,NULL,ndims,dims,incr);
+                  else
+                    r=complete_ND_array(Ar+j,Ai+j,ndims,dims,incr);
+                  if (r<0)
+                    {
+                      FREE(dims);
+                      FREE(incr);
+                      FREE(dims1);
+                      return r;
+                    }
+                  j += gdim.howmany_dims[0].is;
+                  for (k=hrank-2;k>=0;k--)
+                    {
+                      if (i%dims1[k]==0)
+                        {
+                          j += -incr1[k]+gdim.howmany_dims[k+1].is;
+                          break;
+                        }
+                    }
+                }
+            }
+          FREE(dims);
+          FREE(incr);
+          FREE(dims1);
+          FREE(incr1);
+        }
+    }
+  return 0;
+}
+/*--------------------------------------------------------------------------
+ * Check if Scilab is linked with MKL library * Somme fftw functions
+ * are not yet implemented in MKL in particular wisdom and guru_split
+ * functions
+ */
+
+int withMKL(void)
+{
+  return (call_fftw_export_wisdom_to_string()==NULL);
+  /*return 1;*/
+}/*--------------------------------------------------------------------------*/
index ac075e4..0303ca8 100644 (file)
@@ -1,56 +1,74 @@
 /*
- * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
- * Copyright (C) 2006/2007 - INRIA - Alan Layec
- * Copyright (C) 2008 - INRIA - Allan CORNET
- * 
- * This file must be used under the terms of the CeCILL.
- * This source file is licensed as described in the file COPYING, which
- * you should have received as part of this distribution.  The terms
- * are also available at    
- * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
- *
- */
+* Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+* Copyright (C) 2006/2007 - INRIA - Alan Layec
+* Copyright (C) 2008 - INRIA - Allan CORNET
+* Copyright (C) 2012 - INRIA - Serge STEER
+*
+* This file must be used under the terms of the CeCILL.
+* This source file is licensed as described in the file COPYING, which
+* you should have received as part of this distribution.  The terms
+* are also available at
+* http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
+*
+*/
 #ifndef __FFTW_UTILITIES__
 #define __FFTW_UTILITIES__
 
 #include <string.h>
 #include <stdio.h>
 #include "fftw3.h"
-#include "stack-c.h"
 
 
 /* definiton of a guru_dim structure type */
 typedef struct guru_dim_st
 {
-  int rank;
-  fftw_iodim *dims;
-  int howmany_rank;
-  fftw_iodim *howmany_dims;
+    int rank;
+    fftw_iodim *dims;
+    int howmany_rank;
+    fftw_iodim *howmany_dims;
 } guru_dim_struct;
 
-/* definiton of a FFTW_Plan structure type */
+enum Plan_Type {
+    C2C_PLAN=0,
+    R2C_PLAN=1,
+    C2R_PLAN=2,
+    R2R_PLAN=3
+};
+
+/* definition of a FFTW_Plan structure type */
 typedef struct fftw_plan_st
 {
-  /* stored parmeters of fftw_plan_guru_split_dft function */
-  fftw_plan p;
-  guru_dim_struct gdim;
-  unsigned flags;
+    /* stored parameters of fftw_plan_guru_split_dft function */
+    enum Plan_Type plan_type;
+    fftw_plan p;
+    guru_dim_struct gdim;
+    unsigned flags;
 } FFTW_Plan_struct;
 
-extern int C2F(dset)(int *n, double *dx, double *dy, int *incy);
+
 
 /* prototypes of utilities functions */
-fftw_plan GetFFTWPlan(guru_dim_struct *gdim,
-                      double *ri, double *ii,
-                      double *ro, double *io,
-                      unsigned flags, int isn);
+fftw_plan GetFFTWPlan(enum Plan_Type type, guru_dim_struct *gdim,
+    double *ri, double *ii,
+    double *ro, double *io,
+    unsigned flags, int isn);
 
 int FreeFFTWPlan(FFTW_Plan_struct *Sci_Plan);
 
 int CheckGuruDims(guru_dim_struct *gdim1,
-                  guru_dim_struct *gdim2);
+    guru_dim_struct *gdim2);
+
+void ExecuteFFTWPlan(enum Plan_Type type, const fftw_plan p, double *ri, double *ii,double *ro, double *io);
+
+int is_real(double *Ar,double *Ai, int ndims, int *dims);
+int check_array_symmetry(double *Ar,double *Ai, guru_dim_struct gdim);
+int complete_array(double *Ar,double *Ai, guru_dim_struct gdim);
 
+unsigned int getCurrentFftwFlags(void);
+void setCurrentFftwFlags(unsigned int newFftwFlags);
 
+FFTW_Plan_struct *getSci_Backward_Plan(void);
+FFTW_Plan_struct *getSci_Forward_Plan(void);
 
 #endif /* __FFTW_UTILITIES__ */
 /*--------------------------------------------------------------------------*/
index 12fd172..aa63439 100644 (file)
@@ -1,11 +1,11 @@
 /*
  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
  * Copyright (C) 2007 - INRIA - Allan CORNET
- * 
+ *
  * This file must be used under the terms of the CeCILL.
  * This source file is licensed as described in the file COPYING, which
  * you should have received as part of this distribution.  The terms
- * are also available at    
+ * are also available at
  * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
  *
  */
 #ifdef _MSC_VER
 #include "strdup_windows.h"
 #endif
-/*--------------------------------------------------------------------------*/ 
+/*--------------------------------------------------------------------------*/
 char *fftwlibname = NULL;
-/*--------------------------------------------------------------------------*/ 
+/*--------------------------------------------------------------------------*/
 void setfftwlibname(char *libname)
 {
-       if (libname)
-       {
-               if (fftwlibname) {FREE(fftwlibname);fftwlibname = NULL;}
-               fftwlibname = strdup(libname);
-       }
+  if (libname)
+    {
+      if (fftwlibname) {FREE(fftwlibname);fftwlibname = NULL;}
+      fftwlibname = strdup(libname);
+    }
 }
-/*--------------------------------------------------------------------------*/ 
+/*--------------------------------------------------------------------------*/
 char *getfftwlibname(void)
 {
-       char *name = NULL;
+  char *name = NULL;
 
-       if (fftwlibname)
-       {
-               name = strdup(fftwlibname);
-       }
+  if (fftwlibname)
+    {
+      name = strdup(fftwlibname);
+    }
 
-       return name;
+  return name;
 }
-/*--------------------------------------------------------------------------*/ 
+/*--------------------------------------------------------------------------*/
index e5c60b1..00bff96 100644 (file)
@@ -1,11 +1,11 @@
 /*
  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
  * Copyright (C) 2007 - INRIA - Allan CORNET
- * 
+ *
  * This file must be used under the terms of the CeCILL.
  * This source file is licensed as described in the file COPYING, which
  * you should have received as part of this distribution.  The terms
- * are also available at    
+ * are also available at
  * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
  *
  */
index 7b52bc5..22619e2 100644 (file)
@@ -1,25 +1,25 @@
 /*
  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
  * Copyright (C) 2007 - INRIA - Allan CORNET
- * 
+ *
  * This file must be used under the terms of the CeCILL.
  * This source file is licensed as described in the file COPYING, which
  * you should have received as part of this distribution.  The terms
- * are also available at    
+ * are also available at
  * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
  *
  */
 
 #include "with_fftw.h"
-/*--------------------------------------------------------------------------*/ 
+/*--------------------------------------------------------------------------*/
 int C2F(withfftw)(int *rep)
-{ 
-       *rep = 1; 
-       return 0;
+{
+  *rep = 1;
+  return 0;
 }
-/*--------------------------------------------------------------------------*/ 
+/*--------------------------------------------------------------------------*/
 BOOL withfftw(void)
 {
-       return TRUE;
+  return TRUE;
 }
-/*--------------------------------------------------------------------------*/ 
+/*--------------------------------------------------------------------------*/
diff --git a/scilab/modules/fftw/tests/unit_tests/fftw.dia.ref b/scilab/modules/fftw/tests/unit_tests/fftw.dia.ref
deleted file mode 100644 (file)
index f6ea9be..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-//=================================
-//simple vector direct transform
-a = rand(50,1)+%i*rand(50,1);
-y = fftw(a);
-y = fftw(a,-1);
-//inverse transform
-b = fftw(y,1);
-//=================================
-//2D transform
-a = rand(512,512)+%i*rand(512,512);
-y = fftw(a);
-//=================================
-//M-D transform -old calling sequence-
-a = rand(120,1);
-y = a;
-dim=[5 6 4];incr=[1 5 30];
-for i=1:3
- y = fftw(y,-1,dim(i),incr(i));
-end
-//=================================
-//M-D transform -new calling sequence-
-//More efficient than old
-y = fftw(a,-1,[5 6 4],[1 5 30]);
-b = fftw(y,1,[5 6 4],[1 5 30]);
-//=================================
diff --git a/scilab/modules/fftw/tests/unit_tests/fftw.tst b/scilab/modules/fftw/tests/unit_tests/fftw.tst
deleted file mode 100644 (file)
index b687b5c..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-// =============================================================================
-// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
-// Copyright (C) 2007-2008 - INRIA
-//
-//  This file is distributed under the same license as the Scilab package.
-// =============================================================================
-
-// <-- CLI SHELL MODE -->
-
-//=================================
-//simple vector direct transform
-a = rand(50,1)+%i*rand(50,1);
-y = fftw(a);
-y = fftw(a,-1);
-//inverse transform
-b = fftw(y,1);
-//=================================
-//2D transform
-a = rand(512,512)+%i*rand(512,512);
-y = fftw(a);
-//=================================
-//M-D transform -old calling sequence-
-a = rand(120,1);
-y = a;
-dim=[5 6 4];incr=[1 5 30];
-for i=1:3
- y = fftw(y,-1,dim(i),incr(i));
-end
-//=================================
-//M-D transform -new calling sequence-
-//More efficient than old
-y = fftw(a,-1,[5 6 4],[1 5 30]);
-b = fftw(y,1,[5 6 4],[1 5 30]);
-//=================================
index 857d8c1..816865b 100644 (file)
@@ -1,13 +1,20 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2007-2008 - INRIA
+//
+//  This file is distributed under the same license as the Scilab package.
+// =============================================================================
+// <-- CLI SHELL MODE -->
 //=============================================
 ff = fftw_flags();
-if ff <> 64 then bugmes();quit;end;
+assert_checkequal(double(ff),64);
 //=============================================
 //change flags
 r = fftw_flags(["FFTW_MEASURE";"FFTW_CONSERVE_MEMORY"]);
-if r <> 4 then bugmes();quit;end;
+assert_checkequal(double(r),4);
 //=============================================
 //change flags and display current value of fftw flags (both integer and strings)
 [a,S]=fftw_flags("FFTW_PATIENT");
-if a <> 32 then bugmes();quit;end;
-if S <>'FFTW_PATIENT' then bugmes();quit;end;
+assert_checkequal(double(a),32);
+assert_checkequal(S,'FFTW_PATIENT');
 //=============================================
index 2bc5141..8181648 100644 (file)
@@ -9,14 +9,14 @@
 
 //=============================================
 ff = fftw_flags();
-if ff <> 64 then pause,end;
+assert_checkequal(double(ff),64);
 //=============================================
 //change flags
 r = fftw_flags(["FFTW_MEASURE";"FFTW_CONSERVE_MEMORY"]);
-if r <> 4 then pause,end;
+assert_checkequal(double(r),4);
 //=============================================
 //change flags and display current value of fftw flags (both integer and strings)
 [a,S]=fftw_flags("FFTW_PATIENT");
-if a <> 32 then pause,end;
-if S <>'FFTW_PATIENT' then pause,end;
+assert_checkequal(double(a),32);
+assert_checkequal(S,'FFTW_PATIENT');
 //=============================================
diff --git a/scilab/modules/fftw/tests/unit_tests/fftw_part1.dia.ref b/scilab/modules/fftw/tests/unit_tests/fftw_part1.dia.ref
new file mode 100644 (file)
index 0000000..ca8492e
--- /dev/null
@@ -0,0 +1,272 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2012 - INRIA - Serge STEER
+//
+//  This file is distributed under the same license as the Scilab package.
+// =============================================================================
+// <-- JVM NOT MANDATORY -->
+//============================================================================================
+//=================================fft(A [,isn [,flag]]) =====================================
+//============================================================================================
+//1-D transform ******************************************************************************
+//R2C case ------------------------------------------------------------------------------------
+assert_checkequal(fft(1:4),[10,-2+%i*2,-2,-2-%i*2]);
+assert_checkequal(ifft(1:4),conj(fft(1:4)/4));
+assert_checkequal(fft(1:4,-1),[10,-2+%i*2,-2,-2-%i*2]);
+assert_checkequal(fft(1:4,1),conj(fft(1:4,-1)/4));
+//C2R case ------------------------------------------------------------------------------------
+//         ODD case
+A=[1 0 %i -%i 0];
+y=fft(A);
+y_ref=[1, 2.17557050458494672, -0.902113032590307062, 2.90211303259030728, -0.17557050458494649];
+assert_checktrue(isreal(y));
+assert_checkalmostequal(y,y_ref);
+assert_checkalmostequal(A,ifft(y));
+y=fft(A,"symmetric");
+assert_checktrue(isreal(y));
+assert_checkalmostequal(y,y_ref);
+y=fft(A,"nonsymmetric");
+assert_checktrue(~isreal(y));
+assert_checkalmostequal(y,y_ref);
+y=fft(A,-1);
+assert_checktrue(isreal(y));
+assert_checkalmostequal(y,y_ref);
+assert_checkalmostequal(A,fft(y,1));
+//         EVEN case
+A=[1 0 %i 2 -%i 0];
+y=fft(A);
+y_ref=[3, 0.73205080756887719, 1.2679491924311228,-1, 4.7320508075688767,-2.73205080756887719];
+assert_checktrue(isreal(y));
+assert_checkalmostequal(y,y_ref);
+assert_checkalmostequal(A,ifft(y),0,10*%eps);
+y=fft(A,"symmetric");
+assert_checktrue(isreal(y));
+assert_checkalmostequal(y,y_ref);
+y=fft(A,"nonsymmetric");
+assert_checktrue(~isreal(y));
+assert_checkalmostequal(y,y_ref);
+y=fft(A,-1);
+assert_checktrue(isreal(y));
+assert_checkalmostequal(y,y_ref);
+assert_checkalmostequal(A,fft(y,1),10*%eps,10*%eps);
+//R2R case ------------------------------------------------------------------------------------
+//         ODD case
+y=fft(1);
+assert_checktrue(isreal(y));
+assert_checkequal(y,1);
+A=[0 1 2 2 1];
+y=fft(A);
+y_ref=[6,-2.61803398874989446, -0.381966011250104875, -0.381966011250104875, -2.61803398874989446];
+assert_checktrue(isreal(y));
+assert_checkalmostequal(y,y_ref);
+assert_checkalmostequal(A,ifft(y),10*%eps,10*%eps);
+y=fft(A,"symmetric");
+assert_checktrue(isreal(y));
+assert_checkalmostequal(y,y_ref);
+y=fft(A,"nonsymmetric");
+assert_checktrue(~isreal(y));
+assert_checkalmostequal(y,y_ref);
+//        EVEN case
+A=1:2;
+y=fft(A);
+assert_checktrue(isreal(y));
+assert_checkalmostequal(y,[3 -1]);
+assert_checkalmostequal(A,ifft(y),10*%eps,10*%eps);
+A=[0 1 2 5 2 1];
+y=fft(A);
+y_ref=[11,-6, 2,-3, 2,-6];
+assert_checktrue(isreal(y));
+assert_checkequal(y,y_ref);
+assert_checkalmostequal(A,ifft(y),10*%eps,10*%eps);
+y=fft(A,"symmetric");
+assert_checktrue(isreal(y));
+assert_checkalmostequal(y,y_ref);
+y=fft(A,"nonsymmetric");
+assert_checktrue(~isreal(y));
+assert_checkalmostequal(y,y_ref);
+//C2C case ------------------------------------------------------------------------------------
+A=[1+%i 2 5*%i -8+5*%i];
+y=fft(A);
+y_ref=[-5+%i*11,-4-%i*14, 7+%i, 6+%i*6];
+assert_checkalmostequal(y,y_ref);
+assert_checkalmostequal(A,ifft(y));
+//2-D transform  *******************************************************************************
+//R2R case  ------------------------------------------------------------------------------------
+//         ODD X EVEN case
+A=[0   1   1
+   2  -1  -1
+   3   4   4
+   2  -1  -1];
+y=fft(A);
+y_ref=[ 13, 4, 4;
+        -9, 0, 0;
+        13,-8,-8;
+        -9, 0, 0];
+assert_checktrue(isreal(y));
+assert_checkalmostequal(y,y_ref);
+assert_checkalmostequal(A,ifft(y),0,10*%eps);
+y=fft(A,"symmetric");
+assert_checktrue(isreal(y));
+assert_checkalmostequal(y,y_ref);
+y=fft(A,"nonsymmetric");
+assert_checktrue(~isreal(y));
+assert_checkalmostequal(y,y_ref);
+//         EVEN X EVEN case
+A=[0   1  5  1
+   2  -1  6 -1
+   3   4  7  4
+   2  -1  6 -1];
+y=fft(A);
+y_ref=[37, -17, 25,-17;
+       -11, -1,  1, -1;
+        13, -1,-15, -1;
+       -11, -1,  1, -1];
+assert_checktrue(isreal(y));
+assert_checkalmostequal(y,y_ref);
+assert_checkalmostequal(A,ifft(y),0,10*%eps);
+y=fft(A,"symmetric");
+assert_checktrue(isreal(y));
+assert_checkalmostequal(y,y_ref);
+y=fft(A,"nonsymmetric");
+assert_checktrue(~isreal(y));
+assert_checkalmostequal(y,y_ref);
+//         ODD X ODD case
+A=[0  1  1
+   2 -1 -1
+   2 -1 -1];
+y=fft(A);
+y_ref=[ 2, 5, 5;
+        2,-4,-4;
+        2,-4,-4];
+assert_checktrue(isreal(y));
+assert_checkalmostequal(y,y_ref); 
+assert_checkalmostequal(A,ifft(y),0,10*%eps);
+A=[0   1  5  1
+   2  -1  6 -1
+   3   4  7  4
+   2  -1  6 -1];
+y=fft(A);
+y_ref=[37, -17, 25,-17;
+       -11, -1,  1, -1;
+        13, -1,-15, -1;
+       -11, -1,  1, -1];
+assert_checktrue(isreal(y));
+assert_checkalmostequal(y,y_ref);
+assert_checkalmostequal(A,ifft(y),0,10*%eps);
+y=fft(A,-1,"symmetric");
+assert_checktrue(isreal(y));
+assert_checkalmostequal(y,y_ref);
+y=fft(A,-1,"nonsymmetric");
+assert_checktrue(~isreal(y));
+assert_checkalmostequal(y,y_ref);
+A=[1 2 3 3 2;4 6 9 11 8;5 7 10 10 7;4 8 11 9 6];
+y=fft(A);
+y_ref=[ 126,-25.1803398874989490,-2.81966011250105097,-2.81966011250105097,-25.1803398874989490;
+       -28, 10.391435051850296,-1.68915303351051138, 1.21701707851093177,-1.91929909685071642;
+       -26, 6.2360679774997898, 1.76393202250021019, 1.76393202250021019, 6.2360679774997898;
+       -28,-1.91929909685071642, 1.21701707851093177,-1.68915303351051138, 10.391435051850296];
+assert_checktrue(isreal(y));
+assert_checkalmostequal(y,y_ref); 
+assert_checkalmostequal(A,ifft(y));
+y=fft(A,-1,"symmetric");
+assert_checktrue(isreal(y));
+assert_checkalmostequal(y,y_ref);
+y=fft(A,-1,"nonsymmetric");
+assert_checktrue(~isreal(y));
+assert_checkalmostequal(y,y_ref);
+//R2C case ------------------------------------------------------------------------------------
+A=[1 2 3;7 3 9;-1 5 4;0 8 -3];
+y=fft(A);
+y_ref=[38,     -8.5-%i*4.33012701892219276,                -8.5+%i*4.33012701892219276;
+      -2-%i*14, 18.722431864335455-%i*1.76794919243112281  -10.7224318643354568-%i*5.23205080756887675;               
+      -10,     -5.5+%i*4.33012701892219276,                -5.5-%i*4.33012701892219276;
+      -2+%i*14,-10.7224318643354568+%i*5.23205080756887675, 18.722431864335455+%i*1.76794919243112281];    
+assert_checkalmostequal(y,y_ref);
+assert_checkalmostequal(A,ifft(y),0,10*%eps);
+y=fft(A,1);
+y_ref=[3.16666666666666607,                       -0.70833333333333326+%i*0.36084391824351614,-0.70833333333333326-%i*0.36084391824351614;
+      -0.16666666666666660+%i*1.16666666666666652, 1.56020265536128777+%i*0.14732909936926014,-0.89353598869462125+%i*0.43600423396407301;
+      -0.83333333333333337,                       -0.45833333333333320-%i*0.36084391824351603,-0.45833333333333320+%i*0.36084391824351603;
+      -0.16666666666666660-%i*1.16666666666666652,-0.89353598869462125-%i*0.43600423396407301,1.56020265536128777-%i*0.14732909936926014];
+assert_checkalmostequal(y,y_ref);
+//C2R case
+//------------------------------------------------------------------------------------
+//         ODD X EVEN case
+A=[0     %i  -%i
+   2+%i  -1  -1
+   3      4   4
+   2-%i  -1  -1];
+y=fft(A);
+y_ref=[ 11, 6.7320508075688767,   3.2679491924311228;
+        -9, 4.7320508075688767,   1.2679491924311228;
+        11,-5.26794919243112325, -8.7320508075688767;
+       -13, 0.73205080756887719, -2.73205080756887719];
+assert_checktrue(isreal(y));
+assert_checkalmostequal(y,y_ref);  
+assert_checkalmostequal(A,ifft(y),0,10*%eps);
+A=[1 2 3 3 2;4 6 9 11 8;5 7 10 10 7;4 8 11 9 6];
+y=fft(A);
+y_ref=[ 126,-25.1803398874989490,-2.81966011250105097,-2.81966011250105097,-25.1803398874989490;
+       -28, 10.391435051850296,-1.68915303351051138, 1.21701707851093177,-1.91929909685071642;
+       -26, 6.2360679774997898, 1.76393202250021019, 1.76393202250021019, 6.2360679774997898;
+       -28,-1.91929909685071642, 1.21701707851093177,-1.68915303351051138, 10.391435051850296];
+assert_checktrue(isreal(y));
+assert_checkalmostequal(y,y_ref); 
+assert_checkalmostequal(A,ifft(y));
+y=fft(A,-1,"symmetric");
+assert_checktrue(isreal(y));
+assert_checkalmostequal(y,y_ref);
+y=fft(A,-1,"nonsymmetric");
+assert_checktrue(~isreal(y));
+assert_checkalmostequal(y,y_ref);
+//         ODD X ODD case
+A=[0     %i  -%i
+   2+%i  -1  -1
+   2-%i  -1  -1];
+y=fft(A);
+y_ref=[0,                    7.7320508075688767,   4.26794919243112325;
+       1.73205080756887719,  0.46410161513775439, -3;
+       -1.73205080756887719,-2.99999999999999956, -6.46410161513775350];
+assert_checktrue(isreal(y));
+assert_checkalmostequal(y,y_ref);  
+assert_checkalmostequal(A,ifft(y),0,10*%eps);
+y=fft(A,-1,"symmetric");
+assert_checktrue(isreal(y));
+assert_checkalmostequal(y,y_ref);
+y=fft(A,-1,"nonsymmetric");
+assert_checktrue(~isreal(y));
+assert_checkalmostequal(y,y_ref);
+A=[1440, 32-%i*28,-102-%i*188,-102+%i*188, 32+%i*28;
+   140-%i*52,-21+%i*14,-33+%i*8, 31+%i*77, 8+%i*169;
+   30,-179+%i*40,-32-%i*175, 97-%i*107,-191-%i*147;
+   20,-83-%i*162,-127+%i*71,-127-%i*71,-83+%i*162;
+   30,-191+%i*147, 97+%i*107,-32+%i*175,-179-%i*40;
+   140+%i*52, 8-%i*169, 31-%i*77,-33-%i*8,-21-%i*14];
+y=fft(A);
+y_ref=[ 600, 1201.23812370118321, 2697.02967953848838, 2102.2365384314553, 2399.49565832887311;
+        1800.35521029058418, 1800.85854102712074, 897.335302928384408, 598.365730980120588,2102.75200480588182;
+        2097.89073857917083, 901.733860383104911, 600.566385143489583, 602.768240434540644,1796.70756549178577;
+        900, 1503.68526108760511, 2698.74007483319838, 598.106629651731282, 299.468034427465;
+        2.10926142082939805, 1797.22849022236483, 902.940272151356453, 1500.39858431578159,2697.65660185757633;
+        2399.64478970941582, 898.55653188654594, 2102.57661444176256, 601.137293239859559,2098.41798069032438];
+assert_checktrue(isreal(y));
+assert_checkalmostequal(y,y_ref);  
+assert_checkalmostequal(A,ifft(y),0,1000*%eps);
+y=fft(A,-1,"symmetric");
+assert_checktrue(isreal(y));
+assert_checkalmostequal(y,y_ref);
+y=fft(A,-1,"nonsymmetric");
+assert_checktrue(~isreal(y));
+assert_checkalmostequal(y,y_ref);
+//C2C case ------------------------------------------------------------------------------------
+A=[0      %i  3-%i
+   2+%i   -1  -1
+   3       4   4
+   2-3*%i -1  -1];
+y=fft(A);
+y_ref=[14-%i*2, 5.23205080756887675+%i*0.59807621135331601,1.76794919243112281-%i*4.598076211353316;
+       -4,      5.23205080756887675+%i*2.598076211353316,  1.76794919243112281-%i*2.598076211353316;
+       14+%i*2,-6.7679491924311233+%i*4.598076211353316,  -10.2320508075688767-%i*0.59807621135331601;
+       -12,    -2.76794919243112281+%i*2.598076211353316,  -6.23205080756887675-%i*2.598076211353316];
+assert_checkalmostequal(y,y_ref);  
+assert_checkalmostequal(A,ifft(y),0,10*%eps);
diff --git a/scilab/modules/fftw/tests/unit_tests/fftw_part1.tst b/scilab/modules/fftw/tests/unit_tests/fftw_part1.tst
new file mode 100644 (file)
index 0000000..bf81aae
--- /dev/null
@@ -0,0 +1,333 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2012 - INRIA - Serge STEER
+//
+//  This file is distributed under the same license as the Scilab package.
+// =============================================================================
+
+// <-- JVM NOT MANDATORY -->
+
+//============================================================================================
+//=================================fft(A [,isn [,flag]]) =====================================
+//============================================================================================
+
+//1-D transform ******************************************************************************
+//R2C case ------------------------------------------------------------------------------------
+assert_checkequal(fft(1:4),[10,-2+%i*2,-2,-2-%i*2]);
+assert_checkequal(ifft(1:4),conj(fft(1:4)/4));
+assert_checkequal(fft(1:4,-1),[10,-2+%i*2,-2,-2-%i*2]);
+assert_checkequal(fft(1:4,1),conj(fft(1:4,-1)/4));
+//C2R case ------------------------------------------------------------------------------------
+//         ODD case
+A=[1 0 %i -%i 0];
+y=fft(A);
+y_ref=[1, 2.17557050458494672, -0.902113032590307062, 2.90211303259030728, -0.17557050458494649];
+assert_checktrue(isreal(y));
+assert_checkalmostequal(y,y_ref);
+assert_checkalmostequal(A,ifft(y));
+
+y=fft(A,"symmetric");
+assert_checktrue(isreal(y));
+assert_checkalmostequal(y,y_ref);
+
+y=fft(A,"nonsymmetric");
+assert_checktrue(~isreal(y));
+assert_checkalmostequal(y,y_ref);
+
+
+y=fft(A,-1);
+assert_checktrue(isreal(y));
+assert_checkalmostequal(y,y_ref);
+assert_checkalmostequal(A,fft(y,1));
+
+//         EVEN case
+A=[1 0 %i 2 -%i 0];
+y=fft(A);
+y_ref=[3, 0.73205080756887719, 1.2679491924311228,-1, 4.7320508075688767,-2.73205080756887719];
+assert_checktrue(isreal(y));
+assert_checkalmostequal(y,y_ref);
+assert_checkalmostequal(A,ifft(y),0,10*%eps);
+
+y=fft(A,"symmetric");
+assert_checktrue(isreal(y));
+assert_checkalmostequal(y,y_ref);
+
+y=fft(A,"nonsymmetric");
+assert_checktrue(~isreal(y));
+assert_checkalmostequal(y,y_ref);
+
+y=fft(A,-1);
+assert_checktrue(isreal(y));
+assert_checkalmostequal(y,y_ref);
+assert_checkalmostequal(A,fft(y,1),10*%eps,10*%eps);
+
+//R2R case ------------------------------------------------------------------------------------
+//         ODD case
+y=fft(1);
+assert_checktrue(isreal(y));
+assert_checkequal(y,1);
+
+A=[0 1 2 2 1];
+y=fft(A);
+y_ref=[6,-2.61803398874989446, -0.381966011250104875, -0.381966011250104875, -2.61803398874989446];
+assert_checktrue(isreal(y));
+assert_checkalmostequal(y,y_ref);
+assert_checkalmostequal(A,ifft(y),10*%eps,10*%eps);
+
+y=fft(A,"symmetric");
+assert_checktrue(isreal(y));
+assert_checkalmostequal(y,y_ref);
+
+y=fft(A,"nonsymmetric");
+assert_checktrue(~isreal(y));
+assert_checkalmostequal(y,y_ref);
+
+//        EVEN case
+A=1:2;
+y=fft(A);
+assert_checktrue(isreal(y));
+assert_checkalmostequal(y,[3 -1]);
+assert_checkalmostequal(A,ifft(y),10*%eps,10*%eps);
+
+A=[0 1 2 5 2 1];
+y=fft(A);
+y_ref=[11,-6, 2,-3, 2,-6];
+assert_checktrue(isreal(y));
+assert_checkequal(y,y_ref);
+assert_checkalmostequal(A,ifft(y),10*%eps,10*%eps);
+y=fft(A,"symmetric");
+assert_checktrue(isreal(y));
+assert_checkalmostequal(y,y_ref);
+
+y=fft(A,"nonsymmetric");
+assert_checktrue(~isreal(y));
+assert_checkalmostequal(y,y_ref);
+
+
+//C2C case ------------------------------------------------------------------------------------
+A=[1+%i 2 5*%i -8+5*%i];
+y=fft(A);
+y_ref=[-5+%i*11,-4-%i*14, 7+%i, 6+%i*6];
+assert_checkalmostequal(y,y_ref);
+assert_checkalmostequal(A,ifft(y));
+
+//2-D transform  *******************************************************************************
+
+//R2R case  ------------------------------------------------------------------------------------
+//         ODD X EVEN case
+A=[0   1   1
+   2  -1  -1
+   3   4   4
+   2  -1  -1];
+y=fft(A);
+y_ref=[ 13, 4, 4;
+        -9, 0, 0;
+        13,-8,-8;
+        -9, 0, 0];
+
+assert_checktrue(isreal(y));
+assert_checkalmostequal(y,y_ref);
+assert_checkalmostequal(A,ifft(y),0,10*%eps);
+
+y=fft(A,"symmetric");
+assert_checktrue(isreal(y));
+assert_checkalmostequal(y,y_ref);
+
+y=fft(A,"nonsymmetric");
+assert_checktrue(~isreal(y));
+assert_checkalmostequal(y,y_ref);
+
+
+
+//         EVEN X EVEN case
+A=[0   1  5  1
+   2  -1  6 -1
+   3   4  7  4
+   2  -1  6 -1];
+y=fft(A);
+y_ref=[37, -17, 25,-17;
+       -11, -1,  1, -1;
+        13, -1,-15, -1;
+       -11, -1,  1, -1];
+
+assert_checktrue(isreal(y));
+assert_checkalmostequal(y,y_ref);
+assert_checkalmostequal(A,ifft(y),0,10*%eps);
+
+y=fft(A,"symmetric");
+assert_checktrue(isreal(y));
+assert_checkalmostequal(y,y_ref);
+
+y=fft(A,"nonsymmetric");
+assert_checktrue(~isreal(y));
+assert_checkalmostequal(y,y_ref);
+
+
+//         ODD X ODD case
+A=[0  1  1
+   2 -1 -1
+   2 -1 -1];
+y=fft(A);
+y_ref=[ 2, 5, 5;
+        2,-4,-4;
+        2,-4,-4];
+
+assert_checktrue(isreal(y));
+assert_checkalmostequal(y,y_ref); 
+assert_checkalmostequal(A,ifft(y),0,10*%eps);
+
+A=[0   1  5  1
+   2  -1  6 -1
+   3   4  7  4
+   2  -1  6 -1];
+y=fft(A);
+y_ref=[37, -17, 25,-17;
+       -11, -1,  1, -1;
+        13, -1,-15, -1;
+       -11, -1,  1, -1];
+
+assert_checktrue(isreal(y));
+assert_checkalmostequal(y,y_ref);
+assert_checkalmostequal(A,ifft(y),0,10*%eps);
+
+y=fft(A,-1,"symmetric");
+assert_checktrue(isreal(y));
+assert_checkalmostequal(y,y_ref);
+
+y=fft(A,-1,"nonsymmetric");
+assert_checktrue(~isreal(y));
+assert_checkalmostequal(y,y_ref);
+
+
+A=[1 2 3 3 2;4 6 9 11 8;5 7 10 10 7;4 8 11 9 6];
+y=fft(A);
+y_ref=[ 126,-25.1803398874989490,-2.81966011250105097,-2.81966011250105097,-25.1803398874989490;
+       -28, 10.391435051850296,-1.68915303351051138, 1.21701707851093177,-1.91929909685071642;
+       -26, 6.2360679774997898, 1.76393202250021019, 1.76393202250021019, 6.2360679774997898;
+       -28,-1.91929909685071642, 1.21701707851093177,-1.68915303351051138, 10.391435051850296];
+assert_checktrue(isreal(y));
+assert_checkalmostequal(y,y_ref); 
+assert_checkalmostequal(A,ifft(y));
+
+y=fft(A,-1,"symmetric");
+assert_checktrue(isreal(y));
+assert_checkalmostequal(y,y_ref);
+
+y=fft(A,-1,"nonsymmetric");
+assert_checktrue(~isreal(y));
+assert_checkalmostequal(y,y_ref);
+
+
+//R2C case ------------------------------------------------------------------------------------
+A=[1 2 3;7 3 9;-1 5 4;0 8 -3];
+y=fft(A);
+y_ref=[38,     -8.5-%i*4.33012701892219276,                -8.5+%i*4.33012701892219276;
+      -2-%i*14, 18.722431864335455-%i*1.76794919243112281  -10.7224318643354568-%i*5.23205080756887675;               
+      -10,     -5.5+%i*4.33012701892219276,                -5.5-%i*4.33012701892219276;
+      -2+%i*14,-10.7224318643354568+%i*5.23205080756887675, 18.722431864335455+%i*1.76794919243112281];    
+assert_checkalmostequal(y,y_ref);
+assert_checkalmostequal(A,ifft(y),0,10*%eps);
+
+y=fft(A,1);
+y_ref=[3.16666666666666607,                       -0.70833333333333326+%i*0.36084391824351614,-0.70833333333333326-%i*0.36084391824351614;
+      -0.16666666666666660+%i*1.16666666666666652, 1.56020265536128777+%i*0.14732909936926014,-0.89353598869462125+%i*0.43600423396407301;
+      -0.83333333333333337,                       -0.45833333333333320-%i*0.36084391824351603,-0.45833333333333320+%i*0.36084391824351603;
+      -0.16666666666666660-%i*1.16666666666666652,-0.89353598869462125-%i*0.43600423396407301,1.56020265536128777-%i*0.14732909936926014];
+assert_checkalmostequal(y,y_ref);
+//C2R case
+//------------------------------------------------------------------------------------
+//         ODD X EVEN case
+A=[0     %i  -%i
+   2+%i  -1  -1
+   3      4   4
+   2-%i  -1  -1];
+y=fft(A);
+y_ref=[ 11, 6.7320508075688767,   3.2679491924311228;
+        -9, 4.7320508075688767,   1.2679491924311228;
+        11,-5.26794919243112325, -8.7320508075688767;
+       -13, 0.73205080756887719, -2.73205080756887719];
+assert_checktrue(isreal(y));
+assert_checkalmostequal(y,y_ref);  
+assert_checkalmostequal(A,ifft(y),0,10*%eps);
+A=[1 2 3 3 2;4 6 9 11 8;5 7 10 10 7;4 8 11 9 6];
+y=fft(A);
+y_ref=[ 126,-25.1803398874989490,-2.81966011250105097,-2.81966011250105097,-25.1803398874989490;
+       -28, 10.391435051850296,-1.68915303351051138, 1.21701707851093177,-1.91929909685071642;
+       -26, 6.2360679774997898, 1.76393202250021019, 1.76393202250021019, 6.2360679774997898;
+       -28,-1.91929909685071642, 1.21701707851093177,-1.68915303351051138, 10.391435051850296];
+assert_checktrue(isreal(y));
+assert_checkalmostequal(y,y_ref); 
+assert_checkalmostequal(A,ifft(y));
+
+y=fft(A,-1,"symmetric");
+assert_checktrue(isreal(y));
+assert_checkalmostequal(y,y_ref);
+
+y=fft(A,-1,"nonsymmetric");
+assert_checktrue(~isreal(y));
+assert_checkalmostequal(y,y_ref);
+
+
+//         ODD X ODD case
+A=[0     %i  -%i
+   2+%i  -1  -1
+   2-%i  -1  -1];
+y=fft(A);
+y_ref=[0,                    7.7320508075688767,   4.26794919243112325;
+       1.73205080756887719,  0.46410161513775439, -3;
+       -1.73205080756887719,-2.99999999999999956, -6.46410161513775350];
+
+assert_checktrue(isreal(y));
+assert_checkalmostequal(y,y_ref);  
+assert_checkalmostequal(A,ifft(y),0,10*%eps);
+
+y=fft(A,-1,"symmetric");
+assert_checktrue(isreal(y));
+assert_checkalmostequal(y,y_ref);
+
+y=fft(A,-1,"nonsymmetric");
+assert_checktrue(~isreal(y));
+assert_checkalmostequal(y,y_ref);
+
+
+A=[1440, 32-%i*28,-102-%i*188,-102+%i*188, 32+%i*28;
+   140-%i*52,-21+%i*14,-33+%i*8, 31+%i*77, 8+%i*169;
+   30,-179+%i*40,-32-%i*175, 97-%i*107,-191-%i*147;
+   20,-83-%i*162,-127+%i*71,-127-%i*71,-83+%i*162;
+   30,-191+%i*147, 97+%i*107,-32+%i*175,-179-%i*40;
+   140+%i*52, 8-%i*169, 31-%i*77,-33-%i*8,-21-%i*14];
+y=fft(A);
+y_ref=[ 600, 1201.23812370118321, 2697.02967953848838, 2102.2365384314553, 2399.49565832887311;
+        1800.35521029058418, 1800.85854102712074, 897.335302928384408, 598.365730980120588,2102.75200480588182;
+        2097.89073857917083, 901.733860383104911, 600.566385143489583, 602.768240434540644,1796.70756549178577;
+        900, 1503.68526108760511, 2698.74007483319838, 598.106629651731282, 299.468034427465;
+        2.10926142082939805, 1797.22849022236483, 902.940272151356453, 1500.39858431578159,2697.65660185757633;
+        2399.64478970941582, 898.55653188654594, 2102.57661444176256, 601.137293239859559,2098.41798069032438];
+assert_checktrue(isreal(y));
+assert_checkalmostequal(y,y_ref);  
+assert_checkalmostequal(A,ifft(y),0,1000*%eps);
+
+
+y=fft(A,-1,"symmetric");
+assert_checktrue(isreal(y));
+assert_checkalmostequal(y,y_ref);
+
+y=fft(A,-1,"nonsymmetric");
+assert_checktrue(~isreal(y));
+assert_checkalmostequal(y,y_ref);
+
+
+//C2C case ------------------------------------------------------------------------------------
+A=[0      %i  3-%i
+   2+%i   -1  -1
+   3       4   4
+   2-3*%i -1  -1];
+y=fft(A);
+y_ref=[14-%i*2, 5.23205080756887675+%i*0.59807621135331601,1.76794919243112281-%i*4.598076211353316;
+       -4,      5.23205080756887675+%i*2.598076211353316,  1.76794919243112281-%i*2.598076211353316;
+       14+%i*2,-6.7679491924311233+%i*4.598076211353316,  -10.2320508075688767-%i*0.59807621135331601;
+       -12,    -2.76794919243112281+%i*2.598076211353316,  -6.23205080756887675-%i*2.598076211353316];
+assert_checkalmostequal(y,y_ref);  
+assert_checkalmostequal(A,ifft(y),0,10*%eps);
+
+
diff --git a/scilab/modules/fftw/tests/unit_tests/fftw_part2.dia.ref b/scilab/modules/fftw/tests/unit_tests/fftw_part2.dia.ref
new file mode 100644 (file)
index 0000000..8d75478
--- /dev/null
@@ -0,0 +1,386 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2012 - INRIA - Serge STEER
+//
+//  This file is distributed under the same license as the Scilab package.
+// =============================================================================
+// <-- JVM NOT MANDATORY -->
+//3-D transform  *******************************************************************************
+//R2R case  ------------------------------------------------------------------------------------
+A=[0   1   1
+   2  -1  -1
+   3   4   4
+   2  -1  -1];
+A(:,:,2)=A+1;
+A(:,:,3)=A(:,:,2);
+y_ref=matrix([63;-27;39;-27;12;0;-24;0;12;0;-24;0;-12;
+              0;0;0;0;0;0;0;0;0;0;0;
+              -12;0;0;0;0;0;0;0;0;0;0;0],[4 3 3]);
+y=fft(A);
+assert_checktrue(isreal(y));
+assert_checkalmostequal(y,y_ref); 
+assert_checkalmostequal(A,fft(y,1),0,10*%eps);
+y=fft(A,"symmetric");
+assert_checktrue(isreal(y));
+assert_checkalmostequal(y,y_ref); 
+assert_checkalmostequal(A,fft(y,1,"symmetric"),0,10*%eps);
+y=fft(A,"nonsymmetric"); //use R2C
+assert_checktrue(~isreal(y));
+assert_checkalmostequal(y,y_ref); 
+assert_checkalmostequal(A,fft(y,1,"nonsymmetric"),0,10*%eps);
+A=matrix([4750;-163;138;138;-163;-100;-2;9;-148;42;10;-301;246;246;-301;-100;42;-148;9;-2;-12;157;
+          -110;224;37;-101;-94;260;258;345;-49;175;227;110;161;65;-40;-182;161;-390;412;101;168;
+          138;35;21;-95;-81;236;1;219;-215;120;284;-232;-35;-23;215;-191;122;412;35;138;168;101;
+          -35;122;-191;215;-23;219;-232;284;120;-215;21;1;236;-81;-95;-12;37;224;-110;157;65;-390;
+          161;-182;-40;-49;161;110;227;175;-101;345;258;260;-94],[5,4,5]);
+y_ref=matrix([ 9006; 1997.01835368650836; 7499.98164631349118; 7499.98164631349118;
+               1997.01835368650836; 5500; 8003.03595972396761; 4499.30203473224719;
+               3496.74144394796622; 4500.92056159581989; 7994; 4500.41996658886728;
+               7002.58003341113272; 7002.58003341113272; 4500.41996658886728; 5500;
+               4500.92056159581989; 3496.74144394796622; 4499.30203473224719; 8003.03595972396761;
+               3003.23606797749972; 4503.21094298379558; 2498.80193260011856; 4500.56038652002371;
+               3002.80933008143711; 1502.48409399493175; 4997.98726249178435; 6998.63971425121235;
+               4503.41908441918713; 5499.99740938413652; 4000.79645449752343; 3004.49048964150825;
+               3499; 4495.40709100495314; 4504.89210254386671; 5498.03152064027927;
+               3999.73866895309675; 1500.9206722688125; 7001.49266501579041; 3003.15588613093223;
+               2998.76393202250028; 5001.43961347997629; 5493.78905701620442; 6994.19066991856289;
+               5003.19806739988144; 4499.2782026543191; 4996.34845842043978; 3004.96649100621744;
+               7499.64517406068444; 5505.14335301404844; 4497.20354550247703; 3502.59290899504595;
+               8498.50951035849175; 6998.10789745613329; 3499; 7000.20618271046988;
+               5998.73979214458359; 3497.30757754890101; 2497.2015304242459; 3495.29626046592784;
+               2998.76393202250028; 5003.19806739988144; 6994.19066991856289; 5493.78905701620442;
+               5001.43961347997629; 7000.20618271046988; 3495.29626046592784; 2497.2015304242459;
+               3497.30757754890101; 5998.73979214458359; 4497.20354550247703; 3499;
+               6998.10789745613329; 8498.50951035849175; 3502.59290899504595; 4499.2782026543191;
+               5505.14335301404844; 7499.64517406068444; 3004.96649100621744; 4996.34845842043978;
+               3003.23606797749972; 3002.80933008143711; 4500.56038652002371; 2498.80193260011856;
+               4503.21094298379558; 5498.03152064027927; 3003.15588613093223; 7001.49266501579041;
+               1500.9206722688125; 3999.73866895309675; 4000.79645449752343; 4504.89210254386671;
+               4495.40709100495314; 3499; 3004.49048964150825; 1502.48409399493175;
+               5499.99740938413652; 4503.41908441918713; 6998.63971425121235; 4997.98726249178435],[5,4,5]);
+y=fft(A);
+assert_checktrue(isreal(y));
+assert_checkalmostequal(y,y_ref); 
+//R2C case   ------------------------------------------------------------------------------------
+A=matrix([5;4;3;6;4;9;0;5;3;4;3;1;8;2;1;7;2;7;8;4;4;9;
+          1;2;6;6;7;9;5;3;4;9;9;3;4;7;3;5;3;5;5;1;2;6;
+          8;0;7;2;4;8;6;5;2;8;1;3;9;8;5;10],[4,3,5]);
+y_ref=matrix([ 290; 22+%i*4;-26; 22-%i*4; 9.5+%i*9.52627944162882301;
+               -1.1339745962155614+%i*17.1602540378443891;-3.5+%i*25.1147367097487191;
+               -2.8660254037844384+%i*0.16025403784438552; 9.5-%i*9.52627944162882301;
+               -2.8660254037844384-%i*0.16025403784438552;-3.5-%i*25.1147367097487191;
+               -1.1339745962155614-%i*17.1602540378443891;-10.9549150281252636-%i*1.37984007917967944;
+               5.35973404130009712-%i*26.1183685942109989;-23.4614928368734752-%i*1.14281435514402396;
+               -3.59580201879988692+%i*23.0406850570357449;-21.3658553026453930-%i*8.84359942677465227;
+               20.7330326917071268-%i*8.81688081018132586; 3.64531223802112692-%i*9.52499614355328994;
+               7.43941996380932657-%i*16.867370295570808; 17.5396173813961269+%i*3.3290181678526012;
+               15.0849628274577707+%i*11.593028238175755; 25.597333548226878-%i*1.41840966171390725;
+               -18.8967357079763296-%i*30.6614339614318183;-16.5450849718747364+%i*32.005406439473461;
+               -2.0005198567285527+%i*10.4427980896260522; 8.9614928368734752-%i*15.1639036975864734;
+               8.23658783422834162-%i*9.7162555616206916;-4.97109202629695890-%i*8.30757202395887973;
+               0.92910806515476718-%i*30.3790246133370161;-5.43718181239582421+%i*23.1017112524799586;
+               -14.884673669748171-%i*11.3804574337330209; 16.7973299475462241+%i*19.3569789554980396;
+               -0.44355669881229343+%i*5.1399061460535682;-7.8054639738521807-%i*7.52153572775482537;
+               -5.96155747159219818-%i*1.55370934855336351;-16.5450849718747364-%i*32.005406439473461;
+               8.23658783422834162+%i*9.7162555616206916; 8.9614928368734752+%i*15.1639036975864734;
+               -2.0005198567285527-%i*10.4427980896260522; 16.7973299475462241-%i*19.3569789554980396;
+               -5.96155747159219818+%i*1.55370934855336351;-7.8054639738521807+%i*7.52153572775482537;
+               -0.44355669881229343-%i*5.1399061460535682;-4.97109202629695890+%i*8.30757202395887973;
+               -14.884673669748171+%i*11.3804574337330209;-5.43718181239582421-%i*23.1017112524799586;
+               0.92910806515476718+%i*30.3790246133370161;-10.9549150281252636+%i*1.37984007917967944;
+               -3.59580201879988692-%i*23.0406850570357449;-23.4614928368734752+%i*1.14281435514402396;
+               5.35973404130009712+%i*26.1183685942109989; 17.5396173813961269-%i*3.3290181678526012;
+               -18.8967357079763296+%i*30.6614339614318183; 25.597333548226878+%i*1.41840966171390725;
+               15.0849628274577707-%i*11.593028238175755;-21.3658553026453930+%i*8.84359942677465227;
+               7.43941996380932657+%i*16.867370295570808; 3.64531223802112692+%i*9.52499614355328994;
+               20.7330326917071268+%i*8.81688081018132586],[4,3,5]);
+y=fft(A);
+assert_checkalmostequal(y,y_ref); 
+//C2R case   ------------------------------------------------------------------------------------
+A=matrix([ 2900; 220+%i*40;-260; 220-%i*40; 95+%i*95;-11+%i*172;-35+%i*251;-29+%i*2; 95-%i*95;
+           -29-%i*2;-35-%i*251;-11-%i*172;-110-%i*14; 54-%i*261;-235-%i*11;-36+%i*230;-214-%i*88;
+           207-%i*88; 36-%i*95; 74-%i*169; 175+%i*33; 151+%i*116; 256-%i*14;-189-%i*307;
+           -165+%i*320;-20+%i*104; 90-%i*152; 82-%i*97;-50-%i*83; 9-%i*304;-54+%i*231;-149-%i*114;
+           168+%i*194;-4+%i*51;-78-%i*75;-60-%i*16;-165-%i*320; 82+%i*97; 90+%i*152;-20-%i*104;
+           168-%i*194;-60+%i*16;-78+%i*75;-4-%i*51;-50+%i*83;-149+%i*114;-54-%i*231; 9+%i*304;
+           -110+%i*14;-36-%i*230;-235+%i*11; 54+%i*261; 175-%i*33;-189+%i*307; 256+%i*14;
+           151-%i*116;-214+%i*88; 74+%i*169; 36+%i*95; 207+%i*88],[4,3,5]);
+y_ref=matrix([ 2996; 3600; 1800; 2396; 1804.08726109815325; 601.420841162336728; 1797.20231832067839;
+               2402.0440006453523; 2399.91273890184675; 2998.57915883766327; 2.79768167932161305;
+               5401.95599935464725; 2396.96074950014463; 2999.02579525054898; 3601.07865923712325;
+               4800.47728151174852; 5402.68357811465103; 5996.71587420499782; 2994.98775825329631;
+               4800.7569165971172; 1194.78718041472757; 1801.42138987713292; 597.945126438306488;
+               4795.69787130615623; 1806.28063851446973; 2996.33933739403255; 1802.22357633135243;
+               2999.61398771896711; 4800.14227629597099; 1194.58106615498582; 4200.9816123952096;
+               -1.643335439786938; 3000.6599157117771; 3602.13659702117502; 1207.26152998727684;
+               601.910475422587638; 3601.29217048561441; 5398.45474462091079; 4205.6200225335615;
+               3606.49125722100416; 5397.78905489267254; 4200.45827894945342; 2396.05617461713109;
+               1802.27482470993255; 3000.2119789042963; 5400.98960279924631; 2403.91117288032501;
+               1800.15817472797062; 4799.46644149977146; 4206.18012273450677; 591.077741897962369;
+               1197.41747354827976; 2398.62992927763071; 1199.93973694330134; 600.335830922918376;
+               5401.45253626486101; 1201.09608638827149; 2403.75745404970803; 4798.52079450553538;
+               4195.39253641116193],[4,3,5]);
+y=fft(A);
+assert_checktrue(isreal(y));
+assert_checkalmostequal(y,y_ref); 
+y=fft(A,"symmetric");
+assert_checktrue(isreal(y));
+assert_checkalmostequal(y,y_ref);
+y=fft(A,"nonsymmetric");
+assert_checktrue(~isreal(y));
+assert_checkalmostequal(y,y_ref);
+//C2C case
+//------------------------------------------------------------------------------------
+A=[0      %i  3-%i
+   2+%i   -1  -1
+   3       4   4
+   2-3*%i -1  -1];
+A(:,:,2)=A+1;
+A(:,:,3)=A(:,:,2).*A(:,:,2);
+y=fft(A);
+y_ref=matrix([ 130-%i*22;-34-%i*14; 102+%i*10;-98+%i*2; 11.624355652982139+%i*5.18653347947321031;
+               45.6243556529821319+%i*13.1865334794732103;-28.375644347017861+%i*37.1865334794732121;
+               -18.375644347017861+%i*29.1865334794732121;-12.624355652982139-%i*31.1865334794732121;
+               21.3756443470178574-%i*23.1865334794732121;-52.6243556529821319+%i*0.81346652052678969;
+               -42.624355652982139-%i*7.18653347947321031;-30.1435935394489825+%i*63.4256258422040702;
+               23.124355652982139-%i*12.0525588832576496;-33.464101615137757+%i*49.9615242270663131;
+               29.2679491924311215-%i*54.6935750346351952;-0.90192378864668221-%i*5.2224318643354568;
+               -19.633974596215559+%i*23.2224318643354550;-16.2224318643354550-%i*18.6865334794732121;
+               -13.4903810567665765-%i*19.4185842870420871; 24.026279441628823-%i*6.83012701892219098;
+               5.29422863405994804+%i*21.6147367097487226; 8.7057713659400484-%i*20.2942286340599445;
+               11.4378221735089287-%i*21.026279441628823;-57.8564064605510140-%i*47.4256258422040702;
+               -1.1243556529821408+%i*26.0525588832576496;-26.5358983848622465-%i*53.9615242270663131;
+               32.732050807568875+%i*52.6935750346351952; 4.97372055837117344+%i*1.83012701892219409;
+               -10.2942286340599463-%i*28.614736709748719; 24.2942286340599480-%i*4.705771365940052;
+               23.5621778264910695-%i*1.9737205583711752;-6.09807621135331601+%i*24.2224318643354550;
+               -21.3660254037844375-%i*6.2224318643354586; 13.2224318643354550+%i*17.6865334794732085;
+               12.4903810567665818+%i*20.4185842870420871],[4,3,3]);
+assert_checkalmostequal(y,y_ref); 
+//N-D transform  *******************************************************************************
+//R2R case  ------------------------------------------------------------------------------------
+A=matrix([7090;265;265;180;-42;-198;30;15;15;180;-198;-42;160;235;-245;-335;135;182;240;-75;75;
+          -265;465;148;160;-245;235;-265;148;465;240;75;-75;-335;182;135;-410;446;204;-280;-253;
+          353;-450;-198;-372;140;351;229;-48;236;-312;456;181;-279;262;-540;-50;363;385;-99;368;
+          242;-6;-236;-71;-321;158;20;-90;397;109;195;-110;265;265;-120;-370;-110;-650;55;55;-120;
+          -110;-370;-20;-125;-245;91;-153;34;-80;85;-5;-151;-447;416;-20;-245;-125;-151;416;-447;
+          -80;-5;85;91;34;-153;-410;204;446;140;229;351;-450;-372;-198;-280;353;-253;368;-6;242;
+          397;195;109;158;-90;20;-236;-321;-71;-48;-312;236;363;-99;385;262;-50;-540;456;-279;181],[3,4,3,4]);
+y_ref=matrix([ 8640; 6480; 6480; 11520; 5760.26656797432588; 5039.73343202567412; 4320; 7200; 7200;
+               11520; 5039.73343202567412; 5760.26656797432588; 4320; 2160; 2880; 9369.32603294810724;
+               4323.73066958946401; 5040.79842187187296; 7200; 2160.00000000000045; 2880;
+               12230.6739670518928; 3596.2693304105369; 12239.2015781281261; 4320; 2880; 2160;
+               12230.6739670518928; 12239.2015781281261; 3596.2693304105369; 7200; 2880;
+               2160.00000000000045; 9369.32603294810724; 5040.79842187187296; 4323.73066958946401;
+               11520; 4318.1340241797152; 9361.8659758202848; 12240; 5046.12849930729499;
+               7193.87150069270501; 7200; 10079.7334320256741; 10800.2665679743259; 2160;
+               2164.52909146133834; 8635.47090853866212; 7923.73066958946401; 7196.80246635918866;
+               8641.59812579485151; 7921.06627189730625; 6480.53313594865176; 10801.5994078459589;
+               10079.2015781281261; 6482.39782971783188; 7198.66844217947437; 5759.73343202567321;
+               9362.39911176893838; 5038.66716012836696; 7196.26933041053599; 13678.4018742051485;
+               6483.19753364081134; 5038.93372810269375; 6478.40059215404108; 5039.46686405134824;
+               2880.79842187187342; 1441.33155782052563; 9357.60217028216903; 6480.26656797432679;
+               8641.33283987163304; 2877.60088823106116; 4320; 4320; 4320; 3600; 8639.20029607702054;
+               10800.7997039229795; 12960; 8640; 8640; 3600; 10800.7997039229795; 8639.20029607702054;
+               7920; 12960; 10800; 9365.06350946109706; 7196.00276243620829; 8637.60217028216721;
+               10800; 720.000000000000455; 7920; 5034.93649053890294; 8643.99723756379171;
+               5762.39782971783279; 7920; 10800; 12960; 5034.93649053890294; 5762.39782971783279;
+               8643.99723756379171; 10800; 7920; 720.000000000000455; 9365.06350946109706;
+               8637.60217028216721; 7196.00276243620829; 11520; 9361.8659758202848; 4318.1340241797152;
+               2160; 8635.47090853866212; 2164.52909146133834; 7200; 10800.2665679743259;
+               10079.7334320256741; 12240; 7193.87150069270501; 5046.12849930729499;
+               7196.26933041053599; 6483.19753364081134; 13678.4018742051485; 6480.26656797432679;
+               2877.60088823106116; 8641.33283987163304; 2880.79842187187342; 9357.60217028216903;
+               1441.33155782052563; 5038.93372810269375; 5039.46686405134824; 6478.40059215404108;
+               7923.73066958946401; 8641.59812579485151; 7196.80246635918866; 5759.73343202567321;
+               5038.66716012836696; 9362.39911176893838; 10079.2015781281261; 7198.66844217947437;
+               6482.39782971783188; 7921.06627189730625; 10801.5994078459589; 6480.53313594865176],[3,4,3,4]);
+y=fft(A);
+assert_checktrue(isreal(y));
+assert_checkalmostequal(y,y_ref); 
+A=matrix([ 2900; 220+%i*40;-260; 220-%i*40; 95+%i*95;-11+%i*172;-35+%i*251;-29+%i*2; 95-%i*95;
+           -29-%i*2;-35-%i*251;-11-%i*172;-110-%i*14; 54-%i*261;-235-%i*11;-36+%i*230;-214-%i*88;
+           207-%i*88; 36-%i*95; 74-%i*169; 175+%i*33; 151+%i*116; 256-%i*14;-189-%i*307;
+           -165+%i*320;-20+%i*104; 90-%i*152; 82-%i*97;-50-%i*83; 9-%i*304;-54+%i*231;-149-%i*114;
+           168+%i*194;-4+%i*51;-78-%i*75;-60-%i*16;-165-%i*320; 82+%i*97; 90+%i*152;-20-%i*104;
+           168-%i*194;-60+%i*16;-78+%i*75;-4-%i*51;-50+%i*83;-149+%i*114;-54-%i*231; 9+%i*304;
+           -110+%i*14;-36-%i*230;-235+%i*11; 54+%i*261; 175-%i*33;-189+%i*307; 256+%i*14;
+           151-%i*116;-214+%i*88; 74+%i*169; 36+%i*95; 207+%i*88],[4,3,5]);
+y_ref=matrix([ 2996; 3600; 1800; 2396; 1804.08726109815325; 601.420841162336728; 1797.20231832067839;
+               2402.0440006453523; 2399.91273890184675; 2998.57915883766327; 2.79768167932161305;
+               5401.95599935464725; 2396.96074950014463; 2999.02579525054898; 3601.07865923712325;
+               4800.47728151174852; 5402.68357811465103; 5996.71587420499782; 2994.98775825329631;
+               4800.7569165971172; 1194.78718041472757; 1801.42138987713292; 597.945126438306488;
+               4795.69787130615623; 1806.28063851446973; 2996.33933739403255; 1802.22357633135243;
+               2999.61398771896711; 4800.14227629597099; 1194.58106615498582; 4200.9816123952096;
+               -1.643335439786938; 3000.6599157117771; 3602.13659702117502; 1207.26152998727684;
+               601.910475422587638; 3601.29217048561441; 5398.45474462091079; 4205.6200225335615;
+               3606.49125722100416; 5397.78905489267254; 4200.45827894945342; 2396.05617461713109;
+               1802.27482470993255; 3000.2119789042963; 5400.98960279924631; 2403.91117288032501;
+               1800.15817472797062; 4799.46644149977146; 4206.18012273450677; 591.077741897962369;
+               1197.41747354827976; 2398.62992927763071; 1199.93973694330134; 600.335830922918376;
+               5401.45253626486101; 1201.09608638827149; 2403.75745404970803; 4798.52079450553538;
+               4195.39253641116193],[4,3,5]);
+y=fft(A);
+assert_checktrue(isreal(y));
+assert_checkalmostequal(y,y_ref); 
+y=fft(A,"symmetric");
+assert_checktrue(isreal(y));
+assert_checkalmostequal(y,y_ref);
+y=fft(A,"nonsymmetric");
+assert_checktrue(~isreal(y));
+assert_checkalmostequal(y,y_ref);
+//============================================================================================
+//=================================fft(A ,isn, sel [,flag]) ==================================
+//============================================================================================
+//R2C and C2R case ---------------------------------------------------------------------------
+//      Multiple 1D transforms
+A=[0   1   1
+   2  -1  -1
+   3   4   4
+   5   1  -1];
+y_ref = [ 10, 5, 3;
+          -3+%i*3,-3+%i*2,-3;
+          -4, 5, 7;
+          -3-%i*3,-3-%i*2,-3];
+y=fft(A,-1,1);
+assert_checkalmostequal(y,y_ref);
+y=fft(y_ref,1,1);
+assert_checktrue(isreal(y));
+assert_checkalmostequal(A,y);
+y_ref = [ 2.5, 1.25, 0.75;
+          -0.75-%i*0.75,-0.75-%i*0.5,-0.75;
+          -1, 1.25, 1.75;
+          -0.75+%i*0.75,-0.75+%i*0.5,-0.75];
+y=fft(A,1,1);
+assert_checkalmostequal(y,y_ref);
+y=fft(y_ref,-1,1);
+assert_checktrue(isreal(y));
+assert_checkalmostequal(A,y);
+y_ref = [ 2,-1,-1;
+          0, 3, 3;
+          11,-1,-1;
+          5, 5-%i*1.7320508, 5+%i*1.7320508];
+y=fft(A,-1,2);
+assert_checkalmostequal(y,y_ref);
+y=fft(y_ref,1,2);
+assert_checktrue(isreal(y));
+assert_checkalmostequal(A,y);
+y_ref = [ 0.66666666666666663,-0.33333333333333331,-0.33333333333333331;
+          0, 1, 1;
+          3.66666666666666652,-0.33333333333333326,-0.33333333333333326;
+          1.66666666666666652, 1.66666666666666652+%i*0.57735026918962573,..
+          1.66666666666666652-%i*0.57735026918962573];
+y=fft(A,1,2);
+assert_checkalmostequal(y,y_ref);
+y=fft(y_ref,-1,2);
+assert_checktrue(isreal(y));
+assert_checkalmostequal(A,y);
+//      Multiple 1D and 2D transforms of ND arrays
+Dims=[5 3 4];
+A=matrix(1:60,Dims);
+Sel=2;
+y=fft(A,-1,Sel);
+for i=1:Dims(1)
+  for j=1:Dims(3)
+     ind=list(i,:,j);
+    assert_checkalmostequal(y(ind(:)),fft(A(ind(:)),-1));
+  end
+end
+y=fft(y,1,Sel);
+assert_checktrue(isreal(y));
+for i=1:Dims(1)
+  for j=1:Dims(3)
+    ind=list(i,:,j);
+    assert_checkalmostequal(y(ind(:)),A(ind(:)));
+  end
+end
+Sel=3;
+y=fft(A,-1,Sel);
+for i=1:Dims(1)
+  for j=1:Dims(2)
+    ind=list(i,j,:);
+    assert_checkalmostequal(y(ind(:)),fft(A(ind(:)),-1));
+  end
+end
+y=fft(y,1,Sel);
+assert_checktrue(isreal(y));
+for i=1:Dims(1)
+  for j=1:Dims(2)
+    ind=list(i,j,:);
+    assert_checkalmostequal(y(ind(:)),A(ind(:)));
+  end
+end
+Sel=[1 2];
+y=fft(A,-1,Sel);
+for j=1:Dims(3)
+  ind=list(:,:,j);
+  assert_checkalmostequal(y(ind(:)),fft(A(ind(:)),-1));
+end
+y=fft(y,1,Sel);
+assert_checktrue(isreal(y));
+for j=1:Dims(3)
+  ind=list(:,:,j);
+  assert_checkalmostequal(y(ind(:)),A(ind(:)));
+end
+Sel=[1 3];
+y=fft(A,-1,Sel);
+for j=1:Dims(2)
+  ind=list(:,j,:);
+  assert_checkalmostequal(y(ind(:)),fft(A(ind(:)),-1));
+end
+y=fft(y,1,Sel);
+assert_checktrue(isreal(y));
+for j=1:Dims(2)
+  ind=list(:,j,:);
+  assert_checkalmostequal(y(ind(:)),A(ind(:)));
+end
+Dims=[5 3 4 7];
+A=matrix(1:prod(Dims),Dims);
+Sel=[1 3 4];
+y=fft(A,-1,Sel);
+for j=1:Dims(2)
+  ind=list(:,j,:,:);
+  assert_checkalmostequal(y(ind(:)),fft(A(ind(:)),-1));
+end
+y=fft(y,1,Sel);
+assert_checktrue(isreal(y));
+for j=1:Dims(2)
+  ind=list(:,j,:,:);
+  assert_checkalmostequal(y(ind(:)),A(ind(:)));
+end
+Sel=[2  4];
+y=fft(A,-1,Sel);
+for i=1:Dims(1)
+  for j=1:Dims(3)
+    ind=list(i,:,j,:);
+    assert_checkalmostequal(y(ind(:)),fft(A(ind(:)),-1));
+  end
+end
+y=fft(y,1,Sel);
+assert_checktrue(isreal(y));
+for i=1:Dims(1)
+  for j=1:Dims(3)
+    ind=list(i,:,j,:);
+    assert_checkalmostequal(y(ind(:)),A(ind(:)));
+  end
+end
+Sel=3;
+y=fft(A,-1,Sel);
+for i=1:Dims(1)
+  for j=1:Dims(2)
+    for k=1:Dims(4)
+      ind=list(i,j,:,k);
+      assert_checkalmostequal(y(ind(:)),fft(A(ind(:)),-1));
+    end
+  end
+end
+y=fft(y,1,Sel);
+assert_checktrue(isreal(y));
+for i=1:Dims(1)
+  for j=1:Dims(2)
+    for k=1:Dims(4)
+      ind=list(i,j,:,k);
+      assert_checkalmostequal(y(ind(:)),A(ind(:)));
+    end
+  end
+end
diff --git a/scilab/modules/fftw/tests/unit_tests/fftw_part2.tst b/scilab/modules/fftw/tests/unit_tests/fftw_part2.tst
new file mode 100644 (file)
index 0000000..afc9d67
--- /dev/null
@@ -0,0 +1,421 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2012 - INRIA - Serge STEER
+//
+//  This file is distributed under the same license as the Scilab package.
+// =============================================================================
+
+// <-- JVM NOT MANDATORY -->
+
+//3-D transform  *******************************************************************************
+
+//R2R case  ------------------------------------------------------------------------------------
+A=[0   1   1
+   2  -1  -1
+   3   4   4
+   2  -1  -1];
+A(:,:,2)=A+1;
+A(:,:,3)=A(:,:,2);
+y_ref=matrix([63;-27;39;-27;12;0;-24;0;12;0;-24;0;-12;
+              0;0;0;0;0;0;0;0;0;0;0;
+              -12;0;0;0;0;0;0;0;0;0;0;0],[4 3 3]);
+y=fft(A);
+assert_checktrue(isreal(y));
+assert_checkalmostequal(y,y_ref); 
+assert_checkalmostequal(A,fft(y,1),0,10*%eps);
+
+y=fft(A,"symmetric");
+assert_checktrue(isreal(y));
+assert_checkalmostequal(y,y_ref); 
+assert_checkalmostequal(A,fft(y,1,"symmetric"),0,10*%eps);
+
+y=fft(A,"nonsymmetric"); //use R2C
+assert_checktrue(~isreal(y));
+assert_checkalmostequal(y,y_ref); 
+assert_checkalmostequal(A,fft(y,1,"nonsymmetric"),0,10*%eps);
+
+
+A=matrix([4750;-163;138;138;-163;-100;-2;9;-148;42;10;-301;246;246;-301;-100;42;-148;9;-2;-12;157;
+          -110;224;37;-101;-94;260;258;345;-49;175;227;110;161;65;-40;-182;161;-390;412;101;168;
+          138;35;21;-95;-81;236;1;219;-215;120;284;-232;-35;-23;215;-191;122;412;35;138;168;101;
+          -35;122;-191;215;-23;219;-232;284;120;-215;21;1;236;-81;-95;-12;37;224;-110;157;65;-390;
+          161;-182;-40;-49;161;110;227;175;-101;345;258;260;-94],[5,4,5]);
+y_ref=matrix([ 9006; 1997.01835368650836; 7499.98164631349118; 7499.98164631349118;
+               1997.01835368650836; 5500; 8003.03595972396761; 4499.30203473224719;
+               3496.74144394796622; 4500.92056159581989; 7994; 4500.41996658886728;
+               7002.58003341113272; 7002.58003341113272; 4500.41996658886728; 5500;
+               4500.92056159581989; 3496.74144394796622; 4499.30203473224719; 8003.03595972396761;
+               3003.23606797749972; 4503.21094298379558; 2498.80193260011856; 4500.56038652002371;
+               3002.80933008143711; 1502.48409399493175; 4997.98726249178435; 6998.63971425121235;
+               4503.41908441918713; 5499.99740938413652; 4000.79645449752343; 3004.49048964150825;
+               3499; 4495.40709100495314; 4504.89210254386671; 5498.03152064027927;
+               3999.73866895309675; 1500.9206722688125; 7001.49266501579041; 3003.15588613093223;
+               2998.76393202250028; 5001.43961347997629; 5493.78905701620442; 6994.19066991856289;
+               5003.19806739988144; 4499.2782026543191; 4996.34845842043978; 3004.96649100621744;
+               7499.64517406068444; 5505.14335301404844; 4497.20354550247703; 3502.59290899504595;
+               8498.50951035849175; 6998.10789745613329; 3499; 7000.20618271046988;
+               5998.73979214458359; 3497.30757754890101; 2497.2015304242459; 3495.29626046592784;
+               2998.76393202250028; 5003.19806739988144; 6994.19066991856289; 5493.78905701620442;
+               5001.43961347997629; 7000.20618271046988; 3495.29626046592784; 2497.2015304242459;
+               3497.30757754890101; 5998.73979214458359; 4497.20354550247703; 3499;
+               6998.10789745613329; 8498.50951035849175; 3502.59290899504595; 4499.2782026543191;
+               5505.14335301404844; 7499.64517406068444; 3004.96649100621744; 4996.34845842043978;
+               3003.23606797749972; 3002.80933008143711; 4500.56038652002371; 2498.80193260011856;
+               4503.21094298379558; 5498.03152064027927; 3003.15588613093223; 7001.49266501579041;
+               1500.9206722688125; 3999.73866895309675; 4000.79645449752343; 4504.89210254386671;
+               4495.40709100495314; 3499; 3004.49048964150825; 1502.48409399493175;
+               5499.99740938413652; 4503.41908441918713; 6998.63971425121235; 4997.98726249178435],[5,4,5]);
+
+y=fft(A);
+assert_checktrue(isreal(y));
+assert_checkalmostequal(y,y_ref); 
+
+
+//R2C case   ------------------------------------------------------------------------------------
+A=matrix([5;4;3;6;4;9;0;5;3;4;3;1;8;2;1;7;2;7;8;4;4;9;
+          1;2;6;6;7;9;5;3;4;9;9;3;4;7;3;5;3;5;5;1;2;6;
+          8;0;7;2;4;8;6;5;2;8;1;3;9;8;5;10],[4,3,5]);
+y_ref=matrix([ 290; 22+%i*4;-26; 22-%i*4; 9.5+%i*9.52627944162882301;
+               -1.1339745962155614+%i*17.1602540378443891;-3.5+%i*25.1147367097487191;
+               -2.8660254037844384+%i*0.16025403784438552; 9.5-%i*9.52627944162882301;
+               -2.8660254037844384-%i*0.16025403784438552;-3.5-%i*25.1147367097487191;
+               -1.1339745962155614-%i*17.1602540378443891;-10.9549150281252636-%i*1.37984007917967944;
+               5.35973404130009712-%i*26.1183685942109989;-23.4614928368734752-%i*1.14281435514402396;
+               -3.59580201879988692+%i*23.0406850570357449;-21.3658553026453930-%i*8.84359942677465227;
+               20.7330326917071268-%i*8.81688081018132586; 3.64531223802112692-%i*9.52499614355328994;
+               7.43941996380932657-%i*16.867370295570808; 17.5396173813961269+%i*3.3290181678526012;
+               15.0849628274577707+%i*11.593028238175755; 25.597333548226878-%i*1.41840966171390725;
+               -18.8967357079763296-%i*30.6614339614318183;-16.5450849718747364+%i*32.005406439473461;
+               -2.0005198567285527+%i*10.4427980896260522; 8.9614928368734752-%i*15.1639036975864734;
+               8.23658783422834162-%i*9.7162555616206916;-4.97109202629695890-%i*8.30757202395887973;
+               0.92910806515476718-%i*30.3790246133370161;-5.43718181239582421+%i*23.1017112524799586;
+               -14.884673669748171-%i*11.3804574337330209; 16.7973299475462241+%i*19.3569789554980396;
+               -0.44355669881229343+%i*5.1399061460535682;-7.8054639738521807-%i*7.52153572775482537;
+               -5.96155747159219818-%i*1.55370934855336351;-16.5450849718747364-%i*32.005406439473461;
+               8.23658783422834162+%i*9.7162555616206916; 8.9614928368734752+%i*15.1639036975864734;
+               -2.0005198567285527-%i*10.4427980896260522; 16.7973299475462241-%i*19.3569789554980396;
+               -5.96155747159219818+%i*1.55370934855336351;-7.8054639738521807+%i*7.52153572775482537;
+               -0.44355669881229343-%i*5.1399061460535682;-4.97109202629695890+%i*8.30757202395887973;
+               -14.884673669748171+%i*11.3804574337330209;-5.43718181239582421-%i*23.1017112524799586;
+               0.92910806515476718+%i*30.3790246133370161;-10.9549150281252636+%i*1.37984007917967944;
+               -3.59580201879988692-%i*23.0406850570357449;-23.4614928368734752+%i*1.14281435514402396;
+               5.35973404130009712+%i*26.1183685942109989; 17.5396173813961269-%i*3.3290181678526012;
+               -18.8967357079763296+%i*30.6614339614318183; 25.597333548226878+%i*1.41840966171390725;
+               15.0849628274577707-%i*11.593028238175755;-21.3658553026453930+%i*8.84359942677465227;
+               7.43941996380932657+%i*16.867370295570808; 3.64531223802112692+%i*9.52499614355328994;
+               20.7330326917071268+%i*8.81688081018132586],[4,3,5]);
+y=fft(A);
+assert_checkalmostequal(y,y_ref); 
+
+//C2R case   ------------------------------------------------------------------------------------
+A=matrix([ 2900; 220+%i*40;-260; 220-%i*40; 95+%i*95;-11+%i*172;-35+%i*251;-29+%i*2; 95-%i*95;
+           -29-%i*2;-35-%i*251;-11-%i*172;-110-%i*14; 54-%i*261;-235-%i*11;-36+%i*230;-214-%i*88;
+           207-%i*88; 36-%i*95; 74-%i*169; 175+%i*33; 151+%i*116; 256-%i*14;-189-%i*307;
+           -165+%i*320;-20+%i*104; 90-%i*152; 82-%i*97;-50-%i*83; 9-%i*304;-54+%i*231;-149-%i*114;
+           168+%i*194;-4+%i*51;-78-%i*75;-60-%i*16;-165-%i*320; 82+%i*97; 90+%i*152;-20-%i*104;
+           168-%i*194;-60+%i*16;-78+%i*75;-4-%i*51;-50+%i*83;-149+%i*114;-54-%i*231; 9+%i*304;
+           -110+%i*14;-36-%i*230;-235+%i*11; 54+%i*261; 175-%i*33;-189+%i*307; 256+%i*14;
+           151-%i*116;-214+%i*88; 74+%i*169; 36+%i*95; 207+%i*88],[4,3,5]);
+y_ref=matrix([ 2996; 3600; 1800; 2396; 1804.08726109815325; 601.420841162336728; 1797.20231832067839;
+               2402.0440006453523; 2399.91273890184675; 2998.57915883766327; 2.79768167932161305;
+               5401.95599935464725; 2396.96074950014463; 2999.02579525054898; 3601.07865923712325;
+               4800.47728151174852; 5402.68357811465103; 5996.71587420499782; 2994.98775825329631;
+               4800.7569165971172; 1194.78718041472757; 1801.42138987713292; 597.945126438306488;
+               4795.69787130615623; 1806.28063851446973; 2996.33933739403255; 1802.22357633135243;
+               2999.61398771896711; 4800.14227629597099; 1194.58106615498582; 4200.9816123952096;
+               -1.643335439786938; 3000.6599157117771; 3602.13659702117502; 1207.26152998727684;
+               601.910475422587638; 3601.29217048561441; 5398.45474462091079; 4205.6200225335615;
+               3606.49125722100416; 5397.78905489267254; 4200.45827894945342; 2396.05617461713109;
+               1802.27482470993255; 3000.2119789042963; 5400.98960279924631; 2403.91117288032501;
+               1800.15817472797062; 4799.46644149977146; 4206.18012273450677; 591.077741897962369;
+               1197.41747354827976; 2398.62992927763071; 1199.93973694330134; 600.335830922918376;
+               5401.45253626486101; 1201.09608638827149; 2403.75745404970803; 4798.52079450553538;
+               4195.39253641116193],[4,3,5]);
+y=fft(A);
+assert_checktrue(isreal(y));
+assert_checkalmostequal(y,y_ref); 
+y=fft(A,"symmetric");
+assert_checktrue(isreal(y));
+assert_checkalmostequal(y,y_ref);
+
+y=fft(A,"nonsymmetric");
+assert_checktrue(~isreal(y));
+assert_checkalmostequal(y,y_ref);
+
+//C2C case
+//------------------------------------------------------------------------------------
+A=[0      %i  3-%i
+   2+%i   -1  -1
+   3       4   4
+   2-3*%i -1  -1];
+A(:,:,2)=A+1;
+A(:,:,3)=A(:,:,2).*A(:,:,2);
+y=fft(A);
+y_ref=matrix([ 130-%i*22;-34-%i*14; 102+%i*10;-98+%i*2; 11.624355652982139+%i*5.18653347947321031;
+               45.6243556529821319+%i*13.1865334794732103;-28.375644347017861+%i*37.1865334794732121;
+               -18.375644347017861+%i*29.1865334794732121;-12.624355652982139-%i*31.1865334794732121;
+               21.3756443470178574-%i*23.1865334794732121;-52.6243556529821319+%i*0.81346652052678969;
+               -42.624355652982139-%i*7.18653347947321031;-30.1435935394489825+%i*63.4256258422040702;
+               23.124355652982139-%i*12.0525588832576496;-33.464101615137757+%i*49.9615242270663131;
+               29.2679491924311215-%i*54.6935750346351952;-0.90192378864668221-%i*5.2224318643354568;
+               -19.633974596215559+%i*23.2224318643354550;-16.2224318643354550-%i*18.6865334794732121;
+               -13.4903810567665765-%i*19.4185842870420871; 24.026279441628823-%i*6.83012701892219098;
+               5.29422863405994804+%i*21.6147367097487226; 8.7057713659400484-%i*20.2942286340599445;
+               11.4378221735089287-%i*21.026279441628823;-57.8564064605510140-%i*47.4256258422040702;
+               -1.1243556529821408+%i*26.0525588832576496;-26.5358983848622465-%i*53.9615242270663131;
+               32.732050807568875+%i*52.6935750346351952; 4.97372055837117344+%i*1.83012701892219409;
+               -10.2942286340599463-%i*28.614736709748719; 24.2942286340599480-%i*4.705771365940052;
+               23.5621778264910695-%i*1.9737205583711752;-6.09807621135331601+%i*24.2224318643354550;
+               -21.3660254037844375-%i*6.2224318643354586; 13.2224318643354550+%i*17.6865334794732085;
+               12.4903810567665818+%i*20.4185842870420871],[4,3,3]);
+assert_checkalmostequal(y,y_ref); 
+
+//N-D transform  *******************************************************************************
+//R2R case  ------------------------------------------------------------------------------------
+
+A=matrix([7090;265;265;180;-42;-198;30;15;15;180;-198;-42;160;235;-245;-335;135;182;240;-75;75;
+          -265;465;148;160;-245;235;-265;148;465;240;75;-75;-335;182;135;-410;446;204;-280;-253;
+          353;-450;-198;-372;140;351;229;-48;236;-312;456;181;-279;262;-540;-50;363;385;-99;368;
+          242;-6;-236;-71;-321;158;20;-90;397;109;195;-110;265;265;-120;-370;-110;-650;55;55;-120;
+          -110;-370;-20;-125;-245;91;-153;34;-80;85;-5;-151;-447;416;-20;-245;-125;-151;416;-447;
+          -80;-5;85;91;34;-153;-410;204;446;140;229;351;-450;-372;-198;-280;353;-253;368;-6;242;
+          397;195;109;158;-90;20;-236;-321;-71;-48;-312;236;363;-99;385;262;-50;-540;456;-279;181],[3,4,3,4]);
+
+y_ref=matrix([ 8640; 6480; 6480; 11520; 5760.26656797432588; 5039.73343202567412; 4320; 7200; 7200;
+               11520; 5039.73343202567412; 5760.26656797432588; 4320; 2160; 2880; 9369.32603294810724;
+               4323.73066958946401; 5040.79842187187296; 7200; 2160.00000000000045; 2880;
+               12230.6739670518928; 3596.2693304105369; 12239.2015781281261; 4320; 2880; 2160;
+               12230.6739670518928; 12239.2015781281261; 3596.2693304105369; 7200; 2880;
+               2160.00000000000045; 9369.32603294810724; 5040.79842187187296; 4323.73066958946401;
+               11520; 4318.1340241797152; 9361.8659758202848; 12240; 5046.12849930729499;
+               7193.87150069270501; 7200; 10079.7334320256741; 10800.2665679743259; 2160;
+               2164.52909146133834; 8635.47090853866212; 7923.73066958946401; 7196.80246635918866;
+               8641.59812579485151; 7921.06627189730625; 6480.53313594865176; 10801.5994078459589;
+               10079.2015781281261; 6482.39782971783188; 7198.66844217947437; 5759.73343202567321;
+               9362.39911176893838; 5038.66716012836696; 7196.26933041053599; 13678.4018742051485;
+               6483.19753364081134; 5038.93372810269375; 6478.40059215404108; 5039.46686405134824;
+               2880.79842187187342; 1441.33155782052563; 9357.60217028216903; 6480.26656797432679;
+               8641.33283987163304; 2877.60088823106116; 4320; 4320; 4320; 3600; 8639.20029607702054;
+               10800.7997039229795; 12960; 8640; 8640; 3600; 10800.7997039229795; 8639.20029607702054;
+               7920; 12960; 10800; 9365.06350946109706; 7196.00276243620829; 8637.60217028216721;
+               10800; 720.000000000000455; 7920; 5034.93649053890294; 8643.99723756379171;
+               5762.39782971783279; 7920; 10800; 12960; 5034.93649053890294; 5762.39782971783279;
+               8643.99723756379171; 10800; 7920; 720.000000000000455; 9365.06350946109706;
+               8637.60217028216721; 7196.00276243620829; 11520; 9361.8659758202848; 4318.1340241797152;
+               2160; 8635.47090853866212; 2164.52909146133834; 7200; 10800.2665679743259;
+               10079.7334320256741; 12240; 7193.87150069270501; 5046.12849930729499;
+               7196.26933041053599; 6483.19753364081134; 13678.4018742051485; 6480.26656797432679;
+               2877.60088823106116; 8641.33283987163304; 2880.79842187187342; 9357.60217028216903;
+               1441.33155782052563; 5038.93372810269375; 5039.46686405134824; 6478.40059215404108;
+               7923.73066958946401; 8641.59812579485151; 7196.80246635918866; 5759.73343202567321;
+               5038.66716012836696; 9362.39911176893838; 10079.2015781281261; 7198.66844217947437;
+               6482.39782971783188; 7921.06627189730625; 10801.5994078459589; 6480.53313594865176],[3,4,3,4]);
+y=fft(A);
+assert_checktrue(isreal(y));
+assert_checkalmostequal(y,y_ref); 
+A=matrix([ 2900; 220+%i*40;-260; 220-%i*40; 95+%i*95;-11+%i*172;-35+%i*251;-29+%i*2; 95-%i*95;
+           -29-%i*2;-35-%i*251;-11-%i*172;-110-%i*14; 54-%i*261;-235-%i*11;-36+%i*230;-214-%i*88;
+           207-%i*88; 36-%i*95; 74-%i*169; 175+%i*33; 151+%i*116; 256-%i*14;-189-%i*307;
+           -165+%i*320;-20+%i*104; 90-%i*152; 82-%i*97;-50-%i*83; 9-%i*304;-54+%i*231;-149-%i*114;
+           168+%i*194;-4+%i*51;-78-%i*75;-60-%i*16;-165-%i*320; 82+%i*97; 90+%i*152;-20-%i*104;
+           168-%i*194;-60+%i*16;-78+%i*75;-4-%i*51;-50+%i*83;-149+%i*114;-54-%i*231; 9+%i*304;
+           -110+%i*14;-36-%i*230;-235+%i*11; 54+%i*261; 175-%i*33;-189+%i*307; 256+%i*14;
+           151-%i*116;-214+%i*88; 74+%i*169; 36+%i*95; 207+%i*88],[4,3,5]);
+y_ref=matrix([ 2996; 3600; 1800; 2396; 1804.08726109815325; 601.420841162336728; 1797.20231832067839;
+               2402.0440006453523; 2399.91273890184675; 2998.57915883766327; 2.79768167932161305;
+               5401.95599935464725; 2396.96074950014463; 2999.02579525054898; 3601.07865923712325;
+               4800.47728151174852; 5402.68357811465103; 5996.71587420499782; 2994.98775825329631;
+               4800.7569165971172; 1194.78718041472757; 1801.42138987713292; 597.945126438306488;
+               4795.69787130615623; 1806.28063851446973; 2996.33933739403255; 1802.22357633135243;
+               2999.61398771896711; 4800.14227629597099; 1194.58106615498582; 4200.9816123952096;
+               -1.643335439786938; 3000.6599157117771; 3602.13659702117502; 1207.26152998727684;
+               601.910475422587638; 3601.29217048561441; 5398.45474462091079; 4205.6200225335615;
+               3606.49125722100416; 5397.78905489267254; 4200.45827894945342; 2396.05617461713109;
+               1802.27482470993255; 3000.2119789042963; 5400.98960279924631; 2403.91117288032501;
+               1800.15817472797062; 4799.46644149977146; 4206.18012273450677; 591.077741897962369;
+               1197.41747354827976; 2398.62992927763071; 1199.93973694330134; 600.335830922918376;
+               5401.45253626486101; 1201.09608638827149; 2403.75745404970803; 4798.52079450553538;
+               4195.39253641116193],[4,3,5]);
+y=fft(A);
+assert_checktrue(isreal(y));
+assert_checkalmostequal(y,y_ref); 
+y=fft(A,"symmetric");
+assert_checktrue(isreal(y));
+assert_checkalmostequal(y,y_ref);
+
+y=fft(A,"nonsymmetric");
+assert_checktrue(~isreal(y));
+assert_checkalmostequal(y,y_ref);
+
+//============================================================================================
+//=================================fft(A ,isn, sel [,flag]) ==================================
+//============================================================================================
+//R2C and C2R case ---------------------------------------------------------------------------
+//      Multiple 1D transforms
+A=[0   1   1
+   2  -1  -1
+   3   4   4
+   5   1  -1];
+
+y_ref = [ 10, 5, 3;
+          -3+%i*3,-3+%i*2,-3;
+          -4, 5, 7;
+          -3-%i*3,-3-%i*2,-3];
+y=fft(A,-1,1);
+assert_checkalmostequal(y,y_ref);
+y=fft(y_ref,1,1);
+assert_checktrue(isreal(y));
+assert_checkalmostequal(A,y);
+
+y_ref = [ 2.5, 1.25, 0.75;
+          -0.75-%i*0.75,-0.75-%i*0.5,-0.75;
+          -1, 1.25, 1.75;
+          -0.75+%i*0.75,-0.75+%i*0.5,-0.75];
+y=fft(A,1,1);
+assert_checkalmostequal(y,y_ref);
+y=fft(y_ref,-1,1);
+assert_checktrue(isreal(y));
+assert_checkalmostequal(A,y);
+
+y_ref = [ 2,-1,-1;
+          0, 3, 3;
+          11,-1,-1;
+          5, 5-%i*1.7320508, 5+%i*1.7320508];
+
+y=fft(A,-1,2);
+assert_checkalmostequal(y,y_ref);
+y=fft(y_ref,1,2);
+assert_checktrue(isreal(y));
+assert_checkalmostequal(A,y);
+
+y_ref = [ 0.66666666666666663,-0.33333333333333331,-0.33333333333333331;
+          0, 1, 1;
+          3.66666666666666652,-0.33333333333333326,-0.33333333333333326;
+          1.66666666666666652, 1.66666666666666652+%i*0.57735026918962573,..
+          1.66666666666666652-%i*0.57735026918962573];
+y=fft(A,1,2);
+assert_checkalmostequal(y,y_ref);
+y=fft(y_ref,-1,2);
+assert_checktrue(isreal(y));
+assert_checkalmostequal(A,y);
+
+//      Multiple 1D and 2D transforms of ND arrays
+Dims=[5 3 4];
+A=matrix(1:60,Dims);
+Sel=2;
+y=fft(A,-1,Sel);
+for i=1:Dims(1)
+  for j=1:Dims(3)
+     ind=list(i,:,j);
+    assert_checkalmostequal(y(ind(:)),fft(A(ind(:)),-1));
+  end
+end
+
+y=fft(y,1,Sel);
+assert_checktrue(isreal(y));
+for i=1:Dims(1)
+  for j=1:Dims(3)
+    ind=list(i,:,j);
+    assert_checkalmostequal(y(ind(:)),A(ind(:)));
+  end
+end
+
+
+Sel=3;
+y=fft(A,-1,Sel);
+for i=1:Dims(1)
+  for j=1:Dims(2)
+    ind=list(i,j,:);
+    assert_checkalmostequal(y(ind(:)),fft(A(ind(:)),-1));
+  end
+end
+y=fft(y,1,Sel);
+assert_checktrue(isreal(y));
+for i=1:Dims(1)
+  for j=1:Dims(2)
+    ind=list(i,j,:);
+    assert_checkalmostequal(y(ind(:)),A(ind(:)));
+  end
+end
+
+Sel=[1 2];
+y=fft(A,-1,Sel);
+for j=1:Dims(3)
+  ind=list(:,:,j);
+  assert_checkalmostequal(y(ind(:)),fft(A(ind(:)),-1));
+end
+y=fft(y,1,Sel);
+assert_checktrue(isreal(y));
+for j=1:Dims(3)
+  ind=list(:,:,j);
+  assert_checkalmostequal(y(ind(:)),A(ind(:)));
+end
+
+Sel=[1 3];
+y=fft(A,-1,Sel);
+for j=1:Dims(2)
+  ind=list(:,j,:);
+  assert_checkalmostequal(y(ind(:)),fft(A(ind(:)),-1));
+end
+y=fft(y,1,Sel);
+assert_checktrue(isreal(y));
+for j=1:Dims(2)
+  ind=list(:,j,:);
+  assert_checkalmostequal(y(ind(:)),A(ind(:)));
+end
+
+Dims=[5 3 4 7];
+A=matrix(1:prod(Dims),Dims);
+Sel=[1 3 4];
+y=fft(A,-1,Sel);
+for j=1:Dims(2)
+  ind=list(:,j,:,:);
+  assert_checkalmostequal(y(ind(:)),fft(A(ind(:)),-1));
+end
+
+y=fft(y,1,Sel);
+assert_checktrue(isreal(y));
+for j=1:Dims(2)
+  ind=list(:,j,:,:);
+  assert_checkalmostequal(y(ind(:)),A(ind(:)));
+end
+
+Sel=[2  4];
+y=fft(A,-1,Sel);
+for i=1:Dims(1)
+  for j=1:Dims(3)
+    ind=list(i,:,j,:);
+    assert_checkalmostequal(y(ind(:)),fft(A(ind(:)),-1));
+  end
+end
+
+y=fft(y,1,Sel);
+assert_checktrue(isreal(y));
+for i=1:Dims(1)
+  for j=1:Dims(3)
+    ind=list(i,:,j,:);
+    assert_checkalmostequal(y(ind(:)),A(ind(:)));
+  end
+end
+
+Sel=3;
+y=fft(A,-1,Sel);
+for i=1:Dims(1)
+  for j=1:Dims(2)
+    for k=1:Dims(4)
+      ind=list(i,j,:,k);
+      assert_checkalmostequal(y(ind(:)),fft(A(ind(:)),-1));
+    end
+  end
+end
+
+y=fft(y,1,Sel);
+assert_checktrue(isreal(y));
+for i=1:Dims(1)
+  for j=1:Dims(2)
+    for k=1:Dims(4)
+      ind=list(i,j,:,k);
+      assert_checkalmostequal(y(ind(:)),A(ind(:)));
+    end
+  end
+end
diff --git a/scilab/modules/fftw/tests/unit_tests/fftw_part3.dia.ref b/scilab/modules/fftw/tests/unit_tests/fftw_part3.dia.ref
new file mode 100644 (file)
index 0000000..9ee0c4d
--- /dev/null
@@ -0,0 +1,53 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2012 - INRIA - Serge STEER
+//
+//  This file is distributed under the same license as the Scilab package.
+// =============================================================================
+// <-- JVM NOT MANDATORY -->
+//C2C case ------------------------------------------------------------------------------------
+Dims=[5 3 4];
+A=[10     %i  3-%i 5
+   2+%i   -1  -1   7-%i
+   3       4   4   -11
+   2-3*%i -1  -1   0.3+%i
+   -3      -2  -1  8];
+Sel=1;
+y=fft(A,-1,Sel);
+for j=1:Dims(2)
+  ind=list(:,j);
+  assert_checkalmostequal(y(ind(:)),fft(A(ind(:)),-1));
+end
+y=fft(y,1,Sel);
+for j=1:Dims(2)
+  ind=list(:,j);
+  assert_checkalmostequal(y(ind(:)),A(ind(:)),0,10*%eps);
+end
+Sel=2;
+y=fft(A,-1,Sel);
+for i=1:Dims(1)
+  ind=list(i,:);
+  assert_checkalmostequal(y(ind(:)),fft(A(ind(:)),-1));
+end
+y=fft(y,1,Sel);
+for i=1:Dims(1)
+  ind=list(i,:);
+  assert_checkalmostequal(y(ind(:)),A(ind(:)),0,10*%eps);
+end
+Dims=[5 3 4 7 5];
+A=matrix(rand(1,prod(Dims))+%i*rand(1,prod(Dims)),Dims);
+Sel= [2 3 5];
+y=fft(A,-1,Sel);
+for i=1:Dims(1)
+  for j=1:Dims(4)
+    ind=list(i,:,:,j,:);
+    assert_checkalmostequal(y(ind(:)),fft(A(ind(:)),-1));
+  end
+end
+y=fft(y,1,Sel);
+for i=1:Dims(1)
+  for j=1:Dims(4)
+    ind=list(i,:,:,j,:);
+    assert_checkalmostequal(y(ind(:)),A(ind(:)));
+  end
+end
diff --git a/scilab/modules/fftw/tests/unit_tests/fftw_part3.tst b/scilab/modules/fftw/tests/unit_tests/fftw_part3.tst
new file mode 100644 (file)
index 0000000..72323cc
--- /dev/null
@@ -0,0 +1,61 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2012 - INRIA - Serge STEER
+//
+//  This file is distributed under the same license as the Scilab package.
+// =============================================================================
+
+// <-- JVM NOT MANDATORY -->
+
+//C2C case ------------------------------------------------------------------------------------
+Dims=[5 3 4];
+A=[10     %i  3-%i 5
+   2+%i   -1  -1   7-%i
+   3       4   4   -11
+   2-3*%i -1  -1   0.3+%i
+   -3      -2  -1  8];
+
+Sel=1;
+y=fft(A,-1,Sel);
+for j=1:Dims(2)
+  ind=list(:,j);
+  assert_checkalmostequal(y(ind(:)),fft(A(ind(:)),-1));
+end
+y=fft(y,1,Sel);
+for j=1:Dims(2)
+  ind=list(:,j);
+  assert_checkalmostequal(y(ind(:)),A(ind(:)),0,10*%eps);
+end
+
+Sel=2;
+y=fft(A,-1,Sel);
+for i=1:Dims(1)
+  ind=list(i,:);
+  assert_checkalmostequal(y(ind(:)),fft(A(ind(:)),-1));
+end
+y=fft(y,1,Sel);
+for i=1:Dims(1)
+  ind=list(i,:);
+  assert_checkalmostequal(y(ind(:)),A(ind(:)),0,10*%eps);
+end
+
+
+Dims=[5 3 4 7 5];
+A=matrix(rand(1,prod(Dims))+%i*rand(1,prod(Dims)),Dims);
+Sel= [2 3 5];
+y=fft(A,-1,Sel);
+for i=1:Dims(1)
+  for j=1:Dims(4)
+    ind=list(i,:,:,j,:);
+    assert_checkalmostequal(y(ind(:)),fft(A(ind(:)),-1));
+  end
+end
+
+y=fft(y,1,Sel);
+for i=1:Dims(1)
+  for j=1:Dims(4)
+    ind=list(i,:,:,j,:);
+    assert_checkalmostequal(y(ind(:)),A(ind(:)));
+  end
+end
+
diff --git a/scilab/modules/fftw/tests/unit_tests/fftw_part4.dia.ref b/scilab/modules/fftw/tests/unit_tests/fftw_part4.dia.ref
new file mode 100644 (file)
index 0000000..ddbd62d
--- /dev/null
@@ -0,0 +1,152 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2012 - INRIA - Serge STEER
+//
+//  This file is distributed under the same license as the Scilab package.
+// =============================================================================
+// <-- JVM NOT MANDATORY -->
+//R2R case  ------------------------------------------------------------------------------------
+A=[0   1 2 2 1
+   2  -1 3 3 -1
+   3   4 5 5  4
+   2  -1 3 3 -1];
+Dims=[4 5];
+Sel=1;
+y=fft(A,-1,Sel);
+assert_checktrue(isreal(y));
+for j=1:Dims(2)
+  ind=list(:,j);
+  assert_checkalmostequal(y(ind(:)),fft(A(ind(:)),-1));
+end
+y=fft(y,1,Sel);
+assert_checktrue(isreal(y));
+for j=1:Dims(2)
+  ind=list(:,j);
+  assert_checkalmostequal(y(ind(:)),A(ind(:)),0,10*%eps);
+end
+Sel=2;
+y=fft(A,-1,Sel);
+assert_checktrue(isreal(y));
+for i=1:Dims(1)
+  ind=list(i,:);
+  assert_checkalmostequal(y(ind(:)),fft(A(ind(:)),-1));
+end
+y=fft(y,1,Sel);
+assert_checktrue(isreal(y));
+for i=1:Dims(1)
+  ind=list(i,:);
+  assert_checkalmostequal(y(ind(:)),A(ind(:)),0,10*%eps);
+end
+//ND case
+A=[0   1   1
+   2  -1  -1
+   3   4   4
+   2  -1  -1];
+A(:,:,2)=A+1;
+A(:,:,3)=A(:,:,2);
+Dims=size(A);
+Sel=1;
+y=fft(A,-1,Sel);
+assert_checktrue(isreal(y));
+for j=1:Dims(2)
+  for k=1:Dims(3)
+    ind=list(:,j,k);
+    assert_checkalmostequal(y(ind(:)),fft(A(ind(:)),-1));
+  end
+end
+y=fft(y,1,Sel);
+assert_checktrue(isreal(y));
+for j=1:Dims(2)
+  for k=1:Dims(3)
+    ind=list(:,j,k);
+    assert_checkalmostequal(y(ind(:)),A(ind(:)),0,10*%eps);
+  end
+end
+Sel=1:2;
+y=fft(A,-1,Sel);
+assert_checktrue(isreal(y));
+for k=1:Dims(3)
+  ind=list(:,:,k);
+  assert_checkalmostequal(y(ind(:)),fft(A(ind(:)),-1));
+end
+y=fft(y,1,Sel);
+assert_checktrue(isreal(y));
+for k=1:Dims(3)
+  ind=list(:,:,k);
+  assert_checkalmostequal(y(ind(:)),A(ind(:)),0,10*%eps);
+end
+Sel=2:3;
+y=fft(A,-1,Sel);
+assert_checktrue(isreal(y));
+for i=1:Dims(1)
+  ind=list(i,:,:);
+  assert_checkalmostequal(y(ind(:)),fft(A(ind(:)),-1));
+end
+y=fft(y,1,Sel);
+assert_checktrue(isreal(y));
+for i=1:Dims(1)
+  ind=list(i,:,:);
+  assert_checkalmostequal(y(ind(:)),A(ind(:)),0,10*%eps);
+end
+Dims=[5 4 9 5 6];
+A=matrix(rand(1,prod(Dims)),Dims);
+y=fft(A,-1,[2 4]);
+for i1=1:Dims(1) 
+  for i3=1:Dims(3)
+    for i5=1:Dims(5)
+      ind=list(i1,:,i3,:,i5);;
+      assert_checkalmostequal(y(ind(:)),fft(A(ind(:)),-1));
+    end
+  end
+end
+y1=fft(y,1,[2 4]);
+assert_checktrue(isreal(y1));
+assert_checkalmostequal(y1,A);
+y=fft(A,-1,[2 4 5]);
+for i1=1:Dims(1) 
+  for i3=1:Dims(3)
+    ind=list(i1,:,i3,:,:);
+    assert_checkalmostequal(y(ind(:)),fft(A(ind(:)),-1));
+  end
+end
+y1=fft(y,1,[2 4 5]);
+assert_checktrue(isreal(y1));
+assert_checkalmostequal(y1,A);
+Dims=[5 4 7 5 6 3];
+A=matrix(rand(1,prod(Dims)),Dims);
+y=fft(A,-1,[2 5]);
+for i1=1:Dims(1) 
+  for i3=1:Dims(3)
+    for i4=1:Dims(4)
+      for i6=1:Dims(6)
+        ind=list(i1,:,i3,i4,:,i6);
+        assert_checkalmostequal(y(ind(:)),fft(A(ind(:)),-1));
+      end
+    end
+  end
+end
+y1=fft(y,1,[2 5]);
+assert_checktrue(isreal(y1));
+assert_checkalmostequal(y1,A);
+y=fft(A,-1,[2 4 6]);
+for i1=1:Dims(1) 
+  for i3=1:Dims(3)
+    for i5=1:Dims(5)
+      ind=list(i1,:,i3,:,i5,:);
+      assert_checkalmostequal(y(ind(:)),fft(A(ind(:)),-1));
+    end
+  end
+end
+y1=fft(y,1,[2 4 6]);
+assert_checktrue(isreal(y1));
+assert_checkalmostequal(y1,A);
+y=fft(A,-1,[2 4 5 6]);
+for i1=1:Dims(1) 
+  for i3=1:Dims(3)
+    ind=list(i1,:,i3,:,:,:);
+    assert_checkalmostequal(y(ind(:)),fft(A(ind(:)),-1));
+  end
+end
+y1=fft(y,1,[2 4 5 6]);
+assert_checktrue(isreal(y1));
+assert_checkalmostequal(y1,A);
diff --git a/scilab/modules/fftw/tests/unit_tests/fftw_part4.tst b/scilab/modules/fftw/tests/unit_tests/fftw_part4.tst
new file mode 100644 (file)
index 0000000..fb81ce4
--- /dev/null
@@ -0,0 +1,171 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2012 - INRIA - Serge STEER
+//
+//  This file is distributed under the same license as the Scilab package.
+// =============================================================================
+
+// <-- JVM NOT MANDATORY -->
+
+//R2R case  ------------------------------------------------------------------------------------
+A=[0   1 2 2 1
+   2  -1 3 3 -1
+   3   4 5 5  4
+   2  -1 3 3 -1];
+
+Dims=[4 5];
+Sel=1;
+y=fft(A,-1,Sel);
+assert_checktrue(isreal(y));
+for j=1:Dims(2)
+  ind=list(:,j);
+  assert_checkalmostequal(y(ind(:)),fft(A(ind(:)),-1));
+end
+y=fft(y,1,Sel);
+assert_checktrue(isreal(y));
+for j=1:Dims(2)
+  ind=list(:,j);
+  assert_checkalmostequal(y(ind(:)),A(ind(:)),0,10*%eps);
+end
+
+Sel=2;
+y=fft(A,-1,Sel);
+assert_checktrue(isreal(y));
+for i=1:Dims(1)
+  ind=list(i,:);
+  assert_checkalmostequal(y(ind(:)),fft(A(ind(:)),-1));
+end
+y=fft(y,1,Sel);
+assert_checktrue(isreal(y));
+for i=1:Dims(1)
+  ind=list(i,:);
+  assert_checkalmostequal(y(ind(:)),A(ind(:)),0,10*%eps);
+end
+
+//ND case
+A=[0   1   1
+   2  -1  -1
+   3   4   4
+   2  -1  -1];
+A(:,:,2)=A+1;
+A(:,:,3)=A(:,:,2);
+
+Dims=size(A);
+Sel=1;
+y=fft(A,-1,Sel);
+assert_checktrue(isreal(y));
+for j=1:Dims(2)
+  for k=1:Dims(3)
+    ind=list(:,j,k);
+    assert_checkalmostequal(y(ind(:)),fft(A(ind(:)),-1));
+  end
+end
+
+y=fft(y,1,Sel);
+assert_checktrue(isreal(y));
+for j=1:Dims(2)
+  for k=1:Dims(3)
+    ind=list(:,j,k);
+    assert_checkalmostequal(y(ind(:)),A(ind(:)),0,10*%eps);
+  end
+end
+
+Sel=1:2;
+y=fft(A,-1,Sel);
+assert_checktrue(isreal(y));
+for k=1:Dims(3)
+  ind=list(:,:,k);
+  assert_checkalmostequal(y(ind(:)),fft(A(ind(:)),-1));
+end
+
+y=fft(y,1,Sel);
+assert_checktrue(isreal(y));
+for k=1:Dims(3)
+  ind=list(:,:,k);
+  assert_checkalmostequal(y(ind(:)),A(ind(:)),0,10*%eps);
+end
+
+Sel=2:3;
+y=fft(A,-1,Sel);
+assert_checktrue(isreal(y));
+for i=1:Dims(1)
+  ind=list(i,:,:);
+  assert_checkalmostequal(y(ind(:)),fft(A(ind(:)),-1));
+end
+y=fft(y,1,Sel);
+assert_checktrue(isreal(y));
+for i=1:Dims(1)
+  ind=list(i,:,:);
+  assert_checkalmostequal(y(ind(:)),A(ind(:)),0,10*%eps);
+end
+
+Dims=[5 4 9 5 6];
+A=matrix(rand(1,prod(Dims)),Dims);
+y=fft(A,-1,[2 4]);
+for i1=1:Dims(1) 
+  for i3=1:Dims(3)
+    for i5=1:Dims(5)
+      ind=list(i1,:,i3,:,i5);;
+      assert_checkalmostequal(y(ind(:)),fft(A(ind(:)),-1));
+    end
+  end
+end
+y1=fft(y,1,[2 4]);
+assert_checktrue(isreal(y1));
+assert_checkalmostequal(y1,A);
+
+
+y=fft(A,-1,[2 4 5]);
+for i1=1:Dims(1) 
+  for i3=1:Dims(3)
+    ind=list(i1,:,i3,:,:);
+    assert_checkalmostequal(y(ind(:)),fft(A(ind(:)),-1));
+  end
+end
+y1=fft(y,1,[2 4 5]);
+assert_checktrue(isreal(y1));
+assert_checkalmostequal(y1,A);
+
+
+Dims=[5 4 7 5 6 3];
+A=matrix(rand(1,prod(Dims)),Dims);
+y=fft(A,-1,[2 5]);
+for i1=1:Dims(1) 
+  for i3=1:Dims(3)
+    for i4=1:Dims(4)
+      for i6=1:Dims(6)
+        ind=list(i1,:,i3,i4,:,i6);
+        assert_checkalmostequal(y(ind(:)),fft(A(ind(:)),-1));
+      end
+    end
+  end
+end
+
+y1=fft(y,1,[2 5]);
+assert_checktrue(isreal(y1));
+assert_checkalmostequal(y1,A);
+
+
+y=fft(A,-1,[2 4 6]);
+for i1=1:Dims(1) 
+  for i3=1:Dims(3)
+    for i5=1:Dims(5)
+      ind=list(i1,:,i3,:,i5,:);
+      assert_checkalmostequal(y(ind(:)),fft(A(ind(:)),-1));
+    end
+  end
+end
+y1=fft(y,1,[2 4 6]);
+assert_checktrue(isreal(y1));
+assert_checkalmostequal(y1,A);
+
+y=fft(A,-1,[2 4 5 6]);
+for i1=1:Dims(1) 
+  for i3=1:Dims(3)
+    ind=list(i1,:,i3,:,:,:);
+    assert_checkalmostequal(y(ind(:)),fft(A(ind(:)),-1));
+  end
+end
+y1=fft(y,1,[2 4 5 6]);
+assert_checktrue(isreal(y1));
+assert_checkalmostequal(y1,A);
diff --git a/scilab/modules/fftw/tests/unit_tests/fftw_part5.dia.ref b/scilab/modules/fftw/tests/unit_tests/fftw_part5.dia.ref
new file mode 100644 (file)
index 0000000..bdd805f
--- /dev/null
@@ -0,0 +1,45 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2012 - INRIA - Serge STEER
+//
+//  This file is distributed under the same license as the Scilab package.
+// =============================================================================
+// <-- JVM NOT MANDATORY -->
+//=================================fft(A ,isn, dim, incr [,flag]) =============================
+A=[0   1   1
+   2  -1  -1
+   3   4   4
+   5   1  -1];
+y=matrix(fft(A(:),-1,4,1),size(A));
+assert_checkalmostequal(y,fft(A,-1,1));
+y1=matrix(fft(y(:),1,4,1),size(A));
+assert_checkalmostequal(y1,fft(y,1,1));
+y=matrix(fft(A(:),-1,3,4),size(A));
+assert_checkalmostequal(y,fft(A,-1,2));
+y1=matrix(fft(y(:),1,3,4),size(A));
+assert_checkalmostequal(y1,fft(y,1,2));
+Dims=[5 4 9 5 6];
+A=rand(1,prod(Dims));
+y=matrix(fft(A,-1,20,1),[5*4 9 5 6]);
+assert_checkalmostequal(y,fft(matrix(A,[5*4 9 5 6]),-1,1));
+y=matrix(fft(A,-1,45,20),[5*4 9*5 6]);
+assert_checkalmostequal(y,fft(matrix(A,[5*4 9*5 6]),-1,2));
+y1=matrix(fft(y(:),1,45,20),size(A));
+assert_checktrue(isreal(y1));
+assert_checkalmostequal(y1,A);
+Dims=[5 4 9 5 6];
+A=rand(1,prod(Dims));
+y=matrix(fft(A(:),-1,[9 5],[20 180]),[5 4 9 5 6]);
+y1=fft(matrix(A,[5 4 9 5 6]),-1,[3 4]);
+assert_checkalmostequal(y,y1);
+y1=fft(y(:),1,[9 5],[20 180]);
+assert_checkalmostequal(A(:),y1);
+assert_checktrue(isreal(y1));
+Dims=[5 4 9 5 6];
+A=rand(1,prod(Dims));
+y1=fft(matrix(A,[5 4 9 5 6]),-1,[2 4]);
+y=matrix(fft(A(:),-1,[4 5],[5 180]),[5 4 9 5 6]);
+assert_checkalmostequal(y,y1);
+y1=fft(y(:),1,[4 5],[5 180]);
+assert_checkalmostequal(A(:),y1);
+assert_checktrue(isreal(y1));
diff --git a/scilab/modules/fftw/tests/unit_tests/fftw_part5.tst b/scilab/modules/fftw/tests/unit_tests/fftw_part5.tst
new file mode 100644 (file)
index 0000000..3a509cd
--- /dev/null
@@ -0,0 +1,57 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2012 - INRIA - Serge STEER
+//
+//  This file is distributed under the same license as the Scilab package.
+// =============================================================================
+
+// <-- JVM NOT MANDATORY -->
+
+//=================================fft(A ,isn, dim, incr [,flag]) =============================
+A=[0   1   1
+   2  -1  -1
+   3   4   4
+   5   1  -1];
+y=matrix(fft(A(:),-1,4,1),size(A));
+assert_checkalmostequal(y,fft(A,-1,1));
+y1=matrix(fft(y(:),1,4,1),size(A));
+assert_checkalmostequal(y1,fft(y,1,1));
+
+y=matrix(fft(A(:),-1,3,4),size(A));
+assert_checkalmostequal(y,fft(A,-1,2));
+y1=matrix(fft(y(:),1,3,4),size(A));
+assert_checkalmostequal(y1,fft(y,1,2));
+
+Dims=[5 4 9 5 6];
+A=rand(1,prod(Dims));
+y=matrix(fft(A,-1,20,1),[5*4 9 5 6]);
+assert_checkalmostequal(y,fft(matrix(A,[5*4 9 5 6]),-1,1));
+
+y=matrix(fft(A,-1,45,20),[5*4 9*5 6]);
+assert_checkalmostequal(y,fft(matrix(A,[5*4 9*5 6]),-1,2));
+y1=matrix(fft(y(:),1,45,20),size(A));
+assert_checktrue(isreal(y1));
+assert_checkalmostequal(y1,A);
+
+Dims=[5 4 9 5 6];
+A=rand(1,prod(Dims));
+y=matrix(fft(A(:),-1,[9 5],[20 180]),[5 4 9 5 6]);
+y1=fft(matrix(A,[5 4 9 5 6]),-1,[3 4]);
+assert_checkalmostequal(y,y1);
+
+y1=fft(y(:),1,[9 5],[20 180]);
+assert_checkalmostequal(A(:),y1);
+assert_checktrue(isreal(y1));
+
+
+Dims=[5 4 9 5 6];
+A=rand(1,prod(Dims));
+y1=fft(matrix(A,[5 4 9 5 6]),-1,[2 4]);
+
+y=matrix(fft(A(:),-1,[4 5],[5 180]),[5 4 9 5 6]);
+
+assert_checkalmostequal(y,y1);
+
+y1=fft(y(:),1,[4 5],[5 180]);
+assert_checkalmostequal(A(:),y1);
+assert_checktrue(isreal(y1));
index 8b3df88..048cc3a 100644 (file)
@@ -1,11 +1,20 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2007-2008 - INRIA
+//
+//  This file is distributed under the same license as the Scilab package.
+// =============================================================================
+// <-- CLI SHELL MODE -->
 //=================================
 //return fftw wisdom
-txt=get_fftw_wisdom();
-if size(txt)<> [3 1] then bugmes();quit;end
-//=================================
-//set fftw wisdom
-set_fftw_wisdom(txt);
-//=================================
-//reset fftw wisdom
-fftw_forget_wisdom()
-//=================================
+try
+  txt=get_fftw_wisdom();
+  assert_checkequal(size(txt),[3 1]);
+  //=================================
+  //set fftw wisdom
+  set_fftw_wisdom(txt);
+  //=================================
+  //reset fftw wisdom
+  fftw_forget_wisdom()
+  //=================================
+end
index 49956ce..2e5a1bc 100644 (file)
@@ -9,12 +9,14 @@
 
 //=================================
 //return fftw wisdom
-txt=get_fftw_wisdom();
-if size(txt)<> [3 1] then pause,end
-//=================================
-//set fftw wisdom
-set_fftw_wisdom(txt);
-//=================================
-//reset fftw wisdom
-fftw_forget_wisdom()
-//=================================
\ No newline at end of file
+try
+  txt=get_fftw_wisdom();
+  assert_checkequal(size(txt),[3 1]);
+  //=================================
+  //set fftw wisdom
+  set_fftw_wisdom(txt);
+  //=================================
+  //reset fftw wisdom
+  fftw_forget_wisdom()
+  //=================================
+end
diff --git a/scilab/modules/overloading/macros/%hm_fft.sci b/scilab/modules/overloading/macros/%hm_fft.sci
deleted file mode 100644 (file)
index 044a79a..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
-// Copyright (C) INRIA
-// 
-// This file must be used under the terms of the CeCILL.
-// This source file is licensed as described in the file COPYING, which
-// you should have received as part of this distribution.  The terms
-// are also available at    
-// http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
-
-function x=%hm_fft(x,flag)
-rhs=argn(2)
-if rhs == 1 then
-  flag = -1
-end
-dims=matrix(x.dims,-1,1)
-v=matrix(x.entries,-1,1);
-n=size(dims,'*')
-incr=1
-for k=1:n
-  dk=double(dims(k));
-  v=fft(v ,flag,dk,incr)
-  incr=incr*dk
-end
-x.entries=v
-endfunction
index ea1d86d..0c34046 100644 (file)
@@ -1,5 +1,22 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<refentry xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svg="http://www.w3.org/2000/svg" xmlns:mml="http://www.w3.org/1998/Math/MathML" xmlns:db="http://docbook.org/ns/docbook" version="5.0-subset Scilab" xml:lang="en" xml:id="fft">
+<!--
+ * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+ * Copyright (C) 1997   - INRIA
+ * Copyright (C) 2012 - Serge Steer - INRIA
+ * 
+ * This file must be used under the terms of the CeCILL.
+ * This source file is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution.  The terms
+ * are also available at    
+ * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
+ *
+ -->
+<refentry xmlns="http://docbook.org/ns/docbook" 
+          xmlns:xlink="http://www.w3.org/1999/xlink" 
+          xmlns:svg="http://www.w3.org/2000/svg" 
+          xmlns:mml="http://www.w3.org/1998/Math/MathML" 
+          xmlns:db="http://docbook.org/ns/docbook" 
+          version="5.0-subset Scilab" xml:lang="en" xml:id="fft">
   <refnamediv>
     <refname>fft</refname>
     <refpurpose>fast Fourier transform.</refpurpose>
   </refnamediv>
   <refsynopsisdiv>
     <title>Calling Sequence</title>
-    <synopsis>x=fft(a ,-1) or x=fft(a)
-      x=fft(a,1) or x=ifft(a)
-      x=fft(a,-1,dim,incr)
-      x=fft(a,1,dim,incr)
-    </synopsis>
+    <synopsis>X=fft(A [,sign] [,option])
+X=fft(A,sign,selection  [,option])
+X=fft(A,sign,dims,incr [,option] )</synopsis>
   </refsynopsisdiv>
   <refsection>
     <title>Arguments</title>
     <variablelist>
       <varlistentry>
-        <term>x</term>
+        <term>A</term>
         <listitem>
-          <para>real or complex vector or real or complex matrix (2-dim
-            fft)
-          </para>
+          <para>a real or complex vector or real or complex array
+          (vector, matrix or N-D array.</para>
         </listitem>
       </varlistentry>
       <varlistentry>
-        <term>a</term>
+        <term>X</term>
         <listitem>
-          <para>real or complex vector or real or complex matrix (2-dim
-            fft).
-          </para>
+          a real or complex array with same shape as <literal>A</literal>.
+        </listitem>
+      </varlistentry>
+      <varlistentry>
+        <term>sign</term>
+        <listitem>
+          an integer. with possible values <literal>1</literal> or
+          <literal>-1</literal>. Select direct or inverse
+          transform. The default value is <literal>-1</literal>
+          (direct transform).
+        </listitem>
+      </varlistentry>
+      <varlistentry>
+        <term>option</term>
+        <listitem>
+          a character string. with possible values
+          <literal>"symmetric"</literal> or
+          <literal>"nonsymmetric"</literal>. Indicates if
+          <literal>A</literal> is symmetric or not. If this argument
+          is ommitted the algorithm automatically determines if
+          <literal>A</literal> is symmetric or not. See the
+          Description part for details.
         </listitem>
       </varlistentry>
       <varlistentry>
-        <term>dim</term>
+        <term>selection</term>
         <listitem>
-          <para>positive integer</para>
+          a vector containing index on <literal>A</literal> array
+          dimensions.  See the Description part for details.
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>dims</term>
+        <listitem>
+          a vector of positive numbers with integer values, or a
+          vector of positive integers.  See the Description part for details.
+          <para>
+            Each element must be a divisor
+            of the total number of elements of <literal>A</literal>. 
+          </para>
+          <para>
+            The product of the elements must be less than the total
+            number of elements of <literal>A</literal>.
+          </para>
         </listitem>
       </varlistentry>
       <varlistentry>
         <term>incr</term>
         <listitem>
-          <para>positive integer</para>
+          a vector of positive numbers with integer values, or a
+          vector of positive integers.  See the Description part for
+          details.
+          <para>
+           <literal>incr</literal> must have the same number of
+           elements than <literal>dims</literal>.
+          </para>
+         <para>
+            Each element must be a divisor of the total number of
+            elements of <literal>A</literal>.
+          </para>
+         <para>
+            The <literal>incr</literal> elements must be in strictly
+            increasing order.
+          </para>
         </listitem>
       </varlistentry>
     </variablelist>
   </refsection>
   <refsection>
-    <title>Description</title>
+    <title>Description</title> This function realizes direct or
+    inverse 1-D or N-D Discrete Fourier Transforms.
     <variablelist>
       <varlistentry>
         <term>Short syntax </term>
             <varlistentry>
               <term>direct</term>
               <listitem>
-                <para>
-                  <literal>x=fft(a,-1)</literal> or
-                  <literal>x=fft(a)</literal> gives a direct
-                  transform.
-                </para>
+                <literal>X=fft(A,-1 [,option])</literal> or
+                <literal>X=fft(A [,option])</literal> gives a direct
+                transform.
                 <variablelist>
                   <varlistentry>
                     <term>single variate</term>
                     <listitem>
-                      <para>
-                        If <literal>a</literal> is a vector a single variate direct FFT
-                        is computed that is:
-                      </para>
+                      <para>If <literal>A</literal> is a vector a
+                      single variate direct FFT is computed that
+                      is:</para>
                       <para>
                         <latex>
-                          $x(k) = \sum_{m=1}^n {a(m)*e^{-\frac{2i*\pi}{n} (m-1) (k-1)}$
+                          $x(k) = \sum_{m=1}^n {a(m)*e^{-\frac{2i*\pi}{n}
+                          (m-1) (k-1)}$
                         </latex>
                       </para>
-                      <para>
-                        (the <literal>-1</literal> argument refers to the sign of the
-                        exponent..., NOT to "inverse"),
-                      </para>
+                      <para>(the <literal>-1</literal> argument refers
+                      to the sign of the exponent..., NOT to
+                      "inverse"),</para>
                     </listitem>
                   </varlistentry>
+
                   <varlistentry>
                     <term>multivariate</term>
                     <listitem>
-                      <para>
-                        If <literal>a</literal> is a matrix or or
-                        a multidimensional array a multivariate direct
-                        FFT is performed.
-                      </para>
+                      <para>If <literal>A</literal> is a matrix or
+                      a multidimensional array a multivariate direct
+                      FFT is performed.</para>
                     </listitem>
                   </varlistentry>
                 </variablelist>
+
               </listitem>
             </varlistentry>
             <varlistentry>
               <term>inverse</term>
               <listitem>
-                <para>
-                  <literal>a=fft(x,1)</literal> or
-                  <literal>a=ifft(x)</literal>performs the inverse
-                  transform normalized by <literal>1/n</literal>.
-                </para>
+                <para><literal>X=fft(A,1)</literal> or
+                <literal>X=ifft(A)</literal>performs the inverse
+                normalized transform, such
+                that<literal>A==ifft(fft(A))</literal>. </para>
                 <variablelist>
                   <varlistentry>
                     <term>single variate</term>
                     <listitem>
-                      <para>
-                        If <literal>a</literal> is a vector a
-                        single variate inverse FFT is computed
-                      </para>
+                      If <literal>A</literal> is a vector a single
+                      variate inverse FFT is computed
                       <para>
                         <latex>
-                          $x(k) = \sum_{m=1}^n {a(m)*e^{+\frac{2i*\pi}{n} (m-1) (k-1)}$
+                          $x(k) = \sum_{m=1}^n
+                          {a(m)*e^{+\frac{2i*\pi}{n} (m-1) (k-1)}$
                         </latex>
                       </para>
                     </listitem>
                   <varlistentry>
                     <term>multivariate</term>
                     <listitem>
-                      <para>
-                        If <literal>a</literal> is a matrix or or a multidimensionnal
-                        array a multivariate inverse FFT is performed.
-                      </para>
+                      <para>If <literal>a</literal> is a matrix or or
+                      a multidimensionnal array a multivariate inverse
+                      FFT is performed.</para>
                     </listitem>
                   </varlistentry>
                 </variablelist>
           </variablelist>
         </listitem>
       </varlistentry>
+
       <varlistentry>
-        <term>Long syntax for multidimensional FFT</term>
+        <term>Long syntax for FFT along specified dimensions</term>
         <listitem>
-          <para>
-            <literal>x=fft(a,-1,dim,incr)</literal> allows to perform an
-            multidimensional fft.
-          </para>
-          <para>If a is a real or complex vector implicitly indexed by
-            <literal>j1,j2,..,jp</literal> i.e. <literal>a(j1,j2,..,jp)</literal> where
-            <literal>j1</literal> lies in <literal>1:dim(1),</literal> <literal>j2</literal> in
-            <literal>1:dim(2),...</literal> one gets a p-variate FFT by calling p times
-            <literal>fft</literal> as follows
-          </para>
-          <programlisting role=""><![CDATA[ 
-incrk=1; 
-x=a;
-for k=1:p 
-  x=fft(x ,-1,dim(k),incrk)
-  incrk=incrk*dim(k) 
+          <itemizedlist>
+            <listitem>
+              <para>
+                <literal>X=fft(A,sign,selection [,option])</literal>
+                allows to perform efficiently all direct or inverse
+                fft of the "slices" of <literal>A</literal> along
+                selected dimensions.
+              </para>
+              <para>
+                For example, if <literal>A</literal> is a 3-D array
+                <literal>X=fft(A,-1,2)</literal> is equivalent to:
+              </para>
+              <programlisting role=""><![CDATA[ 
+for i1=1:size(A,1),
+  for i3=1:size(A,3),
+    X(i1,:,i3)=fft(A(i1,:,i3),-1);
+  end
+end
+              ]]></programlisting>
+              <para>
+                and <literal>X=fft(A,-1,[1 3])</literal> is equivalent to:
+              </para>
+              <programlisting role=""><![CDATA[ 
+for i2=1:size(A,2),
+  X(:,i2,:)=fft(A(:,i2,:),-1);
 end
- ]]></programlisting>
-          <para>
-            where <literal>dimk</literal> is the dimension of the current variable
-            w.r.t which one is integrating and <literal>incrk</literal> is the increment
-            which separates two successive <literal>jk</literal> elements in
-            <literal>a</literal>.
-          </para>
-          <para>
-            In particular,if <literal>a</literal> is an mxn matrix,
-            <literal>x=fft(a,-1)</literal> is equivalent to the two instructions:
-          </para>
-          <programlisting role=""><![CDATA[ 
-a1=fft(a,-1,m,1);
-x=fft(a1,-1,n,m);
               ]]></programlisting>
+            </listitem>
+            <listitem>
+              <para>
+                <literal>X=fft(A,sign,dims,incr [,option])</literal> is
+                a previous syntax that also allows to perform all direct or
+                inverse fft of the slices of <literal>A</literal> along
+                selected dimensions.
+              </para>
+              <para>
+                For example, if <literal>A</literal> is an array with
+                <literal>n1*n2*n3</literal> elements
+                <literal>X=fft(A,-1,n1,1)</literal> is equivalent to
+                <literal>X=fft(matrix(A,[n1,n2,n3]),-1,1)</literal>.
+                and <literal>X=fft(A,-1,[n1 n3],[1 n1*n2])</literal>
+                is equivalent to
+                <literal>X=fft(matrix(A,[n1,n2,n3]),-1,[1,3])</literal>.
+              </para>
+            </listitem>
+          </itemizedlist>
         </listitem>
       </varlistentry>
+      <varlistentry>
+        <term>Using option argument</term> This argument can be used
+        to inform the fft algorithm about the symmetry of
+        <literal>A</literal> or of all its "slices".  An N-D array
+        <literal>B</literal> with dimensions <literal>n1</literal>,
+        ..., <literal>np</literal> is conjugate symmetric for the fft
+        if and only if <literal>B==conj(B([1 n1:-1:2],[1
+        n2:-1:2],...,[1 np:-1:2])) </literal>.  In such a case the
+        result <literal>X</literal> is real and an efficient specific
+        algorithm can be used.
+        <listitem>
+          <itemizedlist>
+            <listitem>
+              <term>"symmetric"</term> that value causes fft to treat
+              <literal>A</literal> or all its "slices" conjugate
+              symmetric. This option is useful to avoid automatic
+              determination of symmetry or if <literal>A</literal> or
+              all its "slices" are not exactly symmetric because of
+              round-off errors.
+            </listitem>
+            <listitem>
+              <term>"nonsymmetric"</term> that value causes fft not to
+              take care of symmetry. This option is useful to avoid
+              automatic determination of symmetry.
+            </listitem>
+            <listitem>
+              <term>unspecified</term> If the option is omitted the
+              fft algorithm automatically checks for exact symmetry.
+            </listitem>
+
+          </itemizedlist>
+        </listitem>
+      </varlistentry>
+      <varlistentry>
+        <term>Optimizing fft</term>
+         <listitem>
+           <para>
+             Remark: fftw function automatically stores his last
+             parameters in memory to re-use it in a second time. This
+             improves greatly the time computation when consecutives
+             calls (with same parameters) are performed.
+           </para>
+           <para> 
+             It is possible to go further in fft optimization using
+             <link linkend="get_fftw_wisdom">get_fftw_wisdom</link>, <link
+             linkend="set_fftw_wisdom">set_fftw_wisdom</link> functions.
+           </para>
+         </listitem>
+      </varlistentry>
     </variablelist>
   </refsection>
   <refsection>
     <title>Algorithms</title>
     <para>
-      If the <literal>fftw</literal> module has been loaded into
-      Scilab this function uses that library (http://www.fftw.org/). On the
-      other case the fft function is based on the Fortran routines fft842.f
-      (Cooley-Tukey algorithm for vectors of size n=2^m) and dfftbi.f (for
-      other sizes) .
+      This function uses the  <ulink url="http://www.fftw.org/">fftw3</ulink> library.
     </para>
   </refsection>
   <refsection>
     <title>Examples</title>
+    <para>1-D fft</para>
     <programlisting role="example"><![CDATA[ 
 //Frequency components of a signal
 //----------------------------------
-// build a noides signal sampled at 1000hz  containing to pure frequencies 
+// build a noised signal sampled at 1000hz  containing to pure frequencies 
 // at 50 and 70 Hz
 sample_rate=1000;
 t = 0:1/sample_rate:0.6;
@@ -196,14 +316,55 @@ N=size(t,'*'); //number of samples
 s=sin(2*%pi*50*t)+sin(2*%pi*70*t+%pi/4)+grand(1,N,'nor',0,1);
   
 y=fft(s);
-//the fft response is symmetric we retain only the first N/2 points
+
+//s is real so the fft response is conjugate symmetric and we retain only the first N/2 points
 f=sample_rate*(0:(N/2))/N; //associated frequency vector
 n=size(f,'*')
 clf()
 plot(f,abs(y(1:n)))
      ]]></programlisting>
+    <para>2-D fft</para>
     <programlisting role="example"><![CDATA[ 
-//Using explicit formula for  discrete Fourier transform
+----------------------------------
+A = zeros(256,256);
+A(5:24,13:17) = 1;
+X = fftshift(fft(A));
+set(gcf(),"color_map",jetcolormap(128));
+clf;grayplot(0:255,0:255,abs(X)')
+     ]]></programlisting>
+    <para>mupliple fft</para>
+   <programlisting role="example"><![CDATA[ 
+//simple case, 3 1-D fft at a time
+N=2048;
+t=linspace(0,10,2048);
+A=[2*sin(2*%pi*3*t)+ sin(2*%pi*3.5*t)
+  10*sin(2*%pi*8*t)
+   sin(2*%pi*0.5*t)+4*sin(2*%pi*0.8*t)];
+X=fft(A,-1,2);
+
+fs=1/(t(2)-t(1));
+f=fs*(0:(N/2))/N; //associated frequency vector
+clf;plot(f(1:100)',abs(X(:,1:100))')
+legend(["3 and 3.5 Hz","8 Hz","0.5 and 0.8 Hz"],"in_upper_left")
+
+// 45  3-D fft at a time
+Dims=[5 4 9 5 6];
+A=matrix(rand(1,prod(Dims)),Dims);
+
+y=fft(A,-1,[2 4 5]);
+
+//equivalent (but less efficient code)
+y1=zeros(A);
+for i1=1:Dims(1) 
+  for i3=1:Dims(3)
+    ind=list(i1,:,i3,:,:);
+    y1(ind(:))=fft(A(ind(:)),-1);
+  end
+end
+   ]]></programlisting>
+
+    <programlisting role="example"><![CDATA[ 
+//Using explicit formula for  1-D discrete Fourier transform
 //------------------------------------------------
 function xf=DFT(x,flag);
   n=size(x,'*');
@@ -234,8 +395,23 @@ timer();fft(a,-1);timer()
         <link linkend="corr">corr</link>
       </member>
       <member>
-        <link linkend="fftw">fftw</link>
+        <link linkend="fftw_flags">fftw_flags</link>
+      </member>
+      <member>
+        <link linkend="get_fftw_wisdom">get_fftw_wisdom</link>
+      </member>
+      <member>
+        <link linkend="set_fftw_wisdom">set_fftw_wisdom</link>
+      </member>
+      <member>
+        <link linkend="fftw_forget_wisdom">fftw_forget_wisdom</link>
       </member>
     </simplelist>
   </refsection>
+ <refsection>
+    <title>Bibliography</title>
+    <para>
+    Matteo Frigo and Steven G. Johnson, "FFTW Documentation" <ulink url="http://www.fftw.org/#documentation">http://www.fftw.org/#documentation</ulink>
+    </para>
+  </refsection>
 </refentry>
index 0216695..7b5b2b5 100644 (file)
@@ -1,5 +1,22 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<refentry xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svg="http://www.w3.org/2000/svg" xmlns:mml="http://www.w3.org/1998/Math/MathML" xmlns:db="http://docbook.org/ns/docbook" version="5.0-subset Scilab" xml:lang="fr" xml:id="fft">
+<!--
+ * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+ * Copyright (C) 1997   - INRIA
+ * Copyright (C) 2012 - Serge Steer - INRIA
+ * 
+ * This file must be used under the terms of the CeCILL.
+ * This source file is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution.  The terms
+ * are also available at    
+ * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
+ *
+ -->
+<refentry xmlns="http://docbook.org/ns/docbook" 
+          xmlns:xlink="http://www.w3.org/1999/xlink" 
+          xmlns:svg="http://www.w3.org/2000/svg" 
+          xmlns:mml="http://www.w3.org/1998/Math/MathML" 
+          xmlns:db="http://docbook.org/ns/docbook" 
+          version="5.0-subset Scilab" xml:lang="fr" xml:id="fft">
   <refnamediv>
     <refname>fft</refname>
     <refpurpose>Transformée de Fourier discrète rapide.</refpurpose>
     <refpurpose>Transformée de Fourier discrète rapide inverse.</refpurpose>
   </refnamediv>
   <refsynopsisdiv>
-    <title>Calling Sequence</title>
-    <synopsis>x=fft(a ,-1) ou x=fft(a)
-      x=fft(a,1) or x=ifft(a)
-      x=fft(a,-1,dim,incr)
-      x=fft(a,1,dim,incr)
-    </synopsis>
+    <title>Séquence d'appel</title>
+    <synopsis>X=fft(A [,sign] [,option])
+X=fft(A,sign,selection  [,option])
+X=fft(A,sign,dims,incr [,option] )</synopsis>
   </refsynopsisdiv>
   <refsection>
     <title>Arguments</title>
     <variablelist>
       <varlistentry>
-        <term>a</term>
+        <term>A</term>
         <listitem>
-          <para>Vecteur ou matrice réelle ou complexe.</para>
+          <para>un tableau de nombres réels ou complexes (vecteur,
+          matrice, ou tableau N-dimensionnel.</para>
         </listitem>
       </varlistentry>
       <varlistentry>
-        <term>x</term>
+        <term>X</term>
         <listitem>
-          <para>Vecteur  ou matrice réelle complexe ayant les
-            mêmes dimensions que <literal>a</literal>.
+          <para>un tableau de nombres réels ou complexes ayant les
+            mêmes dimensions que <literal>A</literal>.
           </para>
         </listitem>
       </varlistentry>
+   <varlistentry>
+        <term>sign</term>
+        <listitem>
+          un entier. qui peut prendre les valeurs <literal>1</literal>
+          ou <literal>-1</literal>. Détermine le sens de la
+          transformation. La valeur par défaut est
+          <literal>-1</literal> (transformée directe).
+        </listitem>
+      </varlistentry>
       <varlistentry>
-        <term>dim</term>
+        <term>option</term>
         <listitem>
-          <para>un entier positif</para>
+          une chaîne de caratères. qui peut prendre les valeurs
+          <literal>"symmetric"</literal> ou
+          <literal>"nonsymmetric"</literal>. Permet d'indiquer à
+          l'algorithme si <literal>A</literal> est symmétrique ou
+          non. Si cet argument est omis l'algorithme determine
+          automatiquement si <literal>A</literal> est symmétrique ou
+          non. Voir la partie "Description" pour plus de détails.
         </listitem>
       </varlistentry>
       <varlistentry>
-        <term>incr</term>
+        <term>selection</term>
         <listitem>
-          <para>un entier positif</para>
+          un vecteur contenant des index sur les dimensions de
+          <literal>A</literal>.  Voir la partie "Description" pour plus
+          de détails.
         </listitem>
       </varlistentry>
-    </variablelist>
-  </refsection>
-  <refsection>
-    <title>Description</title>
-    <variablelist>
       <varlistentry>
-        <term>Syntaxe courte</term>
+        <term>dims</term>
         <listitem>
           <para>
-            Si <literal>a</literal> est un vecteur,
-            <literal>x=fft(a,-1)</literal> ou
-            <literal>x=fft(a)</literal> calcule la
-            transformée de Fourier discrète directe
-            monovariable de <literal>a</literal>:
+            un vecteur de nombres positifs à valeurs entières, ou un
+            vecteur d'entiers positifs.  Voir la partie "Description"
+            pour plus de détails.
           </para>
           <para>
-            <latex>
-              $x(k) = \sum_{m=1}^n {a(m)*e^{-\frac{2i*\pi}{n} (m-1) (k-1)}$
-            </latex>
+            Chaque élément doit être un diviseur du nombre total
+            d'éléments de <literal>A</literal>.
           </para>
           <para>
-            Et <literal>x=fft(a,+1)</literal> ou
-            <literal>x=ifft(a)</literal> calcule la
-            transformée de Fourier  discrète inverse
-            monovariable de <literal>a</literal>:
-          </para>
-          <para>
-            <latex>
-              $x(k) = \sum_{m=1}^n {a(m)*e^{+\frac{2i*\pi}{n} (m-1) (k-1)}$
-            </latex>
-          </para>
-          <para>
-            A noter: (l'argument <literal>-1</literal> ou  <literal>+1</literal>
-            argument de la fonction <literal>fft</literal>
-            représente le signe de l'exposant de
-            l'exponentielle.
+            Le produit des éléments de <literal>dims</literal> doit
+            être strictement inférieur au nombre total d'éléments de
+            <literal>A</literal>.
           </para>
+    
         </listitem>
+      </varlistentry>
+      <varlistentry>
+        <term>incr</term>
         <listitem>
           <para>
-            Si <literal>a</literal> est une matrice, 
+            un vecteur de nombres positifs à valeurs entières, ou un
+            vecteur d'entiers positifs.  Voir la partie "Description"
+            pour plus de détails.
+          </para>
+          <para>
+            Le nombre d'éléments de <literal>incr</literal> doit être
+            égal au nombre d'éléments de <literal>dims</literal>.
           </para>