jTransforms DoubleFFT_1D 中的功率谱密度

14

我正在使用Jtransforms Java库对给定数据集进行分析。

以下是数据示例:

980,988,1160,1080,928,1068,1156,1152,1176,1264

我正在使用jTransforms中的DoubleFFT_1D函数。数据输出如下:

10952, -152, 80.052, 379.936, -307.691, 12.734, -224.052, 427.607, -48.308, 81.472

我在理解输出结果方面遇到了困难。 我知道输出数组中的第一个元素是10个输入值的总和(10952)。但我不理解输出数组的其他元素。最终,我想在图表上绘制输入数据的功率谱密度,并查找0到.5 Hz之间的数量。

jTransform函数的文档说明(其中a是数据集):

public void realForward(double[] a) 计算实数数据的一维正向DFT,将结果保留在a中。 输出数据的物理布局如下所示:

如果n为偶数,则

a[2*k] = Re[k], 0 <= k < n / 2
a[2*k+1] = Im[k], 0 < k < n / 2
a[1] = Re[n/2]

如果n是奇数,则

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]

该方法仅计算实变换的一半元素。另一半满足对称条件。如果您想要完整的实正向变换,请使用realForwardFull方法。要获取原始数据,请对此方法的输出使用realInverse方法。

参数:a - 要进行变换的数据

现在使用上述方法:(由于我的数据数组长度为10,因此使用“n是偶数”的方法)

Re[0] = 10952
Re[1] = 80.052
Re[2] = -307.691
Re[3] = -224.052
Re[4] = -48.308
Re[5] = 12.734

Im[0] = -152
Im[1] = 379.936
Im[2] = 12.734
Im[3] = 427.607
Im[4] = 81.472

那么有一些问题: 这个输出结果看起来正确吗?对我来说,Re [0] 不应该是 10952,这是原始数组中所有元素的总和。

似乎输出结果应该稍作更正:(我错了吗?)

Re[0] = 80.052
Re[1] = -307.691
Re[2] = -224.052
Re[3] = -48.308
Re[4] = -152

Im[0] = 379.936
Im[1] = 12.734
Im[2] = 427.607
Im[3] = 81.472

现在使用论坛中发布的以下方法:

为了获取bin k的幅度,您需要计算sqrt(re * re + im * im),其中re,im是bin k的FFT输出中的实部和虚部。

对于您的特定FFT,re[k] = a[2*k] and im[k] = a[2*k+1]。因此,要计算功率谱:

for k in 0 to N/2 - 1
{
    spectrum[k] = sqrt(sqr(a[2*k]) + sqr(a[2*k+1]))
}
因此:
spectrum[0] = 388.278
spectrum[1] = 307.955
spectrum[2] = 482.75
spectrum[3] = 94.717

有一些问题。这些数据看起来正确吗?我走在正确的轨道上吗? 那么这个频谱数据会绘制出类似这样的东西:

388.278 at .125 Hz
307.955 at .25 Hz
482.75 at .375 Hz
94.717 at .5 Hz

我离谱了吗?我的目标是从0到.5Hz产生功率谱密度条形图。


这不是你昨天的问题的重复吗:http://stackoverflow.com/questions/4996747/interpreting-jtransform-fft-results? - Paul R
登录后,我无法操作旧线程。我的所有旧问题(包括引用的问题)都没有显示在我的账户中。所以我将其移动并添加了一些跟进数据。抱歉。我不想增加混乱。只是在从访客转为已登录用户时遇到了麻烦。非常感谢您的帮助。有了您的帮助,我感觉自己正在取得进展。 - Damon
1
请向管理员请求帮助解决您的账户问题。另外,您可以将Paul R的回答标记为已采纳并点赞,看起来对您很有帮助。 - Kev
我很想给这个答案点赞,但是在原帖中我无法这样做。这也是我将其移动的原因之一。我不确定该向谁寻求修复,但既然我已经登录,我认为这不应该再成为问题。Paul R的回答确实有所帮助。我很想给他信用,但我无法弄清楚如何在原帖中进行。再次道歉。 - Damon
1
合并了账户并合并了问题。现在应该一切正常了。(将来,您可以标记为需要管理员注意以解决此类问题。本次有其他人标记了它。) - Michael Myers
3个回答

9

我认为你需要按照以下方式解释输出数据:

10952       Re[0] = sum of all inputs = DC component
 -152       Re[5] - see note about a[1] being special - there is no Im[0]
   80.052   Re[1]
  379.936   Im[1]
 -307.691   Re[2]
   12.734   Im[2]
 -224.052   Re[3]
  427.607   Im[3]
  -48.308   Re[4]
   81.472   Im[4]

因此,它们的大小为:
spectrum[0] = 10952
spectrum[1] = sqrt(80.052^2 + 379.936^2) = 388.278
spectrum[2] = sqrt(-307.691^2 + 12.734^2) = 307.427
spectrum[3] = sqrt(-224.052^2 + 427.607^2) = 482.749
spectrum[4] = sqrt(-48.308^2 + 81.472^2) = 94.717

[很抱歉我现在发了两个不同的回答 - 我认为当我正在回答新问题时,两个相关的问题被合并了]


谢谢Paul。这大大地澄清了问题!请原谅我的无知,但是频谱结果[0-4]如何与0到.5 Hz之间的频率相关? - Damon
对于上面的例子,我认为Fs = 1Hz(这样数学计算就正确了)。 - Damon
@Damon:抱歉,是的,我指的是“Fs = 1 Hz”。我会重新发布一个更正过的评论。 - Paul R
@Damon:FFT 不知道也不关心采样率。你在问题中没有提到采样率 - 让我们称其为 Fs。第 k 个频率的中心频率是 k * Fs / N,其中 N 是点数。例如,如果 Fs=1.0 Hz,N=10,则 bin 0 是 DC(0 Hz),bin 1 是 0.1 Hz,bin 2 是 0.2 Hz,bin 3 是 0.3 Hz... - Paul R

1

变换中的每个条目表示样本中频率(复杂)幅度。

给定频率上的功率密度只是该频率处变换的复幅度大小。复数的幅度是从其分量计算出来的,您应该不会遇到问题。

每列表示递增频率的振幅,从0开始(第一个条目),然后是2 Pi/T(其中T是样本长度),直到最后一个样本2 * Pi * N / T(其中N是样本数)

还有其他约定,其中变换返回为-Pi * N / T频率到Pi * N / T,而0频率分量位于数组的中间

希望这可以帮助到您


0
要获取bin k的量级,您需要计算sqrt(re * re + im * im),其中re、im是FFT输出中bin k对应的实部和虚部。
对于您特定的FFT:re[k] = a[2*k]im[k] = a[2*k+1]。因此,要计算功率谱:
for k in 0 to N/2 - 1
  spectrum[k] = sqrt(sqr(a[2*k]) + sqr(a[2*k+1]))

感谢您的帮助。这是我迄今为止收到的最好的信息。我已经使用您的频谱方程式来计算以下数据集的值:<br> 1068、1116、1140、1144、1160、1136、1100、1080、1200、1212、1092、952、1060、1068。 - Damon
1
@Damon,如果这对你有帮助,请点击答案右侧的勾选标志,使其变为绿色。 - lurscher

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接