0

We are currently analyzing a large set of IQ samples in a desktop application and we are interested in implementing many different bandpass filters dynamically.

We realized, that working with scipy offers no suppport for complex bandpass filtering.

We have already checked following link which suggests a solution to the problem when it is decided to approach the problem with complex filters: How to implement bandpass filter on complex valued signal?

We wonder, why that is even necessary, since the data could be transformed to a real format. Instead of $[-f_s/2, f_s/2]$ the range is from $[0,fs]$ (mirrored about the $0\,Hz$ point). This way already implemented filtering tools could be used.

Tiaro
  • 3
  • 3
  • 1
    Just as your signal spectrum wraps around the unit circle in the z plane and has aliases, so does the frequency response of your filter. Real filters have an image at negative frequency and that will show up and an alias as you move around the unit circle in the z plane. There is no free lunch. If you want a one sided filter, the Fourier Transform theorems tell you that your filter taps must be complex. – Andy Walls Jul 24 '20 at 15:40
  • If we didn't misunderstand you @AndyWalls, we totally agree with your point. But why wouldn't you just mutiply the IQ samples by $\cos (2 \pi f_s/2)$ to shift their spectrum in both directions by $f_s/2$, such that the spectrum becomes symmetric and thus the samples become real? – Tiaro Jul 24 '20 at 15:50

2 Answers2

0

A real signal is complex conjugate symmetric, so any filter over $-fs/2$ to $+fs/2$ is really only unique over the range from $0$ to $fs/2$. This would be a primary motivation for working with a fully complex signal as the unique range is then truly extended over the full $-fs/2$ to $+fs/2$ range.

Another more dominant reason to implement a complex filter besides the bandwidth requirement outlined above (where the choice is really sample twice as much or carry two datapaths; similar complexity and certainly you could map either to be similar if that was the only goal) is when the passband itself is not symmetric: specifically as a bandpass filter when the positive frequency passband is not equal and magnitude and conjugate in phase to the negative frequency, or as a baseband filter- the passband shape itself is asymmetric or perhaps completely one sided. Another dominant reason is when real signal conditions would create images very close to the signal where further filtering would be difficult, such as if conditions require operating very close to the Nyquist boundary. If the OP doesn't have these conditions, I don't see a strong motivation for complex filtering, which requires 4 real multipliers for every complex multiplication operation (assuming complex inputs and outputs).

Channel equalization is another example where a full complex filter is often necessary (as an implementation on a baseband signal) but not needed for a passband signal.

