sdr.min_snr(p_d: 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 minimum signal-to-noise ratio (SNR) required to achieve the desired probability of detection \(P_d\).

Parameters:
p_d: ArrayLike

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

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 minimum signal-to-noise ratio (SNR) required to achieve the desired \(P_d\).

See also

sdr.albersheim

Examples

Compute the minimum required SNR to achieve \(P_d = 0.9\) and \(P_{fa} = 10^{-6}\) with a square-law detector.

In [1]: sdr.min_snr(0.9, 1e-6, detector="square-law")
Out[1]: 13.183490056794499

Now suppose the signal is non-coherently integrated \(N_{nc} = 10\) times. Notice the minimum required SNR decreases, but by less than 10 dB. This is because non-coherent integration is less efficient than coherent integration.

In [2]: sdr.min_snr(0.9, 1e-6, detector="square-law", n_nc=10)
Out[2]: 5.267486807285799

Now suppose the signal is coherently integrated for \(N_c = 10\) samples before the square-law detector. Notice the SNR now decreases by exactly 10 dB.

In [3]: sdr.min_snr(0.9, 1e-6, detector="square-law", n_c=10, n_nc=10)
Out[3]: -4.732513192714245

Compare the theoretical minimum required SNR using a linear detector in sdr.min_snr() with the estimated minimum required SNR using Albersheim’s approximation in sdr.albersheim().

In [4]: p_d = 0.9; \
   ...: p_fa = np.logspace(-12, -1, 21)
   ...: 

In [5]: plt.figure(); \
   ...: plt.semilogx(p_fa, sdr.albersheim(p_d, p_fa, n_nc=1), linestyle="--"); \
   ...: plt.semilogx(p_fa, sdr.albersheim(p_d, p_fa, n_nc=2), linestyle="--"); \
   ...: plt.semilogx(p_fa, sdr.albersheim(p_d, p_fa, n_nc=10), linestyle="--"); \
   ...: plt.semilogx(p_fa, sdr.albersheim(p_d, p_fa, n_nc=20), linestyle="--"); \
   ...: plt.gca().set_prop_cycle(None); \
   ...: plt.semilogx(p_fa, sdr.min_snr(p_d, p_fa, n_nc=1, detector="linear"), label="$N_{nc}$ = 1"); \
   ...: plt.semilogx(p_fa, sdr.min_snr(p_d, p_fa, n_nc=2, detector="linear"), label="$N_{nc}$ = 2"); \
   ...: plt.semilogx(p_fa, sdr.min_snr(p_d, p_fa, n_nc=10, detector="linear"), label="$N_{nc}$ = 10"); \
   ...: plt.semilogx(p_fa, sdr.min_snr(p_d, p_fa, n_nc=20, detector="linear"), label="$N_{nc}$ = 20"); \
   ...: plt.legend(); \
   ...: plt.xlabel("Probability of false alarm, $P_{fa}$"); \
   ...: plt.ylabel("Minimum required SNR (dB)"); \
   ...: plt.title("Minimum required SNR across non-coherent combinations for $P_d = 0.9$\nfrom theory (solid) and Albersheim's approximation (dashed)");
   ...: 
../../_images/sdr_min_snr_1.png