Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Fast Fourier Transform #68

Closed
wants to merge 0 commits into from

Conversation

TimmyChiang
Copy link
Contributor

@TimmyChiang TimmyChiang commented May 14, 2023

  • Read Contribute to NTHU-CPP.
  • Rebase to the latest main branch.
  • List all the references.
  • Successfully build the website by mdBook with no error after the change.
  • Exclude any irrelevant files.
  • Link to the issue which is related to your change.
  • Review the content by myself.
  • Pass tests/CI.

@harry900831
Copy link
Contributor

harry900831 commented May 18, 2023

I've turned this PR to draft PR.
Please set it to ready for review after you finish it.
Thanks.

@harry900831 harry900831 marked this pull request as draft May 18, 2023 18:27
@harry900831 harry900831 linked an issue May 18, 2023 that may be closed by this pull request
@TimmyChiang TimmyChiang marked this pull request as ready for review June 23, 2023 08:26
@TimmyChiang
Copy link
Contributor Author

嗨~ 很抱歉沒有辦法把 issue 中的題目全部完成。目前只有將模板題和兩題基本的 string matching 題目放上去。

@harry900831
Copy link
Contributor

Please fix your commit history...

@TimmyChiang TimmyChiang force-pushed the TimmyChiang branch 2 times, most recently from c3eb136 to 7363867 Compare June 24, 2023 04:19
@TimmyChiang
Copy link
Contributor Author

Commit history fixed.

Copy link
Contributor

@harry900831 harry900831 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall, there's still lack of explanation. Please try to figure out how to make your article clear and easy for a CS major student at maybe 3rd grade.

src/SUMMARY.md Outdated
@@ -25,6 +25,7 @@
- [杜教篩](math/du_sieve.md)
- [Arithmetic Function Revisit](math/revisit_arithmetic_function.md)
- [Miscellaneous]()
- [Fast Fourier Transform](miscellaneous/fast_fourier_transform.md)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be under math


本單元介紹快速傅立葉轉換法 (Fast Fourier Transform, 簡稱 FFT ). FFT 是一個計算離散傅立葉轉換 (Discrete Fourier Transform, 簡稱 DFT ) 的演算法。此算法最經典的應用在計算多項式相乘,亦即給定兩個 \\( n \\) 次多項式,求兩多項式的乘積。直覺上有個 \\( O(n^2) \\) 的算法是將係數逐一相乘再相加,而 FFT 利用分治法提供一個 \\( O(n \log n) \\)的算法。為了討論方便,我們有以下假設:

- 所有 \\( n \\) 皆為 \\( 2 \\) 的冪次方
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

這邊簡單提一下若不為 2的密次怎麼辦

或者說 你實作也是考慮 n 是 2 的密次嗎?

是的話實作部分也需要提


### \\( n \\) 次單位根 (The principal nth root of unity)

給定方程式 \\( z^n = 1 \\), 其中 \\( n \\) 為正整數,\\( z \\) 為複數。我們稱 \\( z \\) 為該方程式的 \\( n \\) 次單位根。設 \\( \omega_n = e^{\frac{2 \pi i}{n}} \\), 該方程式的 \\( n \\) 次單位跟有 \\( n \\) 個,分別為 \\( \omega_n, \omega_n^2, \cdots, \omega_n^{n-1} \\) 和 \\( 1 \\).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

單位跟 -> 單位根

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

設 \( \omega_n = e^{\frac{2 \pi i}{n}} \), 該方程式的 \( n \) 次單位跟有 \( n \) 個,分別為 \( \omega_n, \omega_n^2, \cdots, \omega_n^{n-1} \) 和 \( 1 \).

這句看不懂需要多點解釋


$$ \left( \begin{matrix} 1 & \alpha_1 & \cdots & \alpha_1^{n-1} \\\ 1 & \alpha_2 & \cdots & \alpha_2^{n-1} \\\ \vdots & \vdots & \ddots & \vdots \\\ 1 & \alpha_m & \cdots & \alpha_m^{n-1} \end{matrix} \right)_{m \times n} $$

