sdr.albersheim(p_d: ArrayLike, p_fa: ArrayLike, n_nc: ArrayLike = 1) NDArray[float64]

Estimates the minimum input 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 desired probability of false alarm \(P_{fa}\) in \((0, 1)\).

n_nc: ArrayLike = 1

The number of non-coherent combinations \(N_{nc} \ge 1\).

Returns:

The minimum required input SNR \(\gamma\) in dB.

See also

sdr.min_snr

Notes

This function implements Albersheim’s equation, given by

\[A = \ln \frac{0.62}{P_{fa}}\]

\[B = \ln \frac{P_d}{1 - P_d}\]

\[ \text{SNR}_{\text{dB}} = -5 \log_{10} N_{nc} + \left(6.2 + \frac{4.54}{\sqrt{N_{nc} + 0.44}}\right) \log_{10} \left(A + 0.12AB + 1.7B\right) . \]

The error in the estimated minimum SNR is claimed to be less than 0.2 dB for

\[0.1 \leq P_d \leq 0.9\]
\[10^{-7} \leq P_{fa} \leq 10^{-3}\]
\[1 \le N_{nc} \le 8096 .\]

Albersheim’s equation approximates a linear detector. However, the difference between linear and square-law detectors is minimal, so Albersheim’s equation finds wide use.

References

Examples

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 [1]: p_d = 0.9; \
   ...: p_fa = np.logspace(-12, -1, 21)
   ...: 

In [2]: 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=4), linestyle="--"); \
   ...: plt.semilogx(p_fa, sdr.albersheim(p_d, p_fa, n_nc=8), linestyle="--"); \
   ...: plt.semilogx(p_fa, sdr.albersheim(p_d, p_fa, n_nc=16), linestyle="--"); \
   ...: plt.semilogx(p_fa, sdr.albersheim(p_d, p_fa, n_nc=32), linestyle="--"); \
   ...: plt.gca().set_prop_cycle(None); \
   ...: plt.semilogx(p_fa, sdr.min_snr(p_d, p_fa, n_nc=1, detector="linear"), label=1); \
   ...: plt.semilogx(p_fa, sdr.min_snr(p_d, p_fa, n_nc=2, detector="linear"), label=2); \
   ...: plt.semilogx(p_fa, sdr.min_snr(p_d, p_fa, n_nc=4, detector="linear"), label=4); \
   ...: plt.semilogx(p_fa, sdr.min_snr(p_d, p_fa, n_nc=8, detector="linear"), label=8); \
   ...: plt.semilogx(p_fa, sdr.min_snr(p_d, p_fa, n_nc=16, detector="linear"), label=16); \
   ...: plt.semilogx(p_fa, sdr.min_snr(p_d, p_fa, n_nc=32, detector="linear"), label=32); \
   ...: plt.legend(title="$N_{nc}$"); \
   ...: plt.xlabel("Probability of false alarm, $P_{fa}$"); \
   ...: plt.ylabel("Minimum required input 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_albersheim_1.png

Compare the theoretical non-coherent gain for a linear detector against the approximation from Albersheim’s equation. This comparison plots curves for various post-integration probabilities of detection.

In [3]: fig, ax = plt.subplots(1, 2, sharey=True); \
   ...: p_fa = 1e-8; \
   ...: n = np.linspace(1, 100, 31).astype(int);
   ...: 

In [4]: for p_d in [0.5, 0.8, 0.95]:
   ...:     snr = sdr.min_snr(p_d, p_fa, detector="linear")
   ...:     ax[0].semilogx(n, sdr.non_coherent_gain(n, snr, p_fa=p_fa, detector="linear", snr_ref="output"), label=p_d)
   ...: 

In [5]: ax[0].semilogx(n, sdr.coherent_gain(n), color="k", label="Coherent"); \
   ...: ax[0].legend(title="$P_d$"); \
   ...: ax[0].set_xlabel("Number of samples, $N_{nc}$"); \
   ...: ax[0].set_ylabel("Non-coherent gain, $G_{nc}$"); \
   ...: ax[0].set_title("Theoretical");
   ...: 

In [6]: for p_d in [0.5, 0.8, 0.95]:
   ...:     g_nc = sdr.albersheim(p_d, p_fa, 1) - sdr.albersheim(p_d, p_fa, n)
   ...:     ax[1].semilogx(n, g_nc, linestyle="--", label=p_d)
   ...: 

In [7]: ax[1].semilogx(n, sdr.coherent_gain(n), color="k", label="Coherent"); \
   ...: ax[1].legend(title="$P_d$"); \
   ...: ax[1].set_xlabel("Number of samples, $N_{nc}$"); \
   ...: ax[1].set_ylabel("Non-coherent gain, $G_{nc}$"); \
   ...: ax[1].set_title("Albersheim's approximation");
   ...: 
../../_images/sdr_albersheim_2.png