根据定义用C ++计算DFT

时间:2016-05-17 21:18:38

标签: c++ dft

我试图通过最简单的方法来计算DFT及其反演,但它仍然无法正常工作。更糟糕的是,我不确定。这是我的代码:

(realnum是double,freq_func和time_func是复数的向量)

freq_func toFreq(const time_func & waveform)
{
    freq_func res;
    res.resize(waveform.size());

    const realnum N = spectrum.size();

    for (size_t k = 0; k < waveform.size(); k++)
        for (size_t n = 0; n < waveform.size(); n++)
            res[k] += waveform[n] * exp(complex(0, -2*PI*n*k/N));

    return res;
}


time_func toTime(const freq_func & spectrum)
{

    freq_func res;
    res.resize(spectrum.size());

    const realnum N = spectrum.size();

    for (size_t n = 0; n < spectrum.size(); n++)
    {
        for (size_t k = 0; k < spectrum.size(); k++)
            res[n] += spectrum[k] * exp(complex(0, 2*PI*n*k/N));
        res[n] /= N;
    }

    return res;
}

为什么它永远不会持有= toTime(toFreq(a))或a = toFreq(toTime(a))?为什么toTime以相当大的虚部返回结果?还是应该呢?一些在线计算器可以。为什么维基百科声称,除以N可以转移到弗雷克,或者甚至用两个除以1 / sqrt(N)代替,不应该只有一个可能的定义吗?

1 个答案:

答案 0 :(得分:0)

表达式complex(0, 2*PI*n*k/N)创建并初始化complex个数字,实际部分设置为0,虚部设置为2*PI*n*k/N。要实现DFT,您真的希望使用大小为1的复数,并且阶段为2*PI*n*k/N。你可以这样做:

complex(polar(1,2*PI*n*k/N))

用于正向变换,

complex(polar(1,-2*PI*n*k/N))

用于逆变换。

就维基百科的说法而言,这只是DFT定义的问题。不同的实现可以选择不同的定义,因此可以通过不同的因归一化的DFT将选择正向和反向变换,使得往返产生原始序列(例如,x == toTime(toFreq(x)))。其他非标准化DFT可以选择不同的缩放(例如,当缩放对于手头的应用程序不重要时,保存一些缩放操作)。