Math 如何在不丢失数据的情况下将离散信号从时域传输到频域并返回?

Math 如何在不丢失数据的情况下将离散信号从时域传输到频域并返回?,math,signal-processing,fft,frequency-analysis,dft,Math,Signal Processing,Fft,Frequency Analysis,Dft,几周来,我一直在尝试实现一种DFT,它接受任意一组字节,并将它们视为信号。然后将其转换到频域。然后,它会将它们转换回来。它最初只尝试使用一些组件来重建原始信号。失败后,我尝试使用所有组件,但仍然失败 我一直在遵循以下指南来指导如何执行此操作,并且我的代码似乎与给定代码(在我心目中)的方程式相匹配: 干膜厚度: for(int k=0;k

几周来,我一直在尝试实现一种DFT,它接受任意一组字节,并将它们视为信号。然后将其转换到频域。然后,它会将它们转换回来。它最初只尝试使用一些组件来重建原始信号。失败后,我尝试使用所有组件,但仍然失败

我一直在遵循以下指南来指导如何执行此操作,并且我的代码似乎与给定代码(在我心目中)的方程式相匹配:

干膜厚度:

for(int k=0;k
IDFT:

for(int n=0;n
有人能帮我找出问题所在吗


我之前问了一个关于同一个项目的问题,但措辞糟糕,编辑可能会造成更多的混乱,而不是更少。此外,尽管这个问题可能已经得到了回答,但我还有更多的问题需要解决。可以发现至少有三件事是错误的:

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

将代码段2的第5行更改为

    doubleValue[n] += freq_real[k] * Math.cos(val) + freq_imag[k] * Math.sin(val);
time_real[n] = (byte) (Math.floor(doubleValue[n] / data.length))
并确保将doubleValue初始化为零

第三,您需要添加一个规范化步骤

将代码段2的第7行更改为

    doubleValue[n] += freq_real[k] * Math.cos(val) + freq_imag[k] * Math.sin(val);
time_real[n] = (byte) (Math.floor(doubleValue[n] / data.length))
第四,为了您自己的方便,在截断为整数数据类型之前,使用浮点输入和输出测试此浮点算法,不要假设在整数数据上进行往返时会得到精确的正确答案——浮点错误是非常真实的


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

从数值意义上讲,您不能,因为舍入和/或量化误差几乎总是会在往返过程中产生微小差异或信息损失

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

如果扔掉任何项(复数虚项、频率箱或其他),结果将与原始结果相差很远。例如,如果您的frequency\u domain\u magnitude.length或FrequencUsed.length小于数据长度,则您将丢弃术语(除非您使用稍微不同的算法和/或比例因子)


<>你的IDFT中也有至少1到2个致命的错误,如@ ELSISBEN。

可能的重复,在我看来,第一个问题实际上更清楚,无论哪种方式,如果你对问题的措辞不满意,那么编辑,不要重复。请考虑在DSP.STACKExchange。com上问这些问题!