sdr.p_d(snr: ArrayLike, p_fa: ArrayLike, detector: 'coherent' | 'linear' | 'square-law' = 'square-law', complex: bool = True, n_c: int = 1, n_nc: int | None = None) NDArray[float64]

Computes the theoretical probability of detection \(P_d\).

Parameters:
snr: ArrayLike

The signal-to-noise ratio \(S / \sigma^2\) in dB.

p_fa: ArrayLike

The probability of false alarm \(P_{fa}\) in \((0, 1)\).

detector: 'coherent' | 'linear' | 'square-law' = 'square-law'

The detector type.

  • "coherent": A coherent detector, \(T(x) = \mathrm{Re}\{x[n]\}\).

  • "linear": A linear detector, \(T(x) = \left| x[n] \right|\).

  • "square-law": A square-law detector, \(T(x) = \left| x[n] \right|^2\).

complex: bool = True

Indicates whether the input signal is real or complex. This affects how the SNR is converted to noise variance.

n_c: int = 1

The number of samples to coherently integrate \(N_c\).

n_nc: int | None = None

The number of samples to non-coherently integrate \(N_{nc}\). Non-coherent integration is only allowable for linear and square-law detectors.

Returns:

The probability of detection \(P_d\) in \((0, 1)\).

Examples

In [1]: snr = 3  # Signal-to-noise ratio in dB

In [2]: sigma2 = 1  # Noise variance

In [3]: p_fa = 1e-1  # Probability of false alarm

Compute the probability of detection for the coherent detector. Plot the PDFs and observe the theoretical \(P_d\) is achieved.

In [4]: detector = "coherent"; \
   ...: h0 = sdr.h0(sigma2, detector); \
   ...: h1 = sdr.h1(snr, sigma2, detector)
   ...: 

In [5]: threshold = sdr.threshold(p_fa, sigma2, detector); threshold
Out[5]: 0.9061938024368232

In [6]: p_d = sdr.p_d(snr, p_fa, detector); p_d
Out[6]: 0.7630284641923553

In [7]: plt.figure(); \
   ...: sdr.plot.detector_pdfs(h0=h0, h1=h1, threshold=threshold); \
   ...: plt.title("Coherent Detector: Probability density functions");
   ...: 
../../_images/sdr_p_d_1.png

Compute the probability of detection for the linear detector. Plot the PDFs and observe the theoretical \(P_d\) is achieved.

In [8]: detector = "linear"; \
   ...: h0 = sdr.h0(sigma2, detector); \
   ...: h1 = sdr.h1(snr, sigma2, detector)
   ...: 

In [9]: threshold = sdr.threshold(p_fa, sigma2, detector); threshold
Out[9]: 1.5174271293851465

In [10]: p_d = sdr.p_d(snr, p_fa, detector); p_d
Out[10]: 0.5414214845561176

In [11]: plt.figure(); \
   ....: sdr.plot.detector_pdfs(h0=h0, h1=h1, threshold=threshold); \
   ....: plt.title("Linear Detector: Probability density functions");
   ....: 
../../_images/sdr_p_d_2.png

Compute the probability of detection for the square-law detector. Plot the PDFs and observe the theoretical \(P_d\) is achieved.

In [12]: detector = "square-law"; \
   ....: h0 = sdr.h0(sigma2, detector); \
   ....: h1 = sdr.h1(snr, sigma2, detector)
   ....: 

In [13]: threshold = sdr.threshold(p_fa, sigma2, detector); threshold
Out[13]: 2.302585092994046

In [14]: p_d = sdr.p_d(snr, p_fa, detector); p_d
Out[14]: 0.541421484556116

In [15]: plt.figure(); \
   ....: sdr.plot.detector_pdfs(h0=h0, h1=h1, threshold=threshold); \
   ....: plt.title("Square-Law Detector: Probability density functions");
   ....: 
../../_images/sdr_p_d_3.png

Compare the detection performance of each detector.

In [16]: p_fa = 1e-6  # Probability of false alarm

In [17]: plt.figure(); \
   ....: snr = np.linspace(0, 20, 101); \
   ....: sdr.plot.p_d(snr, sdr.p_d(snr, p_fa, "coherent"), label="Coherent"); \
   ....: sdr.plot.p_d(snr, sdr.p_d(snr, p_fa, "linear"), label="Linear"); \
   ....: sdr.plot.p_d(snr, sdr.p_d(snr, p_fa, "square-law"), label="Square-Law"); \
   ....: plt.legend(title="Detector"); \
   ....: plt.title("Probability of detection");
   ....: 
../../_images/sdr_p_d_4.png

Compare the \(P_d\) of the square-law detector for various \(P_{fa}\).

In [18]: plt.figure(); \
   ....: snr = np.linspace(-10, 20, 101);
   ....: 

In [19]: for p_fa in [1e-15, 1e-12, 1e-9, 1e-6, 1e-3, 1e-1]:
   ....:     p_d = sdr.p_d(snr, p_fa)
   ....:     sdr.plot.p_d(snr, p_d, label=f"{p_fa:1.0e}")
   ....: 

In [20]: plt.legend(title="$P_{fa}$", loc="upper left"); \
   ....: plt.title("Square-Law Detector: Probability of detection");
   ....: 
../../_images/sdr_p_d_5.png

Compare the receiver operating characteristics (ROCs) of the square-law detector for various SNRs.

In [21]: plt.figure(); \
   ....: p_fa = np.logspace(-15, 0, 101);
   ....: 

In [22]: for snr in [-5, 0, 5, 10, 15, 20]:
   ....:     p_d = sdr.p_d(snr, p_fa)
   ....:     sdr.plot.roc(p_fa, p_d, label=f"{snr} dB")
   ....: 

In [23]: plt.legend(title="SNR"); \
   ....: plt.title("Square-Law Detector: Receiver operating characteristic");
   ....: 
../../_images/sdr_p_d_6.png