在 FFT algorithm 中,我們聚焦在以下這個特例:第 \\( i \\) 行和第 \\( i \\) 列的公比均為 \\( \omega_n^{i-1} \\) 且 \\( a_{11} \\) 為 \\( 1 \\) 的范德蒙方陣 \\( V \\) 上。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is a_{11}

\right)_{n \times n}
$$

由於反矩陣若存在必為一。經過驗證可以得到 \\( V \\) 的反矩陣如下
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

為ㄧ->唯一

Comment on lines 67 to 81
#### 計算方法

給定 \\( A(x) = a_0 + a_1 x + a_2 x^2 + \cdots + a_{n-1} x^{n-1} \\), 若將多項式次方為偶數的項總和 \\( a_0 + a_2 x^2 + \cdots + a_{n-2} x^{n-2} \\) 記作 \\( A^{[0]}(x) \\), 次方為奇數的項總和 \\( a_1 x + a_3 x^3 + \cdots + a_{n-1} x^{n-1} \\) 記作 \\( A^{[1]}(x) \\), 則

$$
A(x) = A^{[0]}(x^2) + xA^{[1]}(x^2)
$$

觀察發現 \\( A^{[0]}(x) \\) 和 \\( A^{[1]}(x) \\) 的次方均為 \\( A(x) \\) 的一半。換言之,計算 \\( A(x) \\) 只需計算兩個次方為 \\( A(x) \\) 一半的值再相加即可。\\( y \\) 中的元素共有 \\( n \\) 個,表示我們要將 \\( n \\) 個 \\( x \\) 代入 \\( A(x) \\) 計算結果。若以 \\( T(n) \\) 代表計算 \\( n \\) 個 \\( x \\) 代入 \\( A(x) \\) 所需的計算時間,我們可以列出關係式

$$
T(n) = 2T\left(\frac{n}{2}\right) + O(n)
$$

得總時間為 \\( O(n \log n) \\). 值得一提的是,這裡所有的變數 \\( x \\) 可以是任意複數。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

看不懂這是要計算什麼...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

以及那遞迴是怎麼來的

Comment on lines 96 to 114
- Step 2: 利用前述計算 DFT 的方法,在 \\( O(n \log n) \\) 時間算出
$$
y_a = \left( A(1), A(\omega_{2n}), A(\omega_{2n}^2), \cdots, A(\omega_{2n}^{2n-1}) \right)
$$
$$
y_b = \left( B(1), B(\omega_{2n}), B(\omega_{2n}^2), \cdots, B(\omega_{2n}^{2n-1}) \right)
$$

- Step 3: 用 \\( O(n) \\) 時間算出 \\( C(x) \\) 的點值表示式

$$
y_c = \left( A(1)B(1), A(\omega_{2n})B(\omega_{2n}), A(\omega_{2n}^2)B(\omega_{2n}^2), \cdots, A(\omega_{2n}^{2n-1})B(\omega_{2n}^{2n-1}) \right)
$$

- Step 4: 將 \\( C(x) \\) 的點值表示式轉換成係數表示式

$$
c = (c_0, c_1, c_2, \cdots, c_{2n})
$$
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

到這邊我才看懂

我覺得前面就可以依邊 hint 讀者 FFT 大概是要怎麼做的

例如前面介紹點值表示是時就可以hint 讀者既然換成點值可以 O(n) 那 FFT 其中一部就是要換成點值之類的

Comment on lines 127 to 156
$$
\left(
\begin{matrix}
y_0 \\\\
y_1 \\\\
y_2 \\\\
\vdots \\\\
y_{2n}
\end{matrix}
\right)
=
\left(
\begin{matrix}
1 & 1 & 1 & \cdots & 1 \\\\
1 & \omega_{2n} & \omega_{2n}^2 & \cdots & \omega^{2n-1} \\\\
1 & \omega_{2n}^2 & \omega_{2n}^4 & \cdots & \omega^{2(2n-1)} \\\\
\vdots & \vdots & \vdots & \ddots & \vdots \\\\
1 & \omega_{2n}^{2n-1} & \omega_{2n}^{2(2n-1)} & \cdots & \omega_n^{(2n-1)(2n-1)}
\end{matrix}
\right)
\left(
\begin{matrix}
a_0 \\\\
a_1 \\\\
a_2 \\\\
\vdots \\\\
a_{2n}
\end{matrix}
\right)
$$
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

