LICENSE=BSD-3-ClauseCGO_ENABLED=0go-dsp is the signal-processing layer of the Go scientific stack: filter design and filtering, spectral estimation and resampling, with the semantics of SciPy's scipy.signal. Its tests replay recorded SciPy answers, its documentation lists the error of every group of values in ULPs, and it says where it is slower. No cgo.
import "github.com/go-dsp/signal"
z, _ := signal.Butter(8, []float64{0.2}, signal.Lowpass, nil) // zeros, poles, gain
sos, _ := z.SOS(false) // second-order sections
y, _ := signal.SOSFiltFilt(sos, x, nil) // zero-phase filtering
f, p, _ := signal.Welch(x, &signal.SpectralOptions{Fs: 1000, Nperseg: 1024})Each function names the SciPy call it corresponds to and, where it differs, a note on MATLAB's. Option structs have useful zero values, and nothing panics on bad arguments: functions that can fail return an error.
Butterworth, Chebyshev types 1 and 2, elliptic and Bessel filters, order selection, notch and peak filters, as zeros-poles-gain, transfer function or second-order sections.
Window method, frequency-sampling, Parks–McClellan Remez, least squares, Kaiser order estimation, and more than twenty windows including Chebyshev and DPSS.
LFilter, SOSFilt and their zero-phase forms FiltFilt and SOSFiltFilt, with initial conditions; convolution, correlation and overlap-add.
Periodogram, Welch, cross-spectrum, coherence, spectrogram, STFT and its inverse, and Lomb–Scargle for unevenly sampled data.
FFT and polyphase resampling, decimation and Upfirdn; the analytic signal with Hilbert; detrending.
FindPeaks with height, threshold, distance, prominence, width and plateau conditions, and the prominence and width functions behind it.
No cgo. The FIR kernels call the SIMD dot product of go-simd/floats; the transforms come from go-fft.
Every repository of the organization. Ported code keeps its attribution in place.
The fixtures are SciPy's own output, recorded once and replayed. What differs, and why, is in the library's documentation.
Every comparison is recorded from SciPy 1.18.1 with NumPy 2.5.4 and replayed from testdata/oracle, so go test needs no Python and the same recorded output is checked on every architecture CI runs. (signal)
docs/accuracy.md lists the maximum ULP error, the normwise relative error and the exact-equality count for 225 groups of values, and docs/verification.md names the few places where SciPy itself is the less accurate side. (signal)
100% statement coverage with -race, error paths included; fuzz targets for the design constructors, the spectral estimators, the convolutions and the peak finder; gofmt, go vet and govulncheck. (signal)
Tests on amd64, arm64 and 386, under qemu on riscv64, loong64, ppc64le, s390x and arm, and every GOOS/GOARCH pair compiling the tests. (signal)
Best of 5 interleaved rounds on one core (the SciPy process runs with its threads set to 1), on a 16-CPU darwin/arm64 host, with SciPy 1.18.1, measured 2026-10-19 and recorded in the library's docs/perf.md. In the 28 cases measured, no row is slower than SciPy; the closest are within 2%.
| case | go-dsp | SciPy 1.18.1 | SciPy / Go |
|---|---|---|---|
| welch, 10⁶ samples, nperseg 256 (signal) | 8.42 ms | 86.92 ms | 10× |
| welch, 10⁶ samples, nperseg 1024 (signal) | 7.83 ms | 30.74 ms | 3.9× |
| sosfilt, 10⁶ samples, order 8 (signal) | 4.63 ms | 7.20 ms | 1.6× |
| sosfiltfilt, 10⁶ samples, order 8 (signal) | 10.40 ms | 14.94 ms | 1.4× |
| fftconvolve, 10⁶ × 10⁴ (signal) | 10.47 ms | 19.78 ms | 1.9× |
| resample_poly 1/4, 10⁶ samples (signal) | 6.59 ms | 15.35 ms | 2.3× |
| remez, 501 taps (signal) | 1.17 ms | 6.54 ms | 5.6× |
| find_peaks with prominence, 10⁶ samples (signal) | 17.12 ms | 18.96 s | 1100× |
| butter order 8, zpk to sos (signal) | 2.3 µs | 282.7 µs | 120× |
| lfilter FIR, 101 taps, 10⁶ samples (signal) | 14.53 ms | 14.78 ms | 1.02× |
Filter design (Butterworth, Chebyshev, elliptic, Bessel, window method, Parks–McClellan, least squares), windows, filtering and zero-phase filtering, convolution, Welch, STFT and Lomb–Scargle estimation, resampling and peak finding, with the semantics of scipy.signal.
The documentation (Hugo + Hextra): the library's own README, verification, accuracy and performance documents. Source →
Logos and icons for the organization, in SVG / PNG / JPG / ICO / ICNS across colour, white and black variants.
go-dsp builds on go-fft for transforms and windows, go-numerics for special functions and go-simd for its dot-product kernels. Wavelets and audio I/O are planned in this organization and not started; what signal does not provide is listed in the documentation.