sdr.biawgn_capacity(snr: ArrayLike) NDArray[float64]

Calculates the capacity of a binary-input additive white Gaussian noise (BI-AWGN) channel.

Parameters:
snr: ArrayLike

The signal-to-noise ratio S/N=A2/σ2 at the output of the channel in dB.

Note

This SNR is for a real signal. In the case of soft-decision BPSK, the SNR after coherent detection is S/N=2Es/N0, where Es is the energy per symbol and N0 is the noise power spectral density.

Returns:

The capacity C of the channel in bits/1D.

Notes

The BI-AWGN channel is defined as

Y=AX+W,

where X is the input with xi{1,1}, A is the signal amplitude, WN(0,σ2) is the AWGN noise, the SNR is A2/σ2, and Y is the output with yiR.

The capacity of the BI-AWGN channel is

C=maxfXI(X;Y)

I(X;Y)=H(Y)H(Y|X),

where I(X;Y) is the mutual information between the input X and output Y, H(Y) is the differential entropy of the output Y, and H(Y|X) is the conditional entropy of the output Y given the input X. The maximum mutual information is achieved when X is equally likely to be 1 or 1.

The conditional probability density function (PDF) of Y given X=x is

fY|X(y|x)=12πσ2exp((yAx)22σ2).

The marginal PDF of Y is

fY(y)=12fY|X(y|1)+12fY|X(y|1).

The differential entropy of the output Y is

H(Y)=fY(y)logfY(y)dy.

The conditional entropy of the output Y given the input X is

H(Y|X)=fY|X(y|x)logfY|X(y|x)dydx.

In this case, since Y=X+W, the conditional entropy simplifies to

H(Y|X)=H(W)=12log(2πeσ2).

The capacity of the BI-AWGN channel is

C=H(Y)H(Y|X)=fY(y)logfY(y)dy12log(2πeσ2).

However, the integral must be solved using numerical methods. A convenient closed-form upper bound, provided by Yang, is

CCub=log(2)log(1+eSNR),

where SNR=A2/σ2 in linear units.

References

Examples

In [1]: snr = np.linspace(-30, 20, 51)

In [2]: C_ub = np.log2(2) - np.log2(1 + np.exp(-sdr.linear(snr)))

In [3]: C = sdr.biawgn_capacity(snr)

In [4]: plt.figure(); \
   ...: plt.plot(snr, C_ub, linestyle="--", label="$C_{ub}$"); \
   ...: plt.plot(snr, C, label="$C$"); \
   ...: plt.legend(); \
   ...: plt.xlabel("Signal-to-noise ratio (dB), $A^2/\sigma^2$"); \
   ...: plt.ylabel("Capacity (bits/1D), $C$"); \
   ...: plt.title("Capacity of the BI-AWGN Channel");
   ...: 
../../_images/sdr_biawgn_capacity_1.png
In [5]: snr = np.linspace(-30, 20, 51)

In [6]: p = sdr.Q(np.sqrt(sdr.linear(snr)))

In [7]: C_hard = sdr.bsc_capacity(p)

In [8]: C_soft = sdr.biawgn_capacity(snr)

In [9]: plt.figure(); \
   ...: plt.plot(snr, C_hard, label="BSC (hard)"); \
   ...: plt.plot(snr, C_soft, label="BI-AWGN (soft)"); \
   ...: plt.legend(); \
   ...: plt.xlabel("Signal-to-noise ratio (dB), $A^2/\sigma^2$"); \
   ...: plt.ylabel("Capacity (bits/1D), $C$"); \
   ...: plt.title("Capacity of the BSC (hard-decision) and BI-AWGN (soft-decision) Channels");
   ...: 
../../_images/sdr_biawgn_capacity_2.png