Impairments#
- class IQImbalance(alpha: complex, beta: complex, *, name: str = 'iq_impairment')[source]#
Apply an IQ imbalance impairment.
Signal Model#
The output is a widely-linear combination of the input signal and its complex conjugate:
\[y[n] = \alpha x[n] + \beta x^*[n]\]Axes: element-wise – applied pointwise, shape-agnostic.
- param alpha:
Complex weight \(\alpha\) applied to the direct signal \(x[n]\).
- type alpha:
complex
- param beta:
Complex weight \(\beta\) applied to the conjugate signal \(x^*[n]\).
- type beta:
complex
- param name:
Name of the impairment instance. Default is
"iq_impairment".- type name:
str, optional, keyword-only
References
I. Fatadin, S. J. Savory, D. Ives, “Compensation of Quadrature Imbalance in an Optical QPSK Coherent Receiver,” IEEE Photonics Technology Letters 20(20), 2008.
Examples
>>> iq = IQImbalance(alpha=1.0, beta=0.1) >>> print(iq(np.array([1.0+1.0j, 1.0-1.0j]))) [1.1+0.9j 1.1-0.9j]
- class CFO(cfo: float, *, name: str = 'cfo_impairment')[source]#
Apply a Carrier Frequency Offset (CFO).
Signal Model#
The input signal is multiplied by a complex exponential phase ramp:
\[y[n] = x[n] \, e^{j \omega_0 n}\]where \(\omega_0\) is the normalized carrier frequency offset in rad/sample.
Axes: axis -1 – the time index \(n\) runs along the last axis; leading axes are batch, every row sees the same offset.
- param cfo:
Normalized carrier frequency offset \(\omega_0\) in rad/sample.
- type cfo:
float
- param name:
Name of the impairment instance. Default is
"cfo_impairment".- type name:
str, optional, keyword-only
References
J. G. Proakis, M. Salehi, Digital Communications, 5th ed., McGraw-Hill, 2008, Chapter 5.
Examples
>>> cfo = CFO(cfo=np.pi/2) >>> y = cfo(np.ones(4, dtype=complex)) >>> print(np.round(y, 2) + 0.0) [ 1.+0.j 0.+1.j -1.+0.j 0.-1.j]
- class Delay(tau: int, *, pad_zeros: bool = True, name: str = 'delay_impairment')[source]#
Discard the first \(\tau\) samples of the input signal (delay removal).
Signal Model#
The block drops the first \(\tau\) samples, i.e. it advances the signal by \(\tau\) samples:
\[y[n] = x[n + \tau], \qquad 0 \le n < N - \tau\]When
pad_zerosis True, the output is zero-padded at the end to keep the input length \(N\); otherwise the output has length \(N - \tau\).Axes: axis -1 – samples are dropped along the last axis; leading axes are batch.
The name is historical: the block models the receiver-side removal of a known delay – it advances the signal – which is why its model reads \(y[n] = x[n + \tau]\).
- param tau:
Number of samples \(\tau\) to discard (non-negative integer).
- type tau:
int
- param pad_zeros:
If True (default), pads the output with trailing zeros to match the input size \(N\).
- type pad_zeros:
bool, optional, keyword-only
- param name:
Name of the impairment instance. Default is
"delay_impairment".- type name:
str, optional, keyword-only
- raises ValueError:
If
tauis negative (validated at construction).
References
H. Meyr, M. Moeneclaey, S. Fechtel, Digital Communication Receivers, Wiley, 1998, Chapter 4 (timing offsets).
Examples
>>> delay = Delay(2) >>> print(delay(np.array([1.0, 2.0, 3.0, 4.0]))) [3. 4. 0. 0.]