• C#快速傅立叶变换(Fast Fourier Transform)


    /// <summary>
        /// 快速傅立叶变换(Fast Fourier Transform)。
        /// </summary>
        public class TWFFT
        {
            private static void bitrp(float[] xreal, float[] ximag, int n)
            {
                // 位反转置换 Bit-reversal Permutation
                int i, j, a, b, p;
                for (i = 1, p = 0; i < n; i *= 2)
                {
                    p++;
                }
                for (i = 0; i < n; i++)
                {
                    a = i;
                    b = 0;
                    for (j = 0; j < p; j++)
                    {
                        b = b * 2 + a % 2;
                        a = a / 2;
                    }
                    if (b > i)
                    {
                        float t = xreal[i];
                        xreal[i] = xreal[b];
                        xreal[b] = t;
                        t = ximag[i];
                        ximag[i] = ximag[b];
                        ximag[b] = t;
                    }
                }
            }
            public static int FFT(float[] xreal, float[] ximag)
            {
                //n值为2的N次方
                int n = 2;
                while (n <= xreal.Length)
                {
                    n *= 2;
                }
                n /= 2;
                // 快速傅立叶变换,将复数 x 变换后仍保存在 x 中,xreal, ximag 分别是 x 的实部和虚部
                float[] wreal = new float[n / 2];
                float[] wimag = new float[n / 2];
                float treal, timag, ureal, uimag, arg;
                int m, k, j, t, index1, index2;
                bitrp(xreal, ximag, n);
                // 计算 1 的前 n / 2 个 n 次方根的共轭复数 W'j = wreal [j] + i * wimag [j] , j = 0, 1, ... , n / 2 - 1
                arg = (float)(-2 * Math.PI / n);
                treal = (float)Math.Cos(arg);
                timag = (float)Math.Sin(arg);
                wreal[0] = 1.0f;
                wimag[0] = 0.0f;
                for (j = 1; j < n / 2; j++)
                {
                    wreal[j] = wreal[j - 1] * treal - wimag[j - 1] * timag;
                    wimag[j] = wreal[j - 1] * timag + wimag[j - 1] * treal;
                }
                for (m = 2; m <= n; m *= 2)
                {
                    for (k = 0; k < n; k += m)
                    {
                        for (j = 0; j < m / 2; j++)
                        {
                            index1 = k + j;
                            index2 = index1 + m / 2;
                            t = n * j / m;    // 旋转因子 w 的实部在 wreal [] 中的下标为 t
                            treal = wreal[t] * xreal[index2] - wimag[t] * ximag[index2];
                            timag = wreal[t] * ximag[index2] + wimag[t] * xreal[index2];
                            ureal = xreal[index1];
                            uimag = ximag[index1];
                            xreal[index1] = ureal + treal;
                            ximag[index1] = uimag + timag;
                            xreal[index2] = ureal - treal;
                            ximag[index2] = uimag - timag;
                        }
                    }
                }
                return n;
            }
            public static int IFFT(float[] xreal, float[] ximag)
            {
                //n值为2的N次方
                int n = 2;
                while (n <= xreal.Length)
                {
                    n *= 2;
                }
                n /= 2;
                // 快速傅立叶逆变换
                float[] wreal = new float[n / 2];
                float[] wimag = new float[n / 2];
                float treal, timag, ureal, uimag, arg;
                int m, k, j, t, index1, index2;
                bitrp(xreal, ximag, n);
                // 计算 1 的前 n / 2 个 n 次方根 Wj = wreal [j] + i * wimag [j] , j = 0, 1, ... , n / 2 - 1
                arg = (float)(2 * Math.PI / n);
                treal = (float)(Math.Cos(arg));
                timag = (float)(Math.Sin(arg));
                wreal[0] = 1.0f;
                wimag[0] = 0.0f;
                for (j = 1; j < n / 2; j++)
                {
                    wreal[j] = wreal[j - 1] * treal - wimag[j - 1] * timag;
                    wimag[j] = wreal[j - 1] * timag + wimag[j - 1] * treal;
                }
                for (m = 2; m <= n; m *= 2)
                {
                    for (k = 0; k < n; k += m)
                    {
                        for (j = 0; j < m / 2; j++)
                        {
                            index1 = k + j;
                            index2 = index1 + m / 2;
                            t = n * j / m;    // 旋转因子 w 的实部在 wreal [] 中的下标为 t
                            treal = wreal[t] * xreal[index2] - wimag[t] * ximag[index2];
                            timag = wreal[t] * ximag[index2] + wimag[t] * xreal[index2];
                            ureal = xreal[index1];
                            uimag = ximag[index1];
                            xreal[index1] = ureal + treal;
                            ximag[index1] = uimag + timag;
                            xreal[index2] = ureal - treal;
                            ximag[index2] = uimag - timag;
                        }
                    }
                }
                for (j = 0; j < n; j++)
                {
                    xreal[j] /= n;
                    ximag[j] /= n;
                }
                return n;
            }
        }
    public partial class Form8 : Form
        {
            public Form8()
            {
                InitializeComponent();
            }
    
            private void simpleButton1_Click(object sender, EventArgs e)
            {
                float[] a = {
                    0.5751f,0.4514f,0.0439f,0.0272f,0.3127f,0.0129f,0.3840f,0.6831f,
                    0.0928f,0.0353f,0.6124f,0.6085f,0.0158f,0.0164f,0.1901f,0.5869f};
                float[] b = {
                    0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,
                    0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f};
                int n = TWFFT.FFT(a, b);
                //Console.WriteLine("FFT:");
                //Console.WriteLine("FFT的返回值N = {0}", n);
                //Console.WriteLine();
                //Console.WriteLine("i	a	b");
                //Console.WriteLine();
                string str = string.Empty;
                for (int i = 0; i < n; i++)
                {
                    Console.WriteLine("{0}	{1}	{2}", i, a[i], b[i]);
    
                    str += i + ": " + a[i].ToString() + " \ " + b[i].ToString() + "
    ";
                }
                memoEdit1.Text = str;
            }
        }
  • 相关阅读:
    javaScript快速入门
    解决编程式路由往同一地址跳转时会报错的情况
    babel 依赖
    路由拆分可以达到一定程度的性能优化
    正则的扩展
    设计模式
    mysql数据库
    php基本语法
    事件循环
    面向对象编程
  • 原文地址:https://www.cnblogs.com/mapstar/p/13892678.html
Copyright © 2020-2023  润新知