C++ 离散傅里叶变换C++;

C++ 离散傅里叶变换C++;,c++,fft,complextype,C++,Fft,Complextype,我正在尝试编写简单的DFT和IDFT函数,这将是我未来项目的核心。问题是IDFT返回的值与输入值不同,我不明白错误在哪里。 下面是我的源代码: vector<double> input; vector<double> result; vector<complex<double>> output; double IDFT(int n) { double a = 0; double b = 0; int N = output.

我正在尝试编写简单的DFT和IDFT函数,这将是我未来项目的核心。问题是IDFT返回的值与输入值不同,我不明白错误在哪里。 下面是我的源代码:

vector<double> input;
vector<double> result;
vector<complex<double>> output;

double IDFT(int n)
{
    double a = 0;
    double b = 0;
    int N = output.size();
    for(int k = 0; k < N; k++)
    {
        double value = abs(output[k]);
        a+= cos((2 * M_PI * k * n) / N) * value;
        b+= sin((2 * M_PI * k * n) / N) * value;
    }
    complex<double> temp(a, b);
    double result = abs(temp);
    result /= N;
    return result;
}
complex<double> DFT(double in, int k)
{
    double a = 0;
    double b = 0;
    int N = input.size();
    for(int n = 0; n < N; n++)
    {
        a+= cos((2 * M_PI * k * n) / N) * input[n];
        b+= -sin((2 * M_PI * k * n) / N) * input[n];
    }
    complex<double> temp(a, b);
    return temp;
}

int main()
{
    input.push_back(55);
    input.push_back(15);
    input.push_back(86);
    input.push_back(24);
    input.push_back(66);
    input.push_back(245);
    input.push_back(76);

    for(int k = 0; k < input.size(); k++)
    {
        output.push_back(DFT(input[k], k));
        cout << "#" << k << ":\t" << input[k] << " \t>> abs: " << abs(output[k]) << " >> phase: " << arg(output[k]) << endl;
    }
    for(int n = 0; n < output.size(); n++)
    {
        result.push_back(IDFT(n));
        cout << result[n] << endl;
    }
    return 0;
}
矢量输入;
矢量结果;
矢量输出;
双IDFT(整数n)
{
双a=0;
双b=0;
int N=output.size();
对于(int k=0;kcout适用于英特尔核心计算机:

有一个英特尔-
IPP
库。它提供了许多性能非常高的函数。由于使用向量运算,很难编写比函数更快的函数。请尝试:


你的傅里叶逆变换显然被破坏了:你忽略了复数的参数
输出[k]

应该是这样的:

double IDFT(size_t n)
{
    const auto ci = std::complex<double>(0, 1);
    std::complex<double> result;
    size_t N = output.size();
    for (size_t k = 0; k < N; k++)
        result += std::exp((1. / N) * 2 * M_PI * k * n * ci) * output[k];
    result /= N;
    return std::abs(result);
}
双IDFT(尺寸)
{
const auto ci=std::complex(0,1);
复杂结果;
size_t N=output.size();
对于(大小k=0;k
编辑。

如果要明确区分实部和虚部,可以使用:

double IDFT(size_t n)
{
    double a = 0;
    size_t N = output.size();
    for (size_t k = 0; k < N; k++)
    {
        auto phase = (2 * M_PI * k * n) / N;
        a += cos(phase) * output[k].real() - sin(phase) * output[k].imag();
    }
    a /= N;
    return a;
}
双IDFT(尺寸)
{
双a=0;
size_t N=output.size();
对于(大小k=0;k
如果这不仅仅是一个教育练习,为什么要重新发明轮子呢?也许,如果我决定为某个微控制器编译它,我就不会有任何附加库的问题,而且,我必须了解它在低级时是如何工作的。阅读浮点数运算。强烈建议-小、自包含、快速。如果
exp
令人困惑,这相当于将OP的
IDFT()
中的
值更改为
output[k].real()
output[k].imag()