sdr.iq_imbalance(x: NDArray, amplitude: float, phase: float = 0) NDArray

Applies IQ imbalance to the complex time-domain signal \(x[n]\).

Parameters:
x: NDArray

The complex time-domain signal \(x[n]\) to which IQ imbalance is applied.

amplitude: float

The amplitude imbalance \(A\) in dB. A positive value indicates that the in-phase component is larger than the quadrature component.

phase: float = 0

The phase imbalance \(\phi\) in degrees. A positive value indicates that the quadrature component leads the in-phase component.

Returns:

The signal \(x[n]\) with IQ imbalance applied.

Notes

The IQ imbalance is applied as follows.

\[g_I = 10^{(A/2)/20} \exp\left(j \frac{-\phi}{2} \frac{\pi}{180}\right)\]
\[g_Q = 10^{(-A/2)/20} \exp\left(j \frac{\phi}{2} \frac{\pi}{180}\right)\]
\[y[n] = g_I x_I[n] + j g_Q x_Q[n]\]

Examples

Positive amplitude imbalance horizontally stretches the constellation, while negative amplitude imbalance vertically stretches the constellation.

In [1]: psk = sdr.PSK(4, phase_offset=45); \
   ...: s = np.random.randint(0, 4, 1_000); \
   ...: x = psk.modulate(s); \
   ...: y1 = sdr.iq_imbalance(x, 5, 0); \
   ...: y2 = sdr.iq_imbalance(x, -5, 0)
   ...: 

In [2]: plt.figure(figsize=(10, 5)); \
   ...: plt.subplot(1, 2, 1); \
   ...: sdr.plot.constellation(x, label="$x[n]$"); \
   ...: sdr.plot.constellation(y1, label="$y_1[n]$"); \
   ...: plt.legend(); \
   ...: plt.title("5 dB amplitude imbalance"); \
   ...: plt.subplot(1, 2, 2); \
   ...: sdr.plot.constellation(x, label="$x[n]$"); \
   ...: sdr.plot.constellation(y2, label="$y_2[n]$"); \
   ...: plt.legend(); \
   ...: plt.title("-5 dB amplitude imbalance");
   ...: 
../../_images/sdr_iq_imbalance_1.png

Positive phase imbalance stretches to the northwest, while negative phase imbalance stretches to the northeast

In [3]: y1 = sdr.iq_imbalance(x, 0, 20); \
   ...: y2 = sdr.iq_imbalance(x, 0, -20)
   ...: 

In [4]: plt.figure(figsize=(10, 5)); \
   ...: plt.subplot(1, 2, 1); \
   ...: sdr.plot.constellation(x, label="$x[n]$"); \
   ...: sdr.plot.constellation(y1, label="$y_1[n]$"); \
   ...: plt.legend(); \
   ...: plt.title("20 deg phase imbalance"); \
   ...: plt.subplot(1, 2, 2); \
   ...: sdr.plot.constellation(x, label="$x[n]$"); \
   ...: sdr.plot.constellation(y2, label="$y_2[n]$"); \
   ...: plt.legend(); \
   ...: plt.title("-20 deg phase imbalance");
   ...: 
../../_images/sdr_iq_imbalance_2.png