Last active
December 28, 2015 11:49
-
-
Save awekuit/7496127 to your computer and use it in GitHub Desktop.
use jtransforms & breeze FFT
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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