static public Complex Factor(this Complex me, Complex c)
 {
     return(new Complex(
                (me.X * c.X) - (me.Y * c.Y),
                (me.Y * c.X) + (me.X * c.Y)
                ));
 }
        /// <summary>
        // This computes an in-place complex-to-complex FFT
        // x and y are the real and imaginary arrays of 2^m points.
        /// </summary>
        /// <param name="forward"></param>
        /// <param name="m">is this the mean, or the maximum?</param>
        /// <param name="data"></param>
        public static void FFT(bool forward, int m, Complex[] data)
        {
            int
                i, i2, // counter
            j = 0,     // counter
            k,         // counter
            l, l1, l2, // counter
            n = CountPoints(m);
            Complex c = Complex.Empty; // cycle? coefficient?
            Complex t = Complex.Empty; // time?
            Complex u = Complex.Empty; //

            // Do the bit reversal
            // ============================================================================
            i2 = n >> 1;
            for (i = 0; i < n - 1; i++)
            {
                if (i < j)
                {
                    t = data[i];
                    data[i] = data[j];
                    data[j] = t;
                }
                k = i2;
                while (k <= j) { j -= k; k >>= 1; }
                j += k;
            }

            // Compute the FFT
            // ============================================================================
            c = Complex.RootComplex;
            l2 = 1;
            for (l = 0; l < m; l++)
            {
                l1 = l2;
                l2 <<= 1;
                u = new Complex(1.0f, 0.0f);

                for (j = 0; j < l1; j++)
                {
                    for (i = j; i < n; i += l2)
                    {
                        int i1 = i + l1;
                        t = data[i1].Factor(u);
                        data[i1] = data[i] - t;
                        data[i] += t;
                    }
                    u = u.Factor(c);
                }
                c = c.Root(forward);
            }

            // Scaling for forward transform
            // ============================================================================
            if (forward) for (i = 0; i < n; i++) data[i] /= n;
        }
 public static void BitReversal(Complex[] data, int n)
 {
     Complex t = Complex.Empty;
     int i2 = n >> 1;
     int j = 0;
     for (int i = 0; i < n - 1; i++)
     {
         if (i < j) {
             t = data[i];
             data[i] = data[j];
             data[j] = t;
         }
         int k = i2;
         while (k <= j) { j -= k; k >>= 1; }
         j += k;
     }
 }
        static public void BitReversal(Complex[] data, int n)
        {
            Complex t  = Complex.Empty;
            int     i2 = n >> 1;
            int     j  = 0;

            for (int i = 0; i < n - 1; i++)
            {
                if (i < j)
                {
                    t       = data[i];
                    data[i] = data[j];
                    data[j] = t;
                }
                int k = i2;
                while (k <= j)
                {
                    j -= k; k >>= 1;
                }
                j += k;
            }
        }
        /// <summary>
        // This computes an in-place complex-to-complex FFT
        // x and y are the real and imaginary arrays of 2^m points.
        /// </summary>
        /// <param name="forward"></param>
        /// <param name="m">is this the mean, or the maximum?</param>
        /// <param name="data"></param>
        public static void FFT(bool forward, int m, Complex[] data)
        {
            int
                i, i2,                 // counter
                j = 0,                 // counter
                k,                     // counter
                l, l1, l2,             // counter
                n     = CountPoints(m);
            Complex c = Complex.Empty; // cycle? coefficient?
            Complex t = Complex.Empty; // time?
            Complex u = Complex.Empty; //

            // Do the bit reversal
            // ============================================================================
            i2 = n >> 1;
            for (i = 0; i < n - 1; i++)
            {
                if (i < j)
                {
                    t       = data[i];
                    data[i] = data[j];
                    data[j] = t;
                }
                k = i2;
                while (k <= j)
                {
                    j -= k; k >>= 1;
                }
                j += k;
            }

            // Compute the FFT
            // ============================================================================
            c  = Complex.RootComplex;
            l2 = 1;
            for (l = 0; l < m; l++)
            {
                l1   = l2;
                l2 <<= 1;
                u    = new Complex(1.0f, 0.0f);

                for (j = 0; j < l1; j++)
                {
                    for (i = j; i < n; i += l2)
                    {
                        int i1 = i + l1;
                        t        = data[i1].Factor(u);
                        data[i1] = data[i] - t;
                        data[i] += t;
                    }
                    u = u.Factor(c);
                }
                c = c.Root(forward);
            }

            // Scaling for forward transform
            // ============================================================================
            if (forward)
            {
                for (i = 0; i < n; i++)
                {
                    data[i] /= n;
                }
            }
        }
        static public Complex Root(this Complex me, bool forward)
        {
            float inv = (float)Math.Sqrt((1.0f + me.X) / 2.0f);

            return(new Complex(forward ? inv : -inv, Math.Sqrt((1.0f - me.X) / 2.0f)));
        }
 public static Complex Factor(this Complex me, Complex c)
 {
     return new Complex(
         (me.X * c.X) - (me.Y * c.Y),
         (me.Y * c.X) + (me.X * c.Y)
     );
 }