지금까지 고속푸리에변환(이하 FFT)의 원리를 잘 모르고 썼는데 오늘 각잡고 공부해서 깨달았다.
아직 완벽히 이해한건 아닌것 같지만 잊어버리기 전에 남겨놓고자 한다.
(쓰다보니 길어져서 파트를 나누었다. part1은 필요한 지식, part2에 FFT 원리에 대해 포스팅한다.)
감사한 곳
https://codeforces.com/blog/entry/43499
https://codeforces.com/blog/entry/43499
codeforces.com
FFT는 다항식을 빠르게 계산하는 알고리즘이다.
A(x)=∑n−1i=0aixi,B(x)=∑n−1i=0bixiA(x)=∑n−1i=0aixi,B(x)=∑n−1i=0bixi일 때 C(x)=A(x)B(x)C(x)=A(x)B(x)를 빠르게 구하는 알고리즘이다.
그냥 단순 알고리즘으로 구한다면 O(n2)O(n2)이 걸릴 것인데 FFT를 이용하면 O(nlogn)O(nlogn)에 구할 수 있다.
이제 천천히 알아보자.
Point form & Coefficient form
프로그래밍 할 때 다항식을 나타내는데 우리는 주로 배열을 사용한다.
예를들어 A(x)=x2+2x+5A(x)=x2+2x+5라면 A=[1,2,5]A=[1,2,5]로 사용한다.
이렇게 나타내는 방법을 Coefficient form이라고 한다.
반면 미지수가 nn개인 연립 방정식에서 식이 nn개가 주어지면 유일한 해가 존재하는 것이 알려져있다.
3x+2y=53x+2y=5
2x+5y=72x+5y=7
은 식이 2개이고 미지수가 2개이므로 유일한 해가 존재한다.
이를 다항식에 적용해보자.
A(x)=a0+a1x+a2x2+⋯+an−1xn−1A(x)=a0+a1x+a2x2+⋯+an−1xn−1에서 a0,a1,…,an−1a0,a1,…,an−1을 찾아야 한다.
미지수가 nn개니까 (x0,y0),(x1,y1),…,(xn−1,yn−1)(x0,y0),(x1,y1),…,(xn−1,yn−1)을 알고 있다면 계수들을 찾을 수 있을 것이다.
(x0,y0),(x1,y1),…,(xn−1,yn−1)(x0,y0),(x1,y1),…,(xn−1,yn−1) 이런 식으로 나타내는 방법이 Point form이다.
Coefficient form -> Point form
이는 단순히 x=0,1,…,n−1x=0,1,…,n−1을 대입하면 {(0,A(0)),(1,A(1)),…,(n−1,A(n−1))}{(0,A(0)),(1,A(1)),…,(n−1,A(n−1))}인 Point form 을 얻을 수 있다.
nn개의 점을 구하는데 O(n)O(n)이걸리기 때문에 시간 복잡도는 O(n2)O(n2)이 된다. (이를 FFT로 단축시킬 것이다.)
Point form -> Coefficient form
A=(x0,y0),(x1,y1),…,(xn−1,yn−1)A=(x0,y0),(x1,y1),…,(xn−1,yn−1)가 주어져 있다고 하자.
(1x0x20…xn−101x1x21…xn−11……………1xn−1x2n−1…xn−1n−1)−1(y0y1…yn−1)=(a0a1…an−1)
이러한 연립방정식을 해결하여 구할 수 있다.(O(n2))
다항식을 곱하는 과정
1. A, B를 point form 으로 변환 (DFT : O(n2), FFT : O(nlogn))
2. C=AB를 수행 (O(n))
3. point form 인 C를 coefficent form으로 되돌리기 (IDFT : O(n2), IFFT : O(nlogn))
이제 FFT를 알아보려고 하는데 그 전에 여러가지 수학적 사실을 알아야 한다.
한번 가볍게 짚고 넘어가자.
복소수
i2=−1인 i를 허수라고 하고 이를 포함한 수 체계를 복소수라고 한다.
복소수는 z=a+bi(a∈R,b∈R)로 나타낸다.
오일러 공식
exi=cosx+isinx
z=rexi로 하여 모든 복소수를 나타낼 수 있다.
De Moivre 공식
|z|=1이라고 하자.(즉, r=1)
(cosx+isinx)n=cos(nx)+isin(nx)이다.
proof)
zn=(cosx+isinx)n=exin=cos(nx)+isin(nx)
단위 근
자연수 n에 대해 zn=1인 z를 단위 근이라고 한다.
단위 근은 n개 존재하고 각각 w1,w2,…,wn라고 하면 wnj=1이다.
De Moivre 공식에 의해 wnj=cos(nx)+isin(nx)
wnj=1이려면 nx=2πk여야 한다. (삼각함수의 주기성, k∈Z)
그러한 x=2πkn이다.
따라서 단위근은 wj=exi=ei2πjn가 된다.(j∈{0,1,…,n−1})
앞으로 표기할 때 wkn=e2πkni로 표기할 것이다.
Lemma 1
n≥0,k≥0,d≥0 일 때 wdkdn=wkn이다.
proof)
wdkdn=e2πdkdni=e2πkni=wkn
Lemma 2
n>0이고 짝수라면 wn2n=w2=−1
proof)
wn2n=e2πnin2=eπi=−1
Lemma 3
n>0이고 짝수라면 (wkn)2=wkn2이다. (proofed by lemma 1)
Lemma 4
n≥0,k≥0이면 wk+n2n=−wkn
proof)
wk+n2n=e2πni(k+n2)=e2πink+πi=e2πink×(−1)=−wkn
이제 다음 파트에서 FFT를 해보도록 한다.
'프로그래밍 > 알고리즘' 카테고리의 다른 글
[알고리즘] UCPC 2022 예선 후기 (0) | 2022.07.04 |
---|---|
[알고리즘] 파이썬 dict, C++ map/unordered_map (0) | 2022.06.15 |
[알고리즘] Codeforces Round #784 (Div. 4) (0) | 2022.04.22 |
[알고리즘] Codeforces Round #775 (Div. 2, based on Moscow Open Olympiad in Informatics) (0) | 2022.03.09 |
[알고리즘] Codeforces Round #774 (Div. 2) (0) | 2022.03.05 |