根据定义计算DFT(带有<complex>的C ++)

时间:2017-08-13 19:56:41

标签: c++ dft

我正在尝试使用C ++及其标准库来实现离散傅里叶变换的“天真”定义,这是我个人对数学材料的理解,并且我不断输出错误,尽管我的代码似乎是是DFT的数学定义的直接翻译。

这是代码(编辑以便更好地清理输出):

void DFT(std::complex<double>* outputs, int N, std::complex<double>* inputs)
{
  for (int k = 0; k < N; ++k) 
  {
    outputs[k] = std::complex<double>(0.0, 0.0);
    for (int t = 0; t < N; ++t) 
    {
       // tk2π/N
       double angle = t * k * TWOPI / double(N);
       // e^(-jtk2π/N)
       std::complex<double> dft_sino = std::polar(1.0, -angle);

      if(fabs(real(dft_sino)) < std::numeric_limits<float>::epsilon())
        dft_sino = std::complex<double>(0.0, imag(dft_sino));

      if(fabs(imag(dft_sino)) < std::numeric_limits<float>::epsilon())
        dft_sino = std::complex<double>(real(dft_sino), 0.0);

      std::cout << "DFT sinosoid (" << k << "), Sample " << t << ": " << dft_sino << std::endl;
      outputs[k] += inputs[t] * dft_sino;
    }
  }
}

输入集是:

 1+1i
-1+1i
 1-1i
-1-1i
-3-1i
 4-2i
 0-3i
 2-6i

我期望的(已验证)输出是:

 3-12i
 10.24+5.243i
 3+2i
 9.071+10.07i
-5+4i
 1.757-3.243i
-9+6i
-5.071-4.071i

以当前形式输出的程序是:

 3+2i
 3.293+6.364i
-2-1i
 6.121+6.95i
-5-4.91e-15i
 4.707-6.364i
-4+3i
 1.879-2.95i

这里有什么显而易见的东西吗?

编辑:下面是相应DFT正弦曲线样本的样本输出,在求和过程中乘以输入。

DFT sinusoid (0):
Sample 0: 1+0i
Sample 1: 1+0i
Sample 2: 1+0i
Sample 3: 1+0i
Sample 4: 1+0i
Sample 5: 1+0i
Sample 6: 1+0i
Sample 7: 1+0i

DFT sinusoid (1):
Sample 0: 1+0i
Sample 1: 0.7071-0.7071i
Sample 2: 0-1i
Sample 3: -0.7071-0.7071i
Sample 4: -1+0i
Sample 5: -0.7071+0.7071i
Sample 6: 0+1i
Sample 7: 0.7071+0.7071i

DFT sinusoid (2):
Sample 0: 1+0i
Sample 1: 0-1i
Sample 2: -1+0i
Sample 3: 0+1i
Sample 4: 1+0i
Sample 5: 0-1i
Sample 6: -1+0i
Sample 7: 0+1i

DFT sinusoid (3):
Sample 0: 1+0i
Sample 1: -0.7071-0.7071i
Sample 2: 0+1i
Sample 3: 0.7071-0.7071i
Sample 4: -1+0i
Sample 5: 0.7071+0.7071i
Sample 6: 0-1i
Sample 7: -0.7071+0.7071i

DFT sinusoid (4):
Sample 0: 1+0i
Sample 1: -1+0i
Sample 2: 1+0i
Sample 3: -1+0i
Sample 4: 1+0i
Sample 5: -1+0i
Sample 6: 1+0i
Sample 7: -1+0i

DFT sinusoid (5):
Sample 0: 1+0i
Sample 1: -0.7071+0.7071i
Sample 2: 0-1i
Sample 3: 0.7071+0.7071i
Sample 4: -1+0i
Sample 5: 0.7071-0.7071i
Sample 6: 0+1i
Sample 7: -0.7071-0.7071i

DFT sinusoid (6):
Sample 0: 1+0i
Sample 1: 0+1i
Sample 2: -1+0i
Sample 3: 0-1i
Sample 4: 1+0i
Sample 5: 0+1i
Sample 6: -1+0i
Sample 7: 0-1i

DFT sinusoid (7):
Sample 0: 1+0i
Sample 1: 0.7071+0.7071i
Sample 2: 0+1i
Sample 3: -0.7071+0.7071i
Sample 4: -1+0i
Sample 5: -0.7071-0.7071i
Sample 6: 0-1i
Sample 7: 0.7071-0.7071i

1 个答案:

答案 0 :(得分:0)

好消息是你的DFT的实现没有任何问题,我能够通过正确的输入确认该函数产生你期望的输出。这意味着它收到的输入存在问题。以类似的方式实现逆变换表明​​以下输入实际上被馈送到DFT函数:

 1+1i
-1+1i
 1+0i
-1+0i
-3+0i
 4+0i
 0+0i
 2+0i

从这看起来你似乎错过了大多数输入的虚部(除了inputs[0]inputs[1])。由于您未提供如何生成inputs中的数据并将其传递给DFT,因此无法准确说明原因。但是,以下是一些可能导致此类问题的常见原因,您可以将其作为起点,同时调查函数的inputs为什么不符合您的想法:

  • 意外地(或不是)用零覆盖输入缓冲区虚部。这可能反过来是由于:
    • inputs的{​​{1}}和outputs参数提供相同的数组(此实现要求它们是不同的数组);
    • 使用小于转换大小DFT的输入和输出数组,然后在向这些数组写入值时写入越界值;
  • 实际上忘记设置虚部;
  • 从文件或程序的其他部分读取它们时,错误地获取实部/虚部(例如,假设文件包含8个实部,当文件实际上只包含10个值时,则包含8个虚部)。