You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
62 lines
1.3 KiB
62 lines
1.3 KiB
package algorithm
|
|
|
|
import (
|
|
"log"
|
|
"math"
|
|
"math/cmplx"
|
|
"scientificgo.org/fft"
|
|
)
|
|
|
|
func IsPow2(N int) bool {
|
|
if N == 0 {
|
|
return false
|
|
}
|
|
return (uint64(N) & uint64(N-1)) == 0
|
|
}
|
|
|
|
// 频谱计算(全程分析)
|
|
func FFTforward(raw []float64, fs float64) (float64, []float64) {
|
|
rawLen := len(raw)
|
|
power := math.Ceil(math.Log(float64(rawLen)) / math.Log(2))
|
|
|
|
signLen := int(math.Pow(2, power))
|
|
|
|
signArray := make([]float64, signLen)
|
|
copy(signArray[:], raw[:])
|
|
|
|
if !IsPow2(signLen) {
|
|
log.Panicf("fft源数据长度[%d]异常,不是2^n", signLen)
|
|
}
|
|
cpx := Float64ToComplex128Array(signArray)
|
|
fftData := fft.Fft(cpx, false)
|
|
fftLen := signLen / 2
|
|
df := fs / float64(signLen)
|
|
|
|
resp := make([]float64, fftLen)
|
|
for i := 0; i < fftLen; i++ {
|
|
resp[i] = cmplx.Abs(fftData[i]) * 2 / float64(signLen)
|
|
}
|
|
return df, resp
|
|
}
|
|
|
|
func dfftCalc(raw []float64) []float64 {
|
|
cpx := Float64ToComplex128Array(raw)
|
|
rp := fft.Fft(cpx, false)
|
|
frp := Complex128ToFloat64Array(rp)
|
|
return frp
|
|
}
|
|
|
|
func Float64ToComplex128Array(x []float64) []complex128 {
|
|
y := make([]complex128, len(x))
|
|
for i, v := range x {
|
|
y[i] = complex(v, 0)
|
|
}
|
|
return y
|
|
}
|
|
func Complex128ToFloat64Array(x []complex128) []float64 {
|
|
y := make([]float64, len(x))
|
|
for i, v := range x {
|
|
y[i] = real(v)
|
|
}
|
|
return y
|
|
}
|
|
|