fixed dependencies
This commit is contained in:
224
vendor/github.com/mjibson/go-dsp/fft/fft.go
generated
vendored
Normal file
224
vendor/github.com/mjibson/go-dsp/fft/fft.go
generated
vendored
Normal file
@@ -0,0 +1,224 @@
|
||||
/*
|
||||
* Copyright (c) 2011 Matt Jibson <matt.jibson@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
// Package fft provides forward and inverse fast Fourier transform functions.
|
||||
package fft
|
||||
|
||||
import (
|
||||
"github.com/mjibson/go-dsp/dsputils"
|
||||
)
|
||||
|
||||
// FFTReal returns the forward FFT of the real-valued slice.
|
||||
func FFTReal(x []float64) []complex128 {
|
||||
return FFT(dsputils.ToComplex(x))
|
||||
}
|
||||
|
||||
// IFFTReal returns the inverse FFT of the real-valued slice.
|
||||
func IFFTReal(x []float64) []complex128 {
|
||||
return IFFT(dsputils.ToComplex(x))
|
||||
}
|
||||
|
||||
// IFFT returns the inverse FFT of the complex-valued slice.
|
||||
func IFFT(x []complex128) []complex128 {
|
||||
lx := len(x)
|
||||
r := make([]complex128, lx)
|
||||
|
||||
// Reverse inputs, which is calculated with modulo N, hence x[0] as an outlier
|
||||
r[0] = x[0]
|
||||
for i := 1; i < lx; i++ {
|
||||
r[i] = x[lx-i]
|
||||
}
|
||||
|
||||
r = FFT(r)
|
||||
|
||||
N := complex(float64(lx), 0)
|
||||
for n := range r {
|
||||
r[n] /= N
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
// Convolve returns the convolution of x ∗ y.
|
||||
func Convolve(x, y []complex128) []complex128 {
|
||||
if len(x) != len(y) {
|
||||
panic("arrays not of equal size")
|
||||
}
|
||||
|
||||
fft_x := FFT(x)
|
||||
fft_y := FFT(y)
|
||||
|
||||
r := make([]complex128, len(x))
|
||||
for i := 0; i < len(r); i++ {
|
||||
r[i] = fft_x[i] * fft_y[i]
|
||||
}
|
||||
|
||||
return IFFT(r)
|
||||
}
|
||||
|
||||
// FFT returns the forward FFT of the complex-valued slice.
|
||||
func FFT(x []complex128) []complex128 {
|
||||
lx := len(x)
|
||||
|
||||
// todo: non-hack handling length <= 1 cases
|
||||
if lx <= 1 {
|
||||
r := make([]complex128, lx)
|
||||
copy(r, x)
|
||||
return r
|
||||
}
|
||||
|
||||
if dsputils.IsPowerOf2(lx) {
|
||||
return radix2FFT(x)
|
||||
}
|
||||
|
||||
return bluesteinFFT(x)
|
||||
}
|
||||
|
||||
var (
|
||||
worker_pool_size = 0
|
||||
)
|
||||
|
||||
// SetWorkerPoolSize sets the number of workers during FFT computation on multicore systems.
|
||||
// If n is 0 (the default), then GOMAXPROCS workers will be created.
|
||||
func SetWorkerPoolSize(n int) {
|
||||
if n < 0 {
|
||||
n = 0
|
||||
}
|
||||
|
||||
worker_pool_size = n
|
||||
}
|
||||
|
||||
// FFT2Real returns the 2-dimensional, forward FFT of the real-valued matrix.
|
||||
func FFT2Real(x [][]float64) [][]complex128 {
|
||||
return FFT2(dsputils.ToComplex2(x))
|
||||
}
|
||||
|
||||
// FFT2 returns the 2-dimensional, forward FFT of the complex-valued matrix.
|
||||
func FFT2(x [][]complex128) [][]complex128 {
|
||||
return computeFFT2(x, FFT)
|
||||
}
|
||||
|
||||
// IFFT2Real returns the 2-dimensional, inverse FFT of the real-valued matrix.
|
||||
func IFFT2Real(x [][]float64) [][]complex128 {
|
||||
return IFFT2(dsputils.ToComplex2(x))
|
||||
}
|
||||
|
||||
// IFFT2 returns the 2-dimensional, inverse FFT of the complex-valued matrix.
|
||||
func IFFT2(x [][]complex128) [][]complex128 {
|
||||
return computeFFT2(x, IFFT)
|
||||
}
|
||||
|
||||
func computeFFT2(x [][]complex128, fftFunc func([]complex128) []complex128) [][]complex128 {
|
||||
rows := len(x)
|
||||
if rows == 0 {
|
||||
panic("empty input array")
|
||||
}
|
||||
|
||||
cols := len(x[0])
|
||||
r := make([][]complex128, rows)
|
||||
for i := 0; i < rows; i++ {
|
||||
if len(x[i]) != cols {
|
||||
panic("ragged input array")
|
||||
}
|
||||
r[i] = make([]complex128, cols)
|
||||
}
|
||||
|
||||
for i := 0; i < cols; i++ {
|
||||
t := make([]complex128, rows)
|
||||
for j := 0; j < rows; j++ {
|
||||
t[j] = x[j][i]
|
||||
}
|
||||
|
||||
for n, v := range fftFunc(t) {
|
||||
r[n][i] = v
|
||||
}
|
||||
}
|
||||
|
||||
for n, v := range r {
|
||||
r[n] = fftFunc(v)
|
||||
}
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
// FFTN returns the forward FFT of the matrix m, computed in all N dimensions.
|
||||
func FFTN(m *dsputils.Matrix) *dsputils.Matrix {
|
||||
return computeFFTN(m, FFT)
|
||||
}
|
||||
|
||||
// IFFTN returns the forward FFT of the matrix m, computed in all N dimensions.
|
||||
func IFFTN(m *dsputils.Matrix) *dsputils.Matrix {
|
||||
return computeFFTN(m, IFFT)
|
||||
}
|
||||
|
||||
func computeFFTN(m *dsputils.Matrix, fftFunc func([]complex128) []complex128) *dsputils.Matrix {
|
||||
dims := m.Dimensions()
|
||||
t := m.Copy()
|
||||
r := dsputils.MakeEmptyMatrix(dims)
|
||||
|
||||
for n := range dims {
|
||||
dims[n] -= 1
|
||||
}
|
||||
|
||||
for n := range dims {
|
||||
d := make([]int, len(dims))
|
||||
copy(d, dims)
|
||||
d[n] = -1
|
||||
|
||||
for {
|
||||
r.SetDim(fftFunc(t.Dim(d)), d)
|
||||
|
||||
if !decrDim(d, dims) {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
r, t = t, r
|
||||
}
|
||||
|
||||
return t
|
||||
}
|
||||
|
||||
// decrDim decrements an element of x by 1, skipping all -1s, and wrapping up to d.
|
||||
// If a value is 0, it will be reset to its correspending value in d, and will carry one from the next non -1 value to the right.
|
||||
// Returns true if decremented, else false.
|
||||
func decrDim(x, d []int) bool {
|
||||
for n, v := range x {
|
||||
if v == -1 {
|
||||
continue
|
||||
} else if v == 0 {
|
||||
i := n
|
||||
// find the next element to decrement
|
||||
for ; i < len(x); i++ {
|
||||
if x[i] == -1 {
|
||||
continue
|
||||
} else if x[i] == 0 {
|
||||
x[i] = d[i]
|
||||
} else {
|
||||
x[i] -= 1
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
// no decrement
|
||||
return false
|
||||
} else {
|
||||
x[n] -= 1
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
Reference in New Issue
Block a user