Validation: transmitter power amplifier nonlinearity¶
Validated with documented limitations.
1. The component¶
A power amplifier (PA, the output stage of a radio transmitter that boosts the signal to the required transmission power) introduces nonlinear distortion as the signal envelope approaches the amplifier’s saturation point. This module implements two classical memoryless PA distortion models and a factory that selects between them by configuration.
“Memoryless” means the distorted output at any instant depends only on the input envelope at that same instant; bias-network dynamics and thermal time constants are out of scope.
Class signature and entry point:
class BasePANonlinearity(BaseChannel):
transformation: ClassVar[Transformation] = Transformation.PA
@abstractmethod
def apply(self, signal: Signal, ctx: ChannelContext) -> Signal: ...
class RappPA(BasePANonlinearity):
def __init__(self, *, p: float = 2.0, a: float = 1.0) -> None: ...
def apply(self, signal: Signal, ctx: ChannelContext) -> Signal: ...
class SalehPA(BasePANonlinearity):
def __init__(
self,
*,
alpha_a: float = 2.1587,
beta_a: float = 1.1517,
alpha_phi: float = 4.0033,
beta_phi: float = 9.1040,
) -> None: ...
def apply(self, signal: Signal, ctx: ChannelContext) -> Signal: ...
def select_pa_nonlinearity(params_dict: Mapping[str, Any]) -> BasePANonlinearity: ...
Parameter table:
Name |
Type |
Units |
Default |
Purpose |
|---|---|---|---|---|
|
float |
dimensionless |
2.0 |
Rapp smoothness; higher = sharper knee (more abrupt saturation) |
|
float |
amplitude units |
1.0 |
Rapp saturation amplitude; envelope at which output saturates |
|
float |
dimensionless |
2.1587 |
Saleh AM/AM numerator; small-signal gain equals this value |
|
float |
dimensionless |
1.1517 |
Saleh AM/AM denominator coefficient |
|
float |
rad |
4.0033 |
Saleh AM/PM (amplitude-to-phase conversion) numerator |
|
float |
dimensionless |
9.1040 |
Saleh AM/PM denominator coefficient |
Worked example:
import torch
from rfgen.tx_impairments import RappPA, SalehPA
from rfgen.core_types import Signal, SignalMetadata
# Build a test signal with a ramp of amplitudes on the I channel
n = 4
iq = torch.zeros((2, n), dtype=torch.float32)
iq[0] = torch.tensor([0.1, 0.5, 1.0, 2.0])
signal = Signal(iq=iq, metadata=SignalMetadata(...))
out_rapp = RappPA(p=2.0, a=1.0).apply(signal, ctx)
# out_rapp.iq shape: (2, 4), dtype: float32
# I channel compressed near saturation; Q channel = 0.0 (no phase shift)
out_saleh = SalehPA().apply(signal, ctx)
# out_saleh.iq shape: (2, 4), dtype: float32
# Both I and Q non-zero above small-signal regime (AM/PM rotates phase)
Model taxonomy. The Rapp model represents a solid-state power amplifier (SSPA, a PA built on semiconductor devices such as GaAs FETs or GaN HEMTs). The Saleh model represents a travelling-wave tube amplifier (TWTA, a vacuum-tube device used in satellite transponders), with the default coefficients fit to a Hughes 261-H helix TWT at 6 GHz as reported in Saleh (1981). Both models produce complex baseband (the low-frequency representation of a bandpass signal, using in-phase I and quadrature Q channels to encode amplitude and phase) IQ output at float32/complex64 precision.
2. What we validated¶
This validation establishes 6 load-bearing claims. Each is restated and supported by evidence in §3.
Rapp AM/AM closed-form agreement (§3.1): the implementation matches Rapp (1991) Eq. (3) to numerical tolerance.
Saleh AM/AM and AM/PM closed-form agreement (§3.2): the implementation matches Saleh (1981) Eqs. (12)-(13) to numerical tolerance.
Saleh default coefficients reproduce Saleh-1981 Table II (§3.3): all four coefficients match the primary source exactly.
Hard-knee and small-signal limits match published behavior (§3.4): Rapp at large p approaches a soft-limiter; Saleh small-signal gain approaches alpha_a.
Determinism (§3.5): both models produce byte-identical output on repeated calls with identical inputs.
Operating envelope: zero and large input (§3.6): both models are finite at r = 100 and exact at r = 0.
Limits and scope-bounded items appear in §4; full citations are in §5.
3. Evidence per claim¶
3.1 Rapp AM/AM closed-form agreement¶
The Rapp solid-state PA (SSPA) AM/AM transfer is (Rapp 1991, Eq. 3):
y(t) = x(t) * (1 + (|x(t)| / A)^(2p))^(-1/(2p))
For a purely real input (I = r, Q = 0), the output I channel equals
r / (1 + (r/A)^(2p))^(1/(2p)) and the output Q channel equals 0 (no AM/PM
term; phase is preserved). The implementation computes
gain = (1 + (r/a)^(2p))^(-1/(2p)) and multiplies the complex input by the
scalar gain, matching the equation exactly including the origin guard
(torch.where(r > 0, gain, ones_like(r))).
Test: test_rapp_matches_closed_form in
tests/validation/tx_impairments/pa/test_math_fidelity.py evaluates the
equation with a NumPy reference implementation at four input amplitudes
(r = 0.1, 0.5, 1.0, 2.0), p = 2, A = 1.
Measured result. I-channel absolute error ≤ 1×10⁻⁵ at all four amplitudes. Q-channel absolute value ≤ 1×10⁻⁶ (exact zero within float32 precision). Tolerance reflects float32/complex64 precision (~5 significant decimal digits).
Figure 1 shows the AM/AM transfer curve for Rapp at p = 1, 2, and 20 alongside the Saleh curve, confirming the expected compression shape across the full input-envelope range.

