【问题标题】:How can I transfer a discrete signal from the time domain into the frequency domain and back without losing data?如何将离散信号从时域传输到频域并返回而不会丢失数据?
【发布时间】:2011-08-21 22:12:48
【问题描述】:

几周以来,我一直在尝试实现一个 DFT,它采用任意字节集并将它们视为信号。然后将它们转换到频域。之后,它将它们转换回来。它最初只是尝试使用一些组件来重建原始信号。当这失败时,我尝试使用所有组件,但仍然失败。

我一直关注 Wikipedia's Equations 作为如何执行此操作的指南,并且我的代码似乎与给定此代码的(在我看来)给出的方程式相匹配:

DFT:

for (int k = 0; k < frequency_domain_magnitude.length; k++) {
    for (int n = 0; n < data.length; n++) {
        double val = (-2.0 * Math.PI * n * k / data.length);
        freq_imag[k] += data[n] * -Math.sin(val);
        freq_real[k] += data[n] * Math.cos(val);
    }
    frequency_domain_magnitude[k] = Math.sqrt(freq_imag[k] * freq_imag[k] + freq_real[k] * freq_real[k]);
}

IDFT:

for (int n = 0; n < data.length; n++) {
    doubleValue[n] = 0;
    for (int k = 0; k < freqUsed.length; k++) {
        double val = (2.0 * Math.PI * n * k / data.length);
        doubleValue[n] = freq_real[k] * Math.cos(val) - freq_imag[k] * Math.sin(val);
    }
    time_real[n] = (byte) (Math.floor(doubleValue[n]));
}

谁能帮我找出问题所在?

我之前问过一个关于同一个项目的问题,但措辞很糟糕,编辑可能会造成更多的混乱,而不是更少。此外,虽然这个问题可能已经得到解答,但我还有更多需要弄清楚。可以找到here

【问题讨论】:

标签: math signal-processing fft frequency-analysis dft


【解决方案1】:

至少有三件事是错的:

首先,您没有对 IDFT 中的所有频率求和。这是一个很大很大的问题,基本上相当于只取一个离散频率的IDFT,而不是整个频域数据。 其次,您的 IDFT 中有一个标志。

将sn-p 2的第5行改为

    doubleValue[n] += freq_real[k] * Math.cos(val) + freq_imag[k] * Math.sin(val);

并确保将 doubleValue 初始化为零。

第三,您需要添加一个标准化步骤;

将sn-p 2的第7行改为

time_real[n] = (byte) (Math.floor(doubleValue[n] / data.length))

第四,为了您自己的方便,请在截断为整数数据类型之前使用浮点输入和输出测试此浮点算法,并且不要假设在整数数据的往返过程中您会得到精确正确的答案 - - 浮点错误非常真实。

获取其他人的 DFT 和 IDFT 实现并将行为与您在一些非常简单的输入上的实现进行比较以捕获其他错误也可能会有所帮助。由于 DFT 是线性代数,您可能会得到它并不完全正确,但仍然会看到质量上还不错的答案。

【讨论】:

    【解决方案2】:

    在数字意义上,你不能,因为舍入和/或量化误差几乎总是会在往返过程中产生细微的差异或信息丢失。

    但是,如果您正确且完整地实施 DFT 和 IDFT,则可以在此数值误差内重新创建时域数据。 FFT/IFFT 对可能会产生比 DFT/IDFT 对更小的数值误差。

    如果您丢弃任何项(复数虚项或频率区间或其他),结果将与原始项相去甚远。例如,如果您的 frequency_domain_magnitude.length 或您的 freqUsed.length 小于您的数据长度,您将丢弃术语(除非您使用稍微不同的算法和/或比例因子)。

    如@ellisbben 所述,您的 IDFT 中也至少有 1 或 2 个致命的拼写错误。

    【讨论】:

      猜你喜欢
      • 2011-10-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多