FFT 是一种如雷贯耳的快速算法,应用范围及其广泛,就不多说了。不过 DFT 很多人并不是很清楚,只知道 DFT 比 FFT 效率低,速度慢。实际上,在很多应用场合下,DFT 反而会比 FFT 效率高很多。
首先,回顾一下复数的特性:
V = R + jI = M*(R/M + j I/M) = M*(cos(A) + j sin(A)) = M*exp(j A) (1)
wher R is the real and I is the image, M = sqrt(R*R + I*I) and A=arctan2(R, I) is the angle.
DFT/FFT
首要的任务是确定系统的基频(
Fundamental Frequency),
这样就能确定系统一个周期的采样点数。基频在同一个系统中可根据需要而采用不同的值。现在假设系统的采样时间为
Ts,
周期采样点数
N (
对于
FFT,
一般要求
N = 2*M = 2^L, DFT
则无此要求),
则第
H
次谐波的
DFT
的计算公式可以从基本的
Fourier
积分公式中得出:
V(k) = sum (x(k - n) * exp( j 2* n *PI * H /N) *2/N) (2)
这里,
n = 0 to N-1, sum
是
N
项之和
,
也就是一个周波
(cycle)
的数据乘积之和
。
累加一般可以化成迭代形式,公式
(2)
的迭代形式:
V(k) = V(k-1) + (x(k) - x(k-N)) * exp(j 2*k*PI * H/N) * 2/N
(3)
展开形式:
V_R(k) = V_R(k-1) + (x(k) - x(k-N)) * cos(2*k*PI * H/N) * 2/N
V_I(k) = V_I(k-1) + (x(k) - x(k-N)) * sin(2*k*PI * H/N) * 2/N
(4)
通过公式
(
2
)可以得出
:
H = 0, DC offset: V(k) = (x(k) + x(k-1) + … + x(k-N-1) ) * 2/N
H = 1,
基波:
V(k) = (x(k-1) * exp(j 2 * PI /N) + … + x(k-N-1) * exp(j 2* (N-1)* PI/N) * 2/N
….
H = N/2: (
省略
)
从上面的公式可以看出,如果要计算所有的谐波,必须要计算
exp(j 2*n * PI *H /N) = cos(2*n*PI*H/N) + j sin(2*n*PI*H/N) (5)
where n = 0 to N-1
,
H = 0 to N/2
公式(
5
)有一定的规律,因为
cos, sin
是周期性的,也就是说总共
2* N* N/2 (
不算
DC)
个系数中有大量的重复
,
最终都可以归结成
2* N
个系数:
exp(j 2*n * PI * /N) = cos(2*n*PI*/N) + j sin(2*n*PI*/N) (6)
where n = 0 to N-1
FFT
通过巧妙的安排,仅使用
(6)
中
2* N
个系数
(
考虑到
cos(2PI*n/N) = sin(2PI*(n+N/4)/N) ,
可进一步减少到
N)
,
可以排除大量的冗余计算,从而提高速度,有人做过测算,当
N
在
8
以上,
DFT
开始超过
FFT
,
N/2+1
次
DFT
计算量随
N
呈指数形式上升
,
而
FFT
仅呈线性上升。关于
FFT
的蝶形计算,到处都是,这里就不说了。
现在来看看
FFT
的结果,把
N = 2M = 2^L
个数据通过
FFT
或
N/2+1
次
DFT
分解后得到
N/2+1
个复数:
F = [DC, V(1), V(2), …., V(M) ]
序列
F
中的每一个
V
可以用公式
(
1
)求出幅度和相位,也就是说,得到了频谱
,
而这个频谱可由
FFT
算法一次得到,而
DFT
分别做
N/2 +1
次。
如果我们的应用不是得到全部的频谱,比如音响的图示均衡器,仅仅需要某几个频点的幅值,又或者对于一个电力系统,仅关心
50Hz
基波
, 2, 3, 5
次谐波,这时候
FFT
中的
10
次或者
20
次谐波就显得多余了。那么,我们可以做几次
DFT,
例如
4
次,求得几个关键的谐波,这时的运算量反而少于
FFT.
更重要的是对于实时采样系统,使用迭代的
DFT
公式
(3),
可以在定时采样后立刻迭代计算几个关键的谐波,分散计算强度,让
DFT
的运算量更低。
另一个重要的概念是
DFT/FFT
的
基频(
Fundamental Frequency),
假设采样频率为
fs,
采样点数为
N,
那么
基频
:
f0 = fs / N
举个例子,电力电压采样频率为
800 Hz,
如果选用
N = 16,
那么基频就是
50Hz,
意味着经过
FFT/DFT
后,复数
V(1)
就是
50Hz
电压信号的矢量。现在看另一种实际应用,发电机定子接地保护中的
20 Hz
谐波注入
(Low Frequency Signal Injection),
当
20 Hz
信号被注入到零线
(Neutral),
如果依旧使用
50
基频
,
那么计算出的
50Hz
电压以及
150Hz
的三次谐波会受到
20Hz
信号的干扰,因为
50
基频无法排除
20 Hz
信号。这时我们可以使用
10 Hz
基频
,
也就是同样的
800Hz
采样频率
,
但
N = 5*16 = 80,
通过
3
次
DFT
可以得出
2
次谐波
(20Hz) , 5
次谐波
(50Hz)
以及
15
次谐波
(150Hz)
的正确
幅值
。