3.2 Saleh AM/AM and AM/PM closed-form agreement¶
The Saleh TWT model (Saleh 1981, Eqs. 12–13) is:
AM/AM: g(r) = alpha_a * r / (1 + beta_a * r^2)
AM/PM: phi(r) = alpha_phi * r^2 / (1 + beta_phi * r^2) (radians)
y(t) = (x(t) / |x(t)|) * g(r) * exp(j * phi(r))
AM/PM (amplitude-to-phase modulation conversion) is the phenomenon where the
instantaneous phase of the output shifts by an amount that depends on the input
amplitude; this is a TWT-specific effect absent in the Rapp SSPA model. The
implementation computes am_am = alpha_a / (1 + beta_a * r^2) (the ratio
g(r)/r), multiplies the complex input by this scalar to achieve the AM/AM
distortion, then multiplies by exp(j * am_pm) to apply the AM/PM phase
rotation, matching both equations exactly.
Test: test_saleh_matches_closed_form in
tests/validation/tx_impairments/pa/test_math_fidelity.py evaluates
Eqs. (12)–(13) with a NumPy reference at four amplitudes and the canonical
Saleh-1981 Table II coefficients; asserts both I and Q axes.
Measured result. I-channel and Q-channel absolute error ≤ 1×10⁻⁵ at all four amplitudes (r = 0.1, 0.5, 1.0, 2.0). Tolerance is float32/complex64 precision.
Figure 1 (above) shows the Saleh AM/AM compression curve. Figure 2 shows the Saleh AM/PM phase shift versus input envelope, confirming the characteristic saturation-and-rollback shape from Saleh (1981).

