Fourier transformation.
The class implements one dimensional and two dimensional Discrete and Fast Fourier Transformation.
 protected BSDataObject ProcessUsingFourierDirection(BSDataObject iObject, FourierTransform.Direction iDir)
 {
     Complex[] complexDataArray = (from tmp in iObject.DataArray select new Complex(tmp, 0)).ToArray();
     FourierTransform.DFT(complexDataArray, iDir);
     double[] resultingArray = (from tmp in complexDataArray select Math.Sqrt(tmp.Re * tmp.Re + tmp.Im * tmp.Im)).ToArray();
     return new BSDataObject(resultingArray, iObject.ObjName + "_Fouirer");
 }
Example #2
0
        /// <summary>
        /// Two dimensional Fast Fourier Transform.
        /// </summary>
        ///
        /// <param name="data">Data to transform.</param>
        /// <param name="direction">Transformation direction.</param>
        ///
        /// <remarks><para><note>The method accepts <paramref name="data"/> array of 2<sup>n</sup> size
        /// only in each dimension, where <b>n</b> may vary in the [1, 14] range. For example, 16x16 array
        /// is valid, but 15x15 is not.</note></para></remarks>
        ///
        /// <exception cref="ArgumentException">Incorrect data length.</exception>
        ///
        public static void FFT2(Complex[,] data, Direction direction)
        {
            int k = data.GetLength(0);
            int n = data.GetLength(1);

            // check data size
            if (!Tools.IsPowerOf2(k) || !Tools.IsPowerOf2(n))
            {
                throw new ArgumentException("The matrix rows and columns must be a power of 2.");
            }

            if (k < minLength || k > maxLength || n < minLength || n > maxLength)
            {
                throw new ArgumentException("Incorrect data length.");
            }

            // process rows
            var row = new Complex[n];

            for (int i = 0; i < k; i++)
            {
                // copy row
                for (int j = 0; j < row.Length; j++)
                {
                    row[j] = data[i, j];
                }

                // transform it
                FourierTransform.FFT(row, direction);

                // copy back
                for (int j = 0; j < row.Length; j++)
                {
                    data[i, j] = row[j];
                }
            }

            // process columns
            var col = new Complex[k];

            for (int j = 0; j < n; j++)
            {
                // copy column
                for (int i = 0; i < k; i++)
                {
                    col[i] = data[i, j];
                }

                // transform it
                FourierTransform.FFT(col, direction);

                // copy back
                for (int i = 0; i < k; i++)
                {
                    data[i, j] = col[i];
                }
            }
        }
        /// <summary>
        /// Two dimensional Fast Fourier Transform.
        /// </summary>
        ///
        /// <param name="data">Data to transform.</param>
        /// <param name="direction">Transformation direction.</param>
        ///
        /// <remarks><para><note>The method accepts <paramref name="data"/> array of 2<sup>n</sup> size
        /// only in each dimension, where <b>n</b> may vary in the [1, 14] range. For example, 16x16 array
        /// is valid, but 15x15 is not.</note></para></remarks>
        ///
        /// <exception cref="ArgumentException">Incorrect data length.</exception>
        ///
        public static void FFT2(Complex[,] data, Direction direction)
        {
            int k = data.GetLength(0);
            int n = data.GetLength(1);

            // check data size
            if (
                (!Tools.IsPowerOf2(k)) ||
                (!Tools.IsPowerOf2(n)) ||
                (k < minLength) || (k > maxLength) ||
                (n < minLength) || (n > maxLength)
                )
            {
                throw new ArgumentException("Incorrect data length.");
            }



            // process columns
            Complex[] col = new Complex[k];

            for (int j = 0; j < n; j++)
            {
                // copy column
                for (int i = 0; i < k; i++)
                {
                    col[i] = data[i, j];
                }
                // transform it
                FourierTransform.FFT(col, direction);
                // copy back
                for (int i = 0; i < k; i++)
                {
                    data[i, j] = col[i];
                }
            }


            // process rows
            Complex[] row = new Complex[n];

            for (int i = 0; i < k; i++)
            {
                // copy row
                for (int j = 0; j < n; j++)
                {
                    row[j] = data[i, j];
                }
                // transform it
                FourierTransform.FFT(row, direction);
                // copy back
                for (int j = 0; j < n; j++)
                {
                    data[i, j] = row[j];
                }
            }
        }
        /// <summary>
        /// One dimensional Fast Fourier Transform.
        /// </summary>
        ///
        /// <param name="data">Data to transform.</param>
        /// <param name="direction">Transformation direction.</param>
        ///
        /// <remarks><para><note>The method accepts <paramref name="data"/> array of 2<sup>n</sup> size
        /// only, where <b>n</b> may vary in the [1, 14] range.</note></para></remarks>
        ///
        /// <exception cref="ArgumentException">Incorrect data length.</exception>
        ///
        public static void FFT(Complex[] data, Direction direction)
        {
            int n = data.Length;
            int m = Tools.Log2(n);

            // reorder data first
            ReorderData(data);

            // compute FFT
            int tn = 1, tm;

            for (int k = 1; k <= m; k++)
            {
                Complex[] rotation = FourierTransform.GetComplexRotation(k, direction);

                tm   = tn;
                tn <<= 1;

                for (int i = 0; i < tm; i++)
                {
                    Complex t = rotation[i];

                    for (int even = i; even < n; even += tn)
                    {
                        int     odd = even + tm;
                        Complex ce  = data[even];
                        Complex co  = data[odd];

                        double tr = co.Re * t.Re - co.Im * t.Im;
                        double ti = co.Re * t.Im + co.Im * t.Re;

                        data[even].Re += tr;
                        data[even].Im += ti;

                        data[odd].Re = ce.Re - tr;
                        data[odd].Im = ce.Im - ti;
                    }
                }
            }

            if (direction == Direction.Forward)
            {
                for (int i = 0; i < n; i++)
                {
                    data[i].Re /= (double)n;
                    data[i].Im /= (double)n;
                }
            }
        }
