你知道 DFT 中的这种现象吗?

信息处理 自由度
2022-02-10 15:55:41

请让我问你关于 DFT 中的一个现象。下面的 DFT 程序在低采样率下输出出色的结果,但在高采样率下非常糟糕。

具体来说:对于采样率 50 个样本/秒,分段 1000 个样本,现有频率 36.7634 Hz,从 35.2364 Hz 到 40.7896 除以 40 的网格,输出对应于测试频率 36.7635 的最大幅度平方 1.22629e+15。

但是对于 50,000 个样本/秒的采样率,同样分割 1000 个样本,并且现有频率和网格相同,输出对应于测试频率 38.2907 Hz 的最大幅度平方 8.46881e+14。错误为 5 位有效数字。

你知道这种现象吗?如果是,请向我解释一下。

// Grid is created by variables lowTestFreq and highTestFreq
// both of double type, and integer type M.

#include <iostream>
#include "math.h"

int main()
{  
//Unchanged variables.
constexpr double pi = 3.141592653589793; //pure number.
int n = 0; // sample.
double xn = 0; //pure number.
double Re = 0; //pure number.
double Im = 0; //pure number.
double xn_cos = 0; //pure number.
double xn_sin = 0; //pure number.
double PowerSpectrum =0; //pure number. Name given by my dear dsp Teacher Mr. Lyons.

//Sampling frequency and samples of segment.
int samplFreq = 50000; // sample/second.
int N = 1000; //sample.

// 1st existing sinusoidal.
double ampl_1 = 70000; //pure number.
double existFreq_1 = 36.7634; // Hz.
double phase_1 = 0.67 * pi; // rad.
double unitAngle_1 = (existFreq_1 / samplFreq) * (2 * pi); // rad/sample.

// 2nd existing sinusoidal.
double ampl_2 = 60000; // pure number.
double existFreq_2 = 4505.75; // Hz.
double phase_2 = -0.37 * pi; // rad.
double unitAngle_2 = (existFreq_2 / samplFreq) * (2 * pi); // rad/sample.

// Testing grid.
double testFreq = 0; // Hz.
double testUnitAngle = 0; // rad/sample.
double testAngle = 0; // rad.
double lowTestFreq = 35.2364; //Hz.
double highTestFreq = 40.7896; //Hz.
int M = 40; // pure number.
int m = 0; // pure number.
double testFreqStep = (highTestFreq - lowTestFreq) / M; // Hz.

for (m = 0; m <= M; ++m)
{
testFreq = lowTestFreq + m * testFreqStep; // Hz.
testUnitAngle = (testFreq / samplFreq) * (2 * pi); // rad/sample.

Re = 0; Im = 0;

for (n = 1; n <= N; ++n)
{
xn = ampl_1 * sin(n * unitAngle_1 + phase_1)
   + ampl_2 * sin(n * unitAngle_2 + phase_2);

testAngle = n * testUnitAngle;
xn_cos = xn *  cos(testAngle);
xn_sin = xn * -sin(testAngle);

Re += xn_cos;
Im += xn_sin;
}  
 std::cout << "Test Freq " << testFreq; // Hz.
 PowerSpectrum = Re * Re + Im * Im; //pure number.       
 std::cout << " MagnSquared " << PowerSpectrum << std::endl;
}       
return 0;
}
4个回答

如果您采样 50 个样本/秒,则您的奈奎斯特频率仅为 25Hz,因此您的测试信号存在混叠。如果您的采样率小于信号中最高频率的两倍,您应该会得到不同的结果。

您以 50000 个样本/秒的速度采集 1000 个样本。那是20ms的采样周期。对于 36.7634Hz 的频率(其周期或多或少为 27ms)。所以你只对部分时期进行抽样并期望有用的统计数据?

请注意,您的慢采样率或多或少的采样点随机分布在不同的阶段。它并不是真正随机的,但只要您的采样间隔与信号的周期性不太密切相关,至少您可以获得不同相位的合理均匀覆盖。

所有这些都与 DFT 无关,仅与您实际采样的内容有关。基本上它是工作中的垃圾进/垃圾出原则。

如果您遇到精度问题,您应该做的第一件事是将所有浮点数更改为双精度数。如果这不能解决它,我会仔细看看你的代码。

例如,1e14 范围内的运行数字肯定会导致浮点精度损失。它几乎不适合双人床。

赛德

先生们,

请让我对您的所有帮助表示衷心的感谢。我的回答是,与段对应的时间间隔越大,准确度就越高。原因很明显:段中基频的周期越多,精度越高。

关于问候和友谊,Georges Theodosiou