Exemplo n.º 1
0
 private static void     SyncLookupTableLength(int length)
 {
     Debug.Assert(length < 1024 * 10);
     Debug.Assert(length >= 0);
     if (length > _lookupTabletLength)
     {
         int level = (int)Math.Ceiling(Math.Log(length, 2));
         Fourier.InitializeReverseBits(level);
         Fourier.InitializeComplexRotations(level);
         //_cFFTData	= new Complex[ Math2.CeilingBase( length, 2 ) ];
         //_cFFTDataF	= new ComplexF[ Math2.CeilingBase( length, 2 ) ];
         _lookupTabletLength = length;
     }
 }
Exemplo n.º 2
0
        public static double [] SyncCoefficients(double [] Signal)
        {
            Complex [] CompSignal;
            double     Sync;

            double [] ReturnValue;

            CompSignal = ConvertToComplex(HanningWindow(Signal));
            Fourier.FFT(CompSignal, FourierDirection.Forward);
            Sync        = CompSignal[0].Magnitude;
            ReturnValue = new double [CompSignal.Length / 2];
            for (int i = 0; i < ReturnValue.Length; i++)
            {
                ReturnValue[i] = CompSignal[i].Magnitude / Sync;
            }
            ReturnValue[0] = 0;
            return(ReturnValue);
        }
Exemplo n.º 3
0
        public static double [] Autocorrelation(double [] Signal)
        {
            Complex [] InputSignal;
            Complex [] Correlation;

            InputSignal = ConvertToComplex(HanningWindow(Signal));
            Fourier.FFT(InputSignal, FourierDirection.Forward);
            InputSignal[0].Re = 0;
            InputSignal[0].Im = 0;
            Correlation       = new Complex[InputSignal.Length];
            for (int i = 0; i < InputSignal.Length; i++)
            {
                InputSignal[i] = InputSignal[i] / InputSignal.Length;
                Correlation[i] = InputSignal[i] * InputSignal[i].Conjugate;
            }
            Fourier.FFT(Correlation, FourierDirection.Backward);
            // Normalize by the value in the zeroth element of the array
            return(MagnitudeAndSign(Correlation));
        }
Exemplo n.º 4
0
        /// <summary>
        /// Compute a 2D fast fourier transform on a data set of complex numbers
        /// </summary>
        /// <param name="data"></param>
        /// <param name="xLength"></param>
        /// <param name="yLength"></param>
        /// <param name="direction"></param>
        public static void      FFT2(Complex[] data, int xLength, int yLength, FourierDirection direction)
        {
            if (data == null)
            {
                throw new ArgumentNullException("data");
            }
            if (data.Length < xLength * yLength)
            {
                throw new ArgumentOutOfRangeException("data.Length", data.Length, "must be at least as large as 'xLength * yLength' parameter");
            }
            if (Fourier.IsPowerOf2(xLength) == false)
            {
                throw new ArgumentOutOfRangeException("xLength", xLength, "must be a power of 2");
            }
            if (Fourier.IsPowerOf2(yLength) == false)
            {
                throw new ArgumentOutOfRangeException("yLength", yLength, "must be a power of 2");
            }

            int xInc = 1;
            int yInc = xLength;

            if (xLength > 1)
            {
                Fourier.SyncLookupTableLength(xLength);
                for (int y = 0; y < yLength; y++)
                {
                    int xStart = y * yInc;
                    Fourier.LinearFFT_Quick(data, xStart, xInc, xLength, direction);
                }
            }

            if (yLength > 1)
            {
                Fourier.SyncLookupTableLength(yLength);
                for (int x = 0; x < xLength; x++)
                {
                    int yStart = x * xInc;
                    Fourier.LinearFFT_Quick(data, yStart, yInc, yLength, direction);
                }
            }
        }
Exemplo n.º 5
0
        static private void ReorderArray(double[] data)
        {
            Debug.Assert(data != null);

            int length = data.Length / 2;

            Debug.Assert(Fourier.IsPowerOf2(length) == true);
            Debug.Assert(length >= cMinLength);
            Debug.Assert(length <= cMaxLength);

            int[] reversedBits = Fourier.GetReversedBits(Fourier.Log2(length));
            for (int i = 0; i < length; i++)
            {
                int swap = reversedBits[i];
                if (swap > i)
                {
                    Fourier.Swap(ref data[i << 1], ref data[swap << 1]);
                    Fourier.Swap(ref data[i << 1 + 1], ref data[swap << 1 + 1]);
                }
            }
        }
