Filters#
- class SRRCFilter(rho: float, oversampling: int, *, N_h: int = 10, norm: bool = True, scale: float = 1.0, method: Literal['lfilter', 'fft'] = 'lfilter', axis: int = -1, name: str = 'SRRCFilter')[source]#
Square-root raised cosine (SRRC) FIR pulse-shaping filter.
Signal Model#
The output is the discrete convolution of the input with the truncated SRRC impulse response \(h[m]\):
\[y[n] = \sum_{m=0}^{2 N_h L} h[m] \, x[n - m]\]The taps are the continuous-time SRRC response sampled at \(t = m / L\) symbol periods, where \(L\) is the oversampling factor. With a symbol period normalized to \(T = 1\) and a roll-off factor \(\rho \in [0, 1]\):
\[h(t) = \frac{\sin\left(\pi t (1 - \rho)\right) + 4 \rho t \cos\left(\pi t (1 + \rho)\right)} {\pi t \left(1 - (4 \rho t)^2\right)}\]completed at its two removable singularities by
\[h(0) = 1 + \rho \left(\frac{4}{\pi} - 1\right), \qquad h\left(\pm \frac{1}{4 \rho}\right) = \frac{\rho}{\sqrt{2}} \left[ \left(1 + \frac{2}{\pi}\right) \sin \frac{\pi}{4 \rho} + \left(1 - \frac{2}{\pi}\right) \cos \frac{\pi}{4 \rho} \right]\]The response is truncated to \(t \in [-N_h, N_h]\), i.e. \(2 N_h L + 1\) taps, and scaled to unit energy \(\sum_m h^2[m] = 1\) when
normis True.Why the square root, and why on both sides. Nyquist’s first criterion states that a pulse \(g(t)\) produces no intersymbol interference when it vanishes at every non-zero multiple of the symbol period, \(g(mT) = 0\) for \(m \neq 0\). The raised cosine pulse satisfies it. Here the criterion must hold on the cascade transmit filter / matched receive filter, not on either one alone: splitting the raised cosine into two identical square-root factors,
\[G_{\mathrm{RC}}(f) = H_{\mathrm{SRRC}}(f) \, H_{\mathrm{SRRC}}^*(f) = \left| H_{\mathrm{SRRC}}(f) \right|^2\]gives a receive filter matched to the transmit pulse – which maximizes the sampled signal-to-noise ratio in additive white Gaussian noise – while their convolution is the raised cosine, hence ISI-free at the symbol instants. The same
SRRCFilterinstance is therefore placed at the transmitter and at the receiver.Axes: axis -1 – both methods filter along the last axis and broadcast over the leading ones, so a polarization pair
(..., 2, N)is shaped one polarization at a time.- param rho:
Roll-off factor \(\rho \in [0, 1]\).
rho = 0gives the sinc pulse (minimum bandwidth \(1/2T\)),rho = 1doubles the excess bandwidth.- type rho:
float
- param oversampling:
Oversampling factor \(L\) in samples per symbol; the taps are the response sampled at \(t = m / L\).
- type oversampling:
int
- param N_h:
Half-length \(N_h\) of the filter in symbol periods, so the FIR has \(2 N_h L + 1\) taps. Default is 10.
- type N_h:
int, optional, keyword-only
- param norm:
If True, normalize the taps to unit energy \(\sum_m h^2[m] = 1\). Default is True.
- type norm:
bool, optional, keyword-only
- param scale:
Amplitude scaling factor applied to the output. Default is 1.0, applied by both methods.
- type scale:
float, optional, keyword-only
- param method:
Filtering method:
"lfilter"for the causal FIR convolution (scipy.signal.lfilter),"fft"for the circular frequency-domain product with the delay-compensated response returned byH(). Default is"lfilter".- type method:
{“lfilter”, “fft”}, optional, keyword-only
- param axis:
Filtering axis. Default is -1. The
"lfilter"method honours it; the"fft"method always filters along the last axis.- type axis:
int, optional, keyword-only
- param name:
Name of the filter instance. Default is
"SRRCFilter".- type name:
str, optional, keyword-only
References
J. G. Proakis, M. Salehi, Digital Communications, 5th ed., McGraw-Hill, 2008, Chapter 9 (signal design for band-limited channels: Nyquist criterion, raised cosine and its square root).
Examples
>>> srrc = SRRCFilter(0.25, 4) # roll-off 0.25, 4 samples per symbol >>> h = srrc.h() >>> h.shape, round(float(np.sum(h ** 2)), 6) ((81,), 1.0) >>> g = np.convolve(h, h) # transmit pulse * matched filter = raised cosine >>> print(np.round(np.abs(g[len(h) - 1 + 4::4][:5]), 3)) # t = T, 2T, ... [0. 0. 0. 0. 0.]
- class BWFilter(wn: float)[source]#
Ideal (brick-wall) low-pass filter applied in the frequency domain.
Note
Despite the class name, this block does not implement a Butterworth response: the mask below is rectangular, i.e. an ideal low-pass with infinite roll-off, not the \(|H(f)|^2 = 1 / (1 + (f/f_c)^{2N})\) magnitude of a Butterworth filter of order \(N\). The docstring describes what the code does.
Signal Model#
The input block of \(N\) samples is transformed, masked and transformed back:
\[y[n] = \frac{1}{N} \sum_{k=0}^{N-1} H[k] \, X[k] \, e^{j 2 \pi k n / N}, \qquad X[k] = \sum_{n=0}^{N-1} x[n] \, e^{-j 2 \pi k n / N}\]with the rectangular mask
\[\begin{split}H[k] = \begin{cases} 1 & \text{if } |f[k]| \leq w_n / 2 \\ 0 & \text{if } |f[k]| > w_n / 2 \end{cases}\end{split}\]where \(f[k]\) is the frequency of bin \(k\) in cycles per sample (
fftfreq(N, d=1), so \(|f[k]| \leq 1/2\)) and the cutoff \(w_n\) is normalized to the Nyquist frequency, the convention ofscipy.signal: \(w_n = 1\) passes the whole band, \(w_n = 1/L\) keeps the band of a signal oversampled by \(L\). Because the mask is applied to a length-\(N\) DFT, the operation is a circular convolution with a periodic sinc of length \(N\), not a linear one.Axes: axis -1 – the FFT mask acts on the last axis; leading axes are batch.
- param wn:
Critical (cutoff) frequency \(w_n\), normalized so that \(w_n = 1\) is the Nyquist frequency (
scipy.signalconvention), hence \(0 < w_n \leq 1\). The retained band in cycles per sample is \(|f| \leq w_n / 2\).- type wn:
float
- raises ValueError:
If
wnis outside \((0, 1]\).
References
A. V. Oppenheim, R. W. Schafer, Discrete-Time Signal Processing, 3rd ed., Prentice Hall, 2010, Chapter 2 (ideal frequency-selective filters) and Chapter 8 (filtering by DFT multiplication and its circular nature).
Examples
>>> n = np.arange(64) >>> x = np.cos(2*np.pi*4*n/64) + np.cos(2*np.pi*20*n/64) # f = 1/16 and 5/16 >>> y = BWFilter(0.2)(x) # cutoff 0.2 x Nyquist = 0.1 cycles/sample >>> print(np.round(y[:4].real, 6)) [1. 0.92388 0.707107 0.382683]