Skip to main content
Ctrl+K

comnum

  • Getting started
  • Tutorials
  • User guide
  • Gallery of classical results
  • Why the results can be trusted
  • Maturity
    • Comparisons with other libraries
    • Why comnum
    • Benchmarks against other libraries
    • Classical performance
    • API reference
  • GitHub
  • Getting started
  • Tutorials
  • User guide
  • Gallery of classical results
  • Why the results can be trusted
  • Maturity
  • Comparisons with other libraries
  • Why comnum
  • Benchmarks against other libraries
  • Classical performance
  • API reference
  • GitHub

Section Navigation

  • Foundations
    • Constellations and Gray labels
    • Bit error rate of M-QAM over AWGN
    • M-PSK over AWGN with the Python runner
    • BPSK over flat Rayleigh fading
    • Information rates of QAM
  • Coding and shaping
    • Channel coding: from convolutional codes to the finite-length limit
    • Hu, Eleftheriou & Arnold 2005, Fig. 5: a regular PEG code of length 504
    • 5G NR channel codes: LDPC and polar
    • Probabilistic shaping: the rate gain and probabilistic amplitude shaping
  • Waveforms
    • PAPR of OFDM: the CCDF and its closed forms
    • PAPR reduction techniques
    • OFDM with impairments: imperfect channel estimates and nonlinear amplifiers
    • Proakis & Salehi 2008, Sec. 3.3-2: MSK has the error rate of BPSK
    • Thompson et al. 2008, Fig. 2: the CE-OFDM phase demodulator
    • CE-OFDM receivers, spectrum and bandwidth
    • The LoRa modulation: error rates, spectrum and interference
    • Filtered multicarrier and OTFS
  • MIMO
    • MIMO detection: linear, successive cancellation and maximum likelihood
    • Transmit diversity: Alamouti and space-time block codes
    • Alamouti 1998, Fig. 4: transmit diversity against MRRC
    • Ergodic capacity of MIMO channels
    • Large MIMO: message passing (LAMA and OAMP)
    • Biguesh & Gershman 2006, Fig. 4: LS, scaled LS, relaxed MMSE and LMMSE
  • Optical
    • Chromatic dispersion and its compensation
    • Nonlinear fibre propagation and digital back-propagation
    • Häger & Pfister 2021, Fig. 5: linear equalisation and back-propagation
    • WDM nonlinearity: the GN model and digital back-propagation
    • Raman amplification: pumps, gain flattening and the hybrid link
    • Mach–Zehnder and IQ modulators
    • Optical wireless: an LED-lit room and a turbulent free-space link
  • Hardware impairments
    • Power amplifiers and digital predistortion
    • DAC and ADC: quantisation, clipping and jitter
  • Receiver DSP
    • Nyquist pulse shaping and the eye diagram
    • OFDM over multipath: channel estimation
    • OFDM synchronisation and MIMO-OFDM
    • Blind receiver: modulation recognition, SNR and symbol rate
  • Metrics and analysis
    • Analysing a link: variants, probes and signals
  • Systems and standards
    • DVB-S2: MODCODs, constellations and frame error rates
    • 5G NR: numerology, synchronisation block and reference signals
    • DVB-S: the error rate after the Viterbi decoder against Table 3
    • DVB-T: the frame and the error rate after the Viterbi decoder against Annex A
    • CCSDS: the codes of telemetry against the normal approximation
    • 5G NR PDSCH: TS 38.101-4 test 1-2 against the RAN4 alignment
  • Simulation and specifications
    • A coherent receiver as a chain of blocks
    • Wireless links as chains: diversity, OFDM channel estimation, coded modulation
    • Recorded signals: SigMF in, blind receiver out
    • Coverage of the confidence intervals of an error rate
  • Gallery of classical results
  • Optical
  • Optical wireless: an LED-lit room and a turbulent free-space link

Note

Go to the end to download the full example code.

Optical wireless: an LED-lit room and a turbulent free-space link#

Light as the medium outside the fibre, in three panels to open next to the figures of the papers they reproduce.

  1. Illuminance and SNR of a visible-light room. T. Komine and M. Nakagawa, “Fundamental analysis for visible-light communication system using LED lights,” IEEE Trans. Consum. Electron. 50(1), 2004, Figs. 3 and 9: four lights of 60 × 60 LEDs (20 mW, semi-angle 70°) in a 5 × 5 × 3 m room, a desk 0.85 m high, a photodiode of 1 cm² with a field of view of 60° (comnum.OwcRoom). The contours are the illuminance (313.5 to 1211.5 lx); the colour is the SNR of 100 Mb/s on–off keying with the reflections of the walls (\(\rho = 0.7\)) and the PIN-FET receiver of their Table II (comnum.PinFetReceiver): the interference between symbols, not the noise, sets it.

  2. Multipath of an infrared link. J. R. Barry, J. M. Kahn, W. J. Krause, E. A. Lee and D. G. Messerschmitt, IEEE J. Sel. Areas Commun. 11(3), 1993, Fig. 3 (configuration A): the impulse response of a source on the ceiling, by order of reflection, computed recursively on the elements of the walls (with partitions coarser than their Table I, for speed: the second and third orders come out 2 and 4 % above their 0.430 and 0.269 µW).

  3. Turbulence. M. A. Al-Habash, L. C. Andrews and R. L. Phillips, Opt. Eng. 40(8), 2001: the gamma–gamma density of the intensity of a plane wave (comnum.GammaGamma.from_rytov) from weak (Rytov variance 0.2) to saturated turbulence, the last one that of their Fig. 3 (Rytov variance 25, \(\alpha = 8.05\), \(\beta = 1.03\)), against a histogram of draws.

