Skip to main content

Module demapper

Module demapper 

Source
Expand description

Soft demapping: log-likelihood ratios of the bits of received symbols.

The soft demapper is the inverse of the mapper and belongs to the same crate.

§Model

For every symbol and every bit position,

$$ L(b) = \ln \sum_{x:\, b = 0} p(x)\, e^{-|y - x|^{2} / \sigma^{2}} - \ln \sum_{x:\, b = 1} p(x)\, e^{-|y - x|^{2} / \sigma^{2}} $$

with $\sigma^{2}$ the variance of the complex noise, one per symbol with Constellation::llr_with_variances. A positive LLR favours bit 0, the library-wide convention of comnum_core::signal. The sums are computed with log-sum-exp, so that they stay finite at any SNR; Jacobian::MaxLog keeps only the largest term of each sum.

Constellation implements the verb traits Map and Demap on the multi-stream containers: Demap::demap_into gives the exact LLRs under uniform priors, Demap::demap_with_into takes the log-priors $\ln p(x)$ of the points (probabilistic shaping) and the Jacobian in a Demapping. Both write into the caller’s Llr and allocate nothing once its shape is stable (the metric row of a symbol is on the stack up to STACK_POINTS points); with log-priors from log_priors of the normalised Constellation::priors, their LLRs are those of Constellation::llr with the probabilities, bit for bit.

§Examples

use comnum_core::prelude::*;
use comnum_mapping::constellation::Constellation;
let c = Constellation::qam(4)?.normalized();
let bits = Bits::from_stream(vec![0, 1, 1, 1])?;
let x = c.map(&bits)?;
let llr = c.demap(&x, 0.01)?;
// positive LLR: bit 0
let hard: Vec<u8> = comnum_core::signal::hard_decisions(llr.as_slice());
assert_eq!(hard, bits.as_slice());
// shaped priors and max-log: the log-priors of the normalised probabilities
let px = [0.4, 0.3, 0.2, 0.1];
let lp = comnum_mapping::constellation::log_priors(&c.priors(Some(&px))?);
let shaped = c.demap_with(&x, 0.01, Demapping { log_priors: Some(&lp), jacobian: Jacobian::MaxLog })?;
assert_eq!(shaped.as_slice(), c.llr(x.as_slice(), 0.01, Some(&px), Jacobian::MaxLog)?);

Structs§

LabelHalves
The metrics of one symbol over the two halves of its labels for one bit: the label $i$ of a point is in half $b$ when bit shift of $i$ is $b$, and every half keeps its largest metric $\mu_{b}$ and the sum $s_{b} = \sum_{i} e^{\ell_{i} - \mu_{b}}$, so that

Constants§

STACK_POINTS
The largest constellation whose metric row (one f64 per point, 8 KiB) the demapper keeps on the stack; a larger one allocates the row once per call.

Functions§

bpsk_llr
The LLRs $2 y / \sigma^{2}$ of real BPSK symbols (crate::constellation::bpsk, $0 \mapsto +1$) received in real Gaussian noise of variance noise_var per dimension.
llr_from_metrics
The LLRs of the $b = \log_{2} M$ bits of one symbol from its metric row (the $M$ values $\ell_{i}$ of LabelHalves) into out[..b], the most significant bit first.