golang-fft/fft_test.go
Sean Sube 2026148ba3
Some checks failed
Build and Test / test (push) Has been cancelled
Build and Test / docker-test (push) Has been cancelled
Build and Test / lint (push) Has been cancelled
Build and Test / security (push) Has been cancelled
raw robot output
2025-08-11 16:23:29 -05:00

199 lines
3.9 KiB
Go

package main
import (
"math"
"math/cmplx"
"testing"
)
func TestFFTBasic(t *testing.T) {
// Test with simple data
data := []complex128{
complex(1, 0),
complex(2, 0),
complex(3, 0),
complex(4, 0),
}
result := FFT(data)
// Check that result has same length
if len(result) != len(data) {
t.Errorf("FFT result length %d, expected %d", len(result), len(data))
}
// Check that result is not all zeros
allZero := true
for _, val := range result {
if cmplx.Abs(val) > 1e-10 {
allZero = false
break
}
}
if allZero {
t.Error("FFT result is all zeros")
}
}
func TestFFTPowerOfTwo(t *testing.T) {
// Test with non-power-of-2 length
data := []complex128{
complex(1, 0),
complex(2, 0),
complex(3, 0),
complex(4, 0),
complex(5, 0),
}
result := FFT(data)
// Should be padded to next power of 2 (8)
expectedLen := 8
if len(result) != expectedLen {
t.Errorf("FFT result length %d, expected %d", len(result), expectedLen)
}
}
func TestIFFT(t *testing.T) {
// Test that IFFT(FFT(data)) ≈ data
data := []complex128{
complex(1, 0),
complex(2, 0),
complex(3, 0),
complex(4, 0),
}
fftResult := FFT(data)
ifftResult := IFFT(fftResult)
// Check that IFFT recovers original data (within numerical precision)
tolerance := 1e-10
for i, original := range data {
recovered := ifftResult[i]
diff := cmplx.Abs(original - recovered)
if diff > tolerance {
t.Errorf("IFFT recovery failed at index %d: original=%v, recovered=%v, diff=%v",
i, original, recovered, diff)
}
}
}
func TestFFTComplexData(t *testing.T) {
// Test with complex input data
data := []complex128{
complex(1, 1),
complex(2, -1),
complex(-3, 2),
complex(4, 0),
}
result := FFT(data)
// Check that result has same length
if len(result) != len(data) {
t.Errorf("FFT result length %d, expected %d", len(result), len(data))
}
// Check that result is not all zeros
allZero := true
for _, val := range result {
if cmplx.Abs(val) > 1e-10 {
allZero = false
break
}
}
if allZero {
t.Error("FFT result is all zeros")
}
}
func TestFFTEmpty(t *testing.T) {
// Test with empty slice
var data []complex128
result := FFT(data)
if len(result) != 0 {
t.Errorf("FFT of empty slice should return empty slice, got length %d", len(result))
}
}
func TestFFTSingle(t *testing.T) {
// Test with single element
data := []complex128{complex(5, 3)}
result := FFT(data)
if len(result) != 1 {
t.Errorf("FFT of single element should return single element, got length %d", len(result))
}
// Single element FFT should return the same value
if cmplx.Abs(result[0]-data[0]) > 1e-10 {
t.Errorf("FFT of single element should return same value, got %v, expected %v",
result[0], data[0])
}
}
func TestFFTMathematical(t *testing.T) {
// Test with mathematical properties of FFT
// FFT of [1, 0, 0, 0] should be [1, 1, 1, 1]
data := []complex128{
complex(1, 0),
complex(0, 0),
complex(0, 0),
complex(0, 0),
}
result := FFT(data)
// All elements should be approximately 1
tolerance := 1e-10
for i, val := range result {
if cmplx.Abs(val-complex(1, 0)) > tolerance {
t.Errorf("FFT of impulse should be all ones, got %v at index %d", val, i)
}
}
}
func BenchmarkFFT(b *testing.B) {
// Benchmark with power of 2 size
size := 1024
data := make([]complex128, size)
for i := range data {
data[i] = complex(float64(i), float64(i%10))
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
FFT(data)
}
}
func BenchmarkFFTLarge(b *testing.B) {
// Benchmark with larger size
size := 4096
data := make([]complex128, size)
for i := range data {
data[i] = complex(float64(i), float64(i%10))
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
FFT(data)
}
}
func BenchmarkIFFT(b *testing.B) {
// Benchmark IFFT
size := 1024
data := make([]complex128, size)
for i := range data {
data[i] = complex(float64(i), float64(i%10))
}
fftResult := FFT(data)
b.ResetTimer()
for i := 0; i < b.N; i++ {
IFFT(fftResult)
}
}