Skip to content

Instantly share code, notes, and snippets.

@bemasher
Last active January 3, 2016 10:58
Show Gist options
  • Save bemasher/8452626 to your computer and use it in GitHub Desktop.
Save bemasher/8452626 to your computer and use it in GitHub Desktop.
A Cooley-Turkey based DFT in Go. On my Core i7 3770k only about half an order of magnitude slower than FFTW!
package dft
import "math"
type DFT struct {
Log uint
Factors []complex128
}
func NewDFT(lg2 uint, is float64) (dft DFT) {
dft.Log = lg2
mh := 1 << (dft.Log - 1)
dft.Factors = make([]complex128, mh)
phi0 := is * math.Pi / float64(mh)
phi := phi0
for j := 0; j < mh; j++ {
dft.Factors[j] = complex(math.Cos(phi), math.Sin(phi))
phi += phi0
}
return
}
func (dft DFT) Execute(f []complex128) {
n := 1 << dft.Log
RevBinPermute(f)
for i := 0; i < n; i += 2 {
SumDiff(&f[i], &f[i+1])
}
for ldm := uint(2); ldm <= dft.Log; ldm++ {
m := 1 << ldm
mh := m >> 1
stride := 1 << (dft.Log - ldm)
for r := 0; r < n; r += m {
for j, fIdx := 0, stride-1; j < mh; j, fIdx = j+1, fIdx+stride {
i0 := r + j
i1 := i0 + mh
u := f[i0]
v := f[i1] * dft.Factors[fIdx]
f[i0] = u + v
f[i1] = u - v
}
}
}
}
func RevBinPermute(v []complex128) {
n := uint(len(v))
nh := n >> 1
r := uint(0)
for x := uint(1); x < nh; x++ {
r += nh
v[x], v[r] = v[r], v[x]
x++
for i := n; r&i == 0 && i > 0; {
i >>= 1
r ^= i
}
if r > x {
v[x], v[r] = v[r], v[x]
v[n-1-x], v[n-1-r] = v[n-1-r], v[n-1-x]
}
}
}
func SumDiff(a, b *complex128) {
*a, *b = *a+*b, *a-*b
}
@Carrotman42
Copy link

In NewDFT, what do the parameters "lg2" (uint) and "is" (float64) mean?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment