The Shannon-Hartley capacity of a noisy band-limited channel#

In “Communication in the presence of noise” (1949) Shannon proved that a channel of bandwidth \(B\) with white Gaussian noise and signal-to-noise ratio \(S/N\) can carry \(C = B\log_2(1 + S/N)\) bits per second with arbitrarily small error (shannon_capacity()), and no more. Writing \(S/N = (E_b/N_0)(C/B)\) gives the minimum energy per bit for a given spectral efficiency. As bandwidth becomes unlimited the minimum tends to \(\ln 2\), or -1.59 dB, the Shannon limit.

import matplotlib.pyplot as plt
import numpy as np

from engineeringkit.communications import db, shannon_capacity, spectral_efficiency

A telephone line and a Wi-Fi channel#

for name, B, snr_db in [("telephone", 3.1e3, 35), ("Wi-Fi 20 MHz", 20e6, 25)]:
    C = float(shannon_capacity(B, 10 ** (snr_db / 10)))
    print(f"{name:14s}: C = {C / 1e3:9.1f} kbit/s, {float(spectral_efficiency(C, B)):.2f} bit/s/Hz")
telephone     : C =      36.0 kbit/s, 11.63 bit/s/Hz
Wi-Fi 20 MHz  : C =  166187.5 kbit/s, 8.31 bit/s/Hz

The minimum Eb/N0 for each spectral efficiency#

On the boundary \(\eta = \log_2(1 + \eta E_b/N_0)\), so \(E_b/N_0 = (2^\eta - 1)/\eta\).

eta = np.logspace(-3, np.log10(10), 200)
ebn0_min = (2**eta - 1) / eta
assert np.allclose(shannon_capacity(1.0, eta * ebn0_min), eta)
print(f"Shannon limit as eta -> 0: {float(db(ebn0_min[0])):.3f} dB (ln 2 = {float(db(np.log(2))):.3f} dB)")
fig, axes = plt.subplots(1, 2, figsize=(9, 3.6))
snr = np.linspace(-10, 40, 200)
axes[0].plot(snr, shannon_capacity(1.0, 10 ** (snr / 10)))
axes[0].set(xlabel="S/N [dB]", ylabel="C / B [bit/s/Hz]", title="Capacity grows ~1 bit per 3 dB")
axes[1].semilogy(db(ebn0_min), eta)
axes[1].axvline(float(db(np.log(2))), color="gray", ls="--", label="-1.59 dB")
axes[1].fill_betweenx(eta, db(ebn0_min), -2, color="C3", alpha=0.15, label="impossible")
axes[1].set(xlim=(-2, 15), xlabel="$E_b/N_0$ [dB]", ylabel="spectral efficiency [bit/s/Hz]")
axes[1].legend()
fig.tight_layout()

plt.show()
Capacity grows ~1 bit per 3 dB
Shannon limit as eta -> 0: -1.590 dB (ln 2 = -1.592 dB)

Total running time of the script: (0 minutes 0.267 seconds)

Gallery generated by Sphinx-Gallery