FFT算法使用
FFT algorithm usage
我想了解这个 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)
输入是否采用复数对的左右声道数据?是否 returns 频率强度和相位偏移? Time/frequency 域在索引中?
discrete Fourier transform没有左右声道的概念。它将时域信号作为复值序列并将其转换为该信号的频域(频谱)表示。大多数时域信号都是实值,因此虚部为零。
上面的代码是一个经典的递归实现,returns 以 bit reversed order as a complex valued pair. You need to convert the output to polar 形式输出并将输出数组重新排序为非位反转顺序,以使其对您有用。这段代码虽然优雅且具有教育意义,但速度很慢,因此我建议您寻找适合您需要的现有 Java FFT 库。
傅里叶变换很优雅,但值得尝试了解它们的工作原理,因为它们有微妙的副作用,可能会毁了你的一天。
我想了解这个 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)
输入是否采用复数对的左右声道数据?是否 returns 频率强度和相位偏移? Time/frequency 域在索引中?
discrete Fourier transform没有左右声道的概念。它将时域信号作为复值序列并将其转换为该信号的频域(频谱)表示。大多数时域信号都是实值,因此虚部为零。
上面的代码是一个经典的递归实现,returns 以 bit reversed order as a complex valued pair. You need to convert the output to polar 形式输出并将输出数组重新排序为非位反转顺序,以使其对您有用。这段代码虽然优雅且具有教育意义,但速度很慢,因此我建议您寻找适合您需要的现有 Java FFT 库。
傅里叶变换很优雅,但值得尝试了解它们的工作原理,因为它们有微妙的副作用,可能会毁了你的一天。