Skip to content

Instantly share code, notes, and snippets.

@awekuit
Last active December 28, 2015 11:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save awekuit/7496127 to your computer and use it in GitHub Desktop.
Save awekuit/7496127 to your computer and use it in GitHub Desktop.
use jtransforms & breeze FFT
import breeze.linalg.DenseVector
import breeze.math._
import edu.emory.mathcs.jtransforms.fft.{DoubleFFT_1D => jFFT}
def show(v1 : Array[_], v2 : Array[_], v3 : Array[_]) {
println("v1: " + v1.mkString(", "))
println("v2: " + v2.mkString(", "))
println("v3: " + v3.mkString(", "))
}
// data
val data1 = Array[Double](3, 1, 4, 1, 5, 9, 2, 6)
val data2 = data1.clone
val data3 = data1.clone
show(data1, data2, data3)
// FFT
val fftRes1 = breeze.signal.fft(DenseVector(data1)) // use Breeze
val fftRes2 = { // use jFFT
val temp = data2 ++ Array.fill(data2.size)(0.0) // add dummy
val fft = new jFFT(data2.size) // attention!! data2.size == temp.size / 2
fft.realForwardFull(temp) // Side Effect!
temp
}
val fftRes3 = {
// fftRes2では fft.realForwardFull を用いたが
// そこをただの fft.realForward にすると、
// FFTの仕組み上の性質(配列の2番目が無意味である)を利用して
// FFT結果の折り返し(ナイキスト周波数)地点の値を
// その位置(配列の2番め)で返す仕様になっている。
// ここではその仕様を手動で直して確認している
val fft = new jFFT(data3.size)
fft.realForward(data3)
val temp = data3(1)
val tail = data3.drop(2)
Array(data3.head, 0) ++ tail ++ Array(temp, 0) ++ tail.reverse
}
show(fftRes1.activeIterator.map(_._2).toArray, fftRes2, fftRes3)
// Power Spectral
val minPower = 1e-20 * data1.size * data1.size
val toPower : (Double, Double) => Double = (re, im) => Math.log10((re * re + im * im) max minPower)
val power1 = fftRes1.activeIterator.map{ case (_, Complex(re, im)) => toPower(re, im)}.toArray
val power2 = fftRes2.grouped(2).map{case Array(re, im) => toPower(re, im)}.toArray
val power3 = fftRes3.grouped(2).map{case Array(re, im) => toPower(re, im)}.toArray
show(power1, power2, power3)
// IFFT
val inverseFull = (powerSpectral : Array[Double]) => {
val temp = powerSpectral ++ Array.fill(powerSpectral.size)(0.0) // add dummy
val fft = new jFFT(powerSpectral.size)
fft.realInverseFull(temp, true)
temp.grouped(2).map(_.head).toArray
}
val result1 = breeze.signal.ifft(DenseVector(power1)).activeIterator.map(_._2.real).toArray
val result2 = inverseFull(power2)
val result3 = inverseFull(power3) // ここでFullではない realInverse を使っても目的のものは得られない...はず。
// realInverse は、realForwardの上述の通りの独自仕様出力から復元する仕様になっているはず。
// show cepstrum
show(result1, result2, result3)
/*
results::
v1: 3.0, 1.0, 4.0, 1.0, 5.0, 9.0, 2.0, 6.0
v2: 3.0, 1.0, 4.0, 1.0, 5.0, 9.0, 2.0, 6.0
v3: 3.0, 1.0, 4.0, 1.0, 5.0, 9.0, 2.0, 6.0
v1: 31.0 + 0.0i, -4.121320343559643 + 7.192388155425118i, 2.0 + -3.0i, 0.12132034355964283 + 11.192388155425117i, -3.0 + 0.0i, 0.12132034355964283 + -11.192388155425117i, 2.0 + 3.0i, -4.121320343559643 + -7.192388155425118i
v2: 31.0, 0.0, -4.121320343559643, 7.192388155425118, 2.0, -3.0, 0.12132034355964283, 11.192388155425117, -3.0, 0.0, 0.12132034355964283, -11.192388155425117, 2.0, 3.0, -4.121320343559643, -7.192388155425118
v3: 31.0, 0.0, -4.121320343559643, 7.192388155425118, 2.0, -3.0, 0.12132034355964283, 11.192388155425117, -3.0, 0.0, 11.192388155425117, 0.12132034355964283, -3.0, 2.0, 7.192388155425118, -4.121320343559643
v1: 2.9827233876685453, 1.8370561566896957, 1.1139433523068367, 2.0978965511281626, 0.9542425094393249, 2.0978965511281626, 1.1139433523068367, 1.8370561566896957
v2: 2.9827233876685453, 1.8370561566896957, 1.1139433523068367, 2.0978965511281626, 0.9542425094393249, 2.0978965511281626, 1.1139433523068367, 1.8370561566896957
v3: 2.9827233876685453, 1.8370561566896957, 1.1139433523068367, 2.0978965511281626, 0.9542425094393249, 2.0978965511281626, 1.1139433523068367, 1.8370561566896957
v1: 1.7543447521696576, 0.20744960684994912, 0.21363489906177457, 0.29967061270735607, -0.2131316017392717, 0.29967061270735607, 0.21363489906177457, 0.20744960684994912
v2: 1.7543447521696576, 0.20744960684994912, 0.21363489906177457, 0.29967061270735607, -0.2131316017392717, 0.29967061270735607, 0.21363489906177457, 0.20744960684994912
v3: 1.7543447521696576, 0.20744960684994912, 0.21363489906177457, 0.29967061270735607, -0.2131316017392717, 0.29967061270735607, 0.21363489906177457, 0.20744960684994912
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment