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§
- Label
Halves - 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
shiftof $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
f64per 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 variancenoise_varper 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) intoout[..b], the most significant bit first.