freq_bt¶
MATLAB equivalent:
sidFreqBT
freq_bt ¶
Blackman-Tukey spectral analysis for frequency response estimation.
freq_bt ¶
freq_bt(y: ndarray | list, u: ndarray | list | None = None, *, window_size: int | None = None, frequencies: ndarray | None = None, sample_time: float = 1.0) -> FreqResult
Estimate frequency response via Blackman-Tukey spectral analysis.
Estimates the frequency response G(e^{jw}) and noise power spectrum from time-domain input/output data using the Blackman-Tukey method. The algorithm computes biased sample covariances, applies a Hann lag window, and Fourier-transforms to obtain spectral estimates.
This is an open-source replacement for the System Identification
Toolbox function spa.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
y
|
ndarray or list of ndarray, shape (N, ny) or (N, ny, L)
|
Output data. A 1-D array is treated as a single-channel signal.
For multiple trajectories pass a 3-D array |
required |
u
|
ndarray, list of ndarray, or None
|
Input data. Same shape conventions as y. Pass |
None
|
window_size
|
int
|
Hann lag window size M. Must satisfy |
None
|
frequencies
|
(ndarray, shape(nf))
|
Frequency vector in rad/sample. All values must lie in the
interval |
None
|
sample_time
|
float
|
Sample time in seconds. Must be positive. Default is |
1.0
|
Returns:
| Type | Description |
|---|---|
FreqResult
|
Frozen dataclass with fields:
|
Raises:
| Type | Description |
|---|---|
SidError
|
If sample_time is not positive (code: |
SidError
|
If window_size is less than 2 (code: |
SidError
|
If any frequency is outside |
SidError
|
If data contains NaN/Inf (code: |
Examples:
Basic SISO system identification:
>>> import numpy as np
>>> import sid
>>> N = 1000; rng = np.random.default_rng(0)
>>> u = rng.standard_normal(N)
>>> from scipy.signal import lfilter
>>> y = lfilter([1], [1, -0.9], u) + 0.1 * rng.standard_normal(N)
>>> result = sid.freq_bt(y, u)
>>> result.response.shape
(128,)
Time-series spectrum estimation:
Custom window size and frequencies:
Multi-trajectory (ensemble-averaged):
>>> L = 5; N = 1000
>>> u3d = rng.standard_normal((N, 1, L))
>>> y3d = np.zeros_like(u3d)
>>> for l in range(L):
... y3d[:, 0, l] = lfilter([1], [1, -0.9], u3d[:, 0, l]) + 0.1 * rng.standard_normal(N)
>>> result = sid.freq_bt(y3d, u3d)
Notes
Algorithm:
- Validate and orient input data; detect time-series vs. SISO vs. MIMO.
- Compute biased sample covariances R_yy, R_uu, R_yu for lags 0 .. M (ensemble-averaged for multi-trajectory data).
- Apply Hann lag window and Fourier-transform to obtain spectral estimates Phi_y, Phi_u, Phi_yu. Uses the FFT fast path when the frequency grid matches the default 128-point linear grid, and direct DFT otherwise.
- Form the transfer function estimate G = Phi_yu / Phi_u (SISO) or G = Phi_yu * Phi_u^{-1} (MIMO), and the noise spectrum Phi_v = Phi_y - |Phi_yu|^2 / Phi_u (SISO) or Phi_v = Phi_y - Phi_yu * Phi_u^{-1} * Phi_yu' (MIMO).
- Compute asymptotic standard deviations using Ljung (1999) formulae.
Specification: SPEC.md S2 -- Blackman-Tukey Spectral Analysis
References
.. [1] Ljung, L., "System Identification: Theory for the User", 2nd ed., Prentice Hall, 1999. Sections 2.3, 6.3--6.4.
See Also
sid.freq_etfe : Empirical Transfer Function Estimate (no lag window). sid.freq_btfdr : Blackman-Tukey with frequency-dependent resolution. sid.bode_plot : Bode magnitude/phase plot of a FreqResult. sid.spectrum_plot : Plot the noise/output spectrum of a FreqResult.
Changelog
2026-04-08 : First version (Python port) by Pedro Lourenco.