3.3 Saleh default coefficients reproduce Saleh-1981 Table II¶
Saleh (1981) reports four TWT model coefficients fit to a Hughes 261-H helix TWT at 6 GHz (Tables I–II). The implementation uses these as defaults. The same values are republished in ITU-R Recommendation F.1336-5 (2019) as a representative TWTA model for sharing-study simulations.
Coefficient |
Saleh-1981 Table II |
Implementation default |
|---|---|---|
|
2.1587 |
2.1587 |
|
1.1517 |
1.1517 |
|
4.0033 |
4.0033 |
|
9.1040 |
9.1040 |
Tests: test_saleh_defaults_match_canonical_values in
tests/validation/tx_impairments/pa/test_literature_grounding.py asserts
byte-equal equality on all four values. test_fingerprint_params_defaults_round_trip_to_snapshot
confirms the same values appear in the FingerprintParams Pydantic model dump.
Measured result. All four coefficients match exactly (floating-point bit pattern identical).
3.4 Hard-knee and small-signal limits match published behavior¶
Two empirical limits from the literature are exercised as sanity checks:
Rapp hard-knee limit. Rapp (1991) Sec. III states that as p → ∞ the model
approaches an ideal soft-limiter: y = x * min(1, A/|x|). At p = 20 (a finite
approximation), the output is expected to pass through small signals linearly
and clamp large signals near A.
Test: test_rapp_hard_knee_approaches_limiter in
tests/validation/tx_impairments/pa/test_empirical_realism.py applies
RappPA(p=20, a=1) to three amplitudes spanning the small-signal, near-knee,
and saturation regimes.
Measured result.
r = 0.1 (small signal): output matches r = 0.1 within 1% relative tolerance.
r = 0.5 (near knee): output matches r = 0.5 within 2% relative tolerance.
r = 2.0 (above saturation): output matches A = 1.0 within 5% relative tolerance.
Saleh small-signal gain limit. As r → 0, Saleh (1981) Eq. (12) reduces to
g(r)/r → alpha_a. This is the model’s linear-region gain.
Test: test_saleh_small_signal_gain_matches_alpha_a in
tests/validation/tx_impairments/pa/test_empirical_realism.py applies
SalehPA() at r = 0.01 and computes the ratio |output| / |input|.
Measured result. Ratio matches alpha_a = 2.1587 within 1% relative error.
Figure 1 (§3.1) shows the full AM/AM curves for all three Rapp p values and the Saleh model, visually confirming the hard-knee progression and the small-signal slope behavior.
3.5 Determinism¶
Both models are deterministic: given identical inputs and parameters, two successive calls produce byte-identical output. This property is required for reproducible dataset generation.
Tests: test_rapp_pa_is_deterministic and test_saleh_pa_is_deterministic
in tests/validation/tx_impairments/pa/test_experimental_methodology.py apply
each model twice to the same 64-sample input with identical parameters and
assert torch.equal on the output IQ tensors.
Measured result. torch.equal returns True for both models.
3.6 Operating envelope: zero and large input¶
Zero-envelope input. At r = 0 the Rapp expression has the form 0 * gain
where gain evaluates to 1 by the torch.where branch guard. The output is
exactly zero. For Saleh, the AM/AM factor am_am evaluates to alpha_a
(finite) and am_pm = 0, but the complex input is zero, so the output is
exactly zero.
Tests: test_rapp_pa_zero_envelope_maps_to_origin and
test_saleh_pa_zero_envelope_maps_to_origin in
tests/validation/tx_impairments/pa/test_robustness_boundaries.py feed a
single sample at r = 0 and assert both I and Q output equal exactly 0.0.
Large-envelope input. At r = 100 (two orders of magnitude above the Rapp saturation amplitude and well outside the Saleh fit range) both models remain numerically finite.
Tests: test_rapp_pa_large_envelope_stays_finite and
test_saleh_pa_large_envelope_stays_finite in the same file feed r = 100 and
assert np.all(np.isfinite(...)) on the output.
Measured result. Both models return exact zeros at r = 0 and finite outputs at r = 100 with no NaN or Inf values.
Figure 3 shows the log-scale output-envelope sweep from r ≈ 0 to r = 100 for both models, confirming finite behavior throughout the full tested range.

