ãã®æçš¿ã¯é«éããŒãªãšå€æã«ã€ããŠã§ãã ïŒè€çŽ æ°ã§ã®ïŒçŽæ¥ããã³éå€æãèæ ®ãããŸãã 次ã®ããŒãã§ã¯ãolympiadããã°ã©ãã³ã°ã®åé¡ïŒç¹ã«ãæååã®ãé¡äŒŒæ§ãã«é¢ãã1ã€ã®åé¡ïŒã§ã®ã¢ããªã±ãŒã·ã§ã³ã®æ€èšãšãæŽæ°ã§ã®å€æã®å®è£ ã«ã€ããŠèª¬æããäºå®ã§ãã
FFTã¯ãæéO ïŒnâ log n ïŒã®nãã€ã³ãã§æ¬¡æ°n = 2 kã®å€é åŒã®å€ãèšç®ããã¢ã«ãŽãªãºã ã§ãïŒããã€ãŒããã¡ãœããã¯æéO ïŒ n 2 ïŒã§åãã¿ã¹ã¯ãå®è¡ããŸãïŒã åæã«ãéå€æãå®è¡ã§ããŸãã æ°å€ã®é åã®å ç®ãæžç®ãä¹ç®ã¯å€é åŒãããã¯ããã«ç°¡åãªã®ã§ïŒç¹ã«ä¹ç®ïŒãFFTã¯å€é åŒãšé·ãæ°å€ã䜿çšããèšç®ãé«éåããããã«ãã䜿çšãããŸãã
å®çŸ©ãšçšé
ãŸããå€é åŒãšã¯äœããå®çŸ©ããŸãããã
P ïŒ x ïŒ= a 0 + x a 1 + x 2 a 2 + x 3 a 3 + ... + x n - 1 a n - 1
è€çŽ æ°
è€çŽ æ°ã«ç²ŸéããŠããå Žåã¯ããã®ç¹ãã¹ãããã§ããŸããããã§ãªãå Žåã¯ãç°¡åãªå®çŸ©ã以äžã«ç€ºããŸãã
x = a + i b ãããã§i 2 = -1
ããã§ãaã¯å®éšïŒ Real ïŒéšãšåŒã°ãã bã¯èéšïŒ Imaginary ïŒéšã§ãã ã芧ã®ãšããããããã®æ°ããè² ã®ïŒãããŠå®éã«ïŒæ°ããæ ¹ãæœåºããããšãã§ããŸã-ããã¯å€é åŒãæ±ãå Žåã«éåžžã«äŸ¿å©ã§ã-代æ°ã®äž»å®çããã ïŒ
å¹³é¢äžã®ç¹ã®åœ¢ã§ããããè¡šçŸããããšãéåžžã«äŸ¿å©ã§ãã
è€çŽ æ°ã®ãã1ã€ã®æ³šç®ãã¹ãç¹æ§ã¯ã x =ïŒcosα+ isinÎ±ïŒ rã§è¡šçŸã§ããããšã§ããããã§ãαã¯ãæ°å€ãã®æ¥µè§ïŒ åŒæ°ãšåŒã°ããŸã ïŒã rã¯ãŒããããããŸã§ã®è·é¢ïŒ ã¢ãžã¥ã©ã¹ ïŒã§ãã ãããŠã2ã€ã®æ°åãæãããšãïŒ
a =ïŒcosα+ iâ sinÎ±ïŒ r a
b =ïŒcosβ+ iâ sinÎ²ïŒ r b
a b =ïŒcosα+ iâ sinαïŒïŒcosβ+ iâ sinÎ²ïŒ r a r b
a b =ïŒcosαâ cosβ-sinαâ sinβ+ i ïŒsinαâ cosβ+cosβâ sinαïŒïŒ r a r b
a b =ïŒcosïŒÎ±+βïŒ+ iâ sinïŒÎ±+βïŒïŒ r a r b
ã¢ãžã¥ãŒã«ãä¹ç®ãããåŒæ°ãè¿œå ãããŸãã
1ã®è€éãªæ ¹
次ã«ã 1ããã®n次ã®è€éãªæ ¹ãã©ã®ããã«èŠããããç解ããŸãããã x n = 1ãšãããšããã®ã¢ãžã¥ãŒã«ã¯æããã«1ã«çãããnâ argx = 2Ïkãããã§kã¯æŽæ°ã§ãã ããã¯ã nãããèªäœã«æ°ãä¹ç®ããåŸïŒã€ãŸãã nä¹ïŒããã®åŒæ°ããè€æ°ã2ÏïŒ360床ïŒã«ãªãããšãæå³ããŸãã
åŒæ°ãšã¢ãžã¥ãŒã«ãããã£ãŠããå Žåãæ°å€ã®åŒãæãåºããŠãã ããã
α= 2Ïâ x / n ãããã§0 x
Ïi =cosα+ iâ sinα
ã€ãŸã æç»ãããšãçééã§åäžã®ç¹ã®ã¿ãåŸãããŸãã
ç©æ¥µçã«äœ¿çšãã3ã€ã®ç¹ã«æ³šæããŠãã ããïŒãããããªããšãäœãæ©èœããŸããïŒã
Ïaâ Ïb =Ï ïŒ a + b ïŒmod n
Ï0 +Ï1 +Ï2 + ... +Ïn - 1 = 0
Ï0 n / 2 =Ï2 n / 2 =Ï4 n / 2 = ... = 1 ïŒå¶æ°nã®å Žå ïŒ
ãããã®ç¹æ§ã®ããããããã®ãã€ã³ãã§å€é åŒã®å€ãæ€èšããŸãã ãã¡ãããçµæã¯å¿ ãããçŸå®ã®ãã®ã§ã¯ãªããããããã°ã©ã ã¯è€çŽ æ°ãæ±ãå¿ èŠããããŸãã
æ ¹ã®åèšããŒãã§ããçç±
蚌æã¯éåžžã«ç°¡åã§ãïŒletÏ= Ï0 +Ï1 + .... äž¡åŽã«Ï1ïŒïŒ= 1ïŒãæããŸãã ãªããªã Ïiâ Ï1 =Ïi + 1 ã次ã«Ïâ Ï1 =Ï1 +Ï2 + ... +Ïn - 1 + Ï0 ã é ã®åé 眮ãããåèšã¯å€åããªããããããããÏ=Ïâ Ï1ãÏâ ïŒÏ1-1ïŒ= 0ã§ãã ãªããªã Ï1ïŒ= 1ã次ã«Ï= 0 ã
ä»çµã¿
å€é åŒã®æ¬¡æ°ã¯n = 2 kã§ãããšä»®å®ããŸãã ããã§ãªãå Žåã¯ãå è¡ããä¿æ°ããŒãã§æãè¿ã2ã®ã¹ãä¹ã§è£ããŸãã
FFTã®åºæ¬çãªèãæ¹ã¯éåžžã«ç°¡åã§ãã
ãããŠãã ããïŒ
A ïŒ x ïŒ= a 0 + x a 2 + x 2 a 4 + ... + x n / 2-1 a n - 2 ïŒå¶æ°ã®ä¿æ°P ïŒ
B ïŒ x ïŒ= a 1 + x a 3 + x 2 a 5 + ... + x n / 2-1 a n - 1 ïŒå¥æ°ä¿æ°P ïŒ
次ã«ã P ïŒ x ïŒ= A ïŒ x 2 ïŒ+ xâ BïŒ x 2 ïŒã
ããã§ããåå²åŸæãã®åçãé©çšããŸããnç¹ïŒ Ï0 ãÏ1ã ... ïŒã§Pã®å€ãèšç®ããã«ã¯ã n / 2ç¹ïŒ Ï0 ãÏ2ã ... ïŒã§AãšBã®å€ãååž°çã«èšç®ããŸãã P ïŒÏiïŒã®å€ã¯å埩ããã®ãéåžžã«ç°¡åã§ãïŒ
P ïŒÏiïŒ= A ïŒÏ2 i ïŒ+Ïiâ BïŒÏ2 i ïŒ
次æ°n / 2ã®å€é åŒã®å€ãèæ ®ããç¹ãΟi =Ï2 iã§è¡šããšãåŒã¯å€æãããŸãã
P ïŒÏiïŒ= A ïŒÎŸiïŒ+Ïiâ BïŒÎŸiïŒ
iã0ããn - 1ãŸã§ã®å€ãåããΟi ã 0ããn / 2-1ãŸã§ããå®çŸ©ãããŠããªãããšãå¿ããããšãªããããã°ã©ã ã«æ¢ã«é§åã§ããŸãã çµè«-n / 2ãæ³ãšããiãåãå¿ èŠããããŸãã
åäœæéã¯ãååž°åŒT ïŒ n ïŒ= O ïŒ n ïŒ+ 2 T ïŒ n / 2 ïŒã§è¡šãããŸãã ããã¯ããªãããç¥ãããé¢ä¿ã§ããã O ïŒnâ log 2 n ïŒã§æããã«ãªããŸãïŒå€§ãŸãã«èšããšãååž°ã®æ·±ãã¯log 2 nã¬ãã«ã§ãããåã¬ãã«ã§ãã¹ãŠã®åŒã³åºãã§åèšO ïŒ n ïŒæäœãå®è¡ãããŸãïŒã
äœããæžã
éå¹ççãªååž°çFFTå®è£ ã®äŸã次ã«ç€ºããŸãã
é ãfft
#include <vector> #include <complex> using namespace std; typedef complex<double> cd; // STL- . double, sin cos typedef vector<cd> vcd; vcd fft(const vcd &as) { // 1 int n = as.size(); // - ? if (n == 1) return vcd(1, as[0]); vcd w(n); // for (int i = 0; i < n; i++) { double alpha = 2 * M_PI * i / n; w[i] = cd(cos(alpha), sin(alpha)); } // A B vcd A(n / 2), B(n / 2); for (int i = 0; i < n / 2; i++) { A[i] = as[i * 2]; B[i] = as[i * 2 + 1]; } vcd Av = fft(A); vcd Bv = fft(B); vcd res(n); for (int i = 0; i < n; i++) res[i] = Av[i % (n / 2)] + w[i] * Bv[i % (n / 2)]; return res; }
I / Oãè¿œå ããŠãå®è£ ãæ£ããããšã確èªã§ããŸãã å€é åŒP ïŒ x ïŒ= 4 + 3 x + 2 x 2 + x 3 + 0â x 4 + 0â x 5 + 0â x 6 + 0â x 7ã®å Žåãå€ã¯æ¬¡ã®ããã«ãªããŸãã
P ïŒ w 0 ïŒ=ïŒ 1 0. 0 0 0ã0 . 0 0 0 ïŒ
P ïŒ w 1 ïŒ=ïŒ 5. 4 1 4ã4 . 8 2 8 ïŒ
P ïŒ w 2 ïŒ=ïŒ 2. 0 0 0ã2 . 0 0 0 ïŒ
P ïŒ w 3 ïŒ=ïŒ 2. 5 8 6ã0. 8 2 8 ïŒ
P ïŒ w 4 ïŒ=ïŒ 2. 0 0 0ã0 . 0 0 0 ïŒ
P ïŒ w 5 ïŒ=ïŒ 2. 5 8 6 ã -0. 8 2 8 ïŒ
P ïŒ w 6 ïŒ=ïŒ 2. 0 0 0 ã -2. 0 0 0 ïŒ
P ïŒ w 7 ïŒ=ïŒ 5. 4 1 4 ã -4 . 8 2 8 ïŒ
ãã®å Žåã倧èŠæš¡ãªãã¹ãã§ååž°çã§çŽ æŽãªæ¹æ³ã䜿çšã§ããŸãã
次æ°2 12ã®å€é åŒã§ã¯ããã®å®è£ ã¯62ããªç§ã§åäœããçŽ æŽãªå€é åŒã¯1800ããªç§ã§åäœããŸãã éãã¯æããã§ãã
ååž°ãåãé€ã
æé ãéååž°çã«ããã«ã¯ãããã«ã€ããŠèããå¿ èŠããããŸãã ç§ã«ãšã£ãŠæãç°¡åãªæ¹æ³ã¯ãMergeSortïŒããŒãžãœãŒãïŒãšã®é¡äŒŒæ§ãæãããã¹ãŠã®ååž°åŒã³åºãã瀺ãå³ãæãããšã§ãã
ã芧ã®ãšããã1ã€ã®é åãäœæããæåã«å€fftïŒ a 0 ïŒãfftïŒ a 4 ïŒãfftïŒ a 2 ïŒã ...ã§åããããšãã§ããŸãã æ°åa iã¯ããã€ããªè¡šçŸã§ãæ¡åŒµããããæ°åã 0ã1ã2ã3 ã ... ãã§ããããšãç解ããã®ã¯ç°¡åã§ãã ããšãã°ã 1 1 0 = 0 0 1 2ã4 1 0 = 1 0 0 2ãŸãã¯6 = 1 1 0 2ã3 = 0 1 1 2 ã ããã¯æ¬¡ã®ããã«ç解ã§ããŸããååž°ã®äžäœã¬ãã«ã«äžéãããšãããã1ã€ã®äžäœããããïŒæåŸããïŒæ±ºå®ããŸãã ãéåžžã®ãçªå·ä»ãã§ã¯ããããã¯æåãã決å®ãããŸãã ãããã£ãŠãæ°å€ããæ¡åŒµãããå¿ èŠããããŸãã ããã¯ã O ïŒ n forelog 2 n ïŒã®ãé¡ãã§è¡ãããšãã次ã®ã¢ã«ãŽãªãºã ã䜿çšããŠO ïŒ n ïŒã«å¯ŸããŠåçã«ããã°ã©ã ããããšãã§ããŸãã
- 0ããn - 1ã®ãµã€ã¯ã«ãå®è¡ããŸã
- æ°å€ã®æäžäœãŠããããããã®æ°ãæ ŒçŽããåçã«åã«ãŠã³ãããŸãã çŸåšã®æ°ã2ã®çŽ¯ä¹ã§ããå Žåã«ã®ã¿å€æŽãããŸãã1ãã€å¢å ããŸãã
- æ°å€ã®æäžäœããããããã£ãŠããå ŽåãæŽæ°ãå転ããããšã¯é£ãããããŸãããæäžäœãããïŒXORïŒããåãæšãŠããæ®ãïŒæ¢ã«èšç®ãããå€ïŒãå転ãããåãæšãŠãåäœãè¿œå ããŸã
ããã§ããã¹ããããããããé«ãã¹ããããååŸã§ããã¢ã«ãŽãªãºã ãèãåºããŸãã åã®æé ã®ãã¹ãŠã®å€ã1ã€ã®é åã«ä¿åããŸãã å³ããæãããªããã«ãæåã«k = 1ã§ããkã®ãããã¯ã§ããŒã¿ãåŠçããå¿ èŠãããããã®åŸãåã¹ãããã§2åã«ãªããŸãã é·ãkã® 2ã€ã®ãããã¯ãåŠçããåºåã§é·ã2 kã® 1ã€ã®ãããã¯ãååŸããŸãã ãããã©ã®ããã«ååž°çã«è¡ããããã®äŸãèŠãŠãèšäºã®æåããåŒãæãåºããŠç¹°ãè¿ããŠã¿ãŸãããã
2ã€ã®ãããã¯ãããŒãžããããã®ããã·ãŒãžã£ã®åŒæ°ã¯ã2ã€ã®ãã¯ãã«ïŒãã¡ãããåç §ããœãŒã¹ãçµæïŒãæåã®ãããã¯ã®éå§èŠçŽ ã®æ°ïŒ2çªç®ã®ãããã¯ã®çŽåŸïŒããããã¯ã®é·ãã§ãã ãã¡ãããã€ãã¬ãŒã¿ã§ãå®è¡ã§ããŸã-ããå€ãã®STL'nostiã«ã€ããŠã¯ãç°¡æœã«ããããã«ãã®æé ãã¡ã€ã³ã®æé å ã«è»¢éããŸãã
ãããã¯ããŒãž
void fft_merge(const vcd &src, vcd &dest, int start, int len) { int p1 = start; // int en1 = start + len; // int p2 = start + len; // int en2 = star + len * 2; // int pdest = start; // int nlen = len * 2; // for (int i = 0; i < nlen; i++) { double alpha = 2 * M_PI * i / nlen; cd w = cd(cos(alpha), sin(alpha)); // dest[pdest] = src[p1] + w * src[p2]; if (++p1 >= en1) p1 = start; if (++p2 >= en2) p2 = start + len; } }
ãããŠãäž»ãªå€ææé ïŒ
vcd fft(const vcd &as) { int n = as.size(); int k = 0; // n while ((1 << k) < n) k++; vi rev(n); rev[0] = 0; int high1 = -1; for (int i = 1; i < n; i++) { if ((i & (i - 1)) == 0) // . i , i-1 . high1++; rev[i] = rev[i ^ (1 << high1)]; // rev[i] |= (1 << (k - high1 - 1)); // } vcd cur(n); for (int i = 0; i < n; i++) cur[i] = as[rev[i]]; for (int len = 1; len < n; len <<= 1) { vcd ncur(n); for (int i = 0; i < n; i += len * 2) fft_merge(cur, ncur, i, len); cur.swap(ncur); } return cur; }
æé©å
次æ°2 1 6ã®å€é åŒã§ã¯ãååž°ã¯640ããªç§ãååž°ãªã-500ã§åäœããŸããæ¹åã¯ãããŸãããããã°ã©ã ã¯ããã«é«éã«å®è¡ã§ããŸãã Ïi =-Ïi + n / 2ãšããããããã£ã䜿çšããŸãã ãã®ãããã«ãŒãã2ååãããšãã§ããã a iâ Ïj-è€çŽ æ°ã®ãµã€ã³ãã³ãµã€ã³ãä¹ç®ã¯éåžžã«é«äŸ¡ãªæŒç®ã§ãã
fft_mergeïŒïŒ
for (int i = 0; i < len; i++) { double alpha = 2 * M_PI * i / nlen; cd w = cd(cos(alpha), sin(alpha)); // cd val = w * src[p2]; dest[pdest] = src[p1] + val; dest[pdest + len] = src[p1] - val; pdest++; if (++p1 >= en1) p1 = start; if (++p2 >= en2) p2 = start + len; }
ãã®æé©åã«ããé·ç§»ã¯ãããã¿ãã©ã€å€æããšåŒã°ããŸãã ããã°ã©ã ã¯260ããªç§åäœãå§ããŸããã æåãçµ±åããããã«ã 1ã®ãã¹ãŠã®æ ¹ãèšç®ããŠé åã«æžã蟌ã¿ãŸãããã
fft_mergeïŒïŒ
int rstep = roots.size() / nlen; // for (int i = 0; i < len; i++) { cd w = roots[i * rstep]; cd val = w * src[p2];
fftïŒïŒ
roots = vcd(n); for (int i = 0; i < n; i++) { double alpha = 2 * M_PI * i / n; roots[i] = cd(cos(alpha), sin(alpha)); }
çŸåšãé床ã¯78ããªç§ã§ãã æåã®å®è£ ãšæ¯èŒããŠ8åã®æé©åïŒ
ã³ãŒãã®æé©å
çŸåšããã¹ãŠã®å€æã³ãŒãã¯çŽ55è¡ããããŸãã 100ã§ã¯ãããŸããããããã¯éåžžã«å€ããçãããããšãã§ããŸãã æåã«ã fft_mergeã®äœåãªå€æ°ãšæäœã®æãåãé€ããŸãïŒ
void fft_merge(const vcd &src, vcd &dest, int start, int len) { int p1 = start; //int en1 = start + len; // , . int p2 = start + len; //int en2 = start + len * 2; // int pdest = start; //int nlen = len * 2; // //int rstep = roots.size() / nlen; int rstep = roots.size() / (len * 2); for (int i = 0; i < len; i++) { //cd w = roots[i * rstep]; // //cd val = w * src[p2]; cd val = roots[i * rstep] * src[p2]; dest[pdest] = src[p1] + val; dest[pdest + len] = src[p1] - val; pdest++, p1++, p2++; //if (++p1 >= en1) p1 = start; // 2len, len, //if (++p2 >= en2) p2 = start + len; // } }
ããã§ãã«ãŒããfft_mergeããã¡ã€ã³ããã·ãŒãžã£ã«ç§»åã§ããŸãïŒ p2 = p1 + lenã§ããããã p2ãåé€ã§ããŸããããã«ãããããããªæéã®å¢å ãåŸãããŸãããããã¯èå³æ·±ãã§ãã ïŒ
fftïŒïŒ
for (int len = 1; len < n; len <<= 1) { vcd ncur(n); int rstep = roots.size() / (len * 2); for (int pdest = 0; pdest < n;) { int p1 = pdest; for (int i = 0; i < len; i++) { cd val = roots[i * rstep] * cur[p1 + len]; ncur[pdest] = cur[p1] + val; ncur[pdest + len] = cur[p1] - val; pdest++, p1++; } pdest += len; } cur.swap(ncur); }
ã芧ã®ãšãããå€æèªäœã¯ããã»ã©å€ãã¯ããããŸãã-17è¡ã§ãã ä»ã®ãã¹ãŠ-æ ¹ã®äºåèšç®ãšæ°å€ã®å転ã äœæ¥æéãšåŒãæãã«ã³ãŒããä¿åããæºåãã§ããŠããå ŽåïŒ O ïŒ n ïŒã§ã¯ãªãO ïŒnâ log 2 n ïŒïŒã13è¡ã®æ°åã®åºããã次ã®6è¡ã«çœ®ãæããããšãã§ããŸãã
fftïŒïŒã®éå§æ
vcd cur(n); for (int i = 0; i < n; i++) { int ri = 0; for (int i2 = 0; i2 < k; i2++) // ri = (ri << 1) | !!(i & (1 << i2)); // cur[i] = as[ri]; }
ãã®çµæãã³ãŒãã¯æ¬¡ã®ããã«ãªããŸãã
vcd fft(const vcd &as) { int n = as.size(); int k = 0; // n while ((1 << k) < n) k++; vector<int> rev(n); rev[0] = 0; int high1 = -1; for (int i = 1; i < n; i++) { if ((i & (i - 1)) == 0) // . i , i-1 . high1++; rev[i] = rev[i ^ (1 << high1)]; // rev[i] |= (1 << (k - high1 - 1)); // } vcd roots(n); for (int i = 0; i < n; i++) { double alpha = 2 * M_PI * i / n; roots[i] = cd(cos(alpha), sin(alpha)); } vcd cur(n); for (int i = 0; i < n; i++) cur[i] = as[rev[i]]; for (int len = 1; len < n; len <<= 1) { vcd ncur(n); int rstep = roots.size() / (len * 2); for (int pdest = 0; pdest < n;) { int p1 = pdest; for (int i = 0; i < len; i++) { cd val = roots[i * rstep] * cur[p1 + len]; ncur[pdest] = cur[p1] + val; ncur[pdest + len] = cur[p1] - val; pdest++, p1++; } pdest += len; } cur.swap(ncur); } return cur; }
éå€æ
ãã¡ããããã€ã³ãã§å€é åŒã®å€ãååŸããã®ã¯è¯ãããšã§ãããããŒãªãšå€æã¯ãããããè¯ãããããšãã§ããŸã-ããã«ããããã®å€ã䜿çšããŠå€é åŒèªäœãæ§ç¯ããŸãïŒ å€é åŒã®ä¿æ°ã«é¢ããŠããŒãªãšå€æãå€ã®é åã«é©çšããçµæãnã§é€ç®ããã»ã°ã¡ã³ãã1ããn - 1 ïŒ 0ããã®çªå·ä»ãïŒã«ãããšãå ã®å€é åŒã®ä¿æ°ãåŸãããããšãããããŸãã
ããã®ã³ãŒãã¯éåžžã«åçŽã§ã-ãã¹ãŠããã§ã«æžãããŠããŸãã 察åŠã§ãããšæããŸãã
蚌æ
ä¿æ°v i ïŒå ã®å€é åŒã«ã¯ä¿æ°a iããããŸãã ïŒã䜿çšããŠãå€é åŒP ïŒ x ïŒã«éå€æãé©çšããŸãã
v i = a 0 +Ïi a 1 +Ï2 i a 2 +Ï3 i a + ...
å€æã®çµæãèŠãŠã¿ãŸãããã
b i = v 0 +Ïi v 1 +Ï2 i v 2 +Ï3 i v 3 + ...
v jã®å€ãä»£å ¥ããŸãïŒÏaÏb =Ïa + b m o d n ïŒ
1ã€ã®æ³šç®ãã¹ãäºå®ã蚌æããŸãããïŒ x â 0ã®å Žåã Ï0 +Ïx +Ï2 x + ... +Ï ïŒ n - 1 ïŒ x = 0 ã
ããã¯ãæ ¹ã®åèšããŒãã§ãããšããäºå®ãšåæ§ã«èšŒæãããŸããåèšãÏã§è¡šããäž¡åŽã«ÏxãæããŠãäœãèµ·ãã£ããã確èªããŸãã
ããã§ããã®äºå®ãb iã®å€ã®èšç®ã«é©çšããŸãã n - iãå«ãè¡ãé€ããã¹ãŠã®è¡ã¯ãŒãã«ãªã»ãããããããšã«æ³šæããŠãã ããã
ãã®ããã«ïŒ
b i = a n - iâ ïŒ Ï0 + Ï0 + Ï0 + Ï0 + ... ïŒ
b i = a n - iâ n
蚌æããããã«å¿ èŠã§ããã
ç³èŸŒã¿
äžè¬çã«èšãã°ãç§ã¯ãã§ã«èšäºã®åé ã§ã¢ããªã±ãŒã·ã§ã³ã«ã€ããŠå°ã話ããŸããã ç¹ã«ãå€é åŒã®ä¹ç®ã¯æ¬¡ã®ããã«å®è¡ã§ããŸãã
å€é åŒã®é«éä¹ç®
vcd a, b; // // vcd a_vals = fft(a); vcd b_vals = fft(b); vcd c_vals(a_vals.size()); for (int i = 0; i < a_vals.size(); i++) c_vals[i] = a_vals[i] * b_vals[i]; vcd c = fft_rev(c_vals); //
ãã®ããã°ã©ã ã®å®è¡æéãO ïŒnâ log 2 n ïŒã§ãããæãæéã®ãããæäœãããŒãªãšå€æã§ããããšã¯å®¹æã«ããããŸãã ãŸãã2ã€ã®å€é åŒã§ããè€éãªåŒãèšç®ããå¿ èŠãããå Žåã§ãã3ã€ã®å€æããå®è¡ã§ããªãããšã«æ³šæããŠãã ãããå ç®ãšæžç®ãç·åœ¢æéã§æ©èœããŸãã æ®å¿µãªãããå€é åŒã¯ããæç¹ã§èª€ã£ãŠå€0ããšãããšããããããé€ç®ã¯ããã»ã©åçŽã§ã¯ãããŸããã UPD2ïŒæ¬¡æ°nã® 2ã€ã®å€é åŒã®ç©ã®æ¬¡æ°ã2nã«ãªãããšãå¿ããªãã§ãã ããããã®ãããå ¥åãããšãã¯ããäœåãªããŒãå è¡ä¿æ°ãè¿œå ããå¿ èŠããããŸãã
10é²æ°ïŒãŸãã¯ãã以äžïŒã®æ°å€ã·ã¹ãã ãä¿æ°-æ¡ã®å€é åŒãšããŠè¡šãå Žåãé·ãæ°å€ã®ä¹ç®ãéåžžã«é«éã«å®è¡ã§ããŸãã
ãããŠæåŸã«ã次ã®æçš¿ã§åæããã¿ã¹ã¯ïŒæåAãTãGãCãã1 0 5ã®ãªãŒããŒã®åãé·ãã®2è¡ããããŸããæåã®æ倧æ°ãäžèŽããããã«ãè¡ã®1ã€ã®åŸªç°ã·ãããèŠã€ããå¿ èŠããããŸãã æããã«O ïŒ n 2 ïŒã®åçŽãªãœãªã¥ãŒã·ã§ã³ã§ãããFFTã䜿çšãããœãªã¥ãŒã·ã§ã³ããããŸãã
é 匵ã£ãŠ
UPDïŒã³ãŒãå šäœãpastebin ã«æçš¿ããŸãã