feat: initial release
Assisted-by: GLM 5.3 Flash
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
// Copyright (c) 2026 Petr Balvín <opensource@petrbalvin.org> (https://petrbalvin.org)
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
// Command fft demonstrates the Fourier transform: it synthesises a
|
||||
// signal from two sinusoids, transforms it, and prints the dominant
|
||||
// frequency components.
|
||||
//
|
||||
// Usage: go run ./examples/fft
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"math"
|
||||
|
||||
"sourcedock.dev/petrbalvin/tensor"
|
||||
sig "sourcedock.dev/petrbalvin/tensor/signal"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Two sinusoids: 5 Hz and 13 Hz, sampled at 100 Hz for 2 seconds.
|
||||
const (
|
||||
fs = 100.0
|
||||
seconds = 2.0
|
||||
)
|
||||
n := int(fs * seconds)
|
||||
vals := make([]float64, n)
|
||||
for i := range n {
|
||||
t := float64(i) / fs
|
||||
vals[i] = math.Sin(2*math.Pi*5*t) + 0.5*math.Sin(2*math.Pi*13*t)
|
||||
}
|
||||
signal, err := tensor.FromFloats(vals, n)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
spec, err := sig.FFT(signal)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
freqs := sig.FFTFreq(n, 1/fs)
|
||||
|
||||
// Find the two strongest bins (excluding DC).
|
||||
var peaks [2]struct {
|
||||
freq float64
|
||||
mag float64
|
||||
}
|
||||
for i := 1; i < n/2; i++ {
|
||||
m, _ := tensor.ComplexAt(spec, i)
|
||||
mag := math.Hypot(real(m), imag(m))
|
||||
for p := range peaks {
|
||||
if mag > peaks[p].mag {
|
||||
peaks[p].freq, _ = tensor.FloatAt(freqs, i)
|
||||
peaks[p].mag = mag
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, p := range peaks {
|
||||
fmt.Printf("peak at %.1f Hz (magnitude %.1f)\n", p.freq, p.mag)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user