Computing DFT by definition with C++

Computing DFT by definition with C++

本文关键字:with C++ definition by DFT Computing      更新时间:2023-10-16

我正在尝试用最简单的方法计算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;
}

为什么它从来没有持有a=toTime(toFreq(a))或a=toFreq?为什么toTime返回的结果有相当多的虚部?还是应该这样?一些在线计算器是这样做的。为什么维基百科声称,除以N可以移动到Freq,甚至可以用除以1/sqrt(N)来代替,难道不应该只有一个可能的定义吗?

表达式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可以选择不同的缩放(例如,当缩放对手头的应用程序不重要时,可以节省一些缩放操作)。