Documentation
¶
Overview ¶
Package transform implements integral and discrete signal transforms in pure Go using only the standard library.
The package collects the transforms most often needed in numerical analysis, digital-signal processing and applied mathematics and provides correct, self-contained implementations of each.
The following families are covered:
- Discrete Fourier transforms: the direct O(n^2) DFT and IDFT, the radix-2 Cooley-Tukey FFT and IFFT, the mixed-length FFTAny and IFFTAny (which fall back to Bluestein's algorithm for non-power-of-two lengths), the real-input transforms RFFT and IRFFT, two-dimensional FFT2D/IFFT2D, the reusable FFTPlan, and the single-bin Goertzel algorithm;
- spectral helpers: FFTShift, FFTFreq, Magnitude, Phase, PowerSpectrum, Periodogram and the analysis windows Hann, Hamming, Blackman, Bartlett and Welch;
- the discrete cosine and sine transforms DCT, IDCT, DCT1, DCT4, DST and IDST;
- fast linear, circular and cross correlation via Convolve, ConvolveFFT, CircularConvolve, Correlate and AutoCorrelate;
- the numerical Laplace transform Laplace together with three classical inversion methods: the fixed Talbot method InverseLaplaceTalbot, the Gaver-Stehfest method InverseLaplaceStehfest and the Fourier-series Euler method InverseLaplaceEuler;
- the ZTransform, its numerical inverse InverseZTransform, the chirp-z transform ChirpZTransform and Bluestein's algorithm;
- the Hilbert analytic signal together with the derived Envelope, InstantaneousPhase and InstantaneousFrequency, and the discrete-time Fourier transform samplers DTFT and SampleDTFT.
Every routine is deterministic and depends only on the Go standard library.
Index ¶
- func ApplyWindow(x, w []float64) []float64
- func AutoCorrelate(x []float64) []float64
- func Bartlett(n int) []float64
- func Blackman(n int) []float64
- func Bluestein(x []complex128) []complex128
- func ChirpZTransform(x []complex128, m int, w, a complex128) []complex128
- func CircularConvolve(a, b []float64) []float64
- func Convolve(a, b []float64) []float64
- func ConvolveComplex(a, b []complex128) []complex128
- func ConvolveFFT(a, b []float64) []float64
- func Correlate(a, b []float64) []float64
- func CrossCorrelateFFT(a, b []float64) []float64
- func DCT(x []float64) []float64
- func DCT1(x []float64) []float64
- func DCT4(x []float64) []float64
- func DFT(x []complex128) []complex128
- func DFTMatrix(n int) [][]complex128
- func DST(x []float64) []float64
- func DTFT(x []float64, omega float64) complex128
- func DTFTComplex(x []complex128, omega float64) complex128
- func DTFTSample(x []float64, omegas []float64) []complex128
- func Envelope(x []float64) []float64
- func FFT(x []complex128) []complex128
- func FFT2D(m [][]complex128) [][]complex128
- func FFTAny(x []complex128) []complex128
- func FFTFreq(n int, d float64) []float64
- func FFTReal(x []float64) []complex128
- func FFTShift(x []complex128) []complex128
- func Goertzel(x []float64, k, n int) complex128
- func GoertzelPower(x []float64, targetFreq, sampleRate float64) float64
- func Hamming(n int) []float64
- func Hann(n int) []float64
- func Hilbert(x []float64) []complex128
- func HilbertTransform(x []float64) []float64
- func IDCT(X []float64) []float64
- func IDFT(X []complex128) []complex128
- func IDST(X []float64) []float64
- func IFFT(X []complex128) []complex128
- func IFFT2D(m [][]complex128) [][]complex128
- func IFFTAny(X []complex128) []complex128
- func IFFTShift(x []complex128) []complex128
- func IRFFT(X []complex128, n int) []float64
- func InstantaneousFrequency(x []float64, sampleRate float64) []float64
- func InstantaneousPhase(x []float64) []float64
- func InverseLaplaceEuler(F func(complex128) complex128, t float64, m int) float64
- func InverseLaplaceStehfest(F func(float64) float64, t float64, n int) float64
- func InverseLaplaceTalbot(F func(complex128) complex128, t float64, m int) float64
- func InverseZTransform(X func(complex128) complex128, n int, radius float64, m int) []complex128
- func IsPow2(n int) bool
- func Laplace(f func(float64) float64, s complex128, upper float64, n int) complex128
- func Magnitude(X []complex128) []float64
- func NextPow2(n int) int
- func Periodogram(x []float64) []float64
- func Phase(X []complex128) []float64
- func PhaseUnwrap(phase []float64) []float64
- func PowerSpectrum(X []complex128) []float64
- func RFFT(x []float64) []complex128
- func RFFTFreq(n int, d float64) []float64
- func SampleDTFT(x []float64, m int) []complex128
- func StehfestCoefficients(n int) []float64
- func Welch(n int) []float64
- func ZTransform(x []float64, z complex128) complex128
- func ZTransformComplex(x []complex128, z complex128) complex128
- func ZeroPad(x []complex128, n int) []complex128
- func ZeroPadReal(x []float64, n int) []float64
- type FFTPlan
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ApplyWindow ¶
ApplyWindow returns the element-wise product of the signal x and the window w. It panics if the lengths differ.
func AutoCorrelate ¶
AutoCorrelate returns the full autocorrelation of x, i.e. the cross-correlation of x with itself. The result has length 2*len(x)-1 and is symmetric about its center, whose value equals the signal energy.
func Bartlett ¶
Bartlett returns the n-point Bartlett (triangular) window, which tapers linearly to zero at both ends.
func Blackman ¶
Blackman returns the n-point Blackman window, w[i] = 0.42 - 0.5*cos(2*pi*i/(n-1)) + 0.08*cos(4*pi*i/(n-1)). It provides strong side-lobe suppression at the cost of a wider main lobe.
func Bluestein ¶
func Bluestein(x []complex128) []complex128
Bluestein computes the discrete Fourier transform of x for an arbitrary length by expressing it as a convolution (the chirp-z transform with a = 1, w = exp(-2*pi*i/N) and m = N). It runs in O(n log n) time and returns the same result as DFT.
func ChirpZTransform ¶
func ChirpZTransform(x []complex128, m int, w, a complex128) []complex128
ChirpZTransform computes the chirp-z transform of x, sampling the Z-transform along a spiral contour. It returns m points
X[k] = sum_{j=0}^{N-1} x[j] * a^{-j} * w^{j*k}, k = 0 .. m-1,
where a is the complex starting point and w is the ratio between successive spiral points. Setting a = 1 and w = exp(-2*pi*i/N) with m = N reproduces the DFT. The transform is evaluated with Bluestein's convolution method in O((N+m) log(N+m)) time.
func CircularConvolve ¶
CircularConvolve returns the circular (cyclic) convolution of a and b. The shorter input is zero-extended to the length N of the longer one and the result has length N with
c[k] = sum_{n=0}^{N-1} a[n] * b[(k-n) mod N].
func Convolve ¶
Convolve returns the full linear convolution of the real sequences a and b, computed directly. The result has length len(a)+len(b)-1 with
c[k] = sum_i a[i] * b[k-i].
For long inputs ConvolveFFT is asymptotically faster.
func ConvolveComplex ¶
func ConvolveComplex(a, b []complex128) []complex128
ConvolveComplex returns the full linear convolution of the complex sequences a and b, computed directly. The result has length len(a)+len(b)-1.
func ConvolveFFT ¶
ConvolveFFT returns the full linear convolution of the real sequences a and b using the FFT (multiplication in the frequency domain). The result has length len(a)+len(b)-1 and matches Convolve to within floating-point rounding; it is much faster for large inputs.
func Correlate ¶
Correlate returns the full cross-correlation of a and b, defined as the convolution of a with the time-reversed b. The result has length len(a)+len(b)-1; the peak indicates the lag at which the two signals are best aligned.
func CrossCorrelateFFT ¶
CrossCorrelateFFT returns the full cross-correlation of a and b computed via the FFT. It matches Correlate to within floating-point rounding.
func DCT ¶
DCT computes the unnormalized type-II discrete cosine transform of x:
X[k] = sum_{n=0}^{N-1} x[n] * cos(pi/N * (n + 1/2) * k), k = 0 .. N-1.
This is the DCT most commonly meant by "the DCT" and used in signal and image compression. It is inverted by IDCT.
func DCT1 ¶
DCT1 computes the unnormalized type-I discrete cosine transform of x, which requires at least two samples:
X[k] = (x[0] + (-1)^k x[N-1])/2 + sum_{n=1}^{N-2} x[n] cos(pi*n*k/(N-1)).
The type-I transform is symmetric: applying DCT1 twice and scaling by 2/(N-1) recovers the input.
func DCT4 ¶
DCT4 computes the unnormalized type-IV discrete cosine transform of x:
X[k] = sum_{n=0}^{N-1} x[n] cos(pi/N * (n+1/2) * (k+1/2)).
The type-IV transform is its own inverse up to the scale factor 2/N and is the building block of the modified DCT used in audio coding.
func DFT ¶
func DFT(x []complex128) []complex128
DFT computes the discrete Fourier transform of x directly in O(n^2) time, returning X[k] = sum_n x[n] exp(-2*pi*i*k*n/N). It works for any length and serves as the reference implementation for the faster routines.
func DFTMatrix ¶
func DFTMatrix(n int) [][]complex128
DFTMatrix returns the n-by-n discrete Fourier transform matrix W whose entry W[j][k] equals exp(-2*pi*i*j*k/n). Multiplying this matrix by a column vector reproduces DFT.
func DST ¶
DST computes the unnormalized type-I discrete sine transform of x:
X[k] = sum_{n=0}^{N-1} x[n] sin(pi*(n+1)*(k+1)/(N+1)), k = 0 .. N-1.
It is inverted by IDST.
func DTFT ¶
func DTFT(x []float64, omega float64) complex128
DTFT evaluates the discrete-time Fourier transform of the real sequence x at the angular frequency omega (radians/sample), returning sum_{n=0}^{N-1} x[n] e^{-i omega n}.
func DTFTComplex ¶
func DTFTComplex(x []complex128, omega float64) complex128
DTFTComplex evaluates the discrete-time Fourier transform of the complex sequence x at the angular frequency omega (radians/sample).
func DTFTSample ¶
func DTFTSample(x []float64, omegas []float64) []complex128
DTFTSample evaluates the discrete-time Fourier transform of the real sequence x at each of the supplied angular frequencies, returning one complex value per frequency.
func Envelope ¶
Envelope returns the amplitude envelope of the real sequence x, i.e. the magnitude of its analytic signal (see Hilbert).
func FFT ¶
func FFT(x []complex128) []complex128
FFT computes the discrete Fourier transform of x using the radix-2 Cooley-Tukey algorithm. The length of x must be a power of two; FFT panics otherwise. Use FFTAny to transform sequences of arbitrary length.
func FFT2D ¶
func FFT2D(m [][]complex128) [][]complex128
FFT2D computes the two-dimensional discrete Fourier transform of a matrix by transforming every row and then every column. The matrix must be rectangular; each dimension may have any length.
func FFTAny ¶
func FFTAny(x []complex128) []complex128
FFTAny computes the discrete Fourier transform of x for any length. When the length is a power of two it uses the radix-2 FFT; otherwise it uses Bluestein's algorithm, which runs in O(n log n) time.
func FFTFreq ¶
FFTFreq returns the n sample frequencies corresponding to the bins of an n-point DFT taken with sample spacing d (in seconds). The result follows the standard convention: bins 0..(n-1)/2 hold the non-negative frequencies and the remainder hold the negative frequencies.
func FFTReal ¶
func FFTReal(x []float64) []complex128
FFTReal computes the discrete Fourier transform of a real-valued signal x, returning the full complex spectrum of the same length. It accepts any length.
func FFTShift ¶
func FFTShift(x []complex128) []complex128
FFTShift rearranges a spectrum so that the zero-frequency component is moved to the center of the slice, matching the conventional plotting order. It is inverted by IFFTShift.
func Goertzel ¶
func Goertzel(x []float64, k, n int) complex128
Goertzel computes a single DFT bin X[k] of the length-n signal x using the Goertzel algorithm, which is more efficient than a full DFT when only a few bins are required. The result equals DFT(x)[k].
func GoertzelPower ¶
GoertzelPower returns the power (squared magnitude) of the signal x at the frequency targetFreq given the sampleRate, using the Goertzel recurrence. Unlike Goertzel the target frequency need not fall on an exact DFT bin.
func Hamming ¶
Hamming returns the n-point Hamming window, w[i] = 0.54 - 0.46*cos(2*pi*i/(n-1)). It minimizes the nearest side lobe at the cost of slower far-off side-lobe roll-off compared with the Hann window.
func Hann ¶
Hann returns the n-point Hann (raised-cosine) window, w[i] = 0.5*(1 - cos(2*pi*i/(n-1))). The Hann window offers a good balance between main-lobe width and side-lobe suppression for spectral analysis.
func Hilbert ¶
func Hilbert(x []float64) []complex128
Hilbert returns the analytic signal of the real sequence x, whose real part is x and whose imaginary part is the Hilbert transform of x. It is computed with the standard FFT method: the negative-frequency components are zeroed and the positive-frequency components doubled before inverting. The result has the same length as x.
func HilbertTransform ¶
HilbertTransform returns the Hilbert transform of the real sequence x, i.e. the imaginary part of its analytic signal (see Hilbert). It applies a 90-degree phase shift to every frequency component.
func IDCT ¶
IDCT computes the inverse of the type-II transform produced by DCT (it is the scaled type-III transform):
x[n] = (2/N) * ( X[0]/2 + sum_{k=1}^{N-1} X[k] * cos(pi/N*(n+1/2)*k) ).
Applying IDCT to the output of DCT recovers the original signal.
func IDFT ¶
func IDFT(X []complex128) []complex128
IDFT computes the inverse discrete Fourier transform of X directly, returning x[n] = (1/N) sum_k X[k] exp(+2*pi*i*k*n/N). It works for any length.
func IDST ¶
IDST computes the inverse of the type-I sine transform produced by DST. The type-I DST is orthogonal, so the inverse is the same transform scaled by 2/(N+1).
func IFFT ¶
func IFFT(X []complex128) []complex128
IFFT computes the inverse radix-2 FFT of X, including the 1/N scaling. The length of X must be a power of two; IFFT panics otherwise.
func IFFT2D ¶
func IFFT2D(m [][]complex128) [][]complex128
IFFT2D computes the inverse two-dimensional discrete Fourier transform, including the 1/(rows*cols) scaling. The matrix must be rectangular.
func IFFTAny ¶
func IFFTAny(X []complex128) []complex128
IFFTAny computes the inverse discrete Fourier transform of X for any length, including the 1/N scaling.
func IFFTShift ¶
func IFFTShift(x []complex128) []complex128
IFFTShift is the inverse of FFTShift; it moves the zero-frequency component from the center back to the start of the slice.
func IRFFT ¶
func IRFFT(X []complex128, n int) []float64
IRFFT reconstructs a real signal of length n from the floor(n/2)+1 half-spectrum X produced by RFFT. The original length n must be supplied because it cannot be recovered from the half-spectrum alone.
func InstantaneousFrequency ¶
InstantaneousFrequency returns the instantaneous frequency, in the same units as sampleRate (typically Hz), of the real sequence x. It is the time derivative of the unwrapped InstantaneousPhase scaled by sampleRate/(2*pi), computed with central differences.
func InstantaneousPhase ¶
InstantaneousPhase returns the unwrapped instantaneous phase, in radians, of the real sequence x, obtained as the argument of its analytic signal (see Hilbert).
func InverseLaplaceEuler ¶
func InverseLaplaceEuler(F func(complex128) complex128, t float64, m int) float64
InverseLaplaceEuler approximates the inverse Laplace transform f(t) using the Fourier-series method with Euler summation (Abate and Whitt). The Bromwich integral is written as an alternating series which is accelerated by averaging partial sums with binomial weights; m sets the number of Euler-averaged terms (around 15 is a good default). The transform F may be complex-valued and t must be positive.
func InverseLaplaceStehfest ¶
InverseLaplaceStehfest approximates the inverse Laplace transform f(t) using the Gaver-Stehfest algorithm, which evaluates the real-argument transform F at n points:
f(t) ~= (ln 2 / t) * sum_{k=1}^{n} V_k * F(k ln 2 / t).
n must be even (odd values are rounded up). The method needs only real-valued transform samples and works well for smooth, non-oscillatory functions; typical choices are n = 10..14.
func InverseLaplaceTalbot ¶
func InverseLaplaceTalbot(F func(complex128) complex128, t float64, m int) float64
InverseLaplaceTalbot approximates the inverse Laplace transform f(t) of the transform F, supplied as a callable, using the fixed Talbot method of Abate and Valko. The contour is deformed into the left half-plane so that the integrand decays rapidly; m controls the number of terms (and thus the accuracy), with values around 20-40 giving several correct digits for smooth transforms. The argument t must be positive.
func InverseZTransform ¶
func InverseZTransform(X func(complex128) complex128, n int, radius float64, m int) []complex128
InverseZTransform recovers the first n samples of a causal sequence from its Z-transform X(z), which is supplied as a callable. The samples are obtained by numerically evaluating the inversion contour integral on a circle of the given radius using m equally spaced points:
x[j] = (radius^j / m) * sum_{k=0}^{m-1} X(radius*e^{i*theta_k}) * e^{i*j*theta_k}
The radius must lie outside every pole of X(z); m controls accuracy and should be noticeably larger than n.
func Laplace ¶
func Laplace(f func(float64) float64, s complex128, upper float64, n int) complex128
Laplace numerically approximates the Laplace transform
F(s) = integral_0^upper f(t) e^{-s t} dt
of the real function f at the complex point s, using composite Simpson quadrature with n subintervals over the truncated interval [0, upper]. For convergent transforms upper should be large enough that f(t)e^{-s t} has decayed to negligible size; n must be positive and is rounded up to the next even number.
func Magnitude ¶
func Magnitude(X []complex128) []float64
Magnitude returns the element-wise magnitudes (absolute values) of a complex spectrum.
func NextPow2 ¶
NextPow2 returns the smallest power of two that is greater than or equal to n. For n <= 1 it returns 1.
func Periodogram ¶
Periodogram returns the periodogram power-spectral-density estimate of the real signal x, defined as (1/N) |DFT(x)[k]|^2 for k = 0 .. N-1.
func Phase ¶
func Phase(X []complex128) []float64
Phase returns the element-wise phase angles, in radians in the range (-pi, pi], of a complex spectrum.
func PhaseUnwrap ¶
PhaseUnwrap returns a copy of the phase sequence with discontinuities larger than pi removed by adding integer multiples of 2*pi, producing a continuous phase curve.
func PowerSpectrum ¶
func PowerSpectrum(X []complex128) []float64
PowerSpectrum returns the element-wise squared magnitudes |X[k]|^2 of a complex spectrum.
func RFFT ¶
func RFFT(x []float64) []complex128
RFFT computes the discrete Fourier transform of a real-valued signal x and returns only the non-redundant first floor(N/2)+1 frequency bins. The remaining bins are the complex conjugates of these by Hermitian symmetry. Use IRFFT to invert the result.
func RFFTFreq ¶
RFFTFreq returns the floor(n/2)+1 non-negative sample frequencies corresponding to the bins produced by RFFT for an n-point signal with sample spacing d (in seconds).
func SampleDTFT ¶
func SampleDTFT(x []float64, m int) []complex128
SampleDTFT samples the discrete-time Fourier transform of the real sequence x at m frequencies equally spaced over [0, 2*pi), returning
X[k] = sum_{n} x[n] e^{-2*pi*i*k*n/m}, k = 0 .. m-1.
When m equals len(x) this coincides with the DFT; larger m interpolates the spectrum and smaller m produces the aliased (folded) samples.
func StehfestCoefficients ¶
StehfestCoefficients returns the n Gaver-Stehfest weights V_1..V_n (indexed from zero) used by InverseLaplaceStehfest. n must be a positive even number; the function panics otherwise. The weights alternate in sign and grow rapidly, which is why the method is best used in the range n = 8..16.
func Welch ¶
Welch returns the n-point Welch (parabolic) window, w[i] = 1 - ((i-(n-1)/2)/((n-1)/2))^2.
func ZTransform ¶
func ZTransform(x []float64, z complex128) complex128
ZTransform evaluates the one-sided Z-transform of the real sequence x at the complex point z, returning sum_{n=0}^{N-1} x[n] z^{-n}.
func ZTransformComplex ¶
func ZTransformComplex(x []complex128, z complex128) complex128
ZTransformComplex evaluates the one-sided Z-transform of the complex sequence x at the point z, returning sum_{n=0}^{N-1} x[n] z^{-n}. The sum is evaluated by Horner's method for numerical stability.
func ZeroPad ¶
func ZeroPad(x []complex128, n int) []complex128
ZeroPad returns a copy of x extended with zeros to length n. If n is smaller than len(x) the input is truncated.
func ZeroPadReal ¶
ZeroPadReal returns a copy of the real slice x extended with zeros to length n. If n is smaller than len(x) the input is truncated.
Types ¶
type FFTPlan ¶
type FFTPlan struct {
// contains filtered or unexported fields
}
FFTPlan holds precomputed twiddle factors for repeated radix-2 transforms of a fixed power-of-two length. Reusing a plan avoids recomputing the twiddle table on every call and is convenient when transforming many blocks of the same size. A plan is safe for concurrent use because Forward and Inverse do not mutate it.
func NewFFTPlan ¶
NewFFTPlan creates a reusable transform plan for signals of length n, which must be a power of two. NewFFTPlan panics for other lengths.
func (*FFTPlan) Forward ¶
func (p *FFTPlan) Forward(x []complex128) []complex128
Forward computes the discrete Fourier transform of x using the plan. The length of x must equal the plan length. The input is not modified.
func (*FFTPlan) Inverse ¶
func (p *FFTPlan) Inverse(X []complex128) []complex128
Inverse computes the inverse discrete Fourier transform of X using the plan, including the 1/N scaling. The length of X must equal the plan length. The input is not modified.