Mappers#
- class SymbolMapper(alphabet: ndarray, *, name: str = 'Symbol Mapper')[source]#
Symbol mapper converting integer indices to constellation symbols.
Signal Model#
Each integer input \(x[n]\) selects one symbol of the alphabet \(\mathcal{M} = \{s_0, s_1, \ldots, s_{M-1}\}\):
\[y[n] = s_{x[n]}, \qquad x[n] \in \{0, 1, \ldots, M-1\}\]Axes: element-wise – applied pointwise, shape-agnostic.
- param alphabet:
Constellation alphabet \(\mathcal{M} = \{s_0, \ldots, s_{M-1}\}\) as a 1-D array of \(M\) complex symbols.
- type alphabet:
np.ndarray
- param name:
Name of the symbol mapper instance. Default is
"Symbol Mapper".- type name:
str, optional, keyword-only
References
J. G. Proakis, M. Salehi, Digital Communications, 5th ed., McGraw-Hill, 2008, Chapter 3.
Examples
>>> from comnumpy.core.utils import get_alphabet >>> mapper = SymbolMapper(get_alphabet("QAM", 4)) >>> y = mapper(np.array([0, 3, 2, 1])) >>> print(np.round(y, 2)) [-0.71+0.71j 0.71-0.71j 0.71+0.71j -0.71-0.71j]
- class SymbolDemapper(alphabet: ndarray, *, soft: bool = False, sigma2: float = 1.0, name: str = 'Symbol Demapper')[source]#
Symbol demapper: minimum-distance (hard) decisions or bit LLRs (soft).
Signal Model#
With
soft=False(default), each input sample \(x[n]\) is mapped to the index of the nearest symbol of the alphabet \(\mathcal{M} = \{s_0, s_1, \ldots, s_{M-1}\}\):\[y[n] = \arg \min_{m \in \{0, 1, \ldots, M-1\}} \left|x[n] - s_m\right|^2\]With
soft=True, the demapper outputs the max-log log-likelihood ratio of every bit \(i\) of the symbol index (MSB first, \(k = \log_2 M\) bits per symbol, decision D12):\[L_i[n] = \frac{1}{\sigma^2} \left( \min_{m \,:\, b_i(m) = 1} |x[n] - s_m|^2 - \min_{m \,:\, b_i(m) = 0} |x[n] - s_m|^2 \right)\]so \(L_i > 0\) favors bit 0 – the convention expected by
ViterbiDecoder(soft=True). This is the inverse operation ofSymbolMapper.Axes: element-wise – applied pointwise, shape-agnostic; with
soft=Truethe last axis grows from \(N\) symbols to \(k N\) LLRs (bits of a symbol contiguous, MSB first).- param alphabet:
Constellation alphabet \(\mathcal{M} = \{s_0, \ldots, s_{M-1}\}\) as a 1-D array of \(M\) complex symbols; the bits of a symbol are the binary representation of its index.
- type alphabet:
np.ndarray
- param soft:
Output bit LLRs instead of hard symbol decisions. Default False.
- type soft:
bool, keyword-only
- param sigma2:
Noise variance \(\sigma^2\) scaling the LLRs. Default 1.0 (the scaling does not affect Viterbi decoding).
- type sigma2:
float, keyword-only
- param name:
Name of the symbol demapper instance. Default is
"Symbol Demapper".- type name:
str, optional, keyword-only
- raises ValueError:
If the alphabet size is not a power of two – the bit table behind the LLRs is built at construction, in hard mode too, so the constraint applies regardless of
soft.
References
J. G. Proakis, M. Salehi, Digital Communications, 5th ed., McGraw-Hill, 2008, Chapter 4; P. Robertson, E. Villebrun, P. Hoeher, “A comparison of optimal and sub-optimal MAP decoding algorithms operating in the log domain,” ICC 1995 (max-log approximation).
Examples
>>> from comnumpy.core.utils import get_alphabet >>> demapper = SymbolDemapper(get_alphabet("QAM", 4)) >>> x = np.array([-0.7+0.7j, 0.7-0.7j, 0.7+0.7j, -0.7-0.7j]) >>> print(demapper(x)) [0 3 2 1] >>> soft = SymbolDemapper(get_alphabet("QAM", 4), soft=True) >>> print(np.round(soft(x[:2]), 2)) # LLR > 0 favors bit 0 [ 1.98 1.98 -1.98 -1.98]