Mapping
This module contains classes and functions related to mapping
of bits to constellation symbols and demapping of soft-symbols
to log-likelihood ratios (LLRs). The key components are the
Constellation
, Mapper
,
and Demapper
. A Constellation
can be made trainable to enable learning of geometric shaping.
Constellations
Constellation
- class sionna.mapping.Constellation(constellation_type, num_bits_per_symbol, initial_value=None, normalize=True, center=False, trainable=False, dtype=tf.complex64, **kwargs)[source]
Constellation that can be used by a (de)mapper.
This class defines a constellation, i.e., a complex-valued vector of constellation points. A constellation can be trainable. The binary representation of the index of an element of this vector corresponds to the bit label of the constellation point. This implicit bit labeling is used by the
Mapper
andDemapper
classes.- Parameters:
constellation_type (One of ["qam", "pam", "custom"], str) – For “custom”, the constellation points are randomly initialized if no
initial_value
is provided.num_bits_per_symbol (int) – The number of bits per constellation symbol, e.g., 4 for QAM16.
initial_value (\([2^\text{num_bits_per_symbol}]\), NumPy array or Tensor) – Initial values of the constellation points. If
normalize
orcenter
are True, the initial constellation might be changed.normalize (bool) – If True, the constellation is normalized to have unit power. Defaults to True.
center (bool) – If True, the constellation is ensured to have zero mean. Defaults to False.
trainable (bool) – If True, the constellation points are trainable variables. Defaults to False.
dtype ([tf.complex64, tf.complex128], tf.DType) – The dtype of the constellation.
- Output:
\([2^\text{num_bits_per_symbol}]\),
dtype
– The constellation.
Note
One can create a trainable PAM/QAM constellation. This is equivalent to creating a custom trainable constellation which is initialized with PAM/QAM constellation points.
- property center
Indicates if the constellation is centered.
- create_or_check_constellation(num_bits_per_symbol=None, constellation=None, dtype=tf.complex64)[source]
Static method for conviently creating a constellation object or checking that an existing one is consistent with requested settings.
If
constellation
is None, then this method creates aConstellation
object of typeconstellation_type
and withnum_bits_per_symbol
bits per symbol. Otherwise, this method checks that constellation is consistent withconstellation_type
andnum_bits_per_symbol
. If it is,constellation
is returned. Otherwise, an assertion is raised.- Input:
constellation_type (One of [“qam”, “pam”, “custom”], str) – For “custom”, an instance of
Constellation
must be provided.num_bits_per_symbol (int) – The number of bits per constellation symbol, e.g., 4 for QAM16. Only required for
constellation_type
in [“qam”, “pam”].constellation (Constellation) – An instance of
Constellation
or None. In the latter case,constellation_type
andnum_bits_per_symbol
must be provided.
- Output:
Constellation
– A constellation object.
- property normalize
Indicates if the constellation is normalized or not.
- property num_bits_per_symbol
The number of bits per constellation symbol.
- property points
The (possibly) centered and normalized constellation points.
- show(labels=True, figsize=(7, 7))[source]
Generate a scatter-plot of the constellation.
- Input:
labels (bool) – If True, the bit labels will be drawn next to each constellation point. Defaults to True.
figsize (Two-element Tuple, float) – Width and height in inches. Defaults to (7,7).
- Output:
matplotlib.figure.Figure – A handle to a matplot figure object.
qam
- sionna.mapping.qam(num_bits_per_symbol, normalize=True)[source]
Generates a QAM constellation.
This function generates a complex-valued vector, where each element is a constellation point of an M-ary QAM constellation. The bit label of the
n
th point is given by the length-num_bits_per_symbol
binary represenation ofn
.- Input:
num_bits_per_symbol (int) – The number of bits per constellation point. Must be a multiple of two, e.g., 2, 4, 6, 8, etc.
normalize (bool) – If True, the constellation is normalized to have unit power. Defaults to True.
- Output:
\([2^{\text{num_bits_per_symbol}}]\), np.complex64 – The QAM constellation.
Note
The bit label of the nth constellation point is given by the binary representation of its position within the array and can be obtained through
np.binary_repr(n, num_bits_per_symbol)
.The normalization factor of a QAM constellation is given in closed-form as:
\[\sqrt{\frac{1}{2^{n-2}}\sum_{i=1}^{2^{n-1}}(2i-1)^2}\]where \(n= \text{num_bits_per_symbol}/2\) is the number of bits per dimension.
This algorithm is a recursive implementation of the expressions found in Section 5.1 of [3GPPTS38211]. It is used in the 5G standard.
pam
- sionna.mapping.pam(num_bits_per_symbol, normalize=True)[source]
Generates a PAM constellation.
This function generates a real-valued vector, where each element is a constellation point of an M-ary PAM constellation. The bit label of the
n
th point is given by the length-num_bits_per_symbol
binary represenation ofn
.- Input:
num_bits_per_symbol (int) – The number of bits per constellation point. Must be positive.
normalize (bool) – If True, the constellation is normalized to have unit power. Defaults to True.
- Output:
\([2^{\text{num_bits_per_symbol}}]\), np.float32 – The PAM constellation.
Note
The bit label of the nth constellation point is given by the binary representation of its position within the array and can be obtained through
np.binary_repr(n, num_bits_per_symbol)
.The normalization factor of a PAM constellation is given in closed-form as:
\[\sqrt{\frac{1}{2^{n-1}}\sum_{i=1}^{2^{n-1}}(2i-1)^2}\]where \(n= \text{num_bits_per_symbol}\) is the number of bits per symbol.
This algorithm is a recursive implementation of the expressions found in Section 5.1 of [3GPPTS38211]. It is used in the 5G standard.
pam_gray
- sionna.mapping.pam_gray(b)[source]
Maps a vector of bits to a PAM constellation points with Gray labeling.
This recursive function maps a binary vector to Gray-labelled PAM constellation points. It can be used to generated QAM constellations. The constellation is not normalized.
- Input:
b ([n], NumPy array) – Tensor with with binary entries.
- Output:
signed int – The PAM constellation point taking values in \(\{\pm 1,\pm 3,\dots,\pm (2^n-1)\}\).
Note
This algorithm is a recursive implementation of the expressions found in Section 5.1 of [3GPPTS38211]. It is used in the 5G standard.
Mapper
- class sionna.mapping.Mapper(constellation_type=None, num_bits_per_symbol=None, constellation=None, return_indices=False, dtype=tf.complex64, **kwargs)[source]
Maps binary tensors to points of a constellation.
This class defines a layer that maps a tensor of binary values to a tensor of points from a provided constellation.
- Parameters:
constellation_type (One of ["qam", "pam", "custom"], str) – For “custom”, an instance of
Constellation
must be provided.num_bits_per_symbol (int) – The number of bits per constellation symbol, e.g., 4 for QAM16. Only required for
constellation_type
in [“qam”, “pam”].constellation (Constellation) – An instance of
Constellation
or None. In the latter case,constellation_type
andnum_bits_per_symbol
must be provided.return_indices (bool) – If enabled, symbol indices are additionally returned. Defaults to False.
dtype (One of [tf.complex64, tf.complex128], tf.DType) – The output dtype. Defaults to tf.complex64.
- Input:
[…, n], tf.float or tf.int – Tensor with with binary entries.
- Output:
[…,n/Constellation.num_bits_per_symbol], tf.complex – The mapped constellation symbols.
[…,n/Constellation.num_bits_per_symbol], tf.int32 – The symbol indices corresponding to the constellation symbols. Only returned if
return_indices
is set to True.
Note
The last input dimension must be an integer multiple of the number of bits per constellation symbol.
- property constellation
The Constellation used by the Mapper.
Demapping
Demapper
- class sionna.mapping.Demapper(demapping_method, constellation_type=None, num_bits_per_symbol=None, constellation=None, hard_out=False, with_prior=False, dtype=tf.complex64, **kwargs)[source]
Computes log-likelihood ratios (LLRs) or hard-decisions on bits for a tensor of received symbols. If the flag
with_prior
is set, prior knowledge on the bits is assumed to be available.This class defines a layer implementing different demapping functions. All demapping functions are fully differentiable when soft-decisions are computed.
- Parameters:
demapping_method (One of ["app", "maxlog"], str) – The demapping method used.
constellation_type (One of ["qam", "pam", "custom"], str) – For “custom”, an instance of
Constellation
must be provided.num_bits_per_symbol (int) – The number of bits per constellation symbol, e.g., 4 for QAM16. Only required for
constellation_type
in [“qam”, “pam”].constellation (Constellation) – An instance of
Constellation
or None. In the latter case,constellation_type
andnum_bits_per_symbol
must be provided.hard_out (bool) – If True, the demapper provides hard-decided bits instead of soft-values. Defaults to False.
with_prior (bool) – If True, it is assumed that prior knowledge on the bits is available. This prior information is given as LLRs as an additional input to the layer. Defaults to False.
dtype (One of [tf.complex64, tf.complex128] tf.DType (dtype)) – The dtype of y. Defaults to tf.complex64. The output dtype is the corresponding real dtype (tf.float32 or tf.float64).
- Input:
(y,no) or (y, prior, no) – Tuple:
y ([…,n], tf.complex) – The received symbols.
prior ([num_bits_per_symbol] or […,num_bits_per_symbol], tf.float) – Prior for every bit as LLRs. It can be provided either as a tensor of shape [num_bits_per_symbol] for the entire input batch, or as a tensor that is “broadcastable” to […, n, num_bits_per_symbol]. Only required if the
with_prior
flag is set.no (Scalar or […,n], tf.float) – The noise variance estimate. It can be provided either as scalar for the entire input batch or as a tensor that is “broadcastable” to
y
.
- Output:
[…,n*num_bits_per_symbol], tf.float – LLRs or hard-decisions for every bit.
Note
With the “app” demapping method, the LLR for the \(i\text{th}\) bit is computed according to
\[LLR(i) = \ln\left(\frac{\Pr\left(b_i=1\lvert y,\mathbf{p}\right)}{\Pr\left(b_i=0\lvert y,\mathbf{p}\right)}\right) =\ln\left(\frac{ \sum_{c\in\mathcal{C}_{i,1}} \Pr\left(c\lvert\mathbf{p}\right) \exp\left(-\frac{1}{N_o}\left|y-c\right|^2\right) }{ \sum_{c\in\mathcal{C}_{i,0}} \Pr\left(c\lvert\mathbf{p}\right) \exp\left(-\frac{1}{N_o}\left|y-c\right|^2\right) }\right)\]where \(\mathcal{C}_{i,1}\) and \(\mathcal{C}_{i,0}\) are the sets of constellation points for which the \(i\text{th}\) bit is equal to 1 and 0, respectively. \(\mathbf{p} = \left[p_0,\dots,p_{K-1}\right]\) is the vector of LLRs that serves as prior knowledge on the \(K\) bits that are mapped to a constellation point and is set to \(\mathbf{0}\) if no prior knowledge is assumed to be available, and \(\Pr(c\lvert\mathbf{p})\) is the prior probability on the constellation symbol \(c\):
\[\Pr\left(c\lvert\mathbf{p}\right) = \prod_{k=0}^{K-1} \text{sigmoid}\left(p_k \ell(c)_k\right)\]where \(\ell(c)_k\) is the \(k^{th}\) bit label of \(c\), where 0 is replaced by -1. The definition of the LLR has been chosen such that it is equivalent with that of logits. This is different from many textbooks in communications, where the LLR is defined as \(LLR(i) = \ln\left(\frac{\Pr\left(b_i=0\lvert y\right)}{\Pr\left(b_i=1\lvert y\right)}\right)\).
With the “maxlog” demapping method, LLRs for the \(i\text{th}\) bit are approximated like
\[\begin{split}\begin{align} LLR(i) &\approx\ln\left(\frac{ \max_{c\in\mathcal{C}_{i,1}} \Pr\left(c\lvert\mathbf{p}\right) \exp\left(-\frac{1}{N_o}\left|y-c\right|^2\right) }{ \max_{c\in\mathcal{C}_{i,0}} \Pr\left(c\lvert\mathbf{p}\right) \exp\left(-\frac{1}{N_o}\left|y-c\right|^2\right) }\right)\\ &= \max_{c\in\mathcal{C}_{i,0}} \left(\ln\left(\Pr\left(c\lvert\mathbf{p}\right)\right)-\frac{|y-c|^2}{N_o}\right) - \max_{c\in\mathcal{C}_{i,1}}\left( \ln\left(\Pr\left(c\lvert\mathbf{p}\right)\right) - \frac{|y-c|^2}{N_o}\right) . \end{align}\end{split}\]
DemapperWithPrior
- class sionna.mapping.DemapperWithPrior(demapping_method, constellation_type=None, num_bits_per_symbol=None, constellation=None, hard_out=False, dtype=tf.complex64, **kwargs)[source]
Computes log-likelihood ratios (LLRs) or hard-decisions on bits for a tensor of received symbols, assuming that prior knowledge on the bits is available.
This class defines a layer implementing different demapping functions. All demapping functions are fully differentiable when soft-decisions are computed.
This class is deprecated as the functionality has been integrated into
Demapper
.- Parameters:
demapping_method (One of ["app", "maxlog"], str) – The demapping method used.
constellation_type (One of ["qam", "pam", "custom"], str) – For “custom”, an instance of
Constellation
must be provided.num_bits_per_symbol (int) – The number of bits per constellation symbol, e.g., 4 for QAM16. Only required for
constellation_type
in [“qam”, “pam”].constellation (Constellation) – An instance of
Constellation
or None. In the latter case,constellation_type
andnum_bits_per_symbol
must be provided.hard_out (bool) – If True, the demapper provides hard-decided bits instead of soft-values. Defaults to False.
dtype (One of [tf.complex64, tf.complex128] tf.DType (dtype)) – The dtype of y. Defaults to tf.complex64. The output dtype is the corresponding real dtype (tf.float32 or tf.float64).
- Input:
(y, prior, no) – Tuple:
y ([…,n], tf.complex) – The received symbols.
prior ([num_bits_per_symbol] or […,num_bits_per_symbol], tf.float) – Prior for every bit as LLRs. It can be provided either as a tensor of shape [num_bits_per_symbol] for the entire input batch, or as a tensor that is “broadcastable” to […, n, num_bits_per_symbol].
no (Scalar or […,n], tf.float) – The noise variance estimate. It can be provided either as scalar for the entire input batch or as a tensor that is “broadcastable” to
y
.
- Output:
[…,n*num_bits_per_symbol], tf.float – LLRs or hard-decisions for every bit.
Note
With the “app” demapping method, the LLR for the \(i\text{th}\) bit is computed according to
\[LLR(i) = \ln\left(\frac{\Pr\left(b_i=1\lvert y,\mathbf{p}\right)}{\Pr\left(b_i=0\lvert y,\mathbf{p}\right)}\right) =\ln\left(\frac{ \sum_{c\in\mathcal{C}_{i,1}} \Pr\left(c\lvert\mathbf{p}\right) \exp\left(-\frac{1}{N_o}\left|y-c\right|^2\right) }{ \sum_{c\in\mathcal{C}_{i,0}} \Pr\left(c\lvert\mathbf{p}\right) \exp\left(-\frac{1}{N_o}\left|y-c\right|^2\right) }\right)\]where \(\mathcal{C}_{i,1}\) and \(\mathcal{C}_{i,0}\) are the sets of constellation points for which the \(i\text{th}\) bit is equal to 1 and 0, respectively. \(\mathbf{p} = \left[p_0,\dots,p_{K-1}\right]\) is the vector of LLRs that serves as prior knowledge on the \(K\) bits that are mapped to a constellation point, and \(\Pr(c\lvert\mathbf{p})\) is the prior probability on the constellation symbol \(c\):
\[\Pr\left(c\lvert\mathbf{p}\right) = \prod_{k=0}^{K-1} \text{sigmoid}\left(p_k \ell(c)_k\right)\]where \(\ell(c)_k\) is the \(k^{th}\) bit label of \(c\), where 0 is replaced by -1. The definition of the LLR has been chosen such that it is equivalent with that of logits. This is different from many textbooks in communications, where the LLR is defined as \(LLR(i) = \ln\left(\frac{\Pr\left(b_i=0\lvert y\right)}{\Pr\left(b_i=1\lvert y\right)}\right)\).
With the “maxlog” demapping method, LLRs for the \(i\text{th}\) bit are approximated like
\[\begin{split}\begin{align} LLR(i) &\approx\ln\left(\frac{ \max_{c\in\mathcal{C}_{i,1}} \Pr\left(c\lvert\mathbf{p}\right) \exp\left(-\frac{1}{N_o}\left|y-c\right|^2\right) }{ \max_{c\in\mathcal{C}_{i,0}} \Pr\left(c\lvert\mathbf{p}\right) \exp\left(-\frac{1}{N_o}\left|y-c\right|^2\right) }\right)\\ &= \max_{c\in\mathcal{C}_{i,0}} \left(\ln\left(\Pr\left(c\lvert\mathbf{p}\right)\right)-\frac{|y-c|^2}{N_o}\right) - \max_{c\in\mathcal{C}_{i,1}}\left( \ln\left(\Pr\left(c\lvert\mathbf{p}\right)\right) - \frac{|y-c|^2}{N_o}\right) . \end{align}\end{split}\]
SymbolDemapper
- class sionna.mapping.SymbolDemapper(constellation_type=None, num_bits_per_symbol=None, constellation=None, hard_out=False, with_prior=False, dtype=tf.complex64, **kwargs)[source]
Computes normalized log-probabilities (logits) or hard-decisions on symbols for a tensor of received symbols. If the
with_prior
flag is set, prior knowldge on the transmitted constellation points is assumed to be available. The demapping function is fully differentiable when soft-values are computed.- Parameters:
constellation_type (One of ["qam", "pam", "custom"], str) – For “custom”, an instance of
Constellation
must be provided.num_bits_per_symbol (int) – The number of bits per constellation symbol, e.g., 4 for QAM16. Only required for
constellation_type
in [“qam”, “pam”].constellation (Constellation) – An instance of
Constellation
or None. In the latter case,constellation_type
andnum_bits_per_symbol
must be provided.hard_out (bool) – If True, the demapper provides hard-decided symbols instead of soft-values. Defaults to False.
with_prior (bool) – If True, it is assumed that prior knowledge on the constellation points is available. This prior information is given as log-probabilities (logits) as an additional input to the layer. Defaults to False.
dtype (One of [tf.complex64, tf.complex128] tf.DType (dtype)) – The dtype of y. Defaults to tf.complex64. The output dtype is the corresponding real dtype (tf.float32 or tf.float64).
- Input:
(y, no) or (y, prior, no) – Tuple:
y ([…,n], tf.complex) – The received symbols.
prior ([num_points] or […,num_points], tf.float) – Prior for every symbol as log-probabilities (logits). It can be provided either as a tensor of shape [num_points] for the entire input batch, or as a tensor that is “broadcastable” to […, n, num_points]. Only required if the
with_prior
flag is set.no (Scalar or […,n], tf.float) – The noise variance estimate. It can be provided either as scalar for the entire input batch or as a tensor that is “broadcastable” to
y
.
- Output:
[…,n, num_points] or […,n], tf.float – A tensor of shape […,n, num_points] of logits for every constellation point if hard_out is set to False. Otherwise, a tensor of shape […,n] of hard-decisions on the symbols.
Note
The normalized log-probability for the constellation point \(c\) is computed according to
\[\ln\left(\Pr\left(c \lvert y,\mathbf{p}\right)\right) = \ln\left( \frac{\exp\left(-\frac{|y-c|^2}{N_0} + p_c \right)}{\sum_{c'\in\mathcal{C}} \exp\left(-\frac{|y-c'|^2}{N_0} + p_{c'} \right)} \right)\]where \(\mathcal{C}\) is the set of constellation points used for modulation, and \(\mathbf{p} = \left\{p_c \lvert c \in \mathcal{C}\right\}\) the prior information on constellation points given as log-probabilities and which is set to \(\mathbf{0}\) if no prior information on the constellation points is assumed to be available.
SymbolDemapperWithPrior
- class sionna.mapping.SymbolDemapperWithPrior(constellation_type=None, num_bits_per_symbol=None, constellation=None, hard_out=False, dtype=tf.complex64, **kwargs)[source]
Computes normalized log-probabilities (logits) or hard-decisions on symbols for a tensor of received symbols, assuming that prior knowledge on the constellation points is available. The demapping function is fully differentiable when soft-values are computed.
This class is deprecated as the functionality has been integrated into
SymbolDemapper
.- Parameters:
constellation_type (One of ["qam", "pam", "custom"], str) – For “custom”, an instance of
Constellation
must be provided.num_bits_per_symbol (int) – The number of bits per constellation symbol, e.g., 4 for QAM16. Only required for
constellation_type
in [“qam”, “pam”].constellation (Constellation) – An instance of
Constellation
or None. In the latter case,constellation_type
andnum_bits_per_symbol
must be provided.hard_out (bool) – If True, the demapper provides hard-decided symbols instead of soft-values. Defaults to False.
dtype (One of [tf.complex64, tf.complex128] tf.DType (dtype)) – The dtype of y. Defaults to tf.complex64. The output dtype is the corresponding real dtype (tf.float32 or tf.float64).
- Input:
(y, prior, no) – Tuple:
y ([…,n], tf.complex) – The received symbols.
prior ([num_points] or […,num_points], tf.float) – Prior for every symbol as log-probabilities (logits). It can be provided either as a tensor of shape [num_points] for the entire input batch, or as a tensor that is “broadcastable” to […, n, num_points].
no (Scalar or […,n], tf.float) – The noise variance estimate. It can be provided either as scalar for the entire input batch or as a tensor that is “broadcastable” to
y
.
- Output:
[…,n, num_points] or […,n], tf.float – A tensor of shape […,n, num_points] of logits for every constellation point if hard_out is set to False. Otherwise, a tensor of shape […,n] of hard-decisions on the symbols.
Note
The normalized log-probability for the constellation point \(c\) is computed according to
\[\ln\left(\Pr\left(c \lvert y,\mathbf{p}\right)\right) = \ln\left( \frac{\exp\left(-\frac{|y-c|^2}{N_0} + p_c \right)}{\sum_{c'\in\mathcal{C}} \exp\left(-\frac{|y-c'|^2}{N_0} + p_{c'} \right)} \right)\]where \(\mathcal{C}\) is the set of constellation points used for modulation, and \(\mathbf{p} = \left\{p_c \lvert c \in \mathcal{C}\right\}\) the prior information on constellation points given as log-probabilities.
Utility Functions
SymbolLogits2LLRs
- class sionna.mapping.SymbolLogits2LLRs(method, num_bits_per_symbol, hard_out=False, with_prior=False, dtype=tf.float32, **kwargs)[source]
Computes log-likelihood ratios (LLRs) or hard-decisions on bits from a tensor of logits (i.e., unnormalized log-probabilities) on constellation points. If the flag
with_prior
is set, prior knowledge on the bits is assumed to be available.- Parameters:
method (One of ["app", "maxlog"], str) – The method used for computing the LLRs.
num_bits_per_symbol (int) – The number of bits per constellation symbol, e.g., 4 for QAM16.
hard_out (bool) – If True, the layer provides hard-decided bits instead of soft-values. Defaults to False.
with_prior (bool) – If True, it is assumed that prior knowledge on the bits is available. This prior information is given as LLRs as an additional input to the layer. Defaults to False.
dtype (One of [tf.float32, tf.float64] tf.DType (dtype)) – The dtype for the input and output. Defaults to tf.float32.
- Input:
logits or (logits, prior) – Tuple:
logits ([…,n, num_points], tf.float) – Logits on constellation points.
prior ([num_bits_per_symbol] or […n, num_bits_per_symbol], tf.float) – Prior for every bit as LLRs. It can be provided either as a tensor of shape [num_bits_per_symbol] for the entire input batch, or as a tensor that is “broadcastable” to […, n, num_bits_per_symbol]. Only required if the
with_prior
flag is set.
- Output:
[…,n, num_bits_per_symbol], tf.float – LLRs or hard-decisions for every bit.
Note
With the “app” method, the LLR for the \(i\text{th}\) bit is computed according to
\[LLR(i) = \ln\left(\frac{\Pr\left(b_i=1\lvert \mathbf{z},\mathbf{p}\right)}{\Pr\left(b_i=0\lvert \mathbf{z},\mathbf{p}\right)}\right) =\ln\left(\frac{ \sum_{c\in\mathcal{C}_{i,1}} \Pr\left(c\lvert\mathbf{p}\right) e^{z_c} }{ \sum_{c\in\mathcal{C}_{i,0}} \Pr\left(c\lvert\mathbf{p}\right) e^{z_c} }\right)\]where \(\mathcal{C}_{i,1}\) and \(\mathcal{C}_{i,0}\) are the sets of \(2^K\) constellation points for which the \(i\text{th}\) bit is equal to 1 and 0, respectively. \(\mathbf{z} = \left[z_{c_0},\dots,z_{c_{2^K-1}}\right]\) is the vector of logits on the constellation points, \(\mathbf{p} = \left[p_0,\dots,p_{K-1}\right]\) is the vector of LLRs that serves as prior knowledge on the \(K\) bits that are mapped to a constellation point and is set to \(\mathbf{0}\) if no prior knowledge is assumed to be available, and \(\Pr(c\lvert\mathbf{p})\) is the prior probability on the constellation symbol \(c\):
\[\Pr\left(c\lvert\mathbf{p}\right) = \prod_{k=0}^{K-1} \Pr\left(b_k = \ell(c)_k \lvert\mathbf{p} \right) = \prod_{k=0}^{K-1} \text{sigmoid}\left(p_k \ell(c)_k\right)\]where \(\ell(c)_k\) is the \(k^{th}\) bit label of \(c\), where 0 is replaced by -1. The definition of the LLR has been chosen such that it is equivalent with that of logits. This is different from many textbooks in communications, where the LLR is defined as \(LLR(i) = \ln\left(\frac{\Pr\left(b_i=0\lvert y\right)}{\Pr\left(b_i=1\lvert y\right)}\right)\).
With the “maxlog” method, LLRs for the \(i\text{th}\) bit are approximated like
\[\begin{align} LLR(i) &\approx\ln\left(\frac{ \max_{c\in\mathcal{C}_{i,1}} \Pr\left(c\lvert\mathbf{p}\right) e^{z_c} }{ \max_{c\in\mathcal{C}_{i,0}} \Pr\left(c\lvert\mathbf{p}\right) e^{z_c} }\right) . \end{align}\]
LLRs2SymbolLogits
- class sionna.mapping.LLRs2SymbolLogits(num_bits_per_symbol, hard_out=False, dtype=tf.float32, **kwargs)[source]
Computes logits (i.e., unnormalized log-probabilities) or hard decisions on constellation points from a tensor of log-likelihood ratios (LLRs) on bits.
- Parameters:
num_bits_per_symbol (int) – The number of bits per constellation symbol, e.g., 4 for QAM16.
hard_out (bool) – If True, the layer provides hard-decided constellation points instead of soft-values. Defaults to False.
dtype (One of [tf.float32, tf.float64] tf.DType (dtype)) – The dtype for the input and output. Defaults to tf.float32.
- Input:
llrs ([…, n, num_bits_per_symbol], tf.float) – LLRs for every bit.
- Output:
[…,n, num_points], tf.float or […, n], tf.int32 – Logits or hard-decisions on constellation points.
Note
The logit for the constellation \(c\) point is computed according to
\[\begin{split}\begin{align} \log{\left(\Pr\left(c\lvert LLRs \right)\right)} &= \log{\left(\prod_{k=0}^{K-1} \Pr\left(b_k = \ell(c)_k \lvert LLRs \right)\right)}\\ &= \log{\left(\prod_{k=0}^{K-1} \text{sigmoid}\left(LLR(k) \ell(c)_k\right)\right)}\\ &= \sum_{k=0}^{K-1} \log{\left(\text{sigmoid}\left(LLR(k) \ell(c)_k\right)\right)} \end{align}\end{split}\]where \(\ell(c)_k\) is the \(k^{th}\) bit label of \(c\), where 0 is replaced by -1. The definition of the LLR has been chosen such that it is equivalent with that of logits. This is different from many textbooks in communications, where the LLR is defined as \(LLR(i) = \ln\left(\frac{\Pr\left(b_i=0\lvert y\right)}{\Pr\left(b_i=1\lvert y\right)}\right)\).
SymbolLogits2LLRsWithPrior
- class sionna.mapping.SymbolLogits2LLRsWithPrior(method, num_bits_per_symbol, hard_out=False, dtype=tf.float32, **kwargs)[source]
Computes log-likelihood ratios (LLRs) or hard-decisions on bits from a tensor of logits (i.e., unnormalized log-probabilities) on constellation points, assuming that prior knowledge on the bits is available.
This class is deprecated as the functionality has been integrated into
SymbolLogits2LLRs
.- Parameters:
method (One of ["app", "maxlog"], str) – The method used for computing the LLRs.
num_bits_per_symbol (int) – The number of bits per constellation symbol, e.g., 4 for QAM16.
hard_out (bool) – If True, the layer provides hard-decided bits instead of soft-values. Defaults to False.
dtype (One of [tf.float32, tf.float64] tf.DType (dtype)) – The dtype for the input and output. Defaults to tf.float32.
- Input:
(logits, prior) – Tuple:
logits ([…,n, num_points], tf.float) – Logits on constellation points.
prior ([num_bits_per_symbol] or […n, num_bits_per_symbol], tf.float) – Prior for every bit as LLRs. It can be provided either as a tensor of shape [num_bits_per_symbol] for the entire input batch, or as a tensor that is “broadcastable” to […, n, num_bits_per_symbol].
- Output:
[…,n, num_bits_per_symbol], tf.float – LLRs or hard-decisions for every bit.
Note
With the “app” method, the LLR for the \(i\text{th}\) bit is computed according to
\[LLR(i) = \ln\left(\frac{\Pr\left(b_i=1\lvert \mathbf{z},\mathbf{p}\right)}{\Pr\left(b_i=0\lvert \mathbf{z},\mathbf{p}\right)}\right) =\ln\left(\frac{ \sum_{c\in\mathcal{C}_{i,1}} \Pr\left(c\lvert\mathbf{p}\right) e^{z_c} }{ \sum_{c\in\mathcal{C}_{i,0}} \Pr\left(c\lvert\mathbf{p}\right) e^{z_c} }\right)\]where \(\mathcal{C}_{i,1}\) and \(\mathcal{C}_{i,0}\) are the sets of \(2^K\) constellation points for which the \(i\text{th}\) bit is equal to 1 and 0, respectively. \(\mathbf{z} = \left[z_{c_0},\dots,z_{c_{2^K-1}}\right]\) is the vector of logits on the constellation points, \(\mathbf{p} = \left[p_0,\dots,p_{K-1}\right]\) is the vector of LLRs that serves as prior knowledge on the \(K\) bits that are mapped to a constellation point, and \(\Pr(c\lvert\mathbf{p})\) is the prior probability on the constellation symbol \(c\):
\[\Pr\left(c\lvert\mathbf{p}\right) = \prod_{k=0}^{K-1} \Pr\left(b_k = \ell(c)_k \lvert\mathbf{p} \right) = \prod_{k=0}^{K-1} \text{sigmoid}\left(p_k \ell(c)_k\right)\]where \(\ell(c)_k\) is the \(k^{th}\) bit label of \(c\), where 0 is replaced by -1. The definition of the LLR has been chosen such that it is equivalent with that of logits. This is different from many textbooks in communications, where the LLR is defined as \(LLR(i) = \ln\left(\frac{\Pr\left(b_i=0\lvert y\right)}{\Pr\left(b_i=1\lvert y\right)}\right)\).
With the “maxlog” method, LLRs for the \(i\text{th}\) bit are approximated like
\[\begin{align} LLR(i) &\approx\ln\left(\frac{ \max_{c\in\mathcal{C}_{i,1}} \Pr\left(c\lvert\mathbf{p}\right) e^{z_c} }{ \max_{c\in\mathcal{C}_{i,0}} \Pr\left(c\lvert\mathbf{p}\right) e^{z_c} }\right) . \end{align}\]
SymbolLogits2Moments
- class sionna.mapping.SymbolLogits2Moments(constellation_type=None, num_bits_per_symbol=None, constellation=None, dtype=tf.float32, **kwargs)[source]
Computes the mean and variance of a constellation from logits (unnormalized log-probabilities) on the constellation points.
More precisely, given a constellation \(\mathcal{C} = \left[ c_0,\dots,c_{N-1} \right]\) of size \(N\), this layer computes the mean and variance according to
\[\begin{split}\begin{align} \mu &= \sum_{n = 0}^{N-1} c_n \Pr \left(c_n \lvert \mathbf{\ell} \right)\\ \nu &= \sum_{n = 0}^{N-1} \left( c_n - \mu \right)^2 \Pr \left(c_n \lvert \mathbf{\ell} \right) \end{align}\end{split}\]where \(\mathbf{\ell} = \left[ \ell_0, \dots, \ell_{N-1} \right]\) are the logits, and
\[\Pr \left(c_n \lvert \mathbf{\ell} \right) = \frac{\exp \left( \ell_n \right)}{\sum_{i=0}^{N-1} \exp \left( \ell_i \right) }.\]- Parameters:
constellation_type (One of ["qam", "pam", "custom"], str) – For “custom”, an instance of
Constellation
must be provided.num_bits_per_symbol (int) – The number of bits per constellation symbol, e.g., 4 for QAM16. Only required for
constellation_type
in [“qam”, “pam”].constellation (Constellation) – An instance of
Constellation
or None. In the latter case,constellation_type
andnum_bits_per_symbol
must be provided.dtype (One of [tf.float32, tf.float64] tf.DType (dtype)) – The dtype for the input and output. Defaults to tf.float32.
- Input:
logits ([…,n, num_points], tf.float) – Logits on constellation points.
- Output:
mean ([…,n], tf.float) – Mean of the constellation.
var ([…,n], tf.float) – Variance of the constellation
SymbolInds2Bits
- class sionna.mapping.SymbolInds2Bits(num_bits_per_symbol, dtype=tf.float32, **kwargs)[source]
Transforms symbol indices to their binary representations.
- Parameters:
num_bits_per_symbol (int) – Number of bits per constellation symbol
dtype (tf.DType) – Output dtype. Defaults to tf.float32.
- Input:
Tensor, tf.int – Symbol indices
- Output:
input.shape + [num_bits_per_symbol], dtype – Binary representation of symbol indices
PAM2QAM
- class sionna.mapping.PAM2QAM(num_bits_per_symbol, hard_in_out=True)[source]
Transforms PAM symbol indices/logits to QAM symbol indices/logits.
For two PAM constellation symbol indices or logits, corresponding to the real and imaginary components of a QAM constellation, compute the QAM symbol index or logits.
- Parameters:
num_bits_per_symbol (int) – Number of bits per QAM constellation symbol, e.g., 4 for QAM16
hard_in_out (bool) – Determines if inputs and outputs are indices or logits over constellation symbols. Defaults to True.
- Input:
pam1 (Tensor, tf.int, or […,2**(num_bits_per_symbol/2)], tf.float) – Indices or logits for the first PAM constellation
pam2 (Tensor, tf.int, or […,2**(num_bits_per_symbol/2)], tf.float) – Indices or logits for the second PAM constellation
- Output:
qam (Tensor, tf.int, or […,2**num_bits_per_symbol], tf.float) – Indices or logits for the corresponding QAM constellation
QAM2PAM
- class sionna.mapping.QAM2PAM(num_bits_per_symbol)[source]
Transforms QAM symbol indices to PAM symbol indices.
For indices in a QAM constellation, computes the corresponding indices for the two PAM constellations corresponding the real and imaginary components of the QAM constellation.
- Parameters:
num_bits_per_symbol (int) – The number of bits per QAM constellation symbol, e.g., 4 for QAM16.
- Input:
ind_qam (Tensor, tf.int) – Indices in the QAM constellation
- Output:
ind_pam1 (Tensor, tf.int) – Indices for the first component of the corresponding PAM modulation
ind_pam2 (Tensor, tf.int) – Indices for the first component of the corresponding PAM modulation
- References:
- [3GPPTS38211] (1,2,3)
ETSI TS 38.211 “5G NR Physical channels and modulation”, V16.2.0, Jul. 2020 https://www.3gpp.org/ftp/Specs/archive/38_series/38.211/38211-h00.zip