-
sdr.evm(x_hat: ArrayLike, ref: ArrayLike, norm: 'average-power-ref' | 'average-power' | 'peak-power' =
'average-power-ref'
, output: 'rms' | 'all' | float ='rms'
) float Calculates the error-vector magnitude (EVM) of the complex symbols \(\hat{x}[k]\).
- Parameters:¶
- x_hat: ArrayLike¶
The complex symbols \(\hat{x}[k]\) to be measured.
- ref: ArrayLike¶
The complex reference symbols \(x[k]\). This can be the noiseless transmitted symbols or the modulation’s symbol map.
- norm: 'average-power-ref' | 'average-power' | 'peak-power' =
'average-power-ref'
¶ The normalization source used in the EVM calculation.
"average-power-ref"
: The average power of the reference symbols \(x[k]\).
\[P_{\text{ref}} = \frac{1}{N} \sum_{k=0}^{N-1} \left| x[k] \right|^2\]"average-power"
: The average power of the received symbols \(\hat{x}[k]\).
\[P_{\text{ref}} = \frac{1}{N} \sum_{k=0}^{N-1} \left| \hat{x}[k] \right|^2\]"peak-power"
: The peak power of the received symbols \(\hat{x}[k]\).
\[P_{\text{ref}} = \text{max} \left| \hat{x}[k] \right|^2\]- output: 'rms' | 'all' | float =
'rms'
¶ The output type of the EVM calculation.
"rms"
: The root-mean-square (RMS) EVM.
\[ \text{EVM}_{\text{RMS}} = 100 \sqrt{\frac{\frac{1}{N} \sum_{k=0}^{N-1} \left| \hat{x}[k] - x[k] \right|^2}{P_{\text{ref}}}} \]"all"
: The instantaneous EVM for each symbol.
\[ \text{EVM}_{k} = 100 \sqrt{\frac{\left| \hat{x}[k] - x[k] \right|^2}{P_{\text{ref}}}} \]float
: The RMS EVM for the given percentile (0 - 100).
Examples¶
Create QPSK symbols with \(E_s/N_0\) of 20 dB.
In [1]: psk = sdr.PSK(4, phase_offset=45); \ ...: s = np.random.randint(0, psk.order, 1000); \ ...: x = psk.modulate(s); \ ...: x_hat = sdr.awgn(x, 20) ...: In [2]: plt.figure(figsize=(8, 4)); \ ...: sdr.plot.constellation(x_hat, label=r"$\hat{x}[k]$"); \ ...: sdr.plot.symbol_map(psk.symbol_map, label=r"Reference"); \ ...: plt.title("QPSK Constellation at 20 dB $E_s/N_0$"); \ ...: plt.tight_layout(); ...:
Measure the RMS EVM, normalizing with the average power of the reference symbols. Either the symbol map or noiseless transmitted symbols may be passed.
In [3]: sdr.evm(x_hat, psk.symbol_map) Out[3]: 64.72102795130989 In [4]: sdr.evm(x_hat, x) Out[4]: 10.062053563628073
Measure the RMS EVM, normalizing with the average power of the received symbols.
In [5]: sdr.evm(x_hat, psk.symbol_map, norm="average-power") Out[5]: 182.0295817233469
Measure the RMS EVM, normalizing with the peak power of the received symbols.
In [6]: sdr.evm(x_hat, psk.symbol_map, norm="peak-power") Out[6]: 146.0684313831214
Measure the 95th percentile EVM.
In [7]: sdr.evm(x_hat, psk.symbol_map, output=95) Out[7]: 68.8022505582809
Measure the instantaneous EVM for each symbol.
In [8]: inst_evm = sdr.evm(x_hat, psk.symbol_map, output="all") In [9]: plt.figure(figsize=(8, 4)); \ ...: plt.hist(inst_evm, bins=20); \ ...: plt.xlabel("RMS EVM (%)"); \ ...: plt.ylabel("Count"); \ ...: plt.title("EVM Histogram"); \ ...: plt.tight_layout(); ...: