另一个堆栈交换(stackoverflow 和计算机科学堆栈交换)告诉我在这里发帖 - 所以希望现在我可以从了解算法的人那里得到一些帮助,但如果这不是这里的主题,那么我有点用完了地方问....
我编写了自己的 FFT 算法来学习它 - 但我得到的结果与我的预期不同(正确的数字但错误的符号),但我不知道为什么。
我希望这里有一个对 FFT 算法有很好理解的人可以理解我做错了什么,我目前怀疑这是我的旋转因素 - 但我现在不确定......
首先,我预先计算所有的旋转因子和指数。旋转计算如下:
for (int stage = 0; stage < _passes; stage++) //log(N)/log(2)
{
for (int i = 0; i < _N; i++) //N = 2^n
{
//wing span, 2^1, 2^2 etc
float span = pow(2, stage+1);
float k = (i * _N / span) % _N;
float a = pi2 * k / _N;
//iFFT uses complex positive coefficients: exp(i*2*pi*k/N)
Vector2 twiddle = new Vector2(cos(a), sin(a));
//FFT uses complex conjugate: exp(-i*2*pi*k/N)
Vector2 twiddleConj = twiddle.ComplexConjugate();
int arrIndex = stage * _N + i;
_twiddlesR[arrIndex] = twiddle; //inverse array
_twiddlesF[arrIndex] = twiddleConj; //forward array
}
}
这是输出N=4:
First stage:
[0] + (1+0i)[2]
[2] +(-1+0i)[0]
[1] + (1+0i)[3]
[3] +(-1+0i)[1]
Second stage:
[0] + (1+0i)[2]
[1] + (0-i)[3]
[2] +(-1+0i)[0]
[3] + (0+i)[1]
我使用以下代码运行 FFT:
for (int stage = 0; stage < _passes; stage++)
{
for (int k = 0; k < _N; k++)
{
PerformFft(stage, k);
}
}
我的 FFT 函数:
private void PerformFft(int stage, int k)
{
int arrIndex = stage * _N + k;
Vector2[] twiddleArr = _isForward ? _twiddlesF : _twiddlesR;
Vector2Int twiddleIndex = _twiddleIndices[arrIndex];
Vector2 twiddle = twiddleArr[arrIndex];
//ping pong between two read/write arrays by checking if stage is even or odd
Vector2[] writeArr = stage % 2 == 0 ? _complexArr2 :_complexArr1;
Vector2[] readArr = stage % 2 == 0 ? _complexArr1 :_complexArr2;
Vector2 complexA = readArr[twiddleIndex.x];
Vector2 complexB = readArr[twiddleIndex.y];
Vector2 result = complexA + complexB.ComplexMultiply(twiddle);
writeArr[k] = result;
}
对于输出,我得到了正确的数字,但我得到了错误的符号,这里有一些数据:
Input:
0 + 0i
1 + 0i
2 + 0i
3 + 0i
Forward FFT Output:
6 + 0i
2 - 2i
2 + 0i
2 + 2i
但根据这个 FFT 计算器,我接近正确答案,但符号错误:https ://scistatcalc.blogspot.com/2013/12/fft-calculator.html
谁能看到我在这里犯了什么逻辑错误?到目前为止,已经坚持了一周。
