JTransforms FFT:偶数和奇数情况的区别
JTransforms FFT: Difference between even and odd-case
我对任意长度的数组执行 FFT。
API可以引用如下:
realForward
public void realForward(double[] a)
Computes 1D forward DFT of real data leaving the result in a
.
The physical layout of the output data is as follows:
if n
is even then
a[2*k] = Re[k], 0<=k<n/2
a[2*k+1] = Im[k], 0<k<n/2
a[1] = Re[n/2]
if n
is odd then
a[2*k] = Re[k], 0<=k<(n+1)/2
a[2*k+1] = Im[k], 0<k<(n-1)/2
a[1] = Im[(n-1)/2]
在阅读了几个已经回答过的问题后,我仍然无法定义循环来获取幅度值 m_k=sqrt(RE_k²+IM_k²)
。
每种情况下 index=1
处的内容是什么? (或者作者实际上是指 index=0
)?
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]);
}
我对任意长度的数组执行 FFT。 API可以引用如下:
realForward
public void realForward(double[] a)
Computes 1D forward DFT of real data leaving the result in
a
. The physical layout of the output data is as follows:if
n
is even thena[2*k] = Re[k], 0<=k<n/2 a[2*k+1] = Im[k], 0<k<n/2 a[1] = Re[n/2]
if
n
is odd thena[2*k] = Re[k], 0<=k<(n+1)/2 a[2*k+1] = Im[k], 0<k<(n-1)/2 a[1] = Im[(n-1)/2]
在阅读了几个已经回答过的问题后,我仍然无法定义循环来获取幅度值 m_k=sqrt(RE_k²+IM_k²)
。
每种情况下 index=1
处的内容是什么? (或者作者实际上是指 index=0
)?
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]);
}