Dan Boschen
  • 50,942
  • 2
  • 57
  • 135
  • What about SNR considerations? – Cedron Dawg Jul 25 '20 at 00:24
  • @CedronDawg What is your question exactly? Comparing what to what specifically? In most use cases there isn't an SNR difference (both the signal and the noise are -3dB in the positive and negative frequency) but the ability to simplify filtering, separation of images, unless you are doing something completely incorrectly (such as using complex processing on a real signal) - but maybe you are thinking of something else--- let me know more details /specifics of your question-- or if you have insights to share. – Dan Boschen Jul 25 '20 at 00:58
  • Well, the RMS of a pure complex tone is 1.0, while a real tone is 0.707. On a Db scale that is a drop of 1.5. In "power" it's 3 dB. In particular, the SNR is low at zero crossings for a real tone, with the peak being the max. A complex tone is at max throughout the cycle. So, it's another tradeoff consideration. For someone like me who often does stuff down in the one to two cycle range, it sure seems significant. – Cedron Dawg Jul 25 '20 at 01:33
  • @Cedron Keep in mind that the pure complex tone has twice the noise from I + jQ which is +3dB so no change in SNR for your example! When we take the real part of a signal in the receiver, the noise drops by 3dB, this is the motivation to rotate BPSK signals to the real axis and then once carrier recovery is done take the real part to get the +3dB gain. But yes there are a lot of advantages and motivations to use complex signals (I much prefer them-- but SNR doesn't seem to be one of them at least in this context). The max through its cycle is consistent with no image issue. – Dan Boschen Jul 25 '20 at 01:36
  • (Meaning to the extent the noise on the real and imaginary axis are independent noise processes, there would be a drop of 3 dB when you go from complex to real) This may be helpful https://dsp.stackexchange.com/questions/54251/psd-of-complex-white-gaussian-noise/54253#54253 – Dan Boschen Jul 25 '20 at 01:39
  • Assuming adding I to a quarter cycle shifted Q (aligned), the variance at each sample is say, V. When you add the signals, the signal values add, and the noise variances add (V+V), then you divide by two (V+V)/2, so the signal value stays the same at that point and so does the variance. So I don't see where the noise reduction is at, yet it easy to see that the signal values will be smaller. ??? If you just strip the I or Q, clearly the SNR will be worse. – Cedron Dawg Jul 25 '20 at 02:13
  • A complex Gaussian noise process is given by I+jQ where I and Q are each a Gaussian white noise process, half the noise is on the real component and half is on the imaginary, they are each independent of each other. If you haven't seen the link I referred above I think that will explain better. Let's not get into a long discussion here as I am getting the pop-up warning --- and our moderators want us to avoid that. (If you have a real question on that not already explained in the post,then post that as a new question-- if you have a better answer, then post that as a new answer). – Dan Boschen Jul 25 '20 at 02:19
  • Nah, I'd have to look into this some. It may just be a definitional thing that I don't have right. – Cedron Dawg Jul 25 '20 at 02:26
  • @DanBoschen As we understood, the sampled real signal is only unique in the range $0$ to $F_s/2$ (that is probably a typo in your post?). So the reason to use complex signals is to extend the range, $-F_s/2$ to $F_s/2$. We wonder if there is a way to transform the complex signal to a real form. We probably needed to upsample it first. Then it could be multiplied by a complex exponential to shift it to one side, making it a complex passband signal. But how to proceed from there? – Tiaro Jul 27 '20 at 08:01
  • For example reverse of the approach stated in this post. Do you see any disadvantage in that approach? – Tiaro Jul 27 '20 at 08:10
  • @muubie yes you are correct it should have been Fs/2, thanks I updated that. I assume you mean translate to real but maintain all information that was in the imaginary (rather than simply taking the real of the signal). I don't see any issue with doing that. Also in case you didn't compare yet, Matlab/Octave have cfirmpm to design a complex filter (Matlab/Octave)- only needed if the required filter shape itself is actually asymmetric about zero. Otherwise it would just be a real filter on I and Q separately which is common for most filtering requirements. – Dan Boschen Jul 27 '20 at 12:09
  • @DanBoschen Yes we want to maintain all information in the real and imaginary parts. The filters we want to apply would be asymmetric about zero. We had seen that MATLAB/Octave has a tool to generate complex filters, the problem is, we don't know the parameters of the filters in advance, we need to be able to adjust them dynamically, dependent on the current data set. Writing a Octave-Python wrapper would have been a lot of work and a licensing issue too. So converting all information from complex numbers to real numbers and applying real filters seems to be the best solution. Thank you. – Tiaro Jul 27 '20 at 16:37
  • @muubie Undestood, sounds like a good solution to me. – Dan Boschen Jul 27 '20 at 18:14
0

If your filter is real:

If you have a strictly real signal that is bandlimited to well below Fs/4, then you can complex modulate the signal to rotate the spectrum so that it is strictly in the upper (or lower) half of the complex plane (zero complex conjugate). Then you can use strictly real filtering tools on the separated components of the complex signal (e.g. using regular arithmetic instead of complex) to work on the original upper and lower sidebands asymmetrically, and then modulate the resulting signal back down to baseband to get a complex result.

That’s because a strictly real LTI filter applied to a complex signal is equivalent to applying it to the separated components. And also applying this filter to a null half spectrum results in a null half spectrum.

If your filter is complex but symmetric around some axis, you can do something similar to rotate both the data and the spectrum in the complex plane so that you can use strictly real filtering tools on the IQ components. Then rotate back to finish.

Depending on the order of your filter, the two complex modulators can easily cost less than increasing the number of multiply instructions in each filter by 4 to do complex filtering.

hotpaw2
  • 35,346
  • 9
  • 47
  • 90
  • If you have a pure tone with a frequency between $F_s/4$ and $F_s/2$, the range of 4 samples per cycle down to 2 samples per cycle, or as I like to think of it, from the sweet spot to Nyquist, you can simply flip the sign of every other sample. This is the equivalent of rotating the the conjugate pair by a Nyquist pure complex tone. Therefore they end up as a conjugate pair between DC and $F_s/4$ in frequency, the phase negated and the magnitude preserved. Something I figured out to my chagrin after an attempt to try it a different way. https://dsp.stackexchange.com/questions/69325/ – Cedron Dawg Jul 26 '20 at 00:10
  • @hotpaw2 As we understand from your post, the only restriction from transforming a complex signal into a real one is the sampling rate. If we upsampled the signal, it would be possible to transform it to real form. Since there is plenty of computing power (CPU and GPU) and enough memory, we see no reason to not transform to real form. The reason is, we wish to use standard filtering tools, which are unfortunately only implemented for real signals in the libraries we use (scipy and numpy). Basically we try to avoid implementing self-made, error-prone DSP-algorithms. – Tiaro Jul 27 '20 at 08:23