關於多項式、FFT的一些理解

前言

最近寫了一道題[HNOI2017]禮物,要用一下FFT,然而上一次寫FFT已經是8months之前了。。。

所以來複習一下

然後就溫故而知新了

於是來博客寫一下感悟

 

內容一:泰勒展開

它就是這個東西:(將f(x)在x0處進行泰勒展開)

它的本質就是從點x0開始逼近函數f(x)

這個有什麼用呢?

它可以定義複數的exp

我們只需要把x帶成z=a+b*i就可以計算複數的exp

同樣sinx,cosx都可以進行泰勒展開

 

內容二:歐拉公式

如果我們把z帶爲ib

我們就會發現一個神奇(明顯)的現象:所有的項的係數是四個一循環(廢話,i^x的最小循環節不就是4嘛)

e^{ib}=1+\frac{1}{1!}*ib-\frac{1}{2!}*b^2-\frac{1}{3!}ib^3+\frac{1}{4!}b^4+...

如果我們把實數分爲一組,虛數分爲一組:

e^{ib}=(1-\frac{1}{2!}b^2+\frac{1}{4!}b^4+...)+i*(\frac{1}{1!}b-\frac{1}{3!}b^3+\frac{1}{5!}b^5+...)

稍有常識的人就能看出經常被泰勒展開的人就能看出,經常用泰勒展開的人就知道

cosb=1-\frac{1}{2!}b^2+\frac{1}{4!}b^4+...

sinb=\frac{1}{1!}b-\frac{1}{3!}b^3+\frac{1}{5!}b^5+...

於是我們就發現了歐拉公式:

e^{ib}=cosb+i*sinb

所以複數的exp就可以表示爲:

e^{a+ib}=e^a*(cosb+i*sinb)

其實e^a就是這個新複數e^(a+ib)的模長,b就是就是這個新複數與x軸的夾角

 

 

內容三:複數

讓我們再來理解一下複數

我們在複平面上的一個複數z=a+ib,我們也可以把它表示爲另一個複數的exp (有點極座標的思想)

那我們再來理解一下複數的乘法,設z1=e^(a+ib),z2=e^(c+id)

那麼:

z_1*z_2=e^{a+ib}*e^{c+id}=e^a*e^c*e^{i*(b+d)}

把後面那一個帶入歐拉公式,得:

e^a*e^c*(cos(b+d)+i*sin(b+d))

因爲原來複數的長度分別爲e^a和e^c,夾角分別爲b和d

而新複數的長度爲e^a*e^c,夾角爲b+d

於是我們就通過歐拉公式得到了複數乘法的幾何意義:

兩個複數相乘,所得複數模長爲這兩個複數的模長乘積,夾角爲這兩個複數的夾角之和

 

感覺棒棒噠

 

 

內容四:單位根

單位根就是滿足x^n=1的所有複數解,記爲\omega _{n}^{0}\omega _{n}^{1}\omega _{n}^{2}...\omega _{n}^{n-1}

現在有了複數乘法的幾何意義,我們就明白了爲什麼n次單位根是複平面單位圓的n等分點了

單位根的性質我就不再贅述了:https://blog.csdn.net/C20180602_csq/article/details/85015587

有了以上的性質,我們就可以比較輕鬆的看懂FFT的前置知識了

 

 

內容五:多項式基礎知識(不贅述見https://blog.csdn.net/C20180602_csq/article/details/85015587

 

 

內容六:FFT的分治思想

首先我們來考慮如何求f(x)在x取\omega _{n}^{0}\omega _{n}^{1}\omega _{n}^{2}...\omega _{n}^{n-1}的值(假設n是2的冪)

首先單位根有一個很好的性質:\omega _n^i=\omega_{n*k}^{i*k}(顯然)

如果我們把k取2:

\omega_n^0,\omega_n^1,\omega_n^2...\omega_n^{n-1} \Leftrightarrow \omega_{2n}^0,\omega_{2n}^2,\omega_{2n}^4...\omega_{2n}^{2n-2}

再把每一個值乘以\omega_{2n}^1

那麼我們就可以把\omega _{n}^{0}\omega _{n}^{1}\omega _{n}^{2}...\omega _{n}^{n-1}變成\omega_{2n}^0,\omega_{2n}^2,\omega_{2n}^4...\omega_{2n}^{2n-2}(不乘\omega_{2n}^1)和\omega_{2n}^1,\omega_{2n}^3,\omega_{2n}^5...\omega_{2n}^{2n-1}(乘以\omega_{2n}^1

這個有什麼用呢?

它告訴我們:

如果想要求出f(x)在\omega_{2n}^0,\omega_{2n}^1,\omega_{2n}^2...\omega_{2n}^{2n-1}處的取值

那麼我們可以先求出f(x)在\omega _{n}^{0}\omega _{n}^{1}\omega _{n}^{2}...\omega _{n}^{n-1}上的取值,再通過加減乘除得到f(x)在\omega_{2n}^0,\omega_{2n}^1,\omega_{2n}^2...\omega_{2n}^{2n-1}的取值

 

但是因爲\omega _{n}^{0}\omega _{n}^{1}\omega _{n}^{2}...\omega _{n}^{n-1}在2n等分圓上對應的點是\omega_{2n}^0,\omega_{2n}^2,\omega_{2n}^4...\omega_{2n}^{2n-2}(不乘\omega_{2n}^1)和\omega_{2n}^1,\omega_{2n}^3,\omega_{2n}^5...\omega_{2n}^{2n-1}(乘以\omega_{2n}^1

如果直接帶入的話會導致係數不對:

\omega_{2n}^0,\omega_{2n}^2,\omega_{2n}^4...\omega_{2n}^{2n-2}帶入的是一個n次多項式,係數分別爲:a_0,a_2,a_4...a_{n-2}

\omega_{2n}^1,\omega_{2n}^3,\omega_{2n}^5...\omega_{2n}^{2n-1}帶入的也是一個n次多項式,係數分別爲:a_1,a_3,a_5...a_{n-1}

所以我們應該把\omega _{n}^{0}\omega _{n}^{1}\omega _{n}^{2}...\omega _{n}^{n-1}分別帶入兩個不同的多項式求值

說白了一句話:係數與帶入點值同時分治

 

看一個例子就明白了

多項式f(x)=a_0+a_1x+a_2x^2+a_3x^3+...+a_7x^7

需要帶入的點值\omega _{8}^{0},\omega _{8}^{1},\omega _{8}^{2},...\omega _{8}^{7}

我們把f(x)按ai下表的奇偶來分治

f_0(x)=a_0+a_2x+a_4x^2+a_6x^3

f_1(x)=a_1+a_3x+a_5x^2+a_7x^3

把帶入點值分治爲\omega _{8}^{0},\omega _{8}^{2},\omega _{8}^{4},\omega _{8}^{6}\omega _{8}^{1},\omega _{8}^{3},\omega _{8}^{5},\omega _{8}^{7},分別對f0(x)和f1(x)求值

但是因爲\omega _{8}^{0},\omega _{8}^{2},\omega _{8}^{4},\omega _{8}^{6}\Leftrightarrow \omega _{4}^{0},\omega _{4}^{1},\omega _{4}^{2},\omega _{4}^{3}  ,  (\omega _{8}^{0},\omega _{8}^{2},\omega _{8}^{4},\omega _{8}^{6})*\omega_8^1\Leftrightarrow \omega _{8}^{1},\omega _{8}^{3},\omega _{8}^{5},\omega _{8}^{7}

所以我們只需要求f0(x)和f1(x)在\omega _{8}^{0},\omega _{8}^{2},\omega _{8}^{4},\omega _{8}^{6}的值就可以了

然後我們就可以通過暴算得到下面等式:

f(\omega_8^0)=f_0(\omega_4^0)+f_1(\omega_4^0)*\omega_8^0

f(\omega_8^1)=f_0(\omega_4^1)+f_1(\omega_4^1)*\omega_8^1

f(\omega_8^2)=f_0(\omega_4^2)+f_1(\omega_4^2)*\omega_8^2

f(\omega_8^3)=f_0(\omega_4^3)+f_1(\omega_4^3)*\omega_8^3

f(\omega_8^4)=f_0(\omega_4^0)-f_1(\omega_4^0)*\omega_8^0(把左邊的\omega_8^4=-1提出來就好了)

f(\omega_8^5)=f_0(\omega_4^1)-f_1(\omega_4^1)*\omega_8^1

f(\omega_8^6)=f_0(\omega_4^2)-f_1(\omega_4^2)*\omega_8^2

f(\omega_8^7)=f_0(\omega_4^3)-f_1(\omega_4^3)*\omega_8^3

 

讀者自己驗證吧,筆者實在打不動了。。。。

 

 

其實FFT的分治思想的確挺巧妙的,主要是單位複數根的性質太好了

(以後用fft就不要把它當成黑盒算法了)

 

 

發佈了134 篇原創文章 · 獲贊 124 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章