我在 Octave 中实现 DFT。这是我的代码:
function [real_comp, imag_comp] = mydft (samples)
N = columns(samples);
for m = 1:N
real_accum = 0;
imag_accum = 0;
for n = 1:N
real_factor = cos((2 * pi * (n-1) * (m-1)) / N);
# imag_factor = -I * sin((2 * pi * (n-1) * (m-1)) / N);
imag_factor = sin((2 * pi * (n-1) * (m-1)) / N);
real_accum += real_factor * samples(n);
imag_accum += imag_factor * samples(n);
endfor
real_comp(m) = real_acuum;
imag_comp(m) = imag_accum;
endfor
endfunction
我的目标是计算每个 DFT bin 的大小并绘制它。我传入了一个纯实样本列表,并将实部和虚部存储在不同的变量中。这是我正在使用的样本向量:
samples = [0.3535, 0.3535, 0.6464, 1.0607, 0.3535, -1.0607, -1.3535, -0.3535]
样品经过精心挑选,以防止在fs = 8KHz
. DFT 幅度的图表正是我所期望的。这没什么不好。但我没有得到的是,我的 8 点 DFT 中的一些分量应该为零,但并不完全为零,而是一个非常小的接近于零的值。fft()
另一方面,内置函数已将我期望的组件归零。
例如,我使用以下代码打印由我的 DFT 和 octave 的 FFt 生成的输出向量的元素:
fft_out = fft(samples);
[real, imag] = mydft(samples);
dft_out = real + (-I * imag);
for i=1:columns(samples)
disp(fft_out(i));
disp(dft_out(i));
printf("\n");
endfor
点对点比较如下表所示:
bin_index | fft_out | dft_out |
---|---|---|
1 | -1.0000e-04 | -1.0000e-04 |
2 | 0.00000 - 3.99988i | 4.7184e-16 - 3.9999e+00i |
3 | 1.4141 + 1.4144i | 1.4141 + 1.4144i |
4 | 0.0000e+00 - 8.0820e-05i | 1.3878e-16 - 8.0820e-05i |
5 | -1.0000e-04 | -1.0000e-04 - 1.4350e-16i |
6 | 0.0000e+00 + 8.0820e-05i | 2.3037e-15 + 8.0820e-05i |
7 | 1.4141 - 1.4144i | 1.4141 - 1.4144i |
8 | 0.00000 + 3.99988i | -2.0817e-15 + 3.9999e+00i |
现在,我不会太在意微小的差异,但如果我计算 和 的相位角fft_out
,dft_out
disp(arg(fft_out))
disp(arg(dft_out))
在某些情况下,我会翻转标志:
fft_out: 3.14159 -1.57080 0.78550 -1.57080 3.14159 1.57080 -0.78550 1.57080
dft_out:-3.14159 -1.57080 0.78550 -1.57080 -3.14159 1.57080 -0.78550 1.57080
那么,我的 DFT 实现有问题吗?它只是一个舍入或精度问题吗?