Exemplo n.º 6
0
        public static double [] Crosscorrelation(Complex [] SignalConjugate, double [] Signal)
        {
            Complex [] InputSignal;
            Complex [] Correlation;

            InputSignal = ConvertToComplex(HanningWindow(Signal));
            Fourier.FFT(InputSignal, FourierDirection.Forward);
            InputSignal[0].Re     = 0;
            InputSignal[0].Im     = 0;
            SignalConjugate[0].Re = 0;
            SignalConjugate[0].Im = 0;
            Correlation           = new Complex[InputSignal.Length];
            for (int i = 0; i < InputSignal.Length; i++)
            {
                InputSignal[i] = InputSignal[i] / InputSignal.Length;
                Correlation[i] = InputSignal[i] * SignalConjugate[i];
            }
            Fourier.FFT(Correlation, FourierDirection.Backward);
            // Normalize by the product of the standard deviations of the signal
            return(MagnitudeAndSign(Correlation));
        }
Exemplo n.º 7
0
        static private void ReorderArray(Complex[] data)
        {
            Debug.Assert(data != null);

            int length = data.Length;

            Debug.Assert(Fourier.IsPowerOf2(length) == true);
            Debug.Assert(length >= cMinLength);
            Debug.Assert(length <= cMaxLength);

            int[] reversedBits = Fourier.GetReversedBits(Fourier.Log2(length));
            for (int i = 0; i < length; i++)
            {
                int swap = reversedBits[i];
                if (swap > i)
                {
                    Complex temp = data[i];
                    data[i]    = data[swap];
                    data[swap] = temp;
                }
            }
        }
Exemplo n.º 8
0
 static private int[]            GetReversedBits(int numberOfBits)
 {
     Debug.Assert(numberOfBits >= cMinBits);
     Debug.Assert(numberOfBits <= cMaxBits);
     if (_reversedBits[numberOfBits - 1] == null)
     {
         int   maxBits      = Fourier.Pow2(numberOfBits);
         int[] reversedBits = new int[maxBits];
         for (int i = 0; i < maxBits; i++)
         {
             int oldBits = i;
             int newBits = 0;
             for (int j = 0; j < numberOfBits; j++)
             {
                 newBits = (newBits << 1) | (oldBits & 1);
                 oldBits = (oldBits >> 1);
             }
             reversedBits[i] = newBits;
         }
         _reversedBits[numberOfBits - 1] = reversedBits;
     }
     return(_reversedBits[numberOfBits - 1]);
 }
Exemplo n.º 9
0
        /// <summary>
        /// Compute a 1D fast Fourier transform of a dataset of complex numbers.
        /// </summary>
        /// <param name="data"></param>
        /// <param name="direction"></param>
        public static void FFT(Complex[] data, FourierDirection direction)
        {
            int length = data.Length;

            if (data == null)
            {
                throw new ArgumentNullException("data");
            }
            if (data.Length < length)
            {
                throw new ArgumentOutOfRangeException("length", length, "must be at least as large as 'data.Length' parameter");
            }
            if (Fourier.IsPowerOf2(length) == false)
            {
                throw new ArgumentOutOfRangeException("length", length, "must be a power of 2");
            }

            Fourier.SyncLookupTableLength(length);

            int ln = Fourier.Log2(length);

            // reorder array
            Fourier.ReorderArray(data);

            // successive doubling
            int N         = 1;
            int signIndex = (direction == FourierDirection.Forward) ? 0 : 1;

            for (int level = 1; level <= ln; level++)
            {
                int M = N;
                N <<= 1;

                double [] uRLookup = _uRLookup[level, signIndex];
                double [] uILookup = _uILookup[level, signIndex];

                for (int j = 0; j < M; j++)
                {
                    double uR = uRLookup[j];
                    double uI = uILookup[j];

                    for (int even = j; even < length; even += N)
                    {
                        int odd = even + M;

                        double r = data[odd].Re;
                        double i = data[odd].Im;

                        double odduR = r * uR - i * uI;
                        double odduI = r * uI + i * uR;

                        r = data[even].Re;
                        i = data[even].Im;

                        data[even].Re = r + odduR;
                        data[even].Im = i + odduI;

                        data[odd].Re = r - odduR;
                        data[odd].Im = i - odduI;
                    }
                }
            }
        }