class sdr.MLPED(sdr.PED)

Implements a maximum-likelihood phase error detector (ML-PED).

Notes

The data-aided ML-PED is computed using the received complex symbols \(\tilde{a}[k]\) and the known transmitted complex symbols \(a[k]\).

\[\theta_{e,DA}[k] = \Im(\tilde{a}[k]) \cdot \Re(a[k]) - \Re(\tilde{a}[k]) \cdot \Im(a[k])) \]

The data-aided ML-PED is computed using the received complex symbols \(\tilde{a}[k]\) and the complex symbol decisions \(\hat{a}[k]\).

\[\theta_{e,DA}[k] = \Im(\tilde{a}[k]) \cdot \Re(\hat{a}[k]) - \Re(\tilde{a}[k]) \cdot \Im(\hat{a}[k]) \]

References

  • Michael Rice, Digital Communications: A Discrete-Time Approach, Section 7.2.2.

Examples

Compare the data-aided and decision-directed ML-PEDs on QPSK modulation.

In [1]: qpsk = sdr.PSK(4)

In [2]: A_rx, A_ref = 5, 3

In [3]: ped = sdr.MLPED(A_rx, A_ref)
In [4]: error, da_error = ped.data_aided_error(qpsk); \
   ...: error, dd_error = ped.decision_directed_error(qpsk)
   ...: 

In [5]: plt.figure(); \
   ...: plt.plot(error, da_error, label="Data-aided"); \
   ...: plt.plot(error, dd_error, label="Decision-directed"); \
   ...: plt.grid(True, linestyle="--"); \
   ...: plt.legend(); \
   ...: plt.xlabel("Phase of received symbols (radians)"); \
   ...: plt.ylabel("Phase error (radians)"); \
   ...: plt.title("Comparison of data-aided and decision-directed ML-PEDs on QPSK");
   ...: 
../../_images/sdr_MLPED_1.png

Observe that the slope of the phase error \(K_p = A_{rx,rms} A_{ref,rms}\) is the same for both the data-aided and decision-directed PEDs. It’s very important to observe that the gain of the ML-PED is scaled by the received signal amplitude \(A_{rx,rms}\) and the reference signal amplitude \(A_{ref,rms}\). Because of this, the ML-PED should only be used with automatic gain control (AGC).

In [6]: ped.gain
Out[6]: 15

In [7]: A_rx * A_ref
Out[7]: 15

Also note that the unambiguous range of the data-aided ML-PED is \([-\pi, \pi)\) and the decision-directed ML-PED is \([-\pi/M, \pi/M)\).

Constructors

MLPED(A_received: float = 1.0, A_reference: float = 1.0)

Initializes the ML-PED.

Special methods

__call__(received: ArrayLike, reference: ArrayLike) ndarray

Detects the phase error.

Methods

data_aided_error(...) tuple[NDArray[float64], NDArray[float64]]

Simulates the average phase error of the data-aided PED using the specified modulation scheme.

decision_directed_error(...) tuple[NDArray[float64], NDArray[float64]]

Simulates the average phase error of the decision-directed PED using the specified modulation scheme.

Properties

property gain : float

The gain of the phase error detector \(K_p\).

property A_received : float

(Settable) The received signal RMS amplitude \(A_{rx,rms}\).

property A_reference : float

(Settable) The reference signal RMS amplitude \(A_{ref,rms}\).