API reference#

Every name is importable from the package: import comnum; comnum.awgn_ebn0(...). The formulas, the conventions of OptiCommPy that a function follows and its deviations are in its page.

One vocabulary runs through the package: fs is a sampling rate (Hz), fc_hz a carrier, noise_var a noise variance E|w|², ebn0_db and esn0_db the SNRs per bit and per symbol, MIMO matrices are (n_rx, n_tx); the tuning parameters are keyword-only; the functions return NumPy arrays; the closed forms (theory_*, qfunc(), db2lin()…) take a scalar (and return a float) or an array-like (and return an array). The package is typed: comnum/_comnum.pyi describes the extension.

The names are grouped by theme, in the order of a link: the foundations, coding, waveforms, MIMO, the channels (wireless and optical), the hardware, the receiver, the metrics, the standards and the simulation. The same themes order the gallery, the maturity table and the comparisons with the literature.

Foundations#

Random numbers, decibels, sources, constellations and the closed forms of their error and information rates.

Random numbers and conversions#

Every function that draws takes a Rng; the conversions use the power ratio convention (10 log10).

Rng(seed)

A seeded random generator (xoshiro256** seeded through SplitMix64).

db2lin(x_db)

Convert decibels to a linear ratio, 10^{x/10}.

lin2db(x)

Convert a linear ratio to decibels, 10 log10 x.

dbm2w(p_dbm)

Convert a power in dBm to watts, 10^{(P - 30)/10}.

w2dbm(p_w)

Convert a power in watts to dBm, 10 log10 P + 30.

qfunc(x)

The Gaussian tail function Q(x) = erfc(x/√2)/2.

bessel_j0(x)

The Bessel function J0(x) of the first kind and order zero.

entropy(px)

The entropy H = -Σ p log2 p of a distribution (bits): the information per symbol of a shaped source.

Sources#

bits(n, rng)

Independent fair bits.

prbs(order, length, *[, seed])

A maximal-length pseudo-random binary sequence (ITU-T O.150 polynomials).

o150_sequence(name, length)

A pseudo-random test sequence of ITU-T O.150 (05/96), Sec.

symbols(constellation, n, rng, *[, px])

Random symbols and their indices.

maxwell_boltzmann(constellation, lam)

Maxwell–Boltzmann probabilities p(x) ∝ exp(-λ|x|²) of the points.

Constellations#

Constellation(kind, m)

A constellation with Gray labels: point i carries the bits of i, MSB first.

gray_code(n_bits)

The reflected binary Gray code of n_bits bits: g[i] = i ^ (i >> 1).

Dpsk(m)

Differential M-PSK (DBPSK, DQPSK, D8PSK, …) with Gray-labelled phase transitions.

Error rates in closed form#

On scalars or arrays.

theory_ber(m, ebn0_db[, kind])

Theoretical BER over AWGN with Gray mapping (OptiCommPy theoryBER, exact for BPSK).

theory_ser(m, ebn0_db[, kind])

Theoretical SER over AWGN (exact for square QAM and PAM, a tight bound for PSK).

theory_ser_esn0(m, esn0_db[, kind])

Theoretical SER over AWGN as a function of E_s/N_0: theory_ser() with E_b/N_0 = E_s/N_0 - 10 log10(log2 M), for the links whose SNR is per symbol.

theory_ber_gray(m, ebn0_db[, kind, mq])

