【发布时间】:2015-10-08 10:44:43
【问题描述】:
我使用这种 DFT 实现:
/*
Direct fourier transform
*/
int DFT(int dir,int m,double *x1,double *y1)
{
long i,k;
double arg;
double cosarg,sinarg;
double *x2=NULL,*y2=NULL;
x2 = malloc(m*sizeof(double));
y2 = malloc(m*sizeof(double));
if (x2 == NULL || y2 == NULL)
return(FALSE);
for (i=0;i<m;i++) {
x2[i] = 0;
y2[i] = 0;
arg = - dir * 2.0 * 3.141592654 * (double)i / (double)m;
for (k=0;k<m;k++) {
cosarg = cos(k * arg);
sinarg = sin(k * arg);
x2[i] += (x1[k] * cosarg - y1[k] * sinarg);
y2[i] += (x1[k] * sinarg + y1[k] * cosarg);
}
}
/* Copy the data back */
if (dir == 1) {
for (i=0;i<m;i++) {
x1[i] = x2[i] / (double)m;
y1[i] = y2[i] / (double)m;
}
} else {
for (i=0;i<m;i++) {
x1[i] = x2[i];
y1[i] = y2[i];
}
}
free(x2);
free(y2);
return(TRUE);
}
这里放的是http://paulbourke.net/miscellaneous/dft/
第一个问题是为什么在应用直接变换后(dir=1)我们应该缩放值?我阅读了一些关于 DFT 实现的想法,但没有找到任何相关信息。
作为输入,我使用 1024 采样频率的 cos
#define SAMPLES 2048
#define ZEROES_NUMBER 512
double step = PI_2/(SAMPLES-2*ZEROES_NUMBER);
for(int i=0; i<SAMPLES; i++)
{
/*
* Fill in the beginning and end with zeroes
*/
if(i<ZEROES_NUMBER || i > SAMPLES-ZEROES_NUMBER)
{
samplesReal[i] = 0;
samplesImag[i] = 0;
}
/*
* Generate one period cos with 1024 samples
*/
else
{
samplesReal[i] = cos(step*(double)(i-ZEROES_NUMBER));
samplesImag[i] = 0;
}
}
对于绘图,我删除了我上面询问的缩放比例,因为输出值变得非常小并且无法绘制图形。
如您所见,相位始终为 0,幅度谱反转。为什么?
下面是我的更易读的版本,没有缩放,产生相同的结果:
void DFT_transform(double complex* samples, int num, double complex* res)
{
for(int k=0; k<num; k++)
{
res[k] = 0;
for(int n=0; n<num; n++)
{
double complex Wkn = cos(PI_2*(double)k*(double)n/(double)num) -
I*sin(PI_2*(double)k*(double)n/(double)num);
res[k] += samples[n]*Wkn;
}
}
}
【问题讨论】:
-
@LightnessRacesinOrbit 我的实现使用了用 c++ 编写的复杂库。
-
每个问题一个问题。缩放只是一个约定,并且有不同的约定 - 通常它是正向的 1/N,而反向则没有缩放。要查看您的 DFT 是否正常工作,请从纯正弦波开始,然后查看输出箱的 幅度 (sqrt(re^2 + im^2))。
-
@LongSmith:但你问的是 C 代码,是吗?
-
@LongSmith:幅度是指幅度,即
sqrt(re^2 + im^2)?请注意,输入应具有例如x1 中的正弦波和 y1 中的零 - 不要像问题中的代码那样用零填充开头和结尾。您可以根据已知良好的 DFT 或 FFT 实施检查结果,例如Octave(免费的 MATLAB 克隆)。