validation/tests/optical_wireless/komine2004.rs, barry1993.rs and alhabash2001.rs check the same values with tolerances (docs/LITERATURE.md lists the gaps that remain).

Komine 2004: illuminance and SNR, Barry 1993: configuration A, Al-Habash 2001: gamma–gamma, plane wave
import matplotlib.pyplot as plt
import numpy as np

import comnum
from comnum.plot import GREY, LABEL, MUTED

fig, axes = plt.subplots(1, 3, figsize=(14, 4.4), width_ratios=[1.15, 1, 1])

# 1. the room of Komine & Nakagawa
off = (np.arange(60) - 29.5) * 0.01
lights = [(1.25, 1.25), (3.75, 1.25), (1.25, 3.75), (3.75, 3.75)]
chips = np.array([(cx + a, cy + b, 2.5) for cx, cy in lights for a in off for b in off])
down, up = [0.0, 0.0, -1.0], [0.0, 0.0, 1.0]
mode = comnum.lambertian_mode(np.radians(70))
walls = {"north": 0.7, "south": 0.7, "east": 0.7, "west": 0.7}
lit = comnum.OwcRoom([5.0, 5.0, 3.0], walls).illuminate(
    chips, down, mode, 20e-3, bin_s=0.01e-9, partitions=[[50, 50, 30]]
)
rx = comnum.PinFetReceiver.komine2004()
xs = np.linspace(0, 5, 26)
lux = np.zeros((xs.size, xs.size))
snr = np.zeros_like(lux)
for i, x in enumerate(xs):
    for j, y in enumerate(xs):
        point = [x, y, 0.85]
        lux[j, i] = comnum.owc_illuminance(chips, down, mode, 0.73, point, up)
        h = lit.impulse_responses(point, up, 1e-4, np.radians(60), concentrator_index=1.5)
        both = h[0] + h[1]
        s, isi = both.bit_split(10e-9, h[0].first_arrival_s())
        snr[j, i] = rx.ook_snr_db(s, isi, 1e-4, 100e6)
ax = axes[0]
image = ax.pcolormesh(xs, xs, snr, cmap="Blues", shading="gouraud")
fig.colorbar(image, ax=ax, label="SNR with ISI (dB)")
contours = ax.contour(xs, xs, lux, levels=[400, 600, 800, 1000, 1200], colors=LABEL, linewidths=0.8)
ax.clabel(contours, fmt="%d lx", fontsize=7)
ax.set(xlabel="x (m)", ylabel="y (m)", title="Komine 2004: illuminance and SNR", aspect=1)
ax.grid(False)

# 2. configuration A of Barry et al., by order of reflection
rho = {"north": 0.8, "south": 0.8, "east": 0.8, "west": 0.8, "ceiling": 0.8, "floor": 0.3}
lit = comnum.OwcRoom([5.0, 5.0, 3.0], rho).illuminate(
    [2.5, 2.5, 3.0],
    down,
    1.0,
    1.0,
    bin_s=0.5e-9,
    partitions=[[50, 50, 30], [25, 25, 15], [15, 15, 9]],
)
h = lit.impulse_responses([0.5, 1.0, 0.0], up, 1e-4, np.radians(85))
ax = axes[1]
for k, r in enumerate(h[1:], start=1):
    t = (np.arange(r.power_w.size) + 0.5) * r.bin_s * 1e9
    ax.plot(
        t,
        r.power_w / r.bin_s * 1e-3,
        linewidth=1.4,
        label=f"{k} reflection{'s' if k > 1 else ''}: {r.total_w() * 1e6:.3f} µW",
    )
ax.axvline(h[0].first_arrival_s() * 1e9, color=GREY, linestyle=":", linewidth=1.2)
ax.text(
    h[0].first_arrival_s() * 1e9 - 0.6,
    0.5 * ax.get_ylim()[1],
    f"line of sight, {h[0].total_w() * 1e6:.2f} µW",
    fontsize=8,
    color=MUTED,
    rotation=90,
    ha="right",
    va="center",
)
ax.set(
    xlim=(10, 70),
    xlabel="time (ns)",
    ylabel="h(t) (µW/ns for 1 W)",
    title="Barry 1993: configuration A",
)
ax.legend(loc="upper right", fontsize=8)

# 3. gamma-gamma densities of Al-Habash et al.
ax = axes[2]
i = np.linspace(1e-3, 3.5, 600)
for rytov in [0.2, 1.0, 3.5, 25.0]:
    g = comnum.GammaGamma.from_rytov(rytov)
    (line,) = ax.plot(
        i, g.pdf(i), linewidth=1.4, label=f"σ₁² = {rytov:g}: α = {g.alpha:.2f}, β = {g.beta:.2f}"
    )
g = comnum.GammaGamma.from_rytov(25.0)
draws = g.draw(200_000, comnum.Rng(2001))
ax.hist(
    draws,
    bins=np.linspace(0, 3.5, 71),
    density=True,
    color=line.get_color(),
    alpha=0.25,
    linewidth=0,
)
ax.set(
    xlim=(0, 3.5),
    ylim=(0, 2.2),
    xlabel="normalised intensity",
    ylabel="density",
    title="Al-Habash 2001: gamma–gamma, plane wave",
)
ax.legend(loc="upper right", fontsize=8)
fig.tight_layout()
plt.show()

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

Download Jupyter notebook: plot_07_optical_wireless.ipynb

Download Python source code: plot_07_optical_wireless.py

Download zipped: plot_07_optical_wireless.zip

Gallery generated by Sphinx-Gallery

previous

Mach–Zehnder and IQ modulators

next

Hardware impairments

Show Source

© Copyright 2022-2026, Vincent Choqueuse.

Created using Sphinx 9.1.1.

Built with the PyData Sphinx Theme 0.24.0.