a
数组中的大部分返回值都很复杂,并以其固有的频域顺序返回。然而,有一些特殊的情况下,它们是:
- 的为0Hz频率成分是纯实数(奇数和偶数
n
)
- 奈奎斯特频率分量这也是奇
n
纯实。
笔者则选择把所有正常的情况下,在指数2起,并保留一对值的a[0]
和a[1]
来处理这些特殊情况。 a[0]
是0Hz频率分量。对于a[1]
它有点棘手。它始终是最高频率分量的一部分,但如果n
是偶数或奇数,该如何处理。即使是n
,那么最后的频率分量也是纯粹的实数,因此可以直接存储在a[1]
中。对于奇数n
,最后一个频率分量不是纯粹的实数,所以我们仍然需要一对数组元素来存储结果。在这种情况下,由于对从索引2开始,并且该数组具有奇数大小,因此最后一对不适合,因此作者使用a[1]
作为缺失的元素。
也许最简单的方法来看这是几个例子。所以,这里是一个偶数长度n=8
例如:
Bin Complex result Comments
=== ============== =============
0 (a[0],0) Purely real
1 (a[2],a[3])
2 (a[4],a[5])
3 (a[6],a[7])
4 (a[1],0) Purely real
5 (a[6],-a[7]) Symmetric with bin 3
6 (a[4],-a[5]) Symmetric with bin 2
7 (a[2],-a[3]) Symmetric with bin 1
这里是奇数长度n=7
例如:
Bin Complex result Comments
=== ============== =============
0 (a[0],0) Purely real
1 (a[2],a[3])
2 (a[4],a[5])
3 (a[6],a[1])
4 (a[6],-a[1]) Symmetric with bin 3
5 (a[4],-a[5]) Symmetric with bin 2
6 (a[2],-a[3]) Symmetric with bin 1
最后相应的代码计算幅值:
double[] m = new double[n/2 + 1];
boolean isOdd = ((n % 2) == 1);
if (isOdd) {
// odd case
m[0] = abs(a[0]);
for (int i = 1; i < (n-1)/2; i++) {
m[i] = sqrt(a[2*i]*a[2*i] + a[2*i+1]*a[2*i+1]);
}
m[(n-1)/2] = sqrt(a[n-1]*a[n-1] + a[1]*a[1]);
} else {
// even case
m[0] = abs(a[0]);
for (int i = 1; i < n/2; i++) {
m[i] = sqrt(a[2*i]*a[2*i] + a[2*i+1]*a[2*i+1]);
}
m[n/2] = abs(a[1]);
}
谢谢您。那么m的长度是n/2 + 1? 'abs(a [0])'意味着'| a [0] |'?我想知道,我获得了很高的幅度值..从使用来自公共数学库的FFT生成的FFT更大。 – Jan
您的if条件不起作用。我依靠你的意见..但目前还不清楚..你能否编辑你的答案,以便清楚? – Jan
这是正确的长度(假设奇数'n'通常截断除法)。至于生成的幅度有多大,[normalization](http://commons.apache.org/proper/commons-math/javadocs/api-3.4/org/apache/commons/math3/transform/DftNormalization.html)你用commons-Math吗? – SleuthEye