Exact BER of Gray-mapped PAM, square QAM or rectangular QAM over AWGN (K.

theory_ber_rayleigh_mrc(ebn0_db, *[, branches])

BER of BPSK (or Gray QPSK, per bit) with maximal-ratio combining of branches independent Rayleigh-faded branches (J.

theory_ber_dpsk(m, ebn0_db, *[, detection])

Bit error rate of Gray-labelled M-DPSK over AWGN.

theory_differential_phase_tail(psi, esn0_lin)

The probability that the phase angle between two vectors of the same SNR perturbed by independent Gaussian noise exceeds psi in absolute value, 0 <= psi <= pi.

theory_phase_pdf(theta, snr_lin)

Density of the phase error of a carrier in circular Gaussian noise (S.

theory_ber_imperfect_csi(modulation, ...[, ...])

The bit error rate over flat Rayleigh fading of a receiver that equalises with a channel estimate jointly Gaussian with the channel, of correlations rho1 (real) and rho2 (imaginary) and of standard deviation ratio sigma_ratio = σ2/σ1 (M.-X.

theory_ber_dpsk_jakes(m, ebn0_db, fd_ts)

The bit error rate of DBPSK (m = 2) or Gray DQPSK (m = 4) over Jakes' Rayleigh fading of normalised Doppler fd_ts (Chang & Su 2002, eqs.

Information rates and capacity#

The mutual information of constellations over AWGN or Rayleigh fading, the capacities and cutoff rates of coded modulation and BICM.

theory_mi(m, snr_db[, kind, px, fading, points])

Mutual information of a constellation over AWGN (OptiCommPy theoryMI) or Rayleigh fading known at the receiver, by Gauss–Hermite quadrature.

theory_gmi(m, snr_db[, kind, px, fading, points])

Generalised mutual information of a Gray-labelled constellation over AWGN (OptiCommPy theoryGMI) or Rayleigh fading known at the receiver, by Gauss–Hermite quadrature.

theory_cm_capacity(constellation, snr_db, *)

The CM capacity (bits per channel use) of a constellation with uniform inputs over AWGN or Rayleigh fading known at the receiver (Caire, Taricco & Biglieri 1998, eq.

theory_bicm_capacity(constellation, snr_db, *)

The BICM capacity (bits per channel use) of a labelled constellation with uniform inputs (Caire, Taricco & Biglieri 1998, eq.

theory_cm_cutoff_rate(constellation, snr_db, *)

The CM cutoff rate (bits per channel use) with uniform inputs, in closed form (Caire, Taricco & Biglieri 1998, eq.

theory_bicm_cutoff_rate(constellation, snr_db, *)

The BICM cutoff rate (bits per channel use) of a labelled constellation, m(1 - log2(1 + B)) with the Bhattacharyya factor B (Caire, Taricco & Biglieri 1998, eqs.

Coding and shaping#

Codes encode bits into bits and decode LLRs (positive for a 0) into bits, whole blocks at a time (encode, decode); the algebraic codes also decode one word of hard decisions (decode_bits).

Codes#

Crc(name)

A cyclic redundancy check of 5G NR (3GPP TS 38.212, Sec.

Scrambler(c_init)

The Gold scrambler of 3GPP (TS 38.211, Sec.

Interleaver()

A permutation of the positions of a block: Interleaver.random(n, seed=…), Interleaver.block(rows, cols) or Interleaver.qpp(k, f1, f2).

ConvolutionalCode(k, *[, generators, ...])

A terminated rate-1/n convolutional code on blocks of k bits, decoded by Viterbi (Viterbi 1967): the (133, 171) code of constraint length 7 by default, punctured by puncture (Cain, Clark & Geist 1979): the name of a pattern of a standard ("ieee80211_2_3", "ieee80211_3_4", "ieee80211_5_6" of IEEE 802.11-2020, Sec.

TurboCode(k, *[, iterations, max_log, qpp, ...])

The turbo code of LTE: two (13, 15) recursive systematic codes in parallel, rate about 1/3, decoded by iterative log-MAP (Berrou, Glavieux & Thitimajshima 1993).

LdpcCode(n, rows)

An LDPC code: LdpcCode.peg(n, k, var_degree=…, seed=…) (progressive edge growth, Hu, Eleftheriou & Arnold 2005) or LdpcCode(n, rows) from the rows of a parity-check matrix.

PolarCode(n, k, *[, design_ebn0_db, crc, ...])

A polar code of length n (a power of two) and k information bits, built by the Gaussian approximation at design_ebn0_db (Trifonov 2012); decoded by SC (Arıkan 2009), or SC list of size list_size (Tal & Vardy 2015) with the CRC crc choosing the path (CA-SCL).

ReedSolomonCode(m, t, *[, n, first_root, ...])

A Reed–Solomon code over GF(2^m) (symbols of m bits) correcting t symbols per word, with systematic encoding, errors-and-erasures decoding (Berlekamp–Massey, Chien search, Forney 1965) and shortening (Lin & Costello 2004, ch.

BchCode(m, t, *[, n, poly])

A binary BCH code of GF(2^m), narrow sense, of designed distance 2t + 1 (Lin & Costello, Error Control Coding, 2nd ed., 2004, ch.

NrLdpc(k, e, *[, base_graph, rv, qm, rule, ...])

The LDPC code of the data channels of 5G NR (3GPP TS 38.212, Sec.

NrPolar(k, e, *[, link, list_size])

The polar code of the control channels of 5G NR (3GPP TS 38.212, Sec.

free_distance([generators, constraint, puncture])

The free distance of a feed-forward convolutional code, punctured or not: a shortest path on the periodically time-varying trellis.

pack_symbols(bits, m)

Pack bits into symbols of m bits, the most significant first.

unpack_symbols(symbols, m)

Unpack symbols of m bits into bits, the most significant first.

Distribution matching#

Ccdm(composition)

Constant-composition distribution matching (Schulte & Böcherer 2016): k uniform bits to a sequence of n symbols of a fixed composition, by enumerative coding.

Limits and bounds#

theory_shannon_limit_ebn0_db(rate)

The smallest Eb/N0 at which BPSK supports a code rate.

theory_biawgn_capacity(ebn0_db, rate)

Capacity of the binary-input AWGN channel for a code rate (the noise variance is 1/(2 R Eb/N0)).

bpsk_noise_variance(ebn0_db, rate)

The noise variance per dimension of BPSK at E_b/N_0 for a code of rate rate: σ² = 1 / (2 R E_b/N_0) (unit-energy symbols).

bpsk_llr(y, noise_var)

The LLRs of BPSK (0 ↦ +1, 1 ↦ -1) received in real Gaussian noise of variance noise_var per dimension: 2y/σ² (positive for a 0, as every decoder of the package expects).

theory_normal_approximation(n, k, ebn0_db)

The normal approximation of the smallest block error probability of an (n, k) binary code over BPSK and AWGN (Polyanskiy, Poor & Verdú 2010).

theory_rs_wer(n, t, p_s)

The word error rate of a bounded-distance decoder of a t-error-correcting code of n symbols over a memoryless channel of symbol error probability p_s (Proakis & Salehi, Digital Communications, 5th ed., Sec.

theory_rs_ser(n, t, p_s)

The symbol error rate after decoding, approximating that a word of i > t errors keeps its i wrong symbols (Proakis & Salehi, Sec.

theory_rs_ber(n, t, m, p_s)

The bit error rate after decoding of a code over GF(2^m): a wrong symbol carries on average 2^(m-1) / (2^m - 1) wrong bits per bit (Sklar, Sec.

Waveforms#

OFDM#

The modulator, the resource grid and its pilots, the channel estimation, the synchronisation and the gain correction of OFDM.

Ofdm(n_fft, n_subcarriers, *[, ...])

An OFDM (or DFT-spread OFDM) modulator and demodulator.

ResourceGrid(n_subcarriers, n_symbols, *[, ...])

An OFDM resource grid of n_subcarriers × n_symbols with pilots (Coleri et al. 2002).

ofdm_estimate(grid, rx, noise_var[, method, ...])

Channel estimation on a resource grid: LS at the pilots, then "linear" interpolation, or "lmmse" across the subcarriers (van de Beek et al. 1995) with the power-delay profile delays, powers, or the robust uniform profile over max_delay samples (Edfors et al. 1998); linear in time.

ofdm_preamble(ofdm, *[, seed])

The preamble of Schmidl & Cox (1997): two identical halves.

schmidl_cox(r, half)

The timing metric of Schmidl & Cox, |P(d)|²/R(d)².

ofdm_synchronize(r, ofdm)

Timing and fractional frequency offset of the preamble of ofdm in r (Schmidl & Cox 1997).

ofdm_budget(snr_db, loss_db)

The SNR-loss budget of an OFDM receiver (Speth, Fechtel, Fock & Meyr 1999): the largest residual impairments for an allowed loss of SNR.

ofdm_timing_noise(offset, n_fft[, guard, ...])

The power of the intersymbol and intercarrier interference of an FFT window offset samples late (positive) or early (negative) of the end of the guard interval, relative to a subcarrier (Speth et al. 1999, eqs.

Wiener2d(pilots, fd_ts, tau_df, ...[, doppler])

The two-dimensional Wiener interpolator of pilots in time and frequency (Hoeher, Kaiser & Robertson 1997), for a WSSUS channel of uniform delay spectrum: every position is estimated from the n_taps nearest pilots (the weighted distance |dl| fd_ts + |dk| tau_df) by the linear MMSE filter of their eq.

RobustDesign(k, tmax_ts, fmax_tf)

The robust channel estimator of Li, Cimini & Sollenberger (1998): designed for the worst channel of delay spread tmax_ts (over the useful duration) and maximum Doppler fmax_tf (over the block rate), a uniform delay profile on the taps 0 to floor(K tmax_ts) of the DFT grid and a flat band-limited Doppler spectrum.

LowRank(r_hh, noise, rank)

The rank-p LMMSE estimator of Edfors et al. (1998) for the correlation r_hh of N values: h_p = U D_p U^H h_ls, D_p diagonal of delta_k = lambda_k / (lambda_k + noise) for k < p and of 0 beyond.

ls_noise_factor(points)

The noise enhancement of LS estimates over a constellation, beta = E|x|^2 E|1/x|^2 (Edfors et al. 1998): 1 for a constant modulus, 17/9 for 16-QAM.

random_delay_correlation(n, paths, max_delay)

The correlation matrix of n adjacent subcarriers of a channel of paths impulses with delays uniform over [0, max_delay] samples (Edfors et al. 1998, Sec.

gain_limited_correction(r, pilot, eps_db)

Pilot-based gain correction limited to eps (Cimini 1985, eq.

theory_sdr_gain_limited(sir_db, eps_db[, rho])

The signal-to-distortion ratio (dB) of gain-limited correction against a cochannel interferer in Rayleigh fading (Cimini 1985, eq.

theory_sdr_optimum_correction(sir_db)

The signal-to-distortion ratio (dB) of the optimum gain correction against a cochannel interferer in Rayleigh fading (Cimini 1985, eq.

PAPR#

PaprReduction()

A PAPR reduction technique for Ofdm.modulate_with and Ofdm.demodulate_with; build it with one of the static methods (clip, clip_filter, slm, pts, tone_reservation, ace, mu_law, exponential).

papr_db(x)

The PAPR of a block of samples, max |x|² / mean |x|².

papr_db_blocks(x, block_len)

The PAPR of every block of block_len samples (a tail shorter than a block is not a block).

ccdf(values, thresholds)

The empirical complementary distribution P(X > t) of values at every threshold.

theory_papr_ccdf(n, papr_db, *[, ...])

The theoretical CCDF of the PAPR of OFDM with n subcarriers: 1 - exp(-n √(πγ/3) e^(-γ)) for the continuous signal (Ochiai & Imai 2001), or 1 - (1 - e^(-γ))^n at the Nyquist rate (van Nee & Prasad 2000); with candidates, the CCDF after SLM (raised to that power).

clipping_bussgang(ratio_db)

The Bussgang decomposition y = α x + d of clipping at ratio_db above the average power of a complex Gaussian signal (Ochiai & Imai 2002).

Constant-envelope waveforms#

Continuous-phase modulation (CPFSK, MSK, GMSK) and constant-envelope OFDM.

Cpm([h, pulse, length, bt, sps, order])

A continuous-phase modulator (CPFSK, MSK, GMSK, raised-cosine CPM) and its detectors.

msk_precode(bits)

The differential precoder of MSK: the bits b_1 … b_N give the boundary signs d_n = 2b_n - 1 (d_0 = +1) and the CPM symbols a_n = d_n d_{n+1}, as indices (a_n + 1)/2, so that the signal is OQPSK with half-sinusoid pulses carrying d_n (Proakis & Salehi, Sec.

msk_bits(phase_states)

The information bits of MSK from the terminal phase states of a survivor path (the second array of Cpm.ml_detect_path(), in units of π/2): the inverse of msk_precode().

theory_msk_psd(ft)

The power spectral density of MSK at the normalised frequency fT, unit power and T = 1 (Proakis & Salehi, Sec.

CeOfdm(n_subcarriers, h, *[, oversampling, n_cp])

A constant-envelope OFDM (CE-OFDM) modulator and phase demodulator (Thompson et al. 2008).

ce_ofdm_imp_powers(two_pi_h, n)

The powers e^{-φ²} φ^{2i}/i! of the intermodulation products of a phase modulator driven by a Gaussian signal of standard deviation φ = 2πh (Guerreiro et al. 2015, eqs.

ce_ofdm_optimum_gain(two_pi_h[, theta_max])

The optimum asymptotic gain G of CE-OFDM over linear OFDM in AWGN, (2πh)², or (2πh)² erf(θ_max/(√2 · 2πh)) with the phase clipped to ±θ_max (Guerreiro et al. 2015, eq.

theory_ce_ofdm_ber_optimum(two_pi_h, ebn0_db)

The optimum asymptotic BER of QPSK CE-OFDM in AWGN, Q(√(G 2E_b/N_0)) (Guerreiro et al. 2016, eq.

pm_occupied_bandwidth(sigma[, fraction])

The occupied bandwidth B_y/(2B_m) of a carrier phase-modulated by a Gaussian message of standard deviation sigma with a flat spectrum (Pacheco and Hatzinakos 2006, eqs.

Chirp spread spectrum#

The modulation of LoRa and its theory.

Css(sf, *[, oversampling, waveform])

Chirp spread spectrum, the frequency-shift chirp modulation of LoRa (Chiani and Elzanaty 2019; Afisiadis et al. 2020): M = 2^SF chirps of M chips, a noncoherent DFT receiver.

theory_css_ser(sf, snr_db, *[, approximation])

The SER of the noncoherent CSS receiver over AWGN at the SNR per sample (dB), exact (Afisiadis et al. 2020, eq.

theory_css_ber(sf, snr_db)

The BER of the noncoherent CSS receiver over AWGN, SER M/(2(M - 1)).

css_cross_correlation(sf, l, m)

The cross-correlation of two continuous-time LoRa waveforms (Chiani and Elzanaty 2019, eq.

css_max_cross_correlation(sf)

The largest real cross-correlation of the continuous-time waveforms (Chiani and Elzanaty 2019, Table I).

css_continuous_spectrum(sf, f)

The continuous part of the power spectrum of LoRa, G^c(f) B, at f in units of B (Chiani and Elzanaty 2019, eqs.

css_spectral_lines(sf, n_max)

The lines of the spectrum of LoRa at n B/M, |n| ≤ n_max (Chiani and Elzanaty 2019, eq.

css_occupied_bandwidth(sf[, fraction, span])

The band (units of B) that holds fraction of the power of LoRa (Chiani and Elzanaty 2019, Table I, B99).

css_interference_pattern(sf, s1, s2, tau)

The pattern R_k that a same-SF interferer leaves after the dechirping (Afisiadis et al. 2020, eq.

theory_css_ser_interference(sf, snr_db, pi_db, *)

The approximate SER (or, with frame, the frame error rate) under AWGN and a same-SF interferer of power pi_db relative to the signal (Afisiadis et al. 2020, eqs.

Filtered multicarrier and OTFS#

Fbmc(n_fft, *[, overlap])

FBMC/OQAM (staggered multitone) with the PHYDYAS prototype filter.

oqam_stagger(c, m)

Split complex symbols (c[k * M + m]) into the real symbols of OQAM on twice as many half-symbols.

oqam_destagger(a, m)

The inverse of oqam_stagger.

Ufmc(n_fft, n_subbands, subband_size, ...[, ...])

Universal filtered multicarrier (Schaich & Wild 2014): OFDM filtered per sub-band by Dolph–Chebyshev filters, no cyclic prefix, n_fft + filter_len - 1 samples per symbol.

chebyshev_window(n, attenuation_db)

The Dolph–Chebyshev window (as scipy.signal.windows.chebwin).

Otfs(n_fft, n_symbols, *[, n_cp])

Orthogonal time frequency space (Raviteja et al. 2019) with rectangular pulses: the symbols of the n_fft × n_symbols delay–Doppler grid (x[n * M + m], delay m, Doppler n) through the ISFFT and the Heisenberg transform, one cyclic prefix per frame.

MIMO#

One channel matrix (n_rx, n_tx) per channel use, or one for all; the received streams are stream-major (n_rx, n) arrays and the decisions (n_tx, n).

Detection#

mimo_detect(h, y, constellation, noise_var)

Detect the transmitted symbols of a MIMO link y = H x + w.

mimo_llr(h, y, constellation, noise_var[, ...])

Bit log-likelihood ratios of a MIMO link (positive for a 0, most significant bit first), the LLR sequence of every transmitted stream: exact per-stream LLRs after the unbiased linear filter for "mr", "zf" and "mmse", max-log over all hypotheses for "ml", over the final list for "kbest", exact LLRs of the decoupled channel for "amp" and "oamp".

mimo_estimate(h, y, constellation, noise_var)

The unbiased estimates of a linear detector and their noise variances.

Message passing for large MIMO#

message_passing(h, y, constellation, noise_var)

The iterations of LAMA or OAMP on one received vector: the MMSE estimate of every iteration, and the decoupled channel of the last one (Jeon et al. 2018; Ma & Ping 2017).

amp_state_evolution(constellation, beta, ...)

The state evolution of LAMA (Jeon et al. 2018, Corollary 2): the variance of the decoupled channel and the predicted MSE of every iteration, in the large-system limit with columns of unit norm.

amp_thresholds(constellation, *[, px, real])

The recovery thresholds of LAMA (Jeon et al. 2018, Table II): below beta_min LAMA is optimal at every SNR, below beta_max it recovers the noiseless signal; n0_min and n0_max are the critical noise variances at those ratios.

oamp_state_evolution(constellation, ...[, ...])

The empirical state evolution of OAMP with the optimal denoiser (Ma & Ping 2017, eqs.

Channel estimation#

Training-based estimation of a flat MIMO channel (Biguesh and Gershman 2006).

MimoTraining(p)

A training matrix P (t x N) for the estimation of a flat MIMO channel from S = H P + V (Biguesh & Gershman 2006).

blue_weights(trainings)

The weights of the best linear unbiased combination of the LS estimates of several training periods (Biguesh & Gershman, Lemma 4); P_k / P_tot for orthogonal trainings.

blue_combine(estimates, weights)

The combination sum_k w_k H_k of channel estimates (eq.

blue_mse(trainings, noise_var, n_rx)

The MSE sigma^2 r / sum_k 1/tr((P_k P_k^H)^-1) of the BLUE combination of the LS estimates of several periods (eqs.

Space-time codes, precoding and capacity#

Ostbc()

An orthogonal space-time block code (Alamouti, or the rate-3/4 codes for 3 and 4 antennas), with linear maximum-likelihood decoding.

eigenmode(h, total_power, noise_var, *[, ...])

Eigenmode (SVD) transmission over h: precoder V P^(1/2), receive filter Uᴴ, gains and powers of the active modes (water-filling of total_power against noise_var, or equal power).

zf_precoder(h, *[, total_power, alpha])

The (regularised) zero-forcing precoder Hᴴ(H Hᴴ + αI)⁻¹ of the users of the rows of h, scaled to total_power (α = 0 for zero forcing, K σ²/P for the regularised version).

water_filling_powers(gains, total_power)

Water-filling powers of parallel channels: p_i = (μ - 1/g_i)⁺ with Σ p_i the total power.

mimo_capacity(h, snr_db, *[, water_filling])

Capacity of MIMO channel realisations (bits per channel use) at the SNR ρ = P/σ²: log2 det(I + ρ/n_tx H Hᴴ) with equal power, or water-filling on the eigenmodes.

theory_ergodic_capacity(n_rx, n_tx, snr_db)

The ergodic capacity (bits per channel use) of the i.i.d.

theory_outage_probability(n_rx, n_tx, ...)

The probability that a Rayleigh channel drawn once cannot carry rate bits per channel use with equal power, one antenna on one side (Telatar 1999, eq.

theory_outage_capacity(n_rx, n_tx, snr_db, eps)

The ε-capacity (bits per channel use): the rate of outage probability eps over a Rayleigh channel drawn once, one antenna on one side (Telatar 1999, eqs.

Wireless channels#

Noise and flat fading#

awgn(x, snr_db, rng, *[, fs, bandwidth_hz])

Add circular complex Gaussian noise for an SNR of snr_db within the bandwidth bandwidth of a signal sampled at fs (OptiCommPy awgn): σ² = (fs/bandwidth) P_x / SNR.

awgn_ebn0(x, ebn0_db, bits_per_symbol, rng, *)

Add noise for an E_b/N_0 of ebn0_db: σ² = P_x · sps / (b · E_b/N_0) for b bits per symbol at sps samples per symbol.

mimo_channel(n_rx, n_tx, rng, *[, k_factor, ...])

Flat MIMO channel matrices: Rayleigh or Rician fading, with exponential antenna correlation (Kronecker model).

mimo_channels(n, n_rx, n_tx, rng, *[, ...])

Independent flat MIMO channel matrices, one per channel use, as mimo_channel().

exponential_correlation(n, rho)

The exponential correlation matrix [R]_ij = ρ^(j-i) (Hermitian) of n antennas.

Multipath#

Tapped and clustered delay lines, delay–Doppler channels.

TdlChannel(profile, fs, *[, doppler_hz, ...])

A tapped-delay-line multipath channel with Clarke/Jakes Doppler (sum of sinusoids of Zheng & Xiao 2003), SISO or MIMO: every tap is Rayleigh with its power, the delays are rounded to the sampling grid and the powers normalised.

ChannelTaps()

The taps of one realisation of a TdlChannel or a CdlChannel: one tap per delay, with its coefficients at every sample on every link.

power_delay_profile(name[, delay_spread_s])

The taps of a power-delay profile of the standards.

rms_delay_spread(taps)

The RMS delay spread of a power-delay profile.

CdlChannel(profile, delay_spread_s, fs, *[, ...])

A clustered delay line channel of 3GPP TR 38.901 (CDL-A to CDL-E) between two uniform linear arrays, with the Doppler of a moving receiver.

cdl_profile(name, delay_spread_s)

The power-delay profile of a CDL profile of 3GPP TR 38.901 for a desired RMS delay spread: one tap per cluster.

cdl_k_factor_db(name)

The Rician K-factor (dB) of the first cluster of a CDL profile.

path_loss_db(scenario, d2d_m, fc_hz, *[, ...])

The path loss of a link of 3GPP TR 38.901 (Table 7.4.1-1).

shadow_fading_std_db(scenario, d2d_m, fc_hz, *)

The standard deviation of the log-normal shadow fading of a link (Table 7.4.1-1).

los_probability(scenario, d2d_out_m, *[, ...])

The probability of a line of sight (TR 38.901 Table 7.4.2-1).

uma_environment_height(d2d_m, h_ut_m, rng)

The effective environment height of a UMa link (TR 38.901 Table 7.4.1-1, NOTE 1).

building_penetration_db(model, fc_hz, d2d_in_m)

The outdoor-to-indoor penetration of a building (TR 38.901 eq.

delay_doppler_paths(profile, max_doppler_hz, ...)

One realisation of a delay–Doppler channel: one path per tap of a power-delay profile, with a Rayleigh gain and a Doppler shift ν_max cos θ, θ uniform on [-π, π) (DelayDopplerModel of comnum_channel::multipath).

Optical#

Fibre and amplification#

FiberParams(*[, alpha_db_km, d_ps_nm_km, ...])

The parameters of a fibre link of identical spans, each followed by an amplifier.

linear_fiber_channel(x, fiber, length_km, fs)

Loss and dispersion of length_km of fibre on a block sampled at fs (OptiCommPy linearFiberChannel).

Ssfm(fiber, *[, step_km, steps_per_span, ...])

The symmetric split-step Fourier method of OptiCommPy (ssfm), one polarisation.

ManakovPmd(fiber, *[, pmd_ps_sqrt_km, ...])

Dual-polarisation propagation by the Manakov equation with polarisation-mode dispersion (coarse-step model).

ManakovSsfm(fiber, *[, step_rule, ...])

Dual-polarisation nonlinear propagation over the link: the Manakov equation solved by the symmetric split-step method (nonlinear_step="trapezoidal" is OptiCommPy's manakovSSF).

Edfa(*[, gain_db, nf_db, fc_hz])

An ideal erbium-doped fibre amplifier: flat gain and white ASE.

raman_profile(fiber, freqs, power_dbm, raman)

The power profiles of a span with distributed Raman amplification: the coupled equations of stimulated Raman scattering for the co-propagating channels and any number of co- and counter-propagating pumps (RK4, forward-backward sweeps), and the spontaneous Raman noise of every channel (see comnum_channel::optical::raman).

gn_model(fiber, freqs, power_dbm, symbol_rate, *)

The GN model of the nonlinear interference of a WDM link (Poggiolini 2012).

gn_closed_form(fiber, n_channels, ...)

Poggiolini's closed form of the NLI power spectral density at the centre of n_channels rectangular channels spaced by spacing (incoherent accumulation).

gn_isrs_closed_form(fiber, freqs, power_dbm, ...)

The closed form of the ISRS GN model of Semrau, Killey & Bayvel (2019).

format_moments(modulation, *[, px])

The moments of a modulation format that the EGN model needs: Φ = E|a|⁴/E²|a|² − 2 and Ψ = E|a|⁶/E³|a|² − 9 E|a|⁴/E²|a|² + 12 (Carena et al. 2014), both zero for Gaussian symbols.

wdm_grid(n, spacing_hz)

The centre frequencies of n WDM channels, relative to the carrier: the grid of OptiCommPy's simpleWDMTx.

Optical devices#

laser(n, fs, rng, *[, power_dbm, ...])

The field of a laser: power, Wiener phase noise, relative intensity noise and frequency offset (OptiCommPy basicLaserModel).

phase_noise(linewidth_hz, n, fs, rng)

Wiener phase noise of a laser: a random walk starting at 0 whose increments have the variance 2π Δν / fs.

clock_offset(x, ppm)

The samples of a receiver whose sampling clock is off by ppm parts per million: sample m at the instant m (1 + 1e-6 ppm) of x, interpolated by the cubic Lagrange kernel, zero beyond the end (Speth et al. 1999, eqs.

phase_modulator(e, u, *[, vpi])

Phase modulator E e^{jπu/V_π} (OptiCommPy pm).

mzm(e, u, *[, vpi, vb, er_db])

Push-pull Mach–Zehnder modulator (OptiCommPy mzm): E [c_I cos θ + j c_Q sin θ] with θ = π(u + V_b)/(2V_π) and the arm coefficients of the extinction ratio (cos θ for an infinite one); the bias -V_π is the null (carrier suppression), -V_π/2 the quadrature point.

iqm(e, u, *[, vpi, vb_i, vb_q, vphi, ...])

IQ modulator (OptiCommPy iqm): two MZMs driven by Re u and Im u on the halves of the field and recombined with the phase π V_φ/V_π.

Photodiode(*[, responsivity, temperature_k, ...])

A PIN photodiode (OptiCommPy photodiode): responsivity, shot noise 2q(I + I_d)B, thermal noise 4k_BTB/R_L, and a low-pass FIR of bandwidth B.

balanced_photodiode(e1, e2, fs, rng, *[, ...])

Balanced detection i(E₁) - i(E₂).

hybrid_2x4(es, elo)

The 90° optical hybrid (OptiCommPy hybrid_2x4_90deg): the four outputs (E_s - E_lo)/2, j(E_s + E_lo)/2, (jE_s - E_lo)/2 and (-E_s + jE_lo)/2.

coherent_receiver(es, elo, fs, rng, *[, ...])

Single-polarisation coherent receiver (OptiCommPy coherentReceiver): the hybrid and two balanced photodiodes; equals R E_s E_lo* with ideal photodiodes.

Optical wireless#

Indoor visible-light and infrared links (Lambertian emitters, the reflections of a room, the PIN-FET receiver) and free-space optics (turbulence, pointing errors, fog).

OwcRoom(size_m, reflectance)

An empty rectangular room [0, L] × [0, W] × [0, H] with Lambertian walls (Barry et al. 1993): north and south are the walls x = L and x = 0, west and east y = W and y = 0.

OwcIllumination()

The light of a set of emitters carried to the elements of a room (OwcRoom.illuminate).

OwcImpulseResponse()

The received optical power of an indoor channel, bin by bin (see OwcIllumination.impulse_responses).

lambertian_mode(semi_angle_rad)

The Lambertian mode n = -ln 2 / ln cos Φ½ of a source of semi-angle at half power Φ½ (rad): 1 for 60°, 0.65 for 70°.

owc_direction(elevation_rad, azimuth_rad)

The unit vector of elevation elevation_rad (positive up) and azimuth azimuth_rad (from the x axis, towards y).

owc_illuminance(positions, directions, mode, ...)

The illuminance (lx) at point, on a surface of normal normal, of LED chips of centre luminous intensity intensity_cd (Komine & Nakagawa 2004, eq.

PinFetReceiver(responsivity, ...)

A PIN photodiode with a FET preamplifier: shot and thermal noise (Komine & Nakagawa 2004, eqs.

Fso([loss_db, turbulence, ...])

A free-space optical link: a deterministic loss, turbulence and pointing errors, the gain of the intensity h = h_l h_a h_p.

GammaGamma(alpha, beta)

The gamma–gamma distribution of the intensity, of unit mean (Al-Habash, Andrews & Phillips 2001).

PointingError(beam_radius_m, ...)

The misalignment of a Gaussian beam on a circular aperture, a Rayleigh radial displacement (Farid & Hranilovic 2007).

rytov_variance(cn2, wavelength_m, length_m)

The Rytov variance σ₁² = 1.23 C_n² k^{7/6} L^{11/6} of a plane wave.

fog_attenuation_db_per_km(visibility_km, ...)

The attenuation (dB/km) of haze and fog for a visibility visibility_km (Kim et al. 2001).

Hardware impairments#

Amplifiers and predistortion#

pa_rapp(x, *[, gain, saturation, ...])

Rapp's solid-state amplifier: A(r) = g r / (1 + (g r / A_sat)^(2p))^(1/(2p)), no AM/PM (Rapp 1991).

pa_saleh(x, *[, alpha_a, beta_a, alpha_p, ...])

Saleh's travelling-wave tube amplifier (AM/AM and AM/PM; Saleh 1981, default coefficients of his fit).

pa_memory_polynomial(x)

The memory-polynomial amplifier of Ding et al. (2004): orders 1, 3, 5, memory 3.

rapp_predistort(x, *[, gain, saturation, ...])

The static predistorter of Rapp's amplifier: the inverse AM/AM, up to max_output times the saturation (the cascade is then an ideal envelope limiter).

MemoryPolynomialDpd([orders, memory])

A memory-polynomial digital predistorter, trained by indirect learning (Eun & Powers 1997; Ding et al. 2004; Morgan et al. 2006).

amplifier_bussgang(model, power, *[, ...])

Bussgang's decomposition y = K x + d of a memoryless amplifier driven by a circular complex Gaussian signal: the complex gain and the power of the distortion.

envelope_series(f[, n_terms])

The coefficients c_n of the output autocorrelation of a memoryless envelope nonlinearity f driven by a circular complex Gaussian signal of unit power (P.

distortion_spectrum(c, occupied, bins)

The power of the useful term and of the distortion on each of bins frequency bins, for the coefficients c of envelope_series and an input flat on the occupied bins centred on bin 0 (an OFDM signal of occupied subcarriers oversampled to bins; Banelli & Cacopardi, eq.

Converters#

adc(x, bits, *[, fs, full_scale, loading, ...])

An analogue-to-digital converter on the in-phase and quadrature components: the front-end bandwidth (Gaussian, 3 dB at bandwidth_hz), the sampling-clock jitter (first order), the noise of the effective number of bits, then a uniform mid-rise quantiser of bits bits with clipping at the full scale.

dac(x, bits, *[, fs, full_scale, loading, ...])

A digital-to-analogue converter: a uniform mid-rise quantiser of bits bits on the in-phase and quadrature components, a zero-order hold of hold output samples per input sample, then the analogue bandwidth (Gaussian, 3 dB at bandwidth_hz).

theory_quantization_mse(bits, full_scale[, ...])

The exact mean squared error of a uniform mid-rise quantiser of bits bits and full scale full_scale for a Gaussian input of standard deviation sigma (one dimension): granular and overload (clipping) noise together.

optimal_loading(bits)

The loading factor A/σ that minimises the error of a Gaussian input (the optimal uniform quantiser of Max 1960).

theory_sqnr_sine_db(bits)

The SQNR of a full-scale sine through an ideal quantiser: 6.02 N + 1.76 dB (Bennett 1948).

enob_from_sinad_db(sinad_db)

The effective number of bits of a SINAD measured on a full-scale sine: (SINAD - 1.76) / 6.02 (IEEE Std 1241).

theory_jitter_snr_db(f_hz, jitter_s)

The SNR of a sine of frequency f_hz sampled with an RMS clock jitter jitter_s: -20 log10(2π f σ_j) dB (Walden 1999).

zero_order_hold_gain(f_hz, fs, hold)

The amplitude response of a zero-order hold of hold output samples per input sample at the input rate fs: |sin(π f/f_s) / (H sin(π f/(H f_s)))|, which tends to |sinc(f/f_s)|.

Receiver DSP#

Filters and sampling#

pulse_shape(kind, sps, *[, n_taps, rolloff])

Taps of a transmit pulse at sps samples per symbol, normalised to a unit sum (OptiCommPy pulseShape).

rrc_spectrum(n_symbols, sps, rolloff)

Root of the raised-cosine spectrum on the n_symbols·sps bins of a periodic block (1 in the passband): shaping and matched filtering with it are exactly Nyquist.

rrc_taps(t, rolloff, *[, ts])

The root-raised-cosine pulse at the times t (continuous time, symbol period ts): (sin(πt'(1-β)) + 4βt' cos(πt'(1+β))) / (πt'(1 - (4βt')²)) with t' = t/ts, divided by ts, and its limits at t = 0 and |t| = ts/(4β) (Proakis & Salehi, Digital Communications, 5th ed., Sec.

rc_taps(t, rolloff, *[, ts])

The raised-cosine pulse at the times t (continuous time, symbol period ts): sinc(t/ts) cos(πβt/ts) / (1 - (2βt/ts)²) divided by ts, Nyquist (zero at the other symbol instants).

fir_filter(h, x)

FIR filtering with the same alignment (OptiCommPy firFilter); the taps may be real or complex.

convolve(h, x)

Full linear convolution (direct for short filters, by FFT otherwise).

upsample(x, factor)

Insert factor - 1 zeros after every sample.

downsample(x, factor, *[, offset])

Keep the samples offset, offset + factor, ….

decimate(x, sps_in, sps_out)

Decimate from sps_in to sps_out samples per symbol at the phase of maximum variance (OptiCommPy decimate).

resample_fft(x, n_out)

Band-limited resampling of a periodic block to n_out samples (FFT).

low_pass_fir(fc, fs, n_taps, *[, kind])

Low-pass FIR of cut-off fc at the sampling rate fs, unit DC gain (OptiCommPy lowPassFIR).

butterworth_lowpass(x, fs_hz, fc_hz, *[, order])

A Butterworth low-pass IIR filter of order order and 3-dB cut-off fc_hz at the sampling rate fs_hz (bilinear transform with the cut-off prewarped, a cascade of second-order sections of unit DC gain), run forward from rest: the anti-aliasing filter of a receiver, such as the fifth-order filter at 40 % of the sampling rate of Ip & Kahn (J.

pnorm(x)

Scale to unit mean power.

anorm(x)

Scale to unit peak amplitude.

freq_shift(x, offset_hz, fs)

Frequency shift x[n] e^{j2πΔf n/fs}.

select_channel(x, fs_in, offset_hz, fs_out, ...)

One channel of a capture brought to baseband at the rate of its receiver: the mean of the capture removed (the DC offset of the converter), the channel offset_hz above the tuning frequency shifted to 0 Hz, then resampled by the exact ratio fs_out/fs_in (integers in hertz) with a low-pass filter of cut-off cutoff_hz (half amplitude): a sinc under a Dolph–Chebyshev window of 80 dB, about n_taps taps at the input rate (a transition band about 4 fs_in / n_taps wide), without delay.

resample_rational(x, fs_in, fs_out, cutoff_hz, *)

The samples x (at fs_in) resampled to fs_out by the exact rational ratio of the two rates under the 80 dB Chebyshev-windowed low-pass filter of cut-off cutoff_hz (select_channel() without the removal of the mean and the shift).

moving_average(x, n)

Centred moving average over n samples with zeros outside (OptiCommPy movingAverage).

delay_fft(x, delay_s, fs)

Delay a periodic block by delay seconds (FFT phase ramp).

Carrier recovery#

fourth_power_foe(x, fs, *[, m, refined])

Frequency offset of an m-fold symmetric signal by its m-th power spectrum (OptiCommPy fourthPowerFOE with refined=False).

viterbi_viterbi(x, *[, n, m])

Viterbi–Viterbi phase estimates (OptiCommPy viterbi), to apply with derotate(x, θ).

bps(x, constellation, *[, n, b])

Blind phase search (Pfau, Hoffmann and Noé 2009; OptiCommPy bps).

ddpll(x, constellation, *[, fs, kv, tau1, ...])

Decision-directed phase-locked loop (OptiCommPy ddpll): the phase correction to apply with derotate(x, θ).

derotate(x, theta, *[, sign])

Multiply every sample by e^{j·sign·θ[n]}.

unwrap(phi, *[, period])

Unwrap a phase sequence with a given period (numpy.unwrap(period=…)).

Clock recovery#

gardner_ted(x)

Gardner timing error Re{x[1]* (x[2] - x[0])} of three samples at 2 sps.

gardner_ted_nyquist(x)

Gardner timing error for Nyquist pulses, |x[1]|² (|x[0]|² - |x[2]|²).

lagrange_cubic(x, mu)

Cubic Lagrange (Farrow) interpolation of four samples at μ ∈ [-1, 1] (μ = 0 returns x[2]; OptiCommPy interpolator).

gardner_clock_recovery(x, *[, kp, ki, ...])

Gardner clock recovery at 2 samples per symbol (OptiCommPy gardnerClockRecovery).

Equalisation and compensation#

adaptive_equalizer(x, constellation, *[, ...])

The n×n butterfly adaptive equaliser (OptiCommPy mimoAdaptEqualizer).

cdc(x, fiber, length_km, fs)

Compensate the dispersion of length_km of fiber on a block sampled at fs (frequency domain, exact on a periodic block).

cd_taps_needed(fiber, length_km, symbol_rate, fs)

Taps of the dispersion-compensating FIR (OptiCommPy edc rule, 2⌈6.67 |β₂| L R_s² (f_s/R_s)⌉).

cd_fir_taps(fiber, length_km, fs, n_taps)

Centred taps of the dispersion compensation of length_km (frequency sampling).

cd_dispersion_factor(fiber, length_km, fs)

The dispersion factor K = -β₂ L fs²/2 of the digital compensation e^{jKω²} (ω in radians per sample; Savory 2008, Eghbali et al. 2014).

cd_savory_taps(fiber, length_km, fs, *[, n_taps])

Centred taps of Savory's dispersion-compensating FIR, √(j/(4Kπ)) e^{-jn²/(4K)}.

cd_ls_taps(fiber, length_km, fs, n_taps, *)

Centred taps of the least-squares dispersion-compensating FIR over the band |f| <= band_hz.

cd_ls_error(taps, fiber, length_km, fs, *[, ...])

The energy of the error E = (1/2π) ∫ |H(e^{jω}) - e^{jKω²}|² dω of centred dispersion-compensating taps over the band |f| <= band_hz (Eghbali et al. 2014, eq.

Blind estimation#

Modulation recognition, SNR and symbol rate without a reference.

cumulants(x)

The sample cumulants of order two and four of a zero-mean signal, and the normalised C40/C21², C42/C21² (Swami & Sadler 2000).

theory_cumulants(constellation, *[, px])

The cumulants of an alphabet (its theoretical features), with the probabilities of its points.

classify_modulation(x, candidates[, method, ...])

Blind modulation classification at one sample per symbol, timing and carrier recovered.

snr_m2m4_db(x, constellation)

The M2M4 estimate of the SNR (Pauluzzi & Beaulieu 2000), generalised to alphabets of several amplitudes by their kurtosis; it degrades at high SNR for QAM.

snr_crb_nmse(snr_db, n_symbols, *[, sps, real])

The Cramér–Rao bound on the normalised mean squared error of an unbiased SNR estimator from known PSK symbols (Pauluzzi & Beaulieu 2000, eq.

cyclic_autocorrelation(x, alpha, *[, lag, fs])

The cyclic autocorrelation R^α(τ) = mean x[n+τ] x*[n] e^{-j2π α n/f_s}.

estimate_symbol_rate(x, fs, f_min_hz, f_max_hz)

The symbol rate of a linearly modulated signal from the strongest line of the spectrum of its instantaneous power (cyclostationarity, Gardner 1991); the pulse must have an excess bandwidth.

Metrics and analysis#

Error rates, SNR and information rates#

Estimates from received and transmitted sequences.

ber(rx_bits, tx_bits)

Bit error rate of two bit sequences of the same length.

snr_db(rx, tx)

SNR (dB) of a received sequence against the transmitted one, 10 log10(P_tx/P_{rx-tx}).

phase_error_std(rx, tx)

The standard deviation (rad) of the phase error of received symbols against the transmitted ones, once the constant gain and phase of the least-squares fit are removed: sqrt(mean(arg(g z x*)^2)), the metric of Ip & Kahn (J.

fast_ber_calc(rx, tx, constellation)

BER, SER and SNR of a received symbol sequence (OptiCommPy fastBERcalc).

evm(symbols, constellation, *[, tx])

Error vector magnitude as a power ratio E|y - x̂|² / E|x̂|² (OptiCommPy calcEVM); the EVM in percent is 100·√evm.

ber_to_q_db(ber)

The Q factor (dB) of a bit error rate, 20 log10(√2 erfc⁻¹(2 BER)).

monte_carlo_gmi(rx, tx, constellation, *[, px])

Generalised mutual information of bit-wise decoding (OptiCommPy monteCarloGMI).

monte_carlo_mi(rx, tx, constellation, *[, px])

Symbol-wise mutual information for a Gaussian channel of the measured noise variance (OptiCommPy monteCarloMI; the transmitted symbols are snapped to the constellation, so that the estimate never exceeds H(X)).

information_rates(rx, indices, constellation, *)

Mutual information and GMI with the least-squares channel gain: consistent at every SNR, unlike the power normalisation of monte_carlo_mi and monte_carlo_gmi.

posterior_rates(z, indices, constellation, ...)

Achievable rates of a receiver with its own posterior q(x|z) ∝ e^{-|z - x|²/σ̂²}.

Spectrum#

psd(x, *[, fs, nfft])

Welch's power spectral density (periodic Hann window, 50 % overlap), centred.

periodogram(x, *[, fs, nfft])

The averaged periodogram of non-overlapping segments of nfft samples (no window): with nfft the block length of a cyclic signal (OFDM without prefix), it has no leakage, and its out-of-band part is the regrowth of a nonlinearity.

aclr_db(freqs, density, bandwidth_hz, offset_hz)

The adjacent channel leakage ratio (dB) of a density (psd or periodogram): power in [-B/2, B/2) over the larger power of the channels of width B centred at ±offset.

Results and plots#

Results([items, spec])

The results of a campaign: one dict per condition with condition, status, trials, wall_s and metrics ({name: {value, lo, hi, kind, count, total}}).

Trace

The frame after every block of one trial ({name: Frame}, in the order of the chain), from comnum.Chain.trace().

compare(chains, *[, variable])

Run several chains with the same arguments of comnum.Chain.run() and gather their results, the name of every chain as the variable variable.

plot

The classical views of a signal and of the results of a campaign (matplotlib).

Systems and standards#

Reference chains of standards (comnum-systems) and the physical layer of 5G NR.

DVB-S#

Dvbs([rate])

A DVB-S transmitter and frame-aligned receiver (ETSI EN 300 421 V1.1.2) of one inner code rate.

dvb_packets(n, rng)

MPEG-2 transport packets for a simulation: the sync byte 0x47 and 187 random bytes each.

DVB-S2#

Dvbs2(modulation, rate, *[, frame, pilots, ...])

A DVB-S2 transmitter and receiver (ETSI EN 302 307-1) of one MODCOD, constant coding and modulation.

dvbs2_bbframe(data, k_bch, *[, rolloff])

The BBFRAME of k_bch bits of a generic continuous stream: a BBHEADER (CCM, single stream, DFL = k_bch - 80, CRC-8) and the k_bch - 80 data bits, randomised by the PRBS of the standard.

dvbs2_bbframe_data(bbframe)

The data bits of a received BBFRAME and whether the CRC-8 of its BBHEADER holds.

dvbs2_decode_plheader(rx)

The MODCOD field, the short-frame flag and the pilot flag of a received PLHEADER (90 symbols), by maximum likelihood over the 128 PLS codewords.

DVB-T#

Dvbt([mode, guard, constellation, rate])

A DVB-T transmitter and receiver (ETSI EN 300 744 V1.6.2) of one non-hierarchical configuration.

dvbt_channel_gains(profile, frequencies)

The gains of the static channels of Annex B of EN 300 744 (DVB-T) at baseband frequencies: the fixed reception F1 (20 echoes and a direct path, Ricean factor 10 dB) and the portable reception P1 (the 20 echoes of Table B.1), normalised to a unit power gain.

CCSDS#

The channel coding and synchronization of CCSDS 131.0-B-5 (telemetry).

CcsdsRs([e, depth, fill])

The interleaved Reed–Solomon codeblock of CCSDS 131.0-B-5, Sec.

CcsdsLdpc(rate[, k, rule, alpha, ...])

An LDPC code of CCSDS 131.0-B-5, Sec.

CcsdsTurbo(k[, rate, iterations, max_log])

A turbo code of CCSDS 131.0-B-5, Sec.

CcsdsConvolutional([rate])

The convolutional code of CCSDS 131.0-B-5, Sec.

ccsds_randomizer(sequence, n)

The first bits of a pseudo-randomizer of CCSDS 131.0-B-5, Sec.

ccsds_marker(name)

A synchronization marker of CCSDS 131.0-B-5, Sec.

ccsds_cadu(marker, block[, randomizer])

A channel access data unit (CCSDS 131.0-B-5, Table 9-1): the bits of a marker, then the bits of a codeblock, randomized if randomizer is given (the marker never is).

5G NR#

nr_numerology(mu, *[, extended_cp, n_fft])

The numerology mu of NR (the subcarrier spacing 2^mu · 15 kHz; mu = 0 is also the numerology of LTE).

nr_ofdm_modulate(grid, mu, n_fft, *[, ...])

OFDM-modulate a grid of NR: the subcarrier k at the frequency (k - K/2) Δf, the cyclic prefixes of the numerology (the first symbol of every half subframe longer), the IFFT scaled by 1/√K (unit mean power for unit-energy symbols).

nr_pss(n_id2)

The NR primary synchronisation signal of N_ID2 (TS 38.211, Sec.

nr_sss(n_id1, n_id2)

The NR secondary synchronisation signal of (N_ID1, N_ID2) (TS 38.211, Sec.

nr_detect_cell_id(grid)

The cell identity of a received SSB, by the PSS then the SSS (coherently, with the flat channel estimated on the PSS).

nr_ssb_grid(n_cell_id[, i_ssb_bar, pbch])

The SSB of a cell: the PSS and the SSS of unit amplitude, the PBCH DMRS and the 432 PBCH symbols.

nr_ssb_indices(n_cell_id, kind)

The resource elements of one kind in the SSB, as (k, l) pairs (subcarrier, symbol) in the order of the mapping, frequency first: grid[idx[:, 0], idx[:, 1]] reads them in a (240, 4) grid.

nr_pbch_dmrs(n_cell_id[, i_ssb_bar])

The 144 QPSK values of the PBCH DMRS (TS 38.211, Sec.

nr_pdsch_dmrs(n_rb, *[, config_type, ...])

The DMRS of a PDSCH of mapping type A over a slot of 14 symbols, single-symbol, port 1000 (TS 38.211, Sec.

nr_mcs(table, index)

An MCS of the PDSCH (TS 38.214 Tables 5.1.3.1-1 to 5.1.3.1-4).

nr_tbs(n_prb, n_symb, n_dmrs, table, index)

The transport block size of a PDSCH (TS 38.214 Sec.

nr_constellation(qm)

The constellation of the modulation mapper of NR (TS 38.211 Sec.

NrTransportBlock(tbs, rate)

A transport block of the PDSCH and its segmentation (TS 38.212 Sec.

NrHarqProcess(tb)

The soft buffers of a HARQ process of a transport block: the LLRs of every transmission combined on the bits of the full codewords.

NrPdsch(n_rb_grid, prb_start, n_prb, qm, *)

One slot of a single-layer PDSCH (TS 38.211 Sec.

FM broadcasting#

fm_modulate(m, fs, deviation_hz)

The complex envelope of the frequency modulation of the message m (sampled at fs) with the peak deviation deviation_hz for |m| = 1: the phase sums 2π Δf m[n] / fs.

fm_discriminator(x, fs)

The instantaneous frequency (Hz) of x by the polar discriminator, fs/(2π) arg(x[n] x*[n-1]) (0 for the first sample): exact within ±fs/2, insensitive to the amplitude.

fm_preemphasis(x, fs, *[, tau_s])

The pre-emphasis of the message x, the exact inverse of fm_deemphasis() (the FIR (x[n] - a x[n-1]) / (1 - a)).

fm_deemphasis(x, fs, *[, tau_s])

The de-emphasis 1/(1 + j2πfτ) of the message x by the matched pole y[n] = a y[n-1] + (1 - a) x[n], a = exp(-1/(τ fs)) (ITU-R BS.450-4 Sec.

fm_multiplex(left, right, fs, *[, rds_bits, ...])

The stereophonic multiplex of FM broadcasting (ITU-R BS.450-4 Sec.

fm_stereo_decode(mpx, fs, *[, tau_s, fs_audio])

The left and right channels of a multiplex (ITU-R BS.450-4 Sec.

rds_group_bits(blocks, *[, version_b])

The 104 bits of an RDS group of the four information words blocks (each with its checkword and its offset word A, B, C or C', D; NRSC-4 Sec.

rds_differential_encode(bits)

The differential encoding d[k] = d[k-1] xor b[k] of RDS (NRSC-4 Table 1).

rds_receive(mpx, fs)

The RDS of a multiplex: the biphase symbols demodulated from 57 kHz (Gardner clock recovery, Viterbi-Viterbi phase of the BPSK), differentially decoded, synchronised on the offset words, and the groups assembled into the station's name, radiotext and clock (NRSC-4 / EN 50067 Sec.

LTE#

lte_frame(n_cell_id, *[, sfn, n_rb, ports, ...])

The samples of every antenna port of one 10 ms frame of an LTE cell (FDD, normal cyclic prefix): the PSS and the SSS of slots 0 and 10 (port 0), the CRS of every port, the PBCH of slot 1 carrying the master information block of the frame (its 8 bits of frame number sfn // 4, its quarter sfn % 4 of the 40 ms period, transmit diversity for 2 or 4 ports), and QPSK symbols at random on the other elements of port 0 when rng is given (TS 36.211 Sec.

lte_pss(n_id2)

The PSS of LTE of the identity N_ID^(2) (the 62 values of the punctured Zadoff–Chu sequence of length 63, roots 25, 29, 34; TS 36.211 Sec.

lte_cell_search(x, *[, max_cfo_hz, ...])

The cell search of LTE in samples at 1.92 MS/s (the six central resource blocks: select_channel() brings a capture there): the PSS of each of the three identities N_ID^(2) is searched over a grid of frequency offsets in the first 10 ms, the offset refined on the cyclic prefixes of the whole capture, then the SSS of every half frame, equalised by the channel of the PSS, gives the group N_ID^(1) and the start of the frames.

lte_decode_mib(x, cell, *[, passes])

The master information block of every frame of a capture at 1.92 MS/s whose PBCH decodes, for a cell of lte_cell_search(): the channel of every port estimated on the CRS of subframe 0, the PBCH equalised for 1, 2 and 4 ports (transmit diversity), descrambled for each quarter of the 40 ms period, decoded by the wrap-around Viterbi algorithm (tail-biting code) and checked by its CRC, whose mask tells the number of ports (TS 36.212 Sec.

zadoff_chu(u, n_zc)

Register the bindings of this module.

AIS#

ais_transmit(messages, fs)

The GMSK signal of the packets of messages (ITU-R M.1371-5, Annex 2: the training sequence, the HDLC frame with its frame check sequence and bit stuffing, NRZI, GMSK with BT = 0.4 at 9600 bit/s), a silence of 32 bits before each, unit envelope.

ais_receive(x, fs)

The packets of an AIS channel at baseband: the polar discriminator, an integrator over half a bit, the frequency offset of the transmitter removed, a bit clock from the zero crossings, NRZI decoding and the HDLC frames whose frame check sequence is correct, decoded by ais_decode().

ais_decode(bits)

Decode the bits of an AIS message (ITU-R M.1371-5, Annex 8): the position reports (messages 1, 2, 3, 18), the base station report (4), the static and voyage data (5) and the class B static data (24); any other message gives its type and MMSI.

ais_position_report(mmsi, *[, lat_deg, ...])

The bits of a position report (message 1) with the given fields, the other fields zero: the inverse of ais_decode() for that message.

ais_aivdm(bits, *[, channel, sequence])

The !AIVDM sentences of NMEA 0183 (IEC 61162-1) of a message: the six-bit armouring of its bits, the fill bits and the checksum; one or several fragments.

ais_messages(sentences)

The messages of !AIVDM sentences: the checksums checked, the fragments of a message assembled, the payload de-armoured.

ais_front_end_rate()

The sampling rate of the AIS receiver: 16 samples per bit, 153 600 Hz.

Simulation and specifications#

Chains#

Chain(*blocks, **named)

An ordered, named sequence of blocks; a chain is itself a block.

Block()

A block of a chain: block(frame, rng) transforms the frame in place.

Native(kind, /, **params)

A block of the registry of declarative links, Native("awgn_ebn0", ebn0_db=10); the classes of comnum.blocks build them.

Var(name)

A reference to a grid variable, substituted when the chain is built for a condition ($name in a specification).

Frame()

The state carried along a link during one trial: the current samples and what the metrics need (the transmitted bits, symbol indices and symbols, the constellation).

LinkBlock(spec, *[, fiber, name, condition, ...])

One block of the registry of declarative links (see spec_blocks()), built from its specification {"type": ..., <parameters>}.

frame_metrics(frame, metrics, *[, confidence])

The metrics of one frame, as a declarative campaign records them (with the values that the blocks recorded), in the format of the metrics of comnum.run_spec().

blocks

The blocks of the registry of declarative links as classes, for comnum.Chain.

var (the function that makes a Var) is documented here rather than on a page of its own, whose file name would clash with that of Var on case-insensitive file systems:

var(name)

The grid variable name as a block parameter.

comnum.var(name: str) → Var#

The grid variable name as a block parameter.

Parameters:

name (str) – the name of the variable of the grid.

Returns:

the reference, substituted for every condition.

Return type:

Var

Monte Carlo runner#

sim

Monte Carlo campaigns of Python trials, on the Rust runner.

Declarative campaigns#

run_spec(spec, *[, threads, batch, ...])

Run a declarative campaign with the Rust runner (parallel, reproducible).

verify_spec(spec, *[, threads, progress, ...])

Run a specification and check its expected results (closed forms, published curves).

search_spec(spec, *[, threads, batch, ...])

Search the operating point of a specification: the value of a variable at which a metric reaches a target, for every combination of the other grid axes.

spec_conditions(spec)

The conditions of a specification, in order, as dicts.

spec_blocks()

The blocks of the declarative links, their parameters and their ports.

spec_schema()

The JSON Schema of a block of a declarative link: one alternative per block, with the type, default, unit, accepted values and bounds of every parameter, and the ports of the block (x-needs, x-gives), for editors and graphical front ends.

spec_check_link(kinds)

Check the ports of a link of block types: every block finds the facts it needs among those the blocks before it give.

Tolerance(*[, atol, rtol, factor])

The acceptance rule of a measured value v against an expected value e, as comnum verify and the validation cards apply it: |v - e| <= atol + rtol |e| (with atol or rtol), or e/factor <= v <= factor e for a positive e (with factor); a value passes when one of the given rules accepts it.

Recordings#

read_sigmf(path, *[, channel, autoscale])

Read a SigMF recording (SigMF 1.x: every data type, little or big endian, several channels, capture headers, trailing bytes, .sigmf archives).

write_sigmf(base, samples, fs, *[, ...])

Write a SigMF recording base.sigmf-meta and base.sigmf-data.