Esempio n. 1
0
 /// <summary>
 ///   Create a complex number based on an existing complex number
 /// </summary>
 /// <param name = "c"></param>
 public ComplexF(ComplexF c)
 {
     Re = c.Re;
     Im = c.Im;
 }
        /// <summary>
        ///   Multiply each element in the array by a specific value
        /// </summary>
        /// <param name = "array"></param>
        /// <param name = "scale"></param>
        public static void Scale(ComplexF[] array, ComplexF scale)
        {
            Debug.Assert(array != null);

            int length = array.Length;
            for (int i = 0; i < length; i++)
            {
                array[i] *= scale;
            }
        }
Esempio n. 3
0
 public static void FFT(ComplexF[] data, FourierDirection direction)
 {
     if (data == null)
     {
         throw new ArgumentNullException("data");
     }
     FFT(data, data.Length, direction);
 }
Esempio n. 4
0
        public static void FFT_Quick(ComplexF[] data, int length, FourierDirection direction)
        {
            /*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 = Log2(length);

            // reorder array
            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;

                float[] uRLookup = _uRLookupF[level, signIndex];
                float[] uILookup = _uILookupF[level, signIndex];

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

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

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

                        float odduR = r*uR - i*uI;
                        float 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;
                    }
                }
            }
        }
Esempio n. 5
0
        // ReSharper restore RedundantAssignment
        //======================================================================================
        //======================================================================================
        // ReSharper disable RedundantAssignment
        private static void LockBufferCF(int length, ref ComplexF[] buffer)
        {
            Debug.Assert(length >= 0);
            Debug.Assert(_bufferCFLocked == false);

            _bufferCFLocked = true;
            if (length != _bufferCF.Length)
            {
                _bufferCF = new ComplexF[length];
            }
            buffer = _bufferCF;
        }
Esempio n. 6
0
 private static void Swap(ref ComplexF a, ref ComplexF b)
 {
     ComplexF temp = a;
     a = b;
     b = temp;
 }
 // ReSharper restore RedundantAssignment
 /// <summary>
 ///   Get the range of element lengths
 /// </summary>
 /// <param name = "array"></param>
 /// <param name = "minimum"></param>
 /// <param name = "maximum"></param>
 // ReSharper disable RedundantAssignment
 public static void GetLengthRange(ComplexF[] array, ref float minimum, ref float maximum)
 {
     minimum = +float.MaxValue;
     maximum = -float.MaxValue;
     for (int i = 0; i < array.Length; i++)
     {
         float temp = array[i].GetModulus();
         minimum = Math.Min(temp, minimum);
         maximum = Math.Max(temp, maximum);
     }
 }
 // ReSharper restore RedundantAssignment
 //---------------------------------------------------------------------------------------------
 // ReSharper disable RedundantAssignment
 private static void LockWorkspaceF(int length, ref ComplexF[] workspace)
 {
     Debug.Assert(_workspaceFLocked == false);
     _workspaceFLocked = true;
     if (length >= _workspaceF.Length)
     {
         _workspaceF = new ComplexF[length];
     }
     workspace = _workspaceF;
 }
 /// <summary>
 ///   Divide each element in target array with corresponding element in rhs array
 /// </summary>
 /// <param name = "target"></param>
 /// <param name = "rhs"></param>
 public static void Divide(ComplexF[] target, ComplexF[] rhs)
 {
     Divide(target, rhs, target);
 }
Esempio n. 10
0
        /// <summary>
        ///   Divide each element in lhs array with corresponding element in rhs array and
        ///   put product in result array
        /// </summary>
        /// <param name = "lhs"></param>
        /// <param name = "rhs"></param>
        /// <param name = "result"></param>
        public static void Divide(ComplexF[] lhs, ComplexF[] rhs, ComplexF[] result)
        {
            Debug.Assert(lhs != null);
            Debug.Assert(rhs != null);
            Debug.Assert(result != null);
            Debug.Assert(lhs.Length == rhs.Length);
            Debug.Assert(lhs.Length == result.Length);

            ComplexF zero = ComplexF.Zero;
            int length = lhs.Length;
            for (int i = 0; i < length; i++)
            {
                if (rhs[i] != zero)
                {
                    result[i] = lhs[i] / rhs[i];
                }
                else
                {
                    result[i] = zero;
                }
            }
        }
Esempio n. 11
0
 /// <summary>
 ///   Copy an array
 /// </summary>
 /// <param name = "dest"></param>
 /// <param name = "source"></param>
 public static void Copy(ComplexF[] dest, ComplexF[] source)
 {
     Debug.Assert(dest != null);
     Debug.Assert(source != null);
     Debug.Assert(dest.Length == source.Length);
     for (int i = 0; i < dest.Length; i++)
     {
         dest[i] = source[i];
     }
 }
 /// <summary>
 ///   Create a complex number based on an existing complex number
 /// </summary>
 /// <param name = "c"></param>
 public ComplexF(ComplexF c)
 {
     Re = c.Re;
     Im = c.Im;
 }
        //-----------------------------------------------------------------------------------
        //-----------------------------------------------------------------------------------

        /// <summary>
        ///   Determine whether two complex numbers are almost (i.e. within the tolerance) equivalent.
        /// </summary>
        /// <param name = "a"></param>
        /// <param name = "b"></param>
        /// <param name = "tolerance"></param>
        /// <returns></returns>
        public static bool IsEqual(ComplexF a, ComplexF b, float tolerance)
        {
            return((Math.Abs(a.Re - b.Re) < tolerance) && (Math.Abs(a.Im - b.Im) < tolerance));
        }
Esempio n. 14
0
        /// <summary>
        ///   Multiply each element in the array by a specific value
        /// </summary>
        /// <param name = "array"></param>
        /// <param name = "scale"></param>
        /// <param name = "start"></param>
        /// <param name = "length"></param>
        public static void Scale(ComplexF[] array, ComplexF scale, int start, int length)
        {
            Debug.Assert(array != null);
            Debug.Assert(start >= 0);
            Debug.Assert(length >= 0);
            Debug.Assert((start + length) < array.Length);

            for (int i = 0; i < length; i++)
            {
                array[i + start] *= scale;
            }
        }
Esempio n. 15
0
 /// <summary>
 ///   Invert each element in the array
 /// </summary>
 /// <param name = "array"></param>
 public static void Invert(ComplexF[] array)
 {
     for (int i = 0; i < array.Length; i++)
     {
         array[i] = ((ComplexF) 1)/array[i];
     }
 }
Esempio n. 16
0
        /// <summary>
        ///   Shift (offset) the elements in the array
        /// </summary>
        /// <param name = "array"></param>
        /// <param name = "offset"></param>
        public static void Shift(ComplexF[] array, int offset)
        {
            Debug.Assert(array != null);
            Debug.Assert(offset >= 0);
            Debug.Assert(offset < array.Length);

            if (offset == 0)
            {
                return;
            }

            int length = array.Length;
            ComplexF[] workspace = null;
            LockWorkspaceF(length, ref workspace);

            for (int i = 0; i < length; i++)
            {
                workspace[(i + offset)%length] = array[i];
            }
            for (int i = 0; i < length; i++)
            {
                array[i] = workspace[i];
            }

            UnlockWorkspaceF(ref workspace);
        }
Esempio n. 17
0
 /// <summary>
 ///   Determine whether the elements in the two arrays are the same
 /// </summary>
 /// <param name = "array1"></param>
 /// <param name = "array2"></param>
 /// <param name = "tolerance"></param>
 /// <returns></returns>
 public static bool IsEqual(ComplexF[] array1, ComplexF[] array2, float tolerance)
 {
     if (array1.Length != array2.Length)
     {
         return false;
     }
     for (int i = 0; i < array1.Length; i++)
     {
         if (ComplexF.IsEqual(array1[i], array2[i], tolerance) == false)
         {
             return false;
         }
     }
     return true;
 }
Esempio n. 18
0
 private static void UnlockWorkspaceF(ref ComplexF[] workspace)
 {
     Debug.Assert(_workspaceF == workspace);
     Debug.Assert(_workspaceFLocked);
     _workspaceFLocked = false;
     workspace = null;
 }
Esempio n. 19
0
 /// <summary>
 ///   Multiply each element in target array with corresponding element in rhs array
 /// </summary>
 /// <param name = "target"></param>
 /// <param name = "rhs"></param>
 public static void Multiply(ComplexF[] target, ComplexF[] rhs)
 {
     Multiply(target, rhs, target);
 }
Esempio n. 20
0
        private static void ReorderArray(ComplexF[] data)
        {
            Debug.Assert(data != null);

            int length = data.Length;

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

            int[] reversedBits = GetReversedBits(Log2(length));
            for (int i = 0; i < length; i++)
            {
                int swap = reversedBits[i];
                if (swap > i)
                {
                    ComplexF temp = data[i];
                    data[i] = data[swap];
                    data[swap] = temp;
                }
            }
        }
Esempio n. 21
0
        /// <summary>
        ///   Multiply each element in lhs array with corresponding element in rhs array and
        ///   put product in result array
        /// </summary>
        /// <param name = "lhs"></param>
        /// <param name = "rhs"></param>
        /// <param name = "result"></param>
        public static void Multiply(ComplexF[] lhs, ComplexF[] rhs, ComplexF[] result)
        {
            Debug.Assert(lhs != null);
            Debug.Assert(rhs != null);
            Debug.Assert(result != null);
            Debug.Assert(lhs.Length == rhs.Length);
            Debug.Assert(lhs.Length == result.Length);

            int length = lhs.Length;
            for (int i = 0; i < length; i++)
            {
                result[i] = lhs[i] * rhs[i];
            }
        }
Esempio n. 22
0
        private static void UnlockBufferCF(ref ComplexF[] buffer)
        {
            Debug.Assert(_bufferCF == buffer);
            Debug.Assert(_bufferCFLocked);

            _bufferCFLocked = false;
            buffer = null;
        }
Esempio n. 23
0
 /// <summary>
 ///   Scale and offset the elements in the array so that the
 ///   overall range is [0, 1]
 /// </summary>
 /// <param name = "array"></param>
 public static void Normalize(ComplexF[] array)
 {
     float min = 0, max = 0;
     GetLengthRange(array, ref min, ref max);
     Scale(array, (1/(max - min)));
     Offset(array, (-min/(max - min)));
 }
Esempio n. 24
0
        public static void FFT3(ComplexF[] data, int xLength, int yLength, int zLength, FourierDirection direction)
        {
            if (data == null)
            {
                throw new ArgumentNullException("data");
            }
            if (data.Length < xLength*yLength*zLength)
            {
                throw new ArgumentOutOfRangeException("data", data.Length, "must be at least as large as 'xLength * yLength * zLength' parameter");
            }
            if (IsPowerOf2(xLength) == false)
            {
                throw new ArgumentOutOfRangeException("xLength", xLength, "must be a power of 2");
            }
            if (IsPowerOf2(yLength) == false)
            {
                throw new ArgumentOutOfRangeException("yLength", yLength, "must be a power of 2");
            }
            if (IsPowerOf2(zLength) == false)
            {
                throw new ArgumentOutOfRangeException("zLength", zLength, "must be a power of 2");
            }

            const int xInc = 1;
            int yInc = xLength;
            int zInc = xLength*yLength;

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

            if (yLength > 1)
            {
                SyncLookupTableLength(yLength);
                for (int z = 0; z < zLength; z++)
                {
                    for (int x = 0; x < xLength; x++)
                    {
                        int yStart = z*zInc + x*xInc;
                        LinearFFT_Quick(data, yStart, yInc, yLength, direction);
                    }
                }
            }

            if (zLength > 1)
            {
                SyncLookupTableLength(zLength);
                for (int y = 0; y < yLength; y++)
                {
                    for (int x = 0; x < xLength; x++)
                    {
                        int zStart = y*yInc + x*xInc;
                        LinearFFT_Quick(data, zStart, zInc, zLength, direction);
                    }
                }
            }
        }
Esempio n. 25
0
 /// <summary>
 ///   Add a specific value to each element in the array
 /// </summary>
 /// <param name = "array"></param>
 /// <param name = "offset"></param>
 public static void Offset(ComplexF[] array, ComplexF offset)
 {
     int length = array.Length;
     for (int i = 0; i < length; i++)
     {
         array[i] += offset;
     }
 }
Esempio n. 26
0
        private static void LinearFFT(ComplexF[] data, int start, int inc, int length, FourierDirection direction)
        {
            Debug.Assert(data != null);
            Debug.Assert(start >= 0);
            Debug.Assert(inc >= 1);
            Debug.Assert(length >= 1);
            Debug.Assert((start + inc*(length - 1)) < data.Length);

            // copy to buffer
            ComplexF[] buffer = null;
            LockBufferCF(length, ref buffer);
            int j = start;
            for (int i = 0; i < length; i++)
            {
                buffer[i] = data[j];
                j += inc;
            }

            FFT(buffer, length, direction);

            // copy from buffer
            j = start;
            for (int i = 0; i < length; i++)
            {
                data[j] = buffer[i];
                j += inc;
            }
            UnlockBufferCF(ref buffer);
        }
Esempio n. 27
0
 //-----------------------------------------------------------------------------------
 //-----------------------------------------------------------------------------------
 /// <summary>
 ///   Determine whether two complex numbers are almost (i.e. within the tolerance) equivalent.
 /// </summary>
 /// <param name = "a"></param>
 /// <param name = "b"></param>
 /// <param name = "tolerance"></param>
 /// <returns></returns>
 public static bool IsEqual(ComplexF a, ComplexF b, float tolerance)
 {
     return (Math.Abs(a.Re - b.Re) < tolerance) && (Math.Abs(a.Im - b.Im) < tolerance);
 }