LoginSignup
2
0

More than 5 years have passed since last update.

FFT on Groovy

Last updated at Posted at 2016-12-22

すいませんちょい遅れましたが12/21のG* Advent Calendarです。
FFT(高速フーリエ変換)というかDFT(離散フーリエ変換)やります。

使うライブラリ

JTransforms https://github.com/wendykierp/JTransforms

入力波形

input
[0.0, 0.049067674327418015, 0.0980171403295606, 0.14673047445536175, 0.19509032201612825, 0.24298017990326387, 0.29028467725446233, 0.33688985339222005, 0.3826834323650898, 0.4275550934302821, 0.47139673682599764, 0.5141027441932217, 0.5555702330196022, 0.5956993044924334, 0.6343932841636455, 0.6715589548470183, 0.7071067811865475, 0.7409511253549591, 0.7730104533627369, 0.8032075314806448, 0.8314696123025452, 0.8577286100002721, 0.8819212643483549, 0.9039892931234433, 0.9238795325112867, 0.9415440651830208, 0.9569403357322089, 0.970031253194544, 0.9807852804032304, 0.989176509964781, 0.9951847266721968, 0.9987954562051724, 1.0, 0.9987954562051724, 0.9951847266721969, 0.989176509964781, 0.9807852804032304, 0.970031253194544, 0.9569403357322089, 0.9415440651830208, 0.9238795325112867, 0.9039892931234434, 0.881921264348355, 0.8577286100002721, 0.8314696123025453, 0.8032075314806449, 0.7730104533627371, 0.740951125354959, 0.7071067811865476, 0.6715589548470186, 0.6343932841636455, 0.5956993044924335, 0.5555702330196022, 0.5141027441932218, 0.47139673682599786, 0.42755509343028203, 0.3826834323650899, 0.33688985339222033, 0.2902846772544624, 0.24298017990326407, 0.1950903220161286, 0.1467304744553618, 0.09801714032956083, 0.049067674327417966, 1.2246467991473532E-16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

image (1).png

FFTコード

dft_sample.groovy
@Grab("com.github.wendykierp:JTransforms:3.1")

import org.jtransforms.fft.DoubleFFT_1D

def numPoints = 64

// numPoints + 1個のデータ
def x = []
0.step(1 + 1.0 / numPoints, 1.0 / numPoints) { x << it }

// FFTに用いるsin波
def f = x.collect { Math.sin( it * Math.PI) }

// FFT用にサイズを2倍にし、0で埋める
f << [0] * (numPoints - 1)
f = f.flatten()
println f

// FFT用にdoubleに詰めなおす
double[] fDouble = new double[numPoints * 2]
f.eachWithIndex { it, i ->
  fDouble[i] = it
}

def fft = new DoubleFFT_1D(numPoints)
fft.realForward(fDouble)
println fDouble

出力(パワースペクトル)

正規化とか特になにもしれいなのであれですが

output
[40.73548387208331, -0.024548622108927276, -13.589407314865438, 8.881784197001252E-16, -2.7244417193377584, 4.440892098500626E-16, -1.172321899279049, 5.551115123125783E-16, -0.6549698903522008, 5.551115123125783E-17, -0.41983327155349126, 6.38378239159465E-16, -0.29324623849482734, 1.6653345369377348E-16, -0.21732034328985128, 4.718447854656915E-16, -0.1682193329044574, -1.2559397966072083E-15, -0.1346525297928969, 9.020562075079397E-17, -0.11070596112458637, -6.626643678231403E-16, -0.09303715106699177, -3.382710778154774E-16, -0.07964083223305846, -9.922618282587337E-16, -0.06925466172876894, -1.734723475976807E-17, -0.06105183635156024, 2.252972114424878E-16, -0.05447253054678732, -1.4181364416110398E-16, -0.04912684976946835, -0.0, -0.04473660722209264, -1.4181364416110398E-16, -0.04109913630139779, 5.583641188300348E-16, -0.03806409939444906, 1.491862189340054E-16, -0.035518222343737055, -9.922618282587337E-16, -0.03337500672361353, 9.107298248878237E-16, -0.03156765146552513, 5.030698080332741E-16, -0.030044092954215715, -5.620504062164855E-16, -0.028763473809871924, -1.2559397966072083E-15, -0.02769359446339291, -6.245004513516506E-16, -0.02680905360195942, 1.1102230246251565E-16, -0.026089880411642563, -5.551115123125783E-16, -0.025520524589636717, 5.551115123125783E-17, -0.025089112000558356, -7.771561172376096E-16, -0.024786902307144976, -4.440892098500626E-16, -0.024607904706760664, 0.0, 1.2246467991473532E-16, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]

グラフにするとこんな感じ。波数が小さいところに全部集まってるので、FFT自体はできていそう。

image.png

補足

GroovyでFFTしてみた感想

最初はFFTW使おうとしていたので結構苦戦しましたが、使いやすいライブラリが分かってみると簡単!

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0