4. Limits and what is not validated¶
Device-level realism beyond the two reference devices. The Saleh coefficients are fit to a single Hughes 261-H helix TWT at 6 GHz (Saleh 1981, Tables I–II). The Rapp model represents a class of SSPA behavior but was parameterised in Rapp (1991) for satellite broadcasting contexts. The validation does not assert that these coefficient sets describe GaAs MMICs (monolithic microwave integrated circuits), GaN HEMTs (high-electron-mobility transistors), LDMOS (laterally-diffused metal-oxide-semiconductor) Doherty PAs, or any specific commercial device. Users requiring accurate device models must re-fit the coefficients from their own measured AM/AM and AM/PM curves.
Memory effects. Both models are memoryless by definition. Real PAs exhibit asymmetric spectral regrowth driven by thermal time constants and bias-network dynamics (memory effects), visible as asymmetric intermodulation distortion sidebands. Not modelled.
Temperature and bias dependence. Junction-temperature rise and drain-bias drift shift the 1-dB compression point (the input power at which gain drops by 1 dB relative to the small-signal value) over time and with operating conditions. Not modelled.
Frequency dependence. Saleh (1981) defines frequency-dependent extensions (Eqs. 19–22). The implementation uses the frequency-independent form only.
Out-of-band intermodulation spectrum statistics. The closed-form agreement in §3.1–§3.2 verifies per-sample transfer functions. Adjacent-channel power ratio (ACPR) and third-order intermodulation products (IMD3) for a populated wideband input are not measured in this validation.
Non-finite input rejection. Both RappPA.apply and SalehPA.apply raise
ChannelError on NaN or Inf input IQ samples. This guard is implemented and
exercised by test_factory_rejects_unknown_model and the input-hygiene tests
in test_robustness_boundaries.py, but the non-finite-input path itself does
not have its own dedicated boundary test asserting the precise exception message.
Deferred architectural items. The following items change the public API and are out of scope for this validation:
Explicit small-signal gain parameter for Rapp (
G_0 ≠ 1). The current implementation fixes G₀ = 1 implicitly.Frequency-dependent Saleh variant (Saleh-1981 Eqs. 19–22).
Memory-polynomial PA extension.
5. References¶
Published works¶
Rapp, C. (1991). Effects of HPA-Nonlinearity on a 4-DPSK/OFDM Signal for a Digital Sound Broadcasting System. Proc. 2nd European Conf. on Satellite Communications (ECSC-2), Liège, Belgium, pp. 179–184. Primary source for Eq. (3) (Rapp AM/AM) and the SSPA hard-knee limiting behavior. Conference proceedings; no DOI assigned.
Saleh, A.A.M. (1981). Frequency-Independent and Frequency-Dependent Nonlinear Models of TWT Amplifiers. IEEE Transactions on Communications, COM-29(11), pp. 1715–1720. DOI: 10.1109/TCOM.1981.1094911. Primary source for Eqs. (12)–(13) (Saleh AM/AM and AM/PM) and Tables I–II (default TWT coefficients).
Razavi, B. (2012). RF Microelectronics (2nd ed.), Pearson. ISBN 978-0-13-713473-1. Chapter 8. Textbook treatment of AM/AM, AM/PM, intermodulation, power back-off, and the 1-dB compression point.
ITU-R Recommendation F.1336-5 (2019). Reference radiation patterns for fixed and land mobile service antennas for use in coordination studies and interference assessment in the frequency range from 100 MHz to about 70 GHz. International Telecommunication Union. URL: https://www.itu.int/rec/R-REC-F.1336/en Republishes the Saleh-1981 coefficient set as a representative TWTA model for sharing-study simulations; cited here as a secondary corroboration, not as the primary source for the coefficients.
Libraries¶
PyPI distribution |
Installed version |
Documentation URL |
Role in this validation |
|---|---|---|---|
|
2.12.1 |
Executes the PA arithmetic (complex tensor ops, |
|
|
2.4.6 |
NumPy reference implementations in tests; |
|
|
3.11.0 |
Generates the three validation figures |
|
|
2.13.4 |
|