Polyphase Channelizer
This post explores the intuition behind the polyphase channelizer. All of the plots are interactive (generated using Plotly).
The polyphase channelizer is a powerful tool used to efficiently split a wideband signal into multiple narrower channels. The plot below shows a simplified block diagram illustrating how a single channel is extracted, which we will examine first. Once we understand this process, we will modify the block diagram to extract all channels simultaneously.
Consider the following spectrum for a wide-band input signal (x), which has been decomposed into its four constituent channels (ch0, ch1, ch2, and ch3), each containing a narrow-band signal.
Say we wish to extract the four narrow band signals while lowering the sampling rate. There are many ways to do this. Let us first walk through the most intuitive way, which is a straightforward decimation (anti-alias-filtering followed by down-sampling).
Simple Decimation Filter
For illustration, let us extract the signal on channel 3 (denoted “ch3” in the previous plot).
We first apply a digital frequency shift to center the desired channel around DC. In practice, this is done by multiplying the IQ samples in time with a complex sinusoid with the proper frequency.
Next, we apply anti-aliasing filter to attenuate all other channels, preventing them from folding down to DC when we down-sample later. In this case, I used a 64-tap finite impulse response (FIR) low-pass filter synthesized using the firwin function in the scipy.signals module:
The filtered signal looks like this:
Finally, we down-sample the filtered signal with a factor of 4.
As an aside, checkout my post here on visualizing the down-sampling process in the frequency domain.
Notice that during decimation filtering, we are discarding a large amount of the samples, on which we have spent a considerable amount of computation resources. We had to convolve the wide-band input signal with a 64-tap FIR filter.
Furthermore, if we wish to extract the other three channels, we would need to quadruple the amount of computation.
Polyphase Channelizer
A polyphase channelizer realizes the same effect as the decimation filter much more efficiently.
To illustrate this, let us consider the following wide-band waveform, consisting of four narrow-band signals, each with a perfectly flat spectrum:
To aid visualization, let us also assume that the signal has a purely real spectrum. The intuition developed in this case can later be generalized to arbitrary waveforms with complex spectra. We can now plot the spectrum of the signal on a complex IQ plane:
Polyphase Components of the Input Signal
First, the original signal is decomposed into four parallel streams, each operating at one-quarter of the original sampling rate. These streams are staggered with respect to one another by one-sample increments.
At first glance, it may seem surprising that the signals are down-sampled without any anti-aliasing filter. Intuitively, this should make it impossible to recover the desired signals on each channel, since the spectral content would fold over and overlap.
Indeed, if we examine only a single down-sampled stream, this is exactly what happens. However, when we consider all four streams together and decompose each into contributions from the four narrow-band signals, we find that each stream contains a unique mixture of these signals, distinguished by different phase shifts. The following plot illustrates this effect. Play with the slider to visualize the decomposition of different streams.
With each stream alone, it is indeed impossible to recover the four narrow-band signals, as expected from the Nyquist sampling criterion. However, the advantage of a polyphase channelizer is that by cleverly combining the four parallel streams (after some processing), it becomes possible to cancel out the unwanted signal components while preserving the one of interest. Let us see how this is possible, by looking at the frequency response of the filter.
Polyphase Components of the Filter
The filter we wish to apply to the input signal (h) has the following frequency response:
From the block diagram of the polyphase channelizer, we see that, just like the input signal, the filter itself is decomposed into 4 staggered, down-sampled sub-filters. These are called the polyphase components of the original filter h0.
Polyphase Filter Bank
The following plot is slightly busy, but you can disable individual traces by clicking on the legend.
The first set of traces corresponds to the inputs to the polyphase filter bank. More specifically, each plot shows the contribution of a single channel (ch0, ch1, ch2, and ch3) to the four polyphase filters (h0, h1, h2, and h3). Recall from the block diagram that each filter receives contributions from all four channels, but with different delays.
The dotted lines represent the frequency responses of the polyphase filters (h0, h1, h2, and h3).
Finally, the last set of traces corresponds to the outputs of the polyphase filters, obtained by multiplying the input traces with their respective filter responses. In the time domain, this would be a convolution operation.
To focus on the outputs of the filter bank, the following plot replicates the one above, except only the outputs are shown for clarity.
Lastly, after applying a one-sample delay to the outputs of h1, h2, and h3 and zero delay to the output of h0, we obtain the following signals. These are then summed to produce the final output of the polyphase channelizer.
It should now be evident that the contributions from ch1, ch2, and ch3 cancel due to being out of phase, leaving only the contribution from ch0.
Extraction of Other Channels
A closer examination of the previous figure gives us some insight into how the other channels, besides ch0, can be extracted. By applying an appropriate phase shift to the outputs of the polyphase filter bank, we can cause any of ch1, ch2, or ch3 to sum constructively, while the remaining channels cancel out due to being out of phase.
Recall that a phase shift of (\phi) corresponds to a rotation of (\phi) degrees of the frequency spectrum for all positive frequencies, and a rotation of -(\phi) degrees for all negative frequencies. Checkout my post on this topic here.
With that in mind, we can now introduce the complete block diagram for the polyphase channelizer:
Earlier, we saw that at the first output y0, only ch0 adds in phase, while ch1, ch2, and ch3 cancel out. Let’s now examine the other three outputs, each of which incorporates additional phase shifts.
We can see that at each of the outputs y1, y2, and y3, only ch1, ch2, and ch3 respectively add in phase.
Final Implementation
A careful reader may notice that the combining matrix at the output of the polyphase filter bank looks very familiar. In fact, it is identical to the matrix multiplication implementation of the discrete Fourier transform (DFT). This observation allows us to simplify the block diagram of the polyphase channelizer as follows:
Non-ideal FIR Filters
Up to this point, we have only considered low-pass filters with ideal brick-wall responses, where the gain is exactly zero outside the filter bandwidth. In practice, however, FIR filters cannot achieve such a response and will exhibit some ripples outside the cutoff frequency.
This raises an important question: what happens when we down-sample a real FIR filter which does not have zero gain outside the passband? For instance, consider the following non-ideal filter:
As long as the signal completely fits inside the filter bandwidth, the it will pass through the filter without any distortion.
But what happens when we try to implement this filter using a polyphase filter bank? Decomposing this filter into its four polyphase components reveals that each component is distorted due to aliasing, since down-sampling folds the out-of-band filter response back into the passband of each polyphase branch:
If all of the polyphase components are distorted, how can a narrowband signal still pass through the filter bank without distortion? The answer lies in the magic of the polyphase structure: the phase shifts introduced by the delays in the downsampled input and those from the polyphase filter components interact in just the right way. As a result, the outputs acquire the necessary phases such that when combined, the distortions cancel out, leaving us with the expected output.
Sample Python Code to Test Polyphase Filter
The following Python code demonstrates the equivalence between a polyphase filter and the simple decimation filter.
import numpy as np
from scipy.fft import fft, ifft
x = np.random.randn(12)
h = np.random.randn(6)
y_filt_down = ifft(fft(x,12)*fft(h,12))
y_filt_down = y_filt_down[0::3]
h0 = h[0::3]
h1 = h[1::3]
h2 = h[2::3]
x0 = x[0::3]
x1 = x[1::3]
x2 = x[2::3]
y0 = ifft(fft(x0,4)*fft(h0,4))
y1 = ifft(fft(x2,4)*fft(h1,4))
y2 = ifft(fft(x1,4)*fft(h2,4))
y_filt_poly = np.roll(y0, 0) + np.roll(y1, 1) + np.roll(y2, 1)