在R中执行时间序列的fft

时间:2018-03-26 21:49:37

标签: r fft

我想使用FFT将波浪拟合到时间序列。 目标是绘制具有不同谐波的图,并使用它来预测n个数据点。

我使用的代码基于answer

中的@catastrophic-failure
 nff = function(y = NULL, n = NULL, up = 10L, plot = TRUE, add = FALSE, main = NULL, ...){
  #The direct transformation
  #The first frequency is DC, the rest are duplicated
  dff = fft(y)
  #The time
  t = seq(from = 1, to = length(y))
  #Upsampled time
  nt = seq(from = 1, to = length(y)+1-1/up, by = 1/up)
  #New spectrum
  ndff = array(data = 0, dim = c(length(nt), 1L))
  ndff[1] = dff[1] #Always, it's the DC component
  if(n != 0){
    ndff[2:(n+1)] = dff[2:(n+1)] #The positive frequencies always come first
    #The negative ones are trickier
    ndff[length(ndff):(length(ndff) - n + 1)] = dff[length(y):(length(y) - n + 1)]
  }
  #The inverses
  indff = fft(ndff/as.integer(length(y)), inverse = TRUE)
  idff = fft(dff/as.integer(length(y)), inverse = TRUE)
  if(plot){
    if(!add){
      plot(x = t, y = y, xlab = "Time", ylab = "Data",
           main = ifelse(is.null(main), paste(n, "harmonics"), main), type="l", col="green")
      lines(y = Mod(idff), x = t, col = "red")
    }
    lines(y = Mod(indff), x = nt, ...)
  }
  ret = data.frame(time = nt, y = Mod(indff))
  return(ret)
}

对我来说问题是,因为我的数据集中也有负值,所以我无法弄清楚为什么包含正值。

这是原始data

的图

random.x plot

与fft之后的情节相比

just the positive values

如何调整代码,使谐波还包括缺失的负值,以及如何使用它来计算(预测)下n个时间点?

1 个答案:

答案 0 :(得分:1)

当您尝试使用Mod(idff)Mod(indff)在以下行中绘制结果时,会出现问题:

...
  lines(y = Mod(idff), x = t, col = "red")
}
lines(y = Mod(indff), x = nt, ...)

Mod将始终返回与复数的大小相对应的正数。

由于您在具有厄米对称性(通过构造)的序列上计算逆FFT,因此您应该期望得到实值结果。然而,在实践中,由于舍入误差,可能存在小的虚部。通过Re(idff)Re(indff)仅提取实部可以安全地忽略这些内容,如下所示:

...
  lines(y = Re(idff), x = t, col = "red")
}
lines(y = Re(indff), x = nt, ...)

请注意,通常首先确认虚部与实部相比确实非常小,因为相反的情况表明频域值不具有预期的厄米特对称性。 / p>