/// <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;
                }
            }
        }