bundles / scipy 1.17.1 / scipy / signal / _filter_design / bessel
function
scipy.signal._filter_design:bessel
Signature
def bessel ( N , Wn , btype = low , analog = False , output = ba , norm = phase , fs = None ) Summary
Bessel/Thomson digital and analog filter design.
Extended Summary
Design an Nth-order digital or analog Bessel filter and return the filter coefficients.
Parameters
N: intThe order of the filter.
Wn: array_likeA scalar or length-2 sequence giving the critical frequencies (defined by the
normparameter). For analog filters,Wnis an angular frequency (e.g., rad/s).For digital filters,
Wnare in the same units asfs. By default,fsis 2 half-cycles/sample, so these are normalized from 0 to 1, where 1 is the Nyquist frequency. (Wnis thus in half-cycles / sample.)btype: {'lowpass', 'highpass', 'bandpass', 'bandstop'}, optionalThe type of filter. Default is 'lowpass'.
analog: bool, optionalWhen True, return an analog filter, otherwise a digital filter is returned. (See Notes.)
output: {'ba', 'zpk', 'sos'}, optionalType of output: numerator/denominator ('ba'), pole-zero ('zpk'), or second-order sections ('sos'). Default is 'ba'.
norm: {'phase', 'delay', 'mag'}, optionalCritical frequency normalization:
phaseThe filter is normalized such that the phase response reaches its midpoint at angular (e.g. rad/s) frequency
Wn. This happens for both low-pass and high-pass filters, so this is the "phase-matched" case.The magnitude response asymptotes are the same as a Butterworth filter of the same order with a cutoff of
Wn.This is the default, and matches MATLAB's implementation.
delayThe filter is normalized such that the group delay in the passband is 1/
Wn(e.g., seconds). This is the "natural" type obtained by solving Bessel polynomials.magThe filter is normalized such that the gain magnitude is -3 dB at angular frequency
Wn.
fs: float, optionalThe sampling frequency of the digital system.
Returns
b, a: ndarray, ndarrayNumerator (b) and denominator (a) polynomials of the IIR filter. Only returned if
output='ba'.z, p, k: ndarray, ndarray, floatZeros, poles, and system gain of the IIR filter transfer function. Only returned if
output='zpk'.sos: ndarraySecond-order sections representation of the IIR filter. Only returned if
output='sos'.
Notes
Also known as a Thomson filter, the analog Bessel filter has maximally flat group delay and maximally linear phase response, with very little ringing in the step response. [1]
The Bessel is inherently an analog filter. This function generates digital Bessel filters using the bilinear transform, which does not preserve the phase response of the analog filter. As such, it is only approximately correct at frequencies below about fs/4. To get maximally-flat group delay at higher frequencies, the analog Bessel filter must be transformed using phase-preserving techniques.
See besselap for implementation details and references.
The 'sos' output parameter was added in 0.16.0.
The current behavior is for ndarray outputs to have 64 bit precision (float64 or complex128) regardless of the dtype of Wn but outputs may respect the dtype of Wn in a future version.
Array API Standard Support
bessel has experimental support for Python Array API Standard compatible backends in addition to NumPy. Please consider testing these features by setting an environment variable SCIPY_ARRAY_API=1 and providing CuPy, PyTorch, JAX, or Dask arrays as array arguments. The following combinations of backend and device (or other capability) are supported.
==================== ==================== ==================== Library CPU GPU ==================== ==================== ==================== NumPy ✅ n/a CuPy n/a ⛔ PyTorch ✅ ⛔ JAX ⚠️ no JIT ⛔ Dask ⚠️ computes graph n/a ==================== ==================== ====================
See
dev-arrayapifor more information.
Examples
Plot the phase-normalized frequency response, showing the relationship to the Butterworth's cutoff frequency (green):from scipy import signal import matplotlib.pyplot as plt import numpy as np✓
b, a = signal.butter(4, 100, 'low', analog=True) w, h = signal.freqs(b, a)✓
plt.semilogx(w, 20 * np.log10(np.abs(h)), color='silver', ls='dashed')
✗b, a = signal.bessel(4, 100, 'low', analog=True, norm='phase') w, h = signal.freqs(b, a)✓
plt.semilogx(w, 20 * np.log10(np.abs(h))) plt.title('Bessel filter magnitude response (with Butterworth)') plt.xlabel('Frequency [rad/s]') plt.ylabel('Amplitude [dB]')✗
plt.margins(0, 0.1) plt.grid(which='both', axis='both')✓
plt.axvline(100, color='green') # cutoff frequency
✗plt.show()
✓
plt.figure() plt.semilogx(w, np.unwrap(np.angle(h))) plt.axvline(100, color='green') # cutoff frequency plt.axhline(-np.pi, color='red') # phase midpoint plt.title('Bessel filter phase response') plt.xlabel('Frequency [rad/s]') plt.ylabel('Phase [rad]')✗
plt.margins(0, 0.1) plt.grid(which='both', axis='both') plt.show()✓

b, a = signal.bessel(3, 10, 'low', analog=True, norm='mag') w, h = signal.freqs(b, a)✓
plt.semilogx(w, 20 * np.log10(np.abs(h))) plt.axhline(-3, color='red') # -3 dB magnitude plt.axvline(10, color='green') # cutoff frequency plt.title('Amplitude-normalized Bessel filter frequency response') plt.xlabel('Frequency [rad/s]') plt.ylabel('Amplitude [dB]')✗
plt.margins(0, 0.1) plt.grid(which='both', axis='both') plt.show()✓

b, a = signal.bessel(5, 1/0.1, 'low', analog=True, norm='delay') w, h = signal.freqs(b, a)✓
plt.figure() plt.semilogx(w[1:], -np.diff(np.unwrap(np.angle(h)))/np.diff(w)) plt.axhline(0.1, color='red') # 0.1 seconds group delay plt.title('Bessel filter group delay') plt.xlabel('Frequency [rad/s]') plt.ylabel('Group delay [s]')✗
plt.margins(0, 0.1) plt.grid(which='both', axis='both') plt.show()✓

Aliases
-
scipy.signal.bessel