Example #5
0
        /// <summary>
        /// One dimensional Fast Fourier Transform.
        /// </summary>
        ///
        /// <param name="data">Data to transform.</param>
        /// <param name="direction">Transformation direction.</param>
        ///
        /// <remarks><para><note>The method accepts <paramref name="data"/> array of 2<sup>n</sup> size
        /// only, where <b>n</b> may vary in the [1, 14] range.</note></para></remarks>
        ///
        /// <exception cref="ArgumentException">Incorrect data length.</exception>
        ///
        public static void FFT(Complex[] data, Direction direction)
        {
            int n = data.Length;
            int m = Tools.Log2(n);

            // reorder data first
            ReorderData(data);

            // compute FFT
            int tn = 1, tm;

            for (int k = 1; k <= m; k++)
            {
                Complex[] rotation = FourierTransform.GetComplexRotation(k, direction);

                tm   = tn;
                tn <<= 1;

                for (int i = 0; i < tm; i++)
                {
                    Complex t = rotation[i];

                    for (int even = i; even < n; even += tn)
                    {
                        int     odd = even + tm;
                        Complex ce  = data[even];
                        Complex co  = data[odd];

                        double tr = co.Real * t.Real - co.Imaginary * t.Imaginary;
                        double ti = co.Real * t.Imaginary + co.Imaginary * t.Real;

                        data[even] += new Complex(tr, ti);
                        data[odd]   = new Complex(ce.Real - tr, ce.Imaginary - ti);
                    }
                }
            }

            if (direction == Direction.Forward)
            {
                for (int i = 0; i < data.Length; i++)
                {
                    data[i] /= (double)n;
                }
            }
        }
Example #6
0
        /// <summary>
        /// One dimensional Fast Fourier Transform.
        /// </summary>
        ///
        /// <param name="data">Data to transform.</param>
        /// <param name="direction">Transformation direction.</param>
        ///
        /// <remarks><para><note>The method accepts <paramref name="data"/> array of 2<sup>n</sup> size
        /// only, where <b>n</b> may vary in the [1, 14] range.</note></para></remarks>
        ///
        /// <exception cref="ArgumentException">Incorrect data length.</exception>
        ///
        public static void FFT(Complex[] data, Direction direction)
        {
            int n = data.Length;
            int m = Tools.Log2(n);

            // reorder data first
            ReorderData(data);

            // compute FFT
            int tn = 1, tm;

            for (int k = 1; k <= m; k++)
            {
                Complex[] rotation = FourierTransform.GetComplexRotation(k, direction);

                tm   = tn;
                tn <<= 1;

                for (int i = 0; i < tm; i++)
                {
                    var t = rotation[i];

                    for (int even = i; even < n; even += tn)
                    {
                        int odd = even + tm;
                        var ce  = data[even];
                        var cot = data[odd] * t;

                        data[even] += cot;
                        data[odd]   = ce - cot;
                    }
                }
            }

            if (direction == Direction.Forward)
            {
                for (int i = 0; i < n; i++)
                {
                    data[i] /= (double)n;
                }
            }
        }
Example #7
0
        /// <summary>
        ///   1-D Discrete Fourier Transform.
        /// </summary>
        /// 
        /// <param name="data">The data to transform..</param>
        /// <param name="direction">The transformation direction.</param>
        /// 
        public static void DFT(Complex[] data, FourierTransform.Direction direction)
        {
            int n = data.Length;
            var c = new Complex[n];

            // for each destination element
            for (int i = 0; i < c.Length; i++)
            {
                double sumRe = 0;
                double sumIm = 0;
                double phim = 2 * Math.PI * i / (double)n;

                // sum source elements
                for (int j = 0; j < n; j++)
                {
                    double re = data[j].Re();
                    double im = data[j].Im();
                    double cosw = Math.Cos(phim * j);
                    double sinw = Math.Sin(phim * j);

                    if (direction == FourierTransform.Direction.Backward)
                        sinw = -sinw;

                    sumRe += (re * cosw + im * sinw);
                    sumIm += (im * cosw - re * sinw);
                }

                c[i] = new Complex(sumRe, sumIm);
            }

            if (direction == FourierTransform.Direction.Backward)
            {
                for (int i = 0; i < c.Length; i++)
                    data[i] = c[i] / n;
            }
            else
            {
                for (int i = 0; i < c.Length; i++)
                    data[i] = c[i];
            }
        }
Example #8
0
        /// <summary>
        ///   2-D Fast Fourier Transform.
        /// </summary>
        /// 
        /// <param name="data">The data to transform..</param>
        /// <param name="direction">The Transformation direction.</param>
        /// 
        public static void FFT2(Complex[][] data, FourierTransform.Direction direction)
        {
            int n = data.Length;
            int m = data[0].Length;

            // process rows
            for (int i = 0; i < data.Length; i++)
            {
                // transform it
                FFT(data[i], direction);
            }

            // process columns
            var col = new Complex[n];
            for (int j = 0; j < m; j++)
            {
                // copy column
                for (int i = 0; i < col.Length; i++)
                    col[i] = data[i][j];

                // transform it
                FFT(col, direction);

                // copy back
                for (int i = 0; i < col.Length; i++)
                    data[i][j] = col[i];
            }
        }
Example #9
0
        /// <summary>
        ///   1-D Fast Fourier Transform.
        /// </summary>
        /// 
        /// <param name="real">The real part of the complex numbers to transform.</param>
        /// <param name="imag">The imaginary part of the complex numbers to transform.</param>
        /// <param name="direction">The transformation direction.</param>
        /// 
        public static void FFT(double[] real, double[] imag, FourierTransform.Direction direction)
        {
            if (direction == FourierTransform.Direction.Forward)
            {
                FFT(real, imag);
            }
            else
            {
                FFT(imag, real);
            }

            if (direction == FourierTransform.Direction.Backward)
            {
                for (int i = 0; i < real.Length; i++)
                {
                    real[i] /= real.Length;
                    imag[i] /= real.Length;
                }
            }
        }
Example #10
0
        /// <summary>
        ///   1-D Fast Fourier Transform.
        /// </summary>
        /// 
        /// <param name="data">The data to transform..</param>
        /// <param name="direction">The transformation direction.</param>
        /// 
        public static void FFT(Complex[] data, FourierTransform.Direction direction)
        {
            int n = data.Length;

            if (n == 0)
                return;

            if (direction == FourierTransform.Direction.Backward)
            {
                for (int i = 0; i < data.Length; i++)
                    data[i] = new Complex(data[i].Im(), data[i].Re());
            }

            if ((n & (n - 1)) == 0)
            {
                // Is power of 2
                TransformRadix2(data);
            }
            else
            {
                // More complicated algorithm for arbitrary sizes
                TransformBluestein(data);
            }

            if (direction == FourierTransform.Direction.Backward)
            {
                for (int i = 0; i < data.Length; i++)
                {
                    double im = data[i].Im();
                    double re = data[i].Re();
                    data[i] = new Complex(im / n, re / n);
                }
            }
        }
Example #11
0
        /// <summary>
        ///   2-D Discrete Fourier Transform.
        /// </summary>
        /// 
        /// <param name="data">The data to transform.</param>
        /// <param name="direction">The transformation direction.</param>
        /// 
        public static void DFT2(Complex[][] data, FourierTransform.Direction direction)
        {
            int n = data.Length;
            int m = data[0].Length;

            // process rows
            var row = new Complex[m];
            for (int i = 0; i < n; i++)
            {
                // copy row
                for (int j = 0; j < row.Length; j++)
                    row[j] = data[i][j];

                // transform it
                DFT(row, direction);

                // copy back
                for (int j = 0; j < row.Length; j++)
                    data[i][j] = row[j];
            }

            // process columns
            var col = new Complex[n];
            for (int j = 0; j < n; j++)
            {
                // copy column
                for (int i = 0; i < col.Length; i++)
                    col[i] = data[i][j];

                // transform it
                DFT(col, direction);

                // copy back
                for (int i = 0; i < col.Length; i++)
                    data[i][j] = col[i];
            }
        }