【问题标题】:FFT algorithm usageFFT算法使用
【发布时间】:2015-08-13 02:04:49
【问题描述】:

我试图了解这种 FFT 算法的工作原理。 http://rosettacode.org/wiki/Fast_Fourier_transform#Scala

def _fft(cSeq: Seq[Complex], direction: Complex, scalar: Int): Seq[Complex] = {
  if (cSeq.length == 1) {
    return cSeq
  }
  val n = cSeq.length
  assume(n % 2 == 0, "The Cooley-Tukey FFT algorithm only works when the length of the input is even.")

  val evenOddPairs = cSeq.grouped(2).toSeq
  val evens = _fft(evenOddPairs map (_(0)), direction, scalar)
  val odds  = _fft(evenOddPairs map (_(1)), direction, scalar)

  def leftRightPair(k: Int): Pair[Complex, Complex] = {
    val base = evens(k) / scalar
    val offset = exp(direction * (Pi * k / n)) * odds(k) / scalar
    (base + offset, base - offset)
  }

  val pairs = (0 until n/2) map leftRightPair
  val left  = pairs map (_._1)
  val right = pairs map (_._2)
  left ++ right
}

def  fft(cSeq: Seq[Complex]): Seq[Complex] = _fft(cSeq, Complex(0,  2), 1)
def rfft(cSeq: Seq[Complex]): Seq[Complex] = _fft(cSeq, Complex(0, -2), 2)

val data = Seq(Complex(1,0), Complex(1,0), Complex(1,0), Complex(1,0), 
               Complex(0,0), Complex(0,2), Complex(0,0), Complex(0,0))

println(fft(data))

结果

Vector(4.000 + 2.000i, 2.414 + 1.000i, -2.000, 2.414 + 1.828i, 2.000i, -0.414 + 1.000i, 2.000, -0.414 - 3.828i)

输入是否采用复数对的左右声道数据?它是否返回频率强度和相位偏移?时/频域在索引中?

【问题讨论】:

标签: scala fft


【解决方案1】:

discrete Fourier transform 没有左右声道的概念。它将时域信号作为复值序列,并将其转换为该信号的频域(频谱)表示。大多数时域信号都是实数值的,所以虚部为零。

上面的代码是一个经典的递归实现,它以bit reversed 顺序将输出作为复值对返回。您需要将输出转换为polar 形式并将输出数组重新排序为非位反转顺序以使其对您有用。这段代码虽然优雅且具有教育意义,但速度很慢,因此我建议您寻找适合您需要的现有 Java FFT 库。

傅立叶变换很优雅,但值得尝试了解它们的工作原理,因为它们具有微妙的副作用,可能会真正毁掉你的一天。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-28
    • 2020-07-06
    • 2013-04-11
    相关资源
    最近更新 更多