我正在执行基数-2 dif反向fft。我正在使用共轭和缩放的属性来返回结果。我将输入矢量共轭,执行常规基数-2 fft(而不是ifft),将结果共轭,然后按1.0 / N进行缩放。但是,我没有得到正确的结果:
int main(){
const int n = 4;
complex<double> x[n];
// Test signal
x[0] = complex<double>(10,0);
x[1] = complex<double>(-2,0);
x[2] = complex<double>(-2,2);
x[3] = complex<double>(-2,-2);
print(x,n);
fft_inverse(x,n);
print(x,n);
}
//dif fft. works
void fft(complex<double> X[], int N){
if(N == 1){return;}
complex<double> *temp = new complex<double>[N];
for(int i=0; i<N; i++){
temp[i]=X[i];
}
for(int i = 0; i<N/2; i++){
complex<double> tw(cos(-2*M_PI*i/N),sin(-2*M_PI*i/N));
X[i] = temp[i] + temp[i+N/2];
X[i+N/2] = temp[i]-temp[i+N/2];
X[i+N/2] = X[i+N/2]*tw;
}
fft(X,N/2);
fft(X+N/2,N/2);
}
void fft_inverse(complex<double> X[], int N){
//conjugate
for(int i = 0; i<N;i++){
X[i] = conj(X[i]);
}
//perform fft
fft(X,N);
//conjugate again
for(int i = 0; i<N;i++){
X[i] = conj(X[i]);
}
//scale by 1.0/N
double norm_N = 1.0/N;
for(int i = 0; i<N;i++){
X[i] *= norm_N;
}
}
以下是我的结果: 输入:
(10,0) (-2,0) (-2,2) (-2,-2)
输出:
(1,-O) (3,1) (2.5,-0.5) (3.5,-0.5)
输出应为:
(1,0) (2,0) (3,0) (4,0)
发生了什么事?我已经测试了我的fft
输出应该是什么并得到了正确的结果,所以我不确定是什么问题。
答案 0 :(得分:1)
看起来您的代码提供了正确的输出但是这些分区的顺序错误:
octave> X = [ 10, -2, -2+2i, -2-2i ]
X =
10 + 0i -2 + 0i -2 + 2i -2 - 2i
octave> x = ifft(X)
x =
1.00000 + 0.00000i 2.50000 - 0.50000i 3.00000 + 1.00000i 3.50000 - 0.50000i
fft_inverse()
看起来不错,所以我怀疑fft()
可以使用一些进一步的测试/调试 - 可能需要为索引做一些反转。
答案 1 :(得分:1)
让我们回顾一下基础知识:长度为2N的逆fft在p(z)
的统一q^i
的根处评估2N度的多项式q^N = -1
。为了快速做到这一点,多项式被分成偶数和奇数部分p(z)=pe(z^2)+z*po(z^2)
。然后
p(q^i) =pe(q^2i)+q^i*po(q^2i)
p(q^(N+i))=pe(q^2i)-q^i*po(q^2i)
在实现中,pe和po的值是通过递归调用长度为N的ifft
获得的。
前向fft现在是逆操作,从其值计算多项式的系数。为此,通过颠倒上述公式,将p(q^i)
的值转换为pe(q^2i)
和po(q^2i)
的值,
pe(q^2i)=0.5*(p(q^i)+p(q^(N+i)))
po(q^2i)=0.5*(p(q^i)-p(q^(N+i)))*q^(-i)
您应该从代码中识别出来。然后递归地调用fft以从它们现在计算的值确定pe和po的系数。因子0.5通常被省略,并且应用fft例程之外的数组长度作为除法收集。
现在出错的地方在于pe和po的系数在p的系数序列中出现交替,交错。着名的蝴蝶图案。
void fft(complex<double> X[], int N){
fft_internal(X,N,1);
}
void fft_internal(complex<double> X[], int N, int step){
if(N == 1){return;}
complex<double> *temp = new complex<double>[N];
for(int i=0; i<N; i++){
temp[i]=X[step*i];
}
for(int i = 0; i<N/2; i++){
complex<double> tw(cos(-2*M_PI*i/N),sin(-2*M_PI*i/N));
X[2*step*i ] = temp[i] + temp[i+N/2];
X[2*step*i+step] = (temp[i] - temp[i+N/2])*tw;
}
fft_internal(X ,N/2, 2*step);
fft_internal(X+step,N/2, 2*step);
}
使用正确重新排序的输入([2]&lt; - &gt; [1]),
// Test signal
x[0] = complex<double>(10,0);
x[1] = complex<double>(-2,2);
x[2] = complex<double>(-2,0);
x[3] = complex<double>(-2,-2);
这会返回预期的结果。