実現したいこと
Cooley–Tukeyアルゴリズムを使用してIFFTを実装したい
前提
指数関数の符号が逆であるため、FFTの複素共役を取ると逆フーリエ変換を得られる事が分かります。
ただ、FFTと対称的にIFFTを実装する(再帰関数のみで実装する)方法が分からないのでご教授頂ければと思います。
該当のソースコード
一応、以下にCooley–Tukeyアルゴリズムを使用したFFTの実装を載せておきます
C
1#include <stdio.h> 2#include <stdlib.h> 3#include <math.h> 4#include <complex.h> 5 6void fft(double complex* x, int n) { 7 8 if (n == 1) { 9 10 return; 11 } 12 13 double complex* xe = malloc(n / 2 * sizeof(double complex)); 14 double complex* xo = malloc(n / 2 * sizeof(double complex)); 15 16 for (int i = 0; i < n / 2; i++) { 17 18 xe[i] = x[2 * i]; 19 xo[i] = x[2 * i + 1]; 20 } 21 22 fft(xe, n / 2); 23 fft(xo, n / 2); 24 25 for (int i = 0; i < n / 2; i++) { 26 27 double complex w = cexp(-2 * M_PI * I * i / n); 28 double complex t = w * xo[i]; 29 30 x[i] = xe[i] + t; 31 x[i + n / 2] = xe[i] - t; 32 } 33 34 free(xe); 35 free(xo); 36 37 return; 38} 39
試したこと
IFFTは以下のように実装してみましたが、期待した結果が得られませんでした
C
1#include <stdio.h> 2#include <stdlib.h> 3#include <math.h> 4#include <complex.h> 5 6void ifft(double complex* x, int n) { 7 8 if (n == 1) { 9 10 return; 11 } 12 13 double complex* xe = malloc(n / 2 * sizeof(double complex)); 14 double complex* xo = malloc(n / 2 * sizeof(double complex)); 15 16 for (int i = 0; i < n / 2; i++) { 17 18 double complex w = cexp(-2 * M_PI * I * i / n); 19 20 xe[i] = x[i] + x[i + n / 2]; 21 xo[i] = (x[i] - x[i + n / 2]) * w; 22 } 23 24 fft(xe, n / 2); 25 fft(xo, n / 2); 26 27 for (int i = 0; i < n / 2; i++) { 28 29 x[i] = xe[i]; 30 x[i + n / 2] = xo[i]; 31 } 32 33 free(xe); 34 free(xo); 35 36 return; 37} 38
補足情報(FW/ツールのバージョンなど)
Debian 11.5
gcc 10.2.1 (Debian 10.2.1-6)
複素共役をとることへのご自身の理解を併記してください
指数関数の符号が逆ですから、
e^-ix = cos -x + i sin -x = cos x - i sin x = bar{e^ix}
だと理解しています
はい,であればfft関数のあるコードの27行目
double complex w = cexp(-2 * M_PI * I * i / n);
にある回転因子wの肩の符号を逆転させて
double complex w = cexp(2 * M_PI * I * i / n);
にするだけでifft関数ができます.
ifft後は振幅がn倍されるので,これを1/nにして終わりです.
すれ違いのため削除

回答1件
あなたの回答
tips
プレビュー