借助
dsp-collection 库实现 java 离散时间傅里叶变换。 dsp-collection 库里面的 Dft 类主要实现实数信号的傅里叶变换(变换的结果为频域复数信号),也可以进行傅里叶逆变换(变换的结果为时域实数信号)。傅里叶变换:
biz.source_code.dsp.math.Complex[] result = Dft.goertzelSpectrum(data)
傅里叶逆变换:
double[] valueX = Dft.synthesizeFromSpectrum(frequencyX, obb);
对于仿真信号:
x(t)=100sin(10πt)+25sin(30πt)x(t)=100sin(10πt)+25sin(30πt)傅里叶变换
double[] time = new double[150];
double[] valueA = new double[150];
for ( int i = 0; i < 50 * 3; i++ )
{
time[i] = i / 50.0;
valueA[i] = 100 * Math.sin( 2 * Math.PI * 5 * time[i] ) + 25 * Math.sin( 2 * Math.PI * 15 * time[i] );
}
double deltaTime = 1 / 50.0;
Complex[] result = Dft.goertzelSpectrum( valueA );
double deltaFrequency = 0.5 / deltaTime / (result.length - 1);
for ( int i = 0; i < result.length; i++ )
{
System.out.println( "频率:" + String.format( "%.2f", deltaFrequency * i ) + " 幅值:" + String.format( "%.2f", result[i].abs() ) );
}
这里的傅里叶变换是对于一个序列的变换,在这里因为默认是对于实数信号,所以这里不需考虑负频率,不需除以数据长度。重点在于找出频率轴,因为 DFT 得出的是均匀分布的频率,最小值为 0 ,最大值为采样频率的一半,这样我们就可以得到频率序列。频率间隔为
double deltaFrequency = 0.5 / deltaTime / (result.length - 1)
。
运行结果:
频率: 4.67Hz 幅值: 0.00频率: 5.00Hz 幅值: 100.00频率: 5.33Hz 幅值: 0.00...频率: 14.67Hz 幅值: 0.00频率: 15.00Hz 幅值: 25.00频率: 15.33Hz 幅值: 0.00
傅里叶逆变换
double[] time = new double[150];
double[] valueA = new double[150];
for (int i = 0; i < 50 * 3; i++) {
time[i] = i / 50.0;
valueA[i] = 100 * Math.sin(2 * Math.PI * 5 * time[i]) + 25 * Math.sin(2 * Math.PI * 15 * time[i]);
}
double deltaTime = 1 / 50.0;
Complex[] result = Dft.goertzelSpectrum(valueA);
double deltaFrequency = 0.5 / deltaTime / (result.length - 1);
boolean obb = false;
if (valueA.length % 2 == 1) {
obb = true;
} else {
obb = false;
}
double[] valueX = Dft.synthesizeFromSpectrum(result, obb);
for (int i = 0; i < valueX.length; i++) {
System.out.println("No." + i + " 初始:" + String.format("%.2f", valueA[i]) + " 计算得:" + String.format("%.2f", valueX[i]));
}
结果:
No.0 初始: 0.00 计算得:-0.00
No.1 初始: 82.55 计算得: 82.55
No.2 初始: 80.41 计算得: 80.41
No.3 初始: 80.41 计算得: 80.41
No.4 初始: 82.55 计算得: 82.55
...
No.146 初始:-82.55 计算得:-82.55
No.147 初始:-80.41 计算得:-80.41
No.148 初始:-80.41 计算得:-80.41
No.149 初始:-82.55 计算得:-82.55
可以看出,经傅里叶变换,又经过傅里叶逆变换之后的信号是一致的。