简体   繁体   English

R中的快速傅立叶变换。我在做什么错?

[英]Fast Fourier Transform in R. What am I doing wrong?

I am a non-expert in Fourier analysis and quite don't get what R's function fft() does. 我不是傅立叶分析的专家,并且完全不了解R函数fft()的作用。 Even after crossreading a lot I couldnt figure it out. 即使经过大量交叉阅读,我也无法弄清楚。 I built an example. 我建立了一个例子。

require(ggplot2)

freq <- 200  #sample frequency in Hz 
duration <- 3 # length of signal in seconds

#arbitrary sine wave 
x <- seq(-4*pi,4*pi, length.out = freq*duration)
y <- sin(0.25*x) + sin(0.5*x) + sin(x)

which looks like: 看起来像:

在此处输入图片说明

fourier <- fft(y)

#frequency "amounts" and associated frequencies

amo <- Mod(fft(y))

freqvec <- 1:length(amo) 

I ASSUME that fft expects a vector recorded over a timespan of 1 second, so I divide by the timespan 我假设fft期望在1秒的时间跨度内记录一个向量,所以我将其除以时间跨度

freqvec <- freqvec/duration 

#and put this into a data.frame

df <- data.frame(freq = freqvec, ammount = amo)

Now I ASSUMABLY can/have to omit the second half of the data.frame since the frequency "amounts" are only significant to half of the sampling rate due to Nyquist. 现在我可以/必须省略data.frame的后一半,因为由于奈奎斯特,频率“数量”仅占采样率的一半。

df <- df[(1:as.integer(0.5*freq*duration)),]

For plotting I discretize a bit 为了绘图我离散了一点

df.disc <- data.frame(freq = 1:100)
cum.amo <- numeric(100)
for (i in 1:100){
  cum.amo[i] <- sum(df$ammount[c(3*i-2,3*i-1,3*i)])
}
df.disc$ammount <- cum.amo

The plot function for the first 20 frequencies: 前20个频率的绘图函数:

df.disc$freq <- as.factor(df.disc$freq)

ggplot(df.disc[1:20,], aes(x=freq, y=ammount)) + geom_bar(stat = "identity")

The result: 结果:

在此处输入图片说明

Is this really a correct spectrogram of the above function? 这真的是上述功能的正确频谱图吗? Are my two assumptions correct? 我的两个假设正确吗? Where is my mistake? 我的错误在哪里? If there is no, what does this plot now tell me? 如果没有,现在该图告诉我什么?

EDIT: Here is a picture without discretization: 编辑:这是没有离散化的图片:

在此处输入图片说明

THANKS to all of you, 感谢大家,

Micha. 米莎。

Okay, okay. 好吧好吧。 Due to the generally inferior nature of my mistake the solution is quite trivial. 由于我的错误通常具有次等性质,因此解决方案非常简单。 I wrote freq = 200 and duration = 3. But the real duration is from -4pi to 4 pi, hence 8pi resulting in a "real" sample frequency of 1/ ((8*pi)/600) = 23.87324 which does not equal 200. Replacing the respective lines in the example code by 我写了freq = 200且持续时间=3。但是实际持续时间是从-4pi到4 pi,因此8pi导致“实际”采样频率为1 /(((8 * pi)/ 600)= 23.87324),这不等于200.将示例代码中的相应行替换为

freq <- 200  #sample frequency in Hz
duration <- 6 # length of signal in seconds
x <- seq(0,duration, length.out = freq*duration) 
y <- sin(4*pi*x) + sin(6*pi*x) + sin(8*pi*x)

(with a more illustrative function) yields the correct frequencies as demonstrated by the following plot (restricted to the important part of the frequency domain): (具有更具说明性的功能)可以产生正确的频率,如下图所示(限于频域的重要部分):

在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM