zoukankan      html  css  js  c++  java
  • 傅里叶变换

      1 #include <stdio.h>
      2 #include <math.h>
      3 
      4 typedef char int8_t;
      5 typedef unsigned char uint8_t;
      6 typedef unsigned short uint16_t;
      7 typedef short int16_t;
      8 
      9 #define N    64    //傅里叶变换的点数
     10 #define M     6    //蝶形运算的级数,N = 2^M
     11 #define N2    32    //N/2
     12 #define N4    16    //N/4
     13 
     14 #define PI  3.14159    //圆周率
     15 #define PI2 6.28318
     16 
     17 //定义复数结构体
     18 typedef struct                
     19 {
     20     float real;    //实部
     21     float imag;    //虚部
     22 }complex;
     23 
     24 //傅里叶变换序列,一维
     25 float pr[64] = 
     26 {
     27     1234,1285,1151,1086,896,671,541,392,368,565,762,905,987,1103,1352,1601,1593,1565,1576,1565,1379,1152,1208,1150,1086,1124,1092,945,791,561,393,291,352,596,950,1307,1490,1707,1760,1494,1351,1510,1427,1191,1156,1090,953,917,944,847,655,580,457,495,679,877,1015,1084,1256,1519,1469,1411,1423,1509
     28 };
     29 
     30 //正弦函数表
     31 float sin_table[N4 + 1];
     32 
     33 
     34 float find_sin(float x)
     35 {
     36     int i = ((int)(N * x)) >> 1;
     37 
     38     if (i > N4)        //不会超过N/2 
     39         i = N2 - i;
     40 
     41     return sin_table[i];
     42 }
     43 
     44 float find_cos(float x)
     45 {
     46     int i = ((int)(N * x)) >> 1;
     47 
     48     if (i < N4)
     49         return sin_table[N4 - i];
     50     else                //i>Npart4 && i<N/2
     51         return -sin_table[i - N4];
     52 }
     53 
     54 //dir:1 - 傅里叶变换, -1 - 傅里叶逆变换
     55 void fft(complex data[], uint8_t num, uint8_t n, int8_t dir)
     56 {
     57     uint8_t i = 0, j = 0, k = 0, m = 0, t = num - 1;
     58     float angle;
     59     complex w, temp;
     60 
     61     //变址,把自然顺序变为倒位序
     62     for (i = 0; i < t; i++)
     63     {
     64         if (i < j)
     65         {
     66             temp = data[j];
     67             data[j] = data[i];
     68             data[i] = temp;
     69         }
     70         k = N2;
     71         while (k <= j)
     72         {
     73             j -= k;
     74             k >>= 1;
     75         }
     76 
     77         j += k;    
     78     }
     79 
     80     for (i = 1; i <= n; i++)
     81     {
     82         uint8_t km, step = 1 << i;
     83         m = step >> 1;
     84 
     85         for (j = 0; j < m; j++)
     86         {
     87             angle = ((double)j) / m;
     88 
     89             if (dir == 1)
     90                 w.imag = -find_sin(angle);
     91             else if (dir == -1)
     92                 w.imag = find_sin(angle);
     93             w.real = find_cos(angle);
     94 
     95             for (k = j; k < num; k += step)
     96             {
     97                 km = k + m;
     98                 //用下面两行直接计算复数乘法,省去函数调用开销
     99                 temp.real = data[km].real * w.real - data[km].imag * w.imag;
    100                 temp.imag = w.imag * data[km].real + w.real * data[km].imag;
    101 
    102                 data[km].real = data[k].real - temp.real;
    103                 data[km].imag = data[k].imag - temp.imag;
    104 
    105                 data[k].real = data[k].real + temp.real;
    106                 data[k].imag = data[k].imag + temp.imag;            
    107             }
    108         }    
    109     }
    110 
    111     if (dir == -1)
    112     {
    113         for (i = 0; i < num; i++)
    114         {
    115             data[i].real /= num;
    116         }
    117     }
    118 }
    119 
    120 
    121 int main()
    122 {
    123     int i;
    124     complex data[N];
    125 
    126     //初始化输入数据
    127     for (i = 0; i < N; i++)
    128     {
    129         data[i].real = pr[i];
    130         data[i].imag = 0;
    131     }
    132 
    133     //创建正弦表
    134     for (i = 0; i <= N4; i++)
    135     {
    136         sin_table[i] = (float)sin(PI * i /N2);
    137     }
    138 
    139     //正变换
    140     fft(data, N, M, 1);
    141 
    142     for (i = 0; i < N; i++)
    143     {
    144         printf("%.f    %.f
    ", data[i].real, data[i].imag);
    145     }
    146     printf("
    ");
    147 
    148     //波形处理
    149     for (i = 5; i < N; i++)    //10:3.9Hz,11:4.3Hz
    150     {
    151         data[i].imag= 0;
    152         data[i].real = 0;
    153     }
    154 
    155     //逆变换
    156     fft(data, N, M, -1);
    157 
    158     for (i = 0; i < N; i++)
    159     {
    160         printf("%.f    %.f
    ", data[i].real, data[i].imag);
    161     }
    162     printf("
    ");
    163 
    164     return 0;
    165 }
  • 相关阅读:
    SDUT 2109 找女朋友
    Instant Complexity(模拟,递归)
    Lucky and Good Months by Gregorian Calendar(模拟)
    Wall(Graham算法)
    Beauty Contest(graham求凸包算法)
    A Round Peg in a Ground Hole(判断是否是凸包,点是否在凸包内,圆与多边形的关系)
    Pie(二分)
    Expanding Rods(二分)
    Fishnet(计算几何)
    Building a Space Station(kruskal,说好的数论呢)
  • 原文地址:https://www.cnblogs.com/cmembd/p/3507402.html
Copyright © 2011-2022 走看看