Predistorders#
- class HardClipper(cr_dB: float, *, name: str = 'hard_clipping')[source]#
Implements a hard clipping method to reduce the Peak-to-Average Power Ratio (PAPR) of a signal.
Signal Model#
Hard clipping limits the amplitude of the signal to a threshold \(T_m\) while preserving the phase, reducing the peaks of the signal while keeping the average power relatively unchanged:
\[\begin{split}y[n] = \left\{\begin{array}{cl} x[n] & \text{if } |x[n]| \le T_m,\\ T_m \, e^{i \angle x[n]} & \text{if } |x[n]| > T_m, \end{array}\right. \qquad T_m = \gamma \sqrt{P_x}\end{split}\]where:
\(x[n]\) is the input signal and \(y[n]\) the clipped output,
\(P_x = \mathbb{E}\left[|x[n]|^2\right]\) is the mean input power,
\(\gamma = 10^{\mathrm{CR_{dB}}/20}\) is the clipping ratio.
For real-valued inputs, \(T_m \, \mathrm{sign}(x[n])\) replaces the polar form.
Axes: axis -1 – the clipping is applied pointwise, but the threshold \(T_m\) is computed from the mean power along the last axis, so each row of a batch is clipped against its own power – one transmitter per trial (D51).
- param cr_dB:
Clipping ratio \(\mathrm{CR_{dB}}\) in decibels (dB). Determines the threshold for clipping.
- type cr_dB:
float
- param name:
Name of the processor. Default is
"hard_clipping".- type name:
str, optional, keyword-only
References
Y. Rahmatallah, S. Mohan, “Peak-To-Average Power Ratio Reduction in OFDM Systems: A Survey And Taxonomy”, IEEE Communications Surveys & Tutorials, vol. 15, no. 4, pp. 1567-1592, 2013, doi: 10.1109/SURV.2013.021313.00164.
Examples
>>> x = np.array([0.5, 2.0, -3.0]) >>> clipper = HardClipper(cr_dB=0) >>> print(np.round(clipper(x), 3)) [ 0.5 2. -2.102]
- class IctPaprReductor(PAPR_max_dB: float, filter_weight: float, *, N_it: int = 16, shift: bool = False, norm: str = 'ortho', name: str = 'ICT')[source]#
Implements the Iterative Clipping and Filtering (ICT) method for Peak-to-Average Power Ratio (PAPR) reduction in OFDM signals.
Signal Model#
The frequency-domain input is iteratively transformed to the time domain, clipped, transformed back and filtered. Starting from \(X^{(0)}[k] = X[k]\), each iteration \(i = 1, \dots, N_{it}\) computes:
\[s^{(i)}[n] = \mathrm{IDFT}\{X^{(i-1)}\}[n], \qquad X^{(i)}[k] = w \, \mathrm{DFT}\{\mathrm{clip}(s^{(i)})\}[k]\]where \(\mathrm{clip}(\cdot)\) is the phase-preserving amplitude clipping of
HardClipperwith the per-block threshold:\[T_m = \gamma \sqrt{P_s}, \qquad \gamma = \sqrt{10^{\mathrm{PAPR_{max}}/10}},\]and where:
\(X[k]\) is the frequency-domain input at subcarrier \(k\),
\(P_s\) is the mean power of the current time-domain block \(s^{(i)}[n]\),
\(\mathrm{PAPR_{max}}\) is the target maximum PAPR in dB,
\(w\) is the filtering weight applied in the frequency domain.
The output is the time-domain signal \(y[n] = \mathrm{IDFT}\{X^{(N_{it})}\}[n]\).
Axes: axis -1 – each block of the Block layout
(..., T, F)is processed along the block content axis.- param PAPR_max_dB:
Target maximum PAPR \(\mathrm{PAPR_{max}}\) in decibels (dB).
- type PAPR_max_dB:
float
- param filter_weight:
Weighting factor \(w\) applied during the filtering step.
- type filter_weight:
float
- param N_it:
Number of iterations \(N_{it}\) for the clipping and filtering process. Default is 16.
- type N_it:
int, optional, keyword-only
- param shift:
Whether to apply an inverse FFT shift before the final IFFT. Default is False.
- type shift:
bool, optional, keyword-only
- param norm:
Normalization mode for the final IFFT. Default is “ortho”.
- type norm:
str, optional, keyword-only
- param name:
Name of the processor. Default is “ICT”.
- type name:
str, optional, keyword-only
References
Y.-C. Wang, Z.-Q. Luo, “Optimized iterative clipping and filtering for PAPR reduction of OFDM signals”, IEEE Transactions on Communications, vol. 59, no. 1, pp. 33-37, 2011.
Examples
>>> X = np.array([[1, 1, -1, 1, 1, -1, -1, 1]], dtype=complex) >>> reductor = IctPaprReductor(PAPR_max_dB=2.0, filter_weight=1.0) >>> y = reductor(X) >>> print(round(float(compute_papr(y[0], unit="dB")), 2)) 2.0
- class PtsPaprReductor(phase_alphabet: list[complex] | None = None, *, N_sub: int = 16, name: str = 'PTS')[source]#
Implements the Partial Transmit Sequences (PTS) method for Peak-to-Average Power Ratio (PAPR) reduction in OFDM signals.
Signal Model#
Each frequency-domain block \(X[k]\) of length \(N\) is partitioned into \(M\) disjoint adjacent sub-blocks \(X_m[k]\) (each keeping its \(N/M\) contiguous subcarriers and zeros elsewhere). The transmitted time-domain block is the phase-rotated combination:
\[y[n] = \sum_{m=1}^{M} \hat{b}_m \, \mathrm{IDFT}\{X_m\}[n]\]where the phase factors are selected by exhaustive search over the phase alphabet \(\mathcal{B}\) to minimize the PAPR:
\[(\hat{b}_1, \dots, \hat{b}_M) = \arg\min_{b_m \in \mathcal{B}} \mathrm{PAPR}\left(\sum_{m=1}^{M} b_m \, \mathrm{IDFT}\{X_m\}\right)\]and where:
\(X[k]\) is the frequency-domain input at subcarrier \(k\),
\(M\) is the number of sub-blocks,
\(\mathcal{B}\) is the phase factor alphabet,
\(y[n]\) is the time-domain output block.
Axes: declared axis – expects the 2-D Block layout
(T, F), validated inprepare(); one phase combination is optimized per block and the IDFT runs along the block content axis.- param phase_alphabet:
Phase factor alphabet \(\mathcal{B}\) used in the PTS method. Default is
[1, -1].- type phase_alphabet:
list, optional
- param N_sub:
Number of sub-blocks \(M\) the OFDM signal is divided into. Default is 16.
- type N_sub:
int, optional, keyword-only
- param name:
Name of the processor. Default is “PTS”.
- type name:
str, optional, keyword-only
References
L. J. Cimini, N. R. Sollenberger, “Peak-to-average power ratio reduction of an OFDM signal using partial transmit sequences”, 1999 IEEE International Conference on Communications, Vancouver, BC, Canada, 1999, pp. 511-515 vol. 1, doi: 10.1109/ICC.1999.767992.
Examples
>>> reductor = PtsPaprReductor([1, -1], N_sub=2) >>> Y = reductor(np.ones((1, 4), dtype=complex)) >>> print(np.round(Y, 3) + 0.0) [[0.+0.j 1.+1.j 0.+0.j 1.-1.j]] >>> print(round(float(compute_papr(Y[0], unit="dB")), 2)) 3.01