快速傅里葉變換(FFT)詳解


快速傅里葉變換(FFT)詳解

  (這是我第一次寫博,不喜勿噴...)

  關於FFT已經聽聞已久了,這次終於有機會在Function2的介紹下來了解一下FFT了。

  快速傅里葉變換(Fast Fourier Transformation)簡稱FFT。在各大OI競賽中也常有用到,也是一個十分優秀的可以裝逼的好算法

  在這篇blog中,有大量數學推導,因為我懶得寫公式(好復雜,逃),所以用圖片代替了╮(╯▽╰)╭,如有不適,望見諒(逃~~)。

 基礎知識:

多項式的度數:

多項式的線性空間

系數表達

 

向量的卷積

 

分治乘法(如果你急着和MM約會或機房要關門了,那跳過也無妨

點值表達

 

插值

 

 

點值計算分析

 單位復數根

 

單位復數根的性質

  1. 消去引理

    

  2.折半引理

    

  3.求和引理

    

 

鋪墊都鋪完了,讓我們一起進入DFT,FFT,IDFT的美妙世界吧!

離散傅里葉變換(Discrete Fourier Transform 簡稱DFT)

 快速傅里葉變換(FFT)(終於等到你~~)

 

 

逆離散傅里葉變換(Inverse Discrete Fourier Transform 簡稱IDFT)

 FFT的迭代實現

我們類似於需要像這樣實現FFT:

知識點終於講完了,接下來我們就要開始寫板子了

板子題:uoj #34

代碼附上~~

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<algorithm>
 6 #include<cstdlib>
 7 using namespace std;
 8 const int mod=1e9+7;
 9 const double pi=acos(-1);
10 struct cn
11 {
12     double x,y;
13     cn (double x=0,double y=0):x(x),y(y) {}
14 }a[300005],b[300005],c[300005];
15 cn operator + (const cn &a,const cn &b) {return cn(a.x+b.x,a.y+b.y);}
16 cn operator - (const cn &a,const cn &b) {return cn(a.x-b.x,a.y-b.y);}
17 cn operator * (const cn &a,const cn &b) {return cn(a.x*b.x-a.y*b.y,a.x*b.y+a.y*b.x);}
18 void fft(cn a[],int n,int l,int f)                                   
19 {                                                                                
20     int rev[n+5];
21     rev[0]=0;
22     for (int i=1; i<n; i++){
23         rev[i]=(rev[i>>1]>>1)|((i&1)<<l-1);
24         if (i<rev[i]) swap(a[i],a[rev[i]]);
25     }
26     for (int i=1; i<n; i<<=1){
27         cn wi(cos(pi/i),f*sin(pi/i));
28         for (int j=0; j<n; j+=i*2){
29             cn w(1,0);
30             for (int k=0; k<i; k++){
31                 cn x=a[j+k],y=w*a[j+k+i];
32                 a[j+k]=x+y;
33                 a[j+k+i]=x-y;
34                 w=w*wi;
35             }
36         }
37     }
38     if (f==-1)
39         for (int i=0; i<n; i++){
40             a[i].x/=n; a[i].y/=n;
41         }
42 }
43 int main()
44 {
45     int n,m;
46     scanf("%d%d",&n,&m); n++; m++;
47     for (int i=0; i<n; i++) scanf("%lf",&a[i].x);
48     for (int i=0; i<m; i++) scanf("%lf",&b[i].x);
49     int l=0,N=1;
50     while (N<n+m-1) N<<=1,l++;
51     fft(a,N,l,1);
52     fft(b,N,l,1);
53     for (int i=0; i<N; i++) c[i]=a[i]*b[i];
54     fft(c,N,l,-1);
55     for (int i=0; i<n+m-1; i++) printf("%d ",(int)(c[i].x+0.5));
56     return 0;
57 }

鳴謝:LLX大佬

(Ps:一個巨搞笑的東西:傳送門


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM