c++ - ifft 结果与原始信号不同

标签 c++ fft ifft

FFT 工作正常,但当我想采用 IFFT 时,我总是从其结果中看到相同的图形。结果很复杂,无论原始信号如何,图形始终相同。

在实部图中是一个 -sin,周期 = 帧大小

虚部是同周期的-cos

哪里会出问题?

原始信号: original signal

IFFT 真实值(图片上只有一半帧): IFFT real value

我使用的算法 FFT。

double** FFT(double** f, int s, bool inverse) {
    if (s == 1) return f;
    int sH = s / 2;

    double** fOdd = new double*[sH];
    double** fEven = new double*[sH];
    for (int i = 0; i < sH; i++) {
       int j = 2 * i;
       fOdd[i] = f[j];
       fEven[i] = f[j + 1];
    }

    double** sOdd = FFT(fOdd, sH, inverse);
    double** sEven = FFT(fEven, sH, inverse);

    double**spectr = new double*[s];

    double arg = inverse ? DoublePI / s : -DoublePI / s;
    double*oBase = new double[2]{ cos(arg),sin(arg) };
    double*o = new double[2]{ 1,0 };

    for (int i = 0; i < sH; i++) {
        double* sO1 = Mul(o, sOdd[i]);

        spectr[i] = Sum(sEven[i], sO1);
        spectr[i + sH] = Dif(sEven[i], sO1);

        o = Mul(o, oBase);
    }

    return spectr;
}

最佳答案

“蝴蝶”部分错误地应用了系数:

for (int i = 0; i < sH; i++) {
    double* sO1 = sOdd[i];
    double* sE1 = Mul(o, sEven[i]);

    spectr[i] = Sum(sO1, sE1);
    spectr[i + sH] = Dif(sO1, sE1);

    o = Mul(o, oBase);
}

旁注:

我保留了你的符号,但这让事情变得困惑:

fOdd 有索引 0, 2, 4, 6, ... 所以它应该是 fEven

fEven 有索引 1, 3, 5, 7, ... 所以它应该是 fOdd

真的 sOdd 应该是 sLowersEven 应该是 sUpper 因为它们对应于 0 :s/2s/2:s-1 元素分别为:

sLower = FFT(fEven, sH, inverse); // fEven is 0, 2, 4, ...
sUpper = FFT(fOdd, sH, inverse); // fOdd is 1, 3, 5, ...

然后蝴蝶变成:

for (int i = 0; i < sH; i++) {
    double* sL1 = sLower[i];
    double* sU1 = Mul(o, sUpper[i]);

    spectr[i] = Sum(sL1, sU1);
    spectr[i + sH] = Dif(sL1, sU1);

    o = Mul(o, oBase);
}

当这样写时,比较容易与 pseudocode example on wikipedia 进行比较.

@Dai 是正确的,你会泄漏大量内存

关于c++ - ifft 结果与原始信号不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44095442/

相关文章:

c++ - 为什么定义与枚举类冲突?

java - FFT 图像变换的输入和输出应该是什么?

matlab - 在 OpenCV 中显示傅里叶变换

matlab - 频谱的时间序列

c++ - 二维图像上的 FFTW 错误反向变换 [with Qt]

matlab - 时域/频谱/DSP

C++ : How can I solve a first-chance exception caused at an unknown point?

c++ - 如何防止 GUI 在允许第二个操作与 Qt 中的第一个操作一起执行时挂起

ios - 执行 FFT 以查找和弦音频样本的基频

c++ - 拥有一张 map 的 map 还是一张非常大的 map 更有效率?