你前面那麼早就介紹這個矩陣
讀者到這邊反而會ㄇㄤ 掉?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

當初想說把背景知識(工具)一口氣講完後再講怎麼去使用。目前想到兩個解決方法,第一個是直接把范德蒙矩陣從背景知識拿掉,到這邊再拉出來介紹。另一個是背景知識的部分不動,這邊再做回顧就好。你覺得哪個可能比較適合,或是有沒有其他解決方法~

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

我沒什麼想法
你可以多參考其他你覺得寫得不錯的人的做法


## 模板與習題

### 模板
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe you have to describe the use of double and long long, would it cost floating point error and so on.

Comment on lines 274 to 306
### 模板題

> [SPOJ - Polynomial Multiplication](https://www.spoj.com/problems/POLYMUL/)
>
> 給定兩個 \\( n \\) 次多項式的係數,輸出兩個多項式相乘的多項式係數。

<details><summary>Solution</summary>

讀取輸入資料後,直接呼叫 ```multipy()``` 即可。

</details>

### 基礎題

> [SPOJ - Maximum Self-Matching](https://www.spoj.com/problems/MAXMATCH/)
>
> 給定一個只包含 ```a```, ```b``` 和 ```c``` 的字串 ```str```. 定義 \\( m_{str}(i) \\) 為字串 ```str``` 向右移動 \\( i \\) 個字元後與自己匹配的字元個數。求最大的 \\( m_{str}(i) \\) 值以及所有讓 \\( m_{str}(i) \\) 最大的 \\( i \\).

<details><summary>Solution</summary>

設輸入字串 ```str``` 長度為 \\( n \\). 令字串 ```t``` 為將字串中為 ```a``` 的位置設為 ```1```, 其他設為 ```0``` 的字串。構造一個與 ```t``` 對應的多項式 \\( p_t \\)。例如 ```baaca``` 經構造會得到 ```01101```, 對應的多項式為 \\( x^3 + x^2 + 1 \\). ```acaa``` 經構造會得到 ```1011```, 對應的多項式為 \\( x^3 + x + 1 \\). 令 ```r``` 為 ```t``` 的反轉字串,我們同樣地對 ```r``` 構造一個對應的多項式 \\( p_r \\).

將 \\( p_t \\) 和 \\( p_r \\) 相乘得到的多項式,其係數即為右移次方數減 \\( n \\) 個字元的成功匹配數。故只需針對 ```a```, ```b``` 和 ```c``` 各做一次 FFT 後再將係數相加取最大值,即為所求。

</details>

> [SPOJ - Ada and Nucleobase](https://www.spoj.com/problems/ADAMATCH/)
>
> 給定兩個 DNA 序列 ```s``` 和 ```r```, 其中 ```r``` 的長度比 ```s``` 短。輸出 ```r``` 與 ```s``` 中所有連續子字串的 hamming distance 最小值。

<details><summary>Solution</summary>

本題與前一題 [SPOJ - Maximum Self-Matching](https://www.spoj.com/problems/MAXMATCH/) 類似。差異處只有兩點,第一是 ```a```, ```b```, 和 ```c``` 變成 ```A```, ```T```, ```C```, 和 ```G```. 第二是 hamming distance 即自己字串的長度扣掉匹配數。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If possible, please use CSES, CF, Atcoder as the source of the problem.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There should be two section:

  1. Example problem, you have to explain the problem in detail.
  2. Excercise problem, the problem list for reader to exercise.

For example: https://nthu-cp.github.io/NTHU-CPP/sqrt/sqrt_decomposition.html

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also for some problem, it would be great to see the AC code that use the template code you provide.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, I believe there's a lot of cool application for FFT, please include more interesting problem.

@harry900831
Copy link
Contributor

friendly ping

@TimmyChiang
Copy link
Contributor Author

friendly ping

Got it. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add Fast Fourier Transform (FFT)
2 participants