Multiple-Input Multiple-Output (MIMO)

Stream Management

Stream management determines which transmitter is sending which stream towhich receiver. Transmitters and receivers can be user terminals or basestations, depending on whether uplink or downlink transmissions are considered.TheStreamManagement class has various properties thatare needed to recover desired or interfering channel coefficients for precodingand equalization. In order to understand how the various properties ofStreamManagement can be used, we recommend to have a lookat the source code of theLMMSEEqualizer orRZFPrecoder.

The following code snippet shows how to configureStreamManagement for a simple uplink scenario, wherefour transmitters send each one stream to a receiver. Note thatStreamManagement is independent of the actual number ofantennas at the transmitters and receivers.

num_tx=4num_rx=1num_streams_per_tx=1# Indicate which transmitter is associated with which receiver# rx_tx_association[i,j] = 1 means that transmitter j sends one# or mutiple streams to receiver i.rx_tx_association=np.zeros([num_rx,num_tx])rx_tx_association[0,0]=1rx_tx_association[0,1]=1rx_tx_association[0,2]=1rx_tx_association[0,3]=1sm=StreamManagement(rx_tx_association,num_streams_per_tx)
classsionna.phy.mimo.StreamManagement(rx_tx_association,num_streams_per_tx)[source]

Class for management of streams in multi-cell MIMO networks.

Parameters:
  • rx_tx_association ([num_rx,num_tx],np.int) – A binary NumPy array whererx_tx_association[i,j]=1 meansthat receiveri gets one or multiple streams fromtransmitterj.

  • num_streams_per_tx (int) – Indicates the number of streams that are transmitted by eachtransmitter.

Note

Several symmetry constraints onrx_tx_association are imposedto ensure efficient processing. All row sums and all column sumsmust be equal, i.e., all receivers have the same number of associatedtransmitters and all transmitters have the same number of associatedreceivers. It is also assumed that all transmitters send the samenumber of streamsnum_streams_per_tx.

propertydetection_desired_ind

Indices needed to gather desired channels for receive processing

A NumPy array of shape[num_rx*num_streams_per_rx] thatcan be used to gather desired channels from the flattenedchannel tensor of shape[…,num_rx, num_tx, num_streams_per_tx,…].The result of the gather operation can be reshaped to[…,num_rx, num_streams_per_rx,…].

propertydetection_undesired_ind

Indices needed to gather undesired channels for receive processing

A NumPy array of shape[num_rx*num_streams_per_rx] thatcan be used to gather undesired channels from the flattenedchannel tensor of shape[…,num_rx, num_tx, num_streams_per_tx,…].The result of the gather operation can be reshaped to[…,num_rx, num_interfering_streams_per_rx,…].

propertynum_interfering_streams_per_rx

Number of interfering streams received at each eceiver

propertynum_rx

Number of receivers

propertynum_rx_per_tx

Number of receivers communicating with a transmitter

propertynum_streams_per_rx

Number of streams transmitted to each receiver

propertynum_streams_per_tx

Number of streams per transmitter

propertynum_tx

Number of transmitters

propertynum_tx_per_rx

Number of transmitters communicating with a receiver

propertyprecoding_ind

Indices needed to gather channels for precoding

A NumPy array of shape[num_tx, num_rx_per_tx],whereprecoding_ind[i,:] contains the indices of thereceivers to which transmitteri is sending streams.

propertyrx_stream_ids

Mapping of streams to receivers

A Numpy array of shape[num_rx, num_streams_per_rx].This array is obtained fromtx_stream_ids together withtherx_tx_association.rx_stream_ids[i,:] containsthe indices of streams that are supposed to be decoded by receiveri.

propertyrx_tx_association

Association between receivers and transmitters.

A binary NumPy array of shape[num_rx, num_tx],whererx_tx_association[i,j]=1 means that receiverigets one ore multiple streams from transmitterj.

propertystream_association

Association between receivers, transmitters, and streams

A binary NumPy array of shape[num_rx, num_tx, num_streams_per_tx], wherestream_association[i,j,k]=1 means that receiveri getsthek th stream from transmitterj.

propertystream_ind

Indices needed to gather received streams in the correct order

A NumPy array of shape[num_rx*num_streams_per_rx] that can beused to gather streams from the flattened tensor of received streamsof shape[…,num_rx, num_streams_per_rx,…]. The result of thegather operation is then reshaped to[…,num_tx, num_streams_per_tx,…].

propertytx_stream_ids

Mapping of streams to transmitters

A NumPy array of shape[num_tx, num_streams_per_tx].Streams are numbered from 0,1,… and assiged to transmitters inincreasing order, i.e., transmitter 0 gets the firstnum_streams_per_tx and so on.

Precoding

sionna.phy.mimo.cbf_precoding_matrix(h,precision=None)[source]

Computes the conjugate beamforming (CBF) Precoder

This function computes the CBF precoding matrix for a MIMO link, assuming thefollowing model:

\[\mathbf{y} = \mathbf{H}\mathbf{G}\mathbf{x} + \mathbf{n}\]

where\(\mathbf{y}\in\mathbb{C}^K\) is the received signal vector,\(\mathbf{H}\in\mathbb{C}^{K\times M}\) is the known channel matrix,\(\mathbf{G}\in\mathbb{C}^{M\times K}\) is the precoding matrix,\(\mathbf{x}\in\mathbb{C}^K\) is the symbol vector to be precoded,and\(\mathbf{n}\in\mathbb{C}^K\) is a noise vector.

The precoding matrix\(\mathbf{G}\) is defined as :

\[\mathbf{G} = \mathbf{V}\mathbf{D}\]

where

\[\begin{split}\mathbf{V} &= \mathbf{H}^{\mathsf{H}} \\\mathbf{D} &= \mathop{\text{diag}}\left( \lVert \mathbf{v}_{k} \rVert_2^{-1}, k=0,\dots,K-1 \right).\end{split}\]

The matrix\(\mathbf{V}\)ensures that each stream is precoded with a unit-norm vector,i.e.,\(\mathop{\text{tr}}\left(\mathbf{G}\mathbf{G}^{\mathsf{H}}\right)=K\).The function returns the matrix\(\mathbf{G}\).

Input:
  • h ([…,K,M],tf.complex) – 2+D tensor containing the channel matrices

  • precision (None (default) | “single” | “double”) – Precision used for internal calculations and outputs.If set toNone,precision is used

Output:

g ([…,M,K],tf.complex) – 2+D tensor containing the precoding matrices

sionna.phy.mimo.rzf_precoding_matrix(h,alpha=0.0,precision=None)[source]

Computes the Regularized Zero-Forcing (RZF) Precoder

This function computes the RZF precoding matrix for a MIMO link, assuming thefollowing model:

\[\mathbf{y} = \mathbf{H}\mathbf{G}\mathbf{x} + \mathbf{n}\]

where\(\mathbf{y}\in\mathbb{C}^K\) is the received signal vector,\(\mathbf{H}\in\mathbb{C}^{K\times M}\) is the known channel matrix,\(\mathbf{G}\in\mathbb{C}^{M\times K}\) is the precoding matrix,\(\mathbf{x}\in\mathbb{C}^K\) is the symbol vector to be precoded,and\(\mathbf{n}\in\mathbb{C}^K\) is a noise vector.

The precoding matrix\(\mathbf{G}\) is defined as :

\[\mathbf{G} = \mathbf{V}\mathbf{D}\]

where

\[\begin{split}\mathbf{V} &= \mathbf{H}^{\mathsf{H}}\left(\mathbf{H}\mathbf{H}^{\mathsf{H}} + \alpha \mathbf{I} \right)^{-1}\\\mathbf{D} &= \mathop{\text{diag}}\left( \lVert \mathbf{v}_{k} \rVert_2^{-1}, k=0,\dots,K-1 \right)\end{split}\]

where\(\alpha>0\) is the regularization parameter. The matrix\(\mathbf{V}\)ensures that each stream is precoded with a unit-norm vector,i.e.,\(\mathop{\text{tr}}\left(\mathbf{G}\mathbf{G}^{\mathsf{H}}\right)=K\).The function returns the matrix\(\mathbf{G}\).

Input:
  • h ([…,K,M],tf.complex) – 2+D tensor containing the channel matrices

  • alpha (0. (default) | […],tf.float32) – Regularization parameter

  • precision (None (default) | “single” | “double”) – Precision used for internal calculations and outputs.If set toNone,precision is used

Output:

g ([…,M,K],tf.complex) – 2+D tensor containing the precoding matrices

sionna.phy.mimo.rzf_precoder(x,h,alpha=0.0,return_precoding_matrix=False,precision=None)[source]

Regularized Zero-Forcing (RZF) Precoder

This function implements RZF precoding for a MIMO link, assuming thefollowing model:

\[\mathbf{y} = \mathbf{H}\mathbf{G}\mathbf{x} + \mathbf{n}\]

where\(\mathbf{y}\in\mathbb{C}^K\) is the received signal vector,\(\mathbf{H}\in\mathbb{C}^{K\times M}\) is the known channel matrix,\(\mathbf{G}\in\mathbb{C}^{M\times K}\) is the precoding matrix,\(\mathbf{x}\in\mathbb{C}^K\) is the symbol vector to be precoded,and\(\mathbf{n}\in\mathbb{C}^K\) is a noise vector.

The precoding matrix\(\mathbf{G}\) is defined as (Eq. 4.37)[BHS2017] :

\[\mathbf{G} = \mathbf{V}\mathbf{D}\]

where

\[\begin{split}\mathbf{V} &= \mathbf{H}^{\mathsf{H}}\left(\mathbf{H} \mathbf{H}^{\mathsf{H}} + \alpha \mathbf{I} \right)^{-1}\\\mathbf{D} &= \mathop{\text{diag}}\left( \lVert \mathbf{v}_{k} \rVert_2^{-1}, k=0,\dots,K-1 \right)\end{split}\]

where\(\alpha>0\) is the regularization parameter.

This ensures that each stream is precoded with a unit-norm vector,i.e.,\(\mathop{\text{tr}}\left(\mathbf{G}\mathbf{G}^{\mathsf{H}}\right)=K\).The function returns the precoded vector\(\mathbf{G}\mathbf{x}\).

Input:
  • x ([…,K],tf.complex) – Symbol vectors to be precoded

  • h ([…,K,M],tf.complex) – Channel matrices

  • alpha (0. (default) | […],tf.float32) – Regularization parameter

  • return_precoding_matrices (bool, (default,False)) – Indicates if the precoding matrices should be returned or not

  • precision (None (default) | “single” | “double”) – Precision used for internal calculations and outputs.If set toNone,precision is used

Output:
  • x_precoded ([…,M],tf.complex) – Precoded symbol vectors

  • g ([…,M,K],tf.complex) – Precoding matrices. Only returnedifreturn_precoding_matrices=True.

sionna.phy.mimo.grid_of_beams_dft_ula(num_ant,oversmpl=1,precision=None)[source]

Computes the Discrete Fourier Transform (DFT) Grid of Beam (GoB)coefficients for a uniform linear array (ULA)

The coefficient applied to antenna\(n\) for beam\(m\) is expressedas:

\[c_n^m = e^{\frac{2\pi n m}{N O}}, \quad n=0,\dots,N-1, \ m=0,\dots,NO\]

where\(N\) is the number of antennasnum_ant and\(O\) is the oversamplingfactoroversmpl.

Note that the main lobe of beam\(m\) points in the azimuth direction\(\theta = \mathrm{arc sin} \left( 2\frac{m}{N} \right)\) if\(m\leN/2\) and\(\theta = \mathrm{arc sin} \left( 2\frac{m-N}{N} \right)\) if\(m\ge N/2\), where\(\theta=0\) defines the perpendicular to theantenna array.

Input:
  • num_ant (int) – Number of antennas

  • oversmpl (int, (default 1)) – Oversampling factor

  • precision (None (default) | “single” | “double”) – Precision used for internal calculations and outputs.If set toNone,precision is used.

Output:

gob ([num_ant x oversmpl, num_ant],tf.complex) – The\(m\)-th row contains thenum_ant antenna coefficients forthe\(m\)-th DFT beam.

sionna.phy.mimo.grid_of_beams_dft(num_ant_v,num_ant_h,oversmpl_v=1,oversmpl_h=1,precision=None)[source]

Computes the Discrete Fourier Transform (DFT) Grid of Beam (GoB)coefficients for a uniform rectangular array (URA)

GoB indices are arranged over a 2D grid indexed by\((m_v,m_h)\).The coefficient of the beam with index\((m_v,m_h)\) applied to theantenna located at row\(n_v\) and column\(n_h\) of the rectangulararray is expressed as:

\[c_{n_v,n_h}^{m_v,m_h} = e^{\frac{2\pi n_h m_v}{N_h O_h}} e^{\frac{2\pi n_h m_h}{N_v O_v}}\]

where\(n_v=0,\dots,N_v-1\),\(n_h=0,\dots,N_h-1\),\(m_v=0,\dots,N_v O_v\),\(m_h=0,\dots,N_h O_h\),\(N\) is thenumber of antennasnum_ant and\(O_v,O_h\) are the oversamplingfactoroversmpl_v,oversmpl_h in the vertical andhorizontal direction, respectively.

We can rewrite more concisely the matrix coefficients\(c^{m_v,m_h}\) as follows:

\[c^{m_v,m_h} = c^{m_v} \otimes c^{m_h}\]

where\(\otimes\) denotes the Kronecker product and\(c^{m_v},c^{m_h}\) are the ULA DFT beams computed as ingrid_of_beams_dft_ula().

Such a DFT GoB is, e.g., defined in Section 5.2.2.2.1[3GPP38214].

Input:
  • num_ant_v (int) – Number of antenna rows (i.e., in vertical direction) of the rectangulararray

  • num_ant_h (int) – Number of antenna columns (i.e., in horizontal direction) of therectangular array.

  • oversmpl_v (int, (default 1)) – Oversampling factor in vertical direction

  • oversmpl_h (int, (default 1)) – Oversampling factor in horizontal direction

  • precision (None (default) | “single” | “double”) – Precision used for internal calculations and outputs.If set toNone,precision is used.

Output:

gob ([num_ant_v x oversmpl_v, num_ant_h x oversmpl_h, num_ant_v x num_ant_h],tf.complex) – The elements\([m_v,m_h,:]\) contain the antenna coefficients of theDFT beam with index pair\((m_v,m_h)\).

sionna.phy.mimo.flatten_precoding_mat(precoding_mat,by_column=True)[source]

Flattens a […, num_ant_v, num_ant_h] precoding matrix associated witha rectangular array by producing a […, num_ant_v x num_ant_h] precoding vector

Input:
  • precoding_mat ([…, num_antennas_vertical, num_antennas_horizontal],tf.complex) – Precoding matrix. The element\((i,j)\) contains the precodingcoefficient of the antenna element located at row\(i\) and column\(j\) of a rectangular antenna array.

  • by_column (bool, (defaultTrue)) – IfTrue, then flattening occurs on a per-column basis, i.e., the firstcolumn is appended to the second, and so on. Else, flattening is performed ona per-row basis.

Output:

[…, num_antennas_vertical x num_antennas_horizontal],tf.complex – Flattened precoding matrix

sionna.phy.mimo.normalize_precoding_power(precoding_vec,tx_power_list=None,precision=None)[source]

Normalizes the beam coefficient power to 1 by default, or totx_power_list if provided as input

Input:
  • precoding_vec ([N,M],tf.complex) – Each row contains a set of antenna coefficients whose power is to be normalized.

  • tx_power_list ([N], float) – The\(i\)-th element defines the power of the\(i\)-th precodingvector.

  • precision (None (default) | “single” | “double”) – Precision used for internal calculations and outputs.If set toNone,precision is used.

Output:

[N,M]tf.complex – Normalized antenna coefficients

Equalization

sionna.phy.mimo.lmmse_matrix(h,s=None,precision=None)[source]

MIMO LMMSE Equalization matrix

This function computes the LMMSE equalization matrix for a MIMO link,assuming the following model:

\[\mathbf{y} = \mathbf{H}\mathbf{x} + \mathbf{n}\]

where\(\mathbf{y}\in\mathbb{C}^M\) is the received signal vector,\(\mathbf{x}\in\mathbb{C}^K\) is the vector of transmitted symbols,\(\mathbf{H}\in\mathbb{C}^{M\times K}\) is the known channel matrix,and\(\mathbf{n}\in\mathbb{C}^M\) is a noise vector.It is assumed that\(\mathbb{E}\left[\mathbf{x}\right]=\mathbb{E}\left[\mathbf{n}\right]=\mathbf{0}\),\(\mathbb{E}\left[\mathbf{x}\mathbf{x}^{\mathsf{H}}\right]=\mathbf{I}_K\) and\(\mathbb{E}\left[\mathbf{n}\mathbf{n}^{\mathsf{H}}\right]=\mathbf{S}\).

This function returns the LLMSE equalization matrix:

\[\mathbf{G} = \mathbf{H}^{\mathsf{H}} \left(\mathbf{H}\mathbf{H}^{\mathsf{H}} + \mathbf{S}\right)^{-1}.\]

If\(\mathbf{S}=\mathbf{I}_M\), a numerically more stable version of the equalization matrix is computed:

\[\mathbf{G} = \left(\mathbf{H}^{\mathsf{H}}\mathbf{H} + \mathbf{I}\right)^{-1}\mathbf{H}^{\mathsf{H}} .\]
Input:
  • h ([…,M,K],tf.complex) – Channel matrices

  • s (None (default) | […,M,M],tf.complex) – Noise covariance matrices. IfNone, the noise is assumed to be whitewith unit variance.

  • precision (None (default) | “single” | “double”) – Precision used for internal calculations and outputs.If set toNone,precision is used.

Output:

g ([…,K,M],tf.complex) – LLMSE equalization matrices

sionna.phy.mimo.lmmse_equalizer(y,h,s,whiten_interference=True,precision=None)[source]

MIMO LMMSE Equalizer

This function implements LMMSE equalization for a MIMO link, assuming thefollowing model:

\[\mathbf{y} = \mathbf{H}\mathbf{x} + \mathbf{n}\]

where\(\mathbf{y}\in\mathbb{C}^M\) is the received signal vector,\(\mathbf{x}\in\mathbb{C}^K\) is the vector of transmitted symbols,\(\mathbf{H}\in\mathbb{C}^{M\times K}\) is the known channel matrix,and\(\mathbf{n}\in\mathbb{C}^M\) is a noise vector.It is assumed that\(\mathbb{E}\left[\mathbf{x}\right]=\mathbb{E}\left[\mathbf{n}\right]=\mathbf{0}\),\(\mathbb{E}\left[\mathbf{x}\mathbf{x}^{\mathsf{H}}\right]=\mathbf{I}_K\) and\(\mathbb{E}\left[\mathbf{n}\mathbf{n}^{\mathsf{H}}\right]=\mathbf{S}\).

The estimated symbol vector\(\hat{\mathbf{x}}\in\mathbb{C}^K\) is given as(Lemma B.19)[BHS2017] :

\[\hat{\mathbf{x}} = \mathop{\text{diag}}\left(\mathbf{G}\mathbf{H}\right)^{-1}\mathbf{G}\mathbf{y}\]

where

\[\mathbf{G} = \mathbf{H}^{\mathsf{H}} \left(\mathbf{H}\mathbf{H}^{\mathsf{H}} + \mathbf{S}\right)^{-1}.\]

This leads to the post-equalized per-symbol model:

\[\hat{x}_k = x_k + e_k,\quad k=0,\dots,K-1\]

where the variances\(\sigma^2_k\) of the effective residual noiseterms\(e_k\) are given by the diagonal elements of

\[\mathop{\text{diag}}\left(\mathbb{E}\left[\mathbf{e}\mathbf{e}^{\mathsf{H}}\right]\right)= \mathop{\text{diag}}\left(\mathbf{G}\mathbf{H} \right)^{-1} - \mathbf{I}.\]

Note that the scaling by\(\mathop{\text{diag}}\left(\mathbf{G}\mathbf{H}\right)^{-1}\)is important for theDemapper although it doesnot change the signal-to-noise ratio.

The function returns\(\hat{\mathbf{x}}\) and\(\boldsymbol{\sigma}^2=\left[\sigma^2_0,\dots, \sigma^2_{K-1}\right]^{\mathsf{T}}\).

Input:
  • y ([…,M],tf.complex) – Received signals

  • h ([…,M,K],tf.complex) – Channel matrices

  • s ([…,M,M],tf.complex) – Noise covariance matrices

  • whiten_interference (bool, (defaultTrue)) – IfTrue, the interference is first whitened before equalization.In this case, an alternative expression for the receive filter is used thatcan be numerically more stable.

  • precision (None (default) | “single” | “double”) – Precision used for internal calculations and outputs.If set toNone,precision is used.

Output:
  • x_hat ([…,K],tf.complex) – Estimated symbol vectors

  • no_eff (tf.float) – Effective noise variance estimates

sionna.phy.mimo.mf_equalizer(y,h,s,precision=None)[source]

MIMO Matched Filter (MF) Equalizer

This function implements matched filter (MF) equalization for aMIMO link, assuming the following model:

\[\mathbf{y} = \mathbf{H}\mathbf{x} + \mathbf{n}\]

where\(\mathbf{y}\in\mathbb{C}^M\) is the received signal vector,\(\mathbf{x}\in\mathbb{C}^K\) is the vector of transmitted symbols,\(\mathbf{H}\in\mathbb{C}^{M\times K}\) is the known channel matrix,and\(\mathbf{n}\in\mathbb{C}^M\) is a noise vector.It is assumed that\(\mathbb{E}\left[\mathbf{x}\right]=\mathbb{E}\left[\mathbf{n}\right]=\mathbf{0}\),\(\mathbb{E}\left[\mathbf{x}\mathbf{x}^{\mathsf{H}}\right]=\mathbf{I}_K\) and\(\mathbb{E}\left[\mathbf{n}\mathbf{n}^{\mathsf{H}}\right]=\mathbf{S}\).

The estimated symbol vector\(\hat{\mathbf{x}}\in\mathbb{C}^K\) is given as(Eq. 4.11)[BHS2017] :

\[\hat{\mathbf{x}} = \mathbf{G}\mathbf{y}\]

where

\[\mathbf{G} = \mathop{\text{diag}}\left(\mathbf{H}^{\mathsf{H}}\mathbf{H}\right)^{-1}\mathbf{H}^{\mathsf{H}}.\]

This leads to the post-equalized per-symbol model:

\[\hat{x}_k = x_k + e_k,\quad k=0,\dots,K-1\]

where the variances\(\sigma^2_k\) of the effective residual noiseterms\(e_k\) are given by the diagonal elements of the matrix

\[\mathbb{E}\left[\mathbf{e}\mathbf{e}^{\mathsf{H}}\right]= \left(\mathbf{I}-\mathbf{G}\mathbf{H} \right)\left(\mathbf{I}-\mathbf{G}\mathbf{H} \right)^{\mathsf{H}} + \mathbf{G}\mathbf{S}\mathbf{G}^{\mathsf{H}}.\]

Note that the scaling by\(\mathop{\text{diag}}\left(\mathbf{H}^{\mathsf{H}}\mathbf{H}\right)^{-1}\)in the definition of\(\mathbf{G}\)is important for theDemapper although it doesnot change the signal-to-noise ratio.

The function returns\(\hat{\mathbf{x}}\) and\(\boldsymbol{\sigma}^2=\left[\sigma^2_0,\dots, \sigma^2_{K-1}\right]^{\mathsf{T}}\).

Input:
  • y ([…,M],tf.complex) – Received signals

  • h ([…,M,K],tf.complex) – Channel matrices

  • s ([…,M,M],tf.complex) – Noise covariance matrices

  • precision (None (default) | “single” | “double”) – Precision used for internal calculations and outputs.If set toNone,precision is used.

Output:
  • x_hat ([…,K],tf.complex) – Estimated symbol vectors

  • no_eff (tf.float) – Effective noise variance estimates

sionna.phy.mimo.zf_equalizer(y,h,s,precision=None)[source]

Applies MIMO ZF Equalizer

This function implements zero-forcing (ZF) equalization for a MIMO link, assuming thefollowing model:

\[\mathbf{y} = \mathbf{H}\mathbf{x} + \mathbf{n}\]

where\(\mathbf{y}\in\mathbb{C}^M\) is the received signal vector,\(\mathbf{x}\in\mathbb{C}^K\) is the vector of transmitted symbols,\(\mathbf{H}\in\mathbb{C}^{M\times K}\) is the known channel matrix,and\(\mathbf{n}\in\mathbb{C}^M\) is a noise vector.It is assumed that\(\mathbb{E}\left[\mathbf{x}\right]=\mathbb{E}\left[\mathbf{n}\right]=\mathbf{0}\),\(\mathbb{E}\left[\mathbf{x}\mathbf{x}^{\mathsf{H}}\right]=\mathbf{I}_K\) and\(\mathbb{E}\left[\mathbf{n}\mathbf{n}^{\mathsf{H}}\right]=\mathbf{S}\).

The estimated symbol vector\(\hat{\mathbf{x}}\in\mathbb{C}^K\) is given as(Eq. 4.10)[BHS2017] :

\[\hat{\mathbf{x}} = \mathbf{G}\mathbf{y}\]

where

\[\mathbf{G} = \left(\mathbf{H}^{\mathsf{H}}\mathbf{H}\right)^{-1}\mathbf{H}^{\mathsf{H}}.\]

This leads to the post-equalized per-symbol model:

\[\hat{x}_k = x_k + e_k,\quad k=0,\dots,K-1\]

where the variances\(\sigma^2_k\) of the effective residual noiseterms\(e_k\) are given by the diagonal elements of the matrix

\[\mathbb{E}\left[\mathbf{e}\mathbf{e}^{\mathsf{H}}\right]= \mathbf{G}\mathbf{S}\mathbf{G}^{\mathsf{H}}.\]

The function returns\(\hat{\mathbf{x}}\) and\(\boldsymbol{\sigma}^2=\left[\sigma^2_0,\dots, \sigma^2_{K-1}\right]^{\mathsf{T}}\).

Input:
  • y ([…,M],tf.complex) – Received signals

  • h ([…,M,K],tf.complex) – Channel matrices

  • s ([…,M,M],tf.complex) – Noise covariance matrices

  • precision (None (default) | “single” | “double”) – Precision used for internal calculations and outputs.If set toNone,precision is used.

Output:
  • x_hat ([…,K],tf.complex) – Estimated symbol vectors

  • no_eff (tf.float) – Effective noise variance estimates

Detection

classsionna.phy.mimo.EPDetector(output,num_bits_per_symbol,hard_out=False,l=10,beta=0.9,precision=None,**kwargs)[source]

MIMO Expectation Propagation (EP) detector

This block implements Expectation Propagation (EP) MIMO detection as describedin[EP2014]. It can generate hard- or soft-decisions for symbols or bits.

This block assumes the following channel model:

\[\mathbf{y} = \mathbf{H}\mathbf{x} + \mathbf{n}\]

where\(\mathbf{y}\in\mathbb{C}^M\) is the received signal vector,\(\mathbf{x}\in\mathcal{C}^S\) is the vector of transmitted symbols whichare uniformly and independently drawn from the constellation\(\mathcal{C}\),\(\mathbf{H}\in\mathbb{C}^{M\times S}\) is the known channel matrix,and\(\mathbf{n}\in\mathbb{C}^M\) is a complex Gaussian noise vector.It is assumed that\(\mathbb{E}\left[\mathbf{n}\right]=\mathbf{0}\) and\(\mathbb{E}\left[\mathbf{n}\mathbf{n}^{\mathsf{H}}\right]=\mathbf{S}\),where\(\mathbf{S}\) has full rank.

The channel model is first whitened usingwhiten_channel()and then converted to its real-valued equivalent,seecomplex2real_channel(), prior to MIMO detection.

The computation of LLRs is done by converting the symbol logitsthat naturally arise in the algorithm to LLRs usingPAM2QAM(). Custom conversions of symbol logits to LLRscan be implemented by using the soft-symbol output.

The detector is currently restricted to QAM constellations.

Parameters:
  • output ("bit" |"symbol") – Type of output, either LLRs on bits or logits on constellation symbols

  • num_bits_per_symbol (int) – Number of bits per QAM constellation symbol, e.g., 4 for QAM16.

  • hard_out (bool, (defaultFalse)) – IfTrue, the detector computes hard-decided bit values orconstellation point indices instead of soft-values.

  • l (int, (default 10)) – Number of iterations

  • beta (float, (default 0.9)) – Parameter\(\beta\in[0,1]\) for update smoothing

  • precision (None (default) | “single” | “double”) – Precision used for internal calculations and outputs.If set toNone,precision is used.

Input:
  • y ([…,M],tf.complex) – Received signals

  • h ([…,M,num_streams],tf.complex) – Channel matrices

  • s ([…,M,M],tf.complex) – Noise covariance matrices

Output:
  • One of

  • […, num_streams, num_bits_per_symbol],tf.float – LLRs or hard-decisions for every bit of every stream, ifoutput equals“bit”.

  • […, num_streams, num_points], tf.float or […, num_streams],tf.int32 – Logits or hard-decisions for constellation symbols for every stream, ifoutput equals“symbol”.Hard-decisions correspond to the symbol indices.

classsionna.phy.mimo.KBestDetector(output,num_streams,k,constellation_type=None,num_bits_per_symbol=None,constellation=None,hard_out=False,use_real_rep=False,list2llr=None,precision=None,**kwargs)[source]

MIMO K-Best detector

This block implements K-Best MIMO detection as describedin (Eq. 4-5)[FT2015]. It can either generate hard decisions (for symbolsor bits) or compute LLRs.

The algorithm operates in either the complex or real-valued domain.Although both options produce identical results, the former has the advantagethat it can be applied to arbitrary non-QAM constellations. It also reducesthe number of streams (or depth) by a factor of two.

The way soft-outputs (i.e., LLRs) are computed is determined by thelist2llr function. The default solutionList2LLRSimple assigns a predeterminedvalue to all LLRs without counter-hypothesis.

This block assumes the following channel model:

\[\mathbf{y} = \mathbf{H}\mathbf{x} + \mathbf{n}\]

where\(\mathbf{y}\in\mathbb{C}^M\) is the received signal vector,\(\mathbf{x}\in\mathcal{C}^S\) is the vector of transmitted symbols whichare uniformly and independently drawn from the constellation\(\mathcal{C}\),\(\mathbf{H}\in\mathbb{C}^{M\times S}\) is the known channel matrix,and\(\mathbf{n}\in\mathbb{C}^M\) is a complex Gaussian noise vector.It is assumed that\(\mathbb{E}\left[\mathbf{n}\right]=\mathbf{0}\) and\(\mathbb{E}\left[\mathbf{n}\mathbf{n}^{\mathsf{H}}\right]=\mathbf{S}\),where\(\mathbf{S}\) has full rank.

In a first optional step, the channel model is converted to its real-valued equivalent,seecomplex2real_channel(). We assume in the sequel the complex-valuedrepresentation. Then, the channel is whitened usingwhiten_channel():

\[\begin{split}\tilde{\mathbf{y}} &= \mathbf{S}^{-\frac{1}{2}}\mathbf{y}\\&= \mathbf{S}^{-\frac{1}{2}}\mathbf{H}\mathbf{x} + \mathbf{S}^{-\frac{1}{2}}\mathbf{n}\\&= \tilde{\mathbf{H}}\mathbf{x} + \tilde{\mathbf{n}}.\end{split}\]

Next, the columns of\(\tilde{\mathbf{H}}\) are sorted accordingto their norm in descending order. Then, the QR decomposition of theresulting channel matrix is computed:

\[\tilde{\mathbf{H}} = \mathbf{Q}\mathbf{R}\]

where\(\mathbf{Q}\in\mathbb{C}^{M\times S}\) is unitary and\(\mathbf{R}\in\mathbb{C}^{S\times S}\) is upper-triangular.The channel outputs are then pre-multiplied by\(\mathbf{Q}^{\mathsf{H}}\).This leads to the final channel model on which the K-Best detection algorithm operates:

\[\bar{\mathbf{y}} = \mathbf{R}\bar{\mathbf{x}} + \bar{\mathbf{n}}\]

where\(\bar{\mathbf{y}}\in\mathbb{C}^S\),\(\bar{\mathbf{x}}\in\mathbb{C}^S\), and\(\bar{\mathbf{n}}\in\mathbb{C}^S\)with\(\mathbb{E}\left[\bar{\mathbf{n}}\right]=\mathbf{0}\) and\(\mathbb{E}\left[\bar{\mathbf{n}}\bar{\mathbf{n}}^{\mathsf{H}}\right]=\mathbf{I}\).

LLR Computation

The K-Best algorithm produces\(K\) candidate solutions\(\bar{\mathbf{x}}_k\in\mathcal{C}^S\)and their associated distance metrics\(d_k=\lVert \bar{\mathbf{y}} - \mathbf{R}\bar{\mathbf{x}}_k \rVert^2\)for\(k=1,\dots,K\). If the real-valued channel representation is used, the distancemetrics are scaled by 0.5 to account for the reduced noise power in each complex dimension.A hard-decision is simply the candidate with the shortest distance.Various ways to compute LLRs from this list (and possiblyadditional side-information) are possible. The (sub-optimal) default solutionisList2LLRSimple. Custom solutions can be provided.

Parameters:
  • output ("bit" |"symbol") – Type of output, either LLRs on bits or logits on constellation symbols

  • num_streams (int) – Number of transmitted streams

  • k (int`) – Number of paths to keep. Cannot be larger than thenumber of constellation points to the power of the number ofstreams.

  • constellation_type ("qam" |"pam" |"custom") – For “custom”, an instance ofConstellationmust be provided.

  • num_bits_per_symbol (int) – Number of bits per constellation symbol, e.g., 4 for QAM16.Only required forconstellation_type in [“qam”, “pam”].

  • constellation (None (default) |Constellation) – IfNone,constellation_typeandnum_bits_per_symbol must be provided.

  • hard_out (bool, (defaultFalse)) – IfTrue, the detector computes hard-decided bit values orconstellation point indices instead of soft-values.

  • use_real_rep (bool, (defaultFalse)) – IfTrue, the detector use the real-valued equivalent representationof the channel. Note that this only works with a QAM constellation.

  • list2llr (None (default) |List2LLR) – The function to be used to compute LLRs from a list of candidate solutions.IfNone, the default solutionList2LLRSimpleis used.

  • precision (None (default) | “single” | “double”) – Precision used for internal calculations and outputs.If set toNone,precision is used.

Input:
  • y ([…,M],tf.complex) – Received signals

  • h ([…,M,num_streams],tf.complex) – Channel matrices

  • s ([…,M,M],tf.complex) – Noise covariance matrices

Output:
  • One of

  • […, num_streams, num_bits_per_symbol],tf.float – LLRs or hard-decisions for every bit of every stream, ifoutput equals“bit”.

  • […, num_streams, num_points], tf.float or […, num_streams],tf.int32 – Logits or hard-decisions for constellation symbols for every stream, ifoutput equals“symbol”.Hard-decisions correspond to the symbol indices.

propertylist2llr

Set/get the function to be used to computeLLRs from a list of candidate solutions

Type:

List2LLR

classsionna.phy.mimo.LinearDetector(equalizer,output,demapping_method,constellation_type=None,num_bits_per_symbol=None,constellation=None,hard_out=False,precision=None,**kwargs)[source]

Convenience class that combines an equalizer,such aslmmse_equalizer(), and aDemapper.

Parameters:
  • equalizer ("lmmse" |"zf" |"mf" |equalizer function) – The equalizer to be used. Either one of the existing equalizerslmmse_equalizer(),zf_equalizer(), ormf_equalizer() can be used, or a custom equalizercallable provided that has the same input/output specification.

  • output ("bit" |"symbol") – Type of output, either LLRs on bits or logits on constellation symbols

  • demapping_method ("app" |"maxlog") – Demapping method to be used

  • constellation_type ("qam" |"pam" |"custom") – For “custom”, an instance ofConstellationmust be provided.

  • num_bits_per_symbol (int) – Number of bits per constellation symbol, e.g., 4 for QAM16.Only required forconstellation_type in [“qam”, “pam”].

  • constellation (None (default) |Constellation) – IfNone,constellation_typeandnum_bits_per_symbol must be provided.

  • hard_out (bool, (defaultFalse)) – IfTrue, the detector computes hard-decided bit values orconstellation point indices instead of soft-values.

  • precision (None (default) | “single” | “double”) – Precision used for internal calculations and outputs.If set toNone,precision is used.

Input:
  • y ([…,M],tf.complex) – Received signals

  • h ([…,M,num_streams],tf.complex) – Channel matrices

  • s ([…,M,M],tf.complex) – Noise covariance matrices

Output:
  • One of

  • […, num_streams, num_bits_per_symbol],tf.float – LLRs or hard-decisions for every bit of every stream, ifoutput equals“bit”

  • […, num_streams, num_points],tf.float or […, num_streams],tf.int32 – Logits or hard-decisions for constellation symbols for every stream, ifoutput equals“symbol”Hard-decisions correspond to the symbol indices.

classsionna.phy.mimo.MaximumLikelihoodDetector(output,demapping_method,num_streams,constellation_type=None,num_bits_per_symbol=None,constellation=None,hard_out=False,precision=None,**kwargs)[source]

MIMO maximum-likelihood (ML) detector

This block implements MIMO maximum-likelihood (ML) detection assuming thefollowing channel model:

\[\mathbf{y} = \mathbf{H}\mathbf{x} + \mathbf{n}\]

where\(\mathbf{y}\in\mathbb{C}^M\) is the received signal vector,\(\mathbf{x}\in\mathcal{C}^K\) is the vector of transmitted symbols whichare uniformly and independently drawn from the constellation\(\mathcal{C}\),\(\mathbf{H}\in\mathbb{C}^{M\times K}\) is the known channel matrix,and\(\mathbf{n}\in\mathbb{C}^M\) is a complex Gaussian noise vector.It is assumed that\(\mathbb{E}\left[\mathbf{n}\right]=\mathbf{0}\) and\(\mathbb{E}\left[\mathbf{n}\mathbf{n}^{\mathsf{H}}\right]=\mathbf{S}\),where\(\mathbf{S}\) has full rank.Optionally, prior information of the transmitted signal\(\mathbf{x}\)can be provided, either as LLRs on the bits mapped onto\(\mathbf{x}\) or as logits on the individualconstellation points forming\(\mathbf{x}\).

Prior to demapping, the received signal is whitened:

\[\begin{split}\tilde{\mathbf{y}} &= \mathbf{S}^{-\frac{1}{2}}\mathbf{y}\\&= \mathbf{S}^{-\frac{1}{2}}\mathbf{H}\mathbf{x} + \mathbf{S}^{-\frac{1}{2}}\mathbf{n}\\&= \tilde{\mathbf{H}}\mathbf{x} + \tilde{\mathbf{n}}\end{split}\]

The block can compute ML detection of symbols or bits with eithersoft- or hard-decisions. Note that decisions are computed symbol-/bit-wiseand not jointly for the entire vector\(\textbf{x}\) (or the underlying vectorof bits).

ML detection of bits:

Soft-decisions on bits are called log-likelihood ratios (LLR).With the “app” demapping method, the LLR for the\(i\text{th}\) bitof the\(k\text{th}\) user is then computed according to

\[\begin{split}\begin{align} LLR(k,i)&= \ln\left(\frac{\Pr\left(b_{k,i}=1\lvert \mathbf{y},\mathbf{H}\right)}{\Pr\left(b_{k,i}=0\lvert \mathbf{y},\mathbf{H}\right)}\right)\\ &=\ln\left(\frac{ \sum_{\mathbf{x}\in\mathcal{C}_{k,i,1}} \exp\left( -\left\lVert\tilde{\mathbf{y}}-\tilde{\mathbf{H}}\mathbf{x}\right\rVert^2 \right) \Pr\left( \mathbf{x} \right) }{ \sum_{\mathbf{x}\in\mathcal{C}_{k,i,0}} \exp\left( -\left\lVert\tilde{\mathbf{y}}-\tilde{\mathbf{H}}\mathbf{x}\right\rVert^2 \right) \Pr\left( \mathbf{x} \right) }\right)\end{align}\end{split}\]

where\(\mathcal{C}_{k,i,1}\) and\(\mathcal{C}_{k,i,0}\) are thesets of vectors of constellation points for which the\(i\text{th}\) bitof the\(k\text{th}\) user is equal to 1 and 0, respectively.\(\Pr\left( \mathbf{x} \right)\) is the prior distribution of the vector ofconstellation points\(\mathbf{x}\). Assuming that the constellation points andbit levels are independent, it is computed from the prior of the bits according to

\[\Pr\left( \mathbf{x} \right) = \prod_{k=1}^K \prod_{i=1}^{I} \sigma \left( LLR_p(k,i) \right)\]

where\(LLR_p(k,i)\) is the prior knowledge of the\(i\text{th}\) bit of the\(k\text{th}\) user given as an LLR and which is set to\(0\) if no prior knowledge is assumed to be available,and\(\sigma\left(\cdot\right)\) is the sigmoid function.The definition of the LLR has been chosen such that it is equivalent with that of logit. This isdifferent from many textbooks in communications, where the LLR isdefined as\(LLR(k,i) = \ln\left(\frac{\Pr\left(b_{k,i}=0\lvert \mathbf{y},\mathbf{H}\right)}{\Pr\left(b_{k,i}=1\lvert \mathbf{y},\mathbf{H}\right)}\right)\).

With the “maxlog” demapping method, the LLR for the\(i\text{th}\) bitof the\(k\text{th}\) user is approximated like

\[\begin{split}\begin{align} LLR(k,i) \approx&\ln\left(\frac{ \max_{\mathbf{x}\in\mathcal{C}_{k,i,1}} \left( \exp\left( -\left\lVert\tilde{\mathbf{y}}-\tilde{\mathbf{H}}\mathbf{x}\right\rVert^2 \right) \Pr\left( \mathbf{x} \right) \right) }{ \max_{\mathbf{x}\in\mathcal{C}_{k,i,0}} \left( \exp\left( -\left\lVert\tilde{\mathbf{y}}-\tilde{\mathbf{H}}\mathbf{x}\right\rVert^2 \right) \Pr\left( \mathbf{x} \right) \right) }\right)\\ = &\min_{\mathbf{x}\in\mathcal{C}_{k,i,0}} \left( \left\lVert\tilde{\mathbf{y}}-\tilde{\mathbf{H}}\mathbf{x}\right\rVert^2 - \ln \left(\Pr\left( \mathbf{x} \right) \right) \right) - \min_{\mathbf{x}\in\mathcal{C}_{k,i,1}} \left( \left\lVert\tilde{\mathbf{y}}-\tilde{\mathbf{H}}\mathbf{x}\right\rVert^2 - \ln \left( \Pr\left( \mathbf{x} \right) \right) \right). \end{align}\end{split}\]

ML detection of symbols:

Soft-decisions on symbols are called logits (i.e., unnormalized log-probability).

With the “app” demapping method, the logit for theconstellation point\(c \in \mathcal{C}\) of the\(k\text{th}\) user is computed according to

\[\begin{align} \text{logit}(k,c) &= \ln\left(\sum_{\mathbf{x} : x_k = c} \exp\left( -\left\lVert\tilde{\mathbf{y}}-\tilde{\mathbf{H}}\mathbf{x}\right\rVert^2 \right)\Pr\left( \mathbf{x} \right)\right).\end{align}\]

With the “maxlog” demapping method, the logit for the constellation point\(c \in \mathcal{C}\)of the\(k\text{th}\) user is approximated like

\[\text{logit}(k,c) \approx \max_{\mathbf{x} : x_k = c} \left( -\left\lVert\tilde{\mathbf{y}}-\tilde{\mathbf{H}}\mathbf{x}\right\rVert^2 + \ln \left( \Pr\left( \mathbf{x} \right) \right) \right).\]

When hard decisions are requested, this block returns for the\(k\) th stream

\[\hat{c}_k = \underset{c \in \mathcal{C}}{\text{argmax}} \left( \sum_{\mathbf{x} : x_k = c} \exp\left( -\left\lVert\tilde{\mathbf{y}}-\tilde{\mathbf{H}}\mathbf{x}\right\rVert^2 \right)\Pr\left( \mathbf{x} \right) \right)\]

where\(\mathcal{C}\) is the set of constellation points.

Parameters:
  • output ("bit" |"symbol") – Type of output, either LLRs on bits or logits on constellation symbols

  • demapping_method ("app" |"maxlog") – Demapping method to be used

  • num_streams (int) – Number of transmitted streams

  • constellation_type ("qam" |"pam" |"custom") – For “custom”, an instance ofConstellationmust be provided.

  • num_bits_per_symbol (int) – Number of bits per constellation symbol, e.g., 4 for QAM16.Only required forconstellation_type in [“qam”, “pam”].

  • constellation (None (default) |Constellation) – IfNone,constellation_typeandnum_bits_per_symbol must be provided.

  • hard_out (bool, (defaultFalse)) – IfTrue, the detector computes hard-decided bit values orconstellation point indices instead of soft-values.

  • precision (None (default) | “single” | “double”) – Precision used for internal calculations and outputs.If set toNone,precision is used.

Input:
  • y ([…,M],tf.complex) – Received signals

  • h ([…,M,num_streams],tf.complex) – Channel matrices

  • s ([…,M,M],tf.complex) – Noise covariance matrices

  • prior (None (default) | […,num_streams,num_bits_per_symbol] or […,num_streams,num_points],tf.float) – Prior of the transmitted signals.Ifoutput equals “bit”, then LLRs of the transmitted bits are expected.Ifoutput equals “symbol”, then logits of the transmitted constellation points are expected.

Output:
  • One of

  • […, num_streams, num_bits_per_symbol],tf.float – LLRs or hard-decisions for every bit of every stream, ifoutput equals“bit”.

  • […, num_streams, num_points], tf.float or […, num_streams],tf.int32 – Logits or hard-decisions for constellation symbols for every stream, ifoutput equals“symbol”.Hard-decisions correspond to the symbol indices.

classsionna.phy.mimo.MMSEPICDetector(output,demapping_method='maxlog',num_iter=1,constellation_type=None,num_bits_per_symbol=None,constellation=None,hard_out=False,precision=None,**kwargs)[source]

Minimum mean square error (MMSE) with parallel interference cancellation (PIC) detector

This block implements the MMSE PIC detector, as proposed in[CST2011].Fornum_iter>1, this implementation performs MMSE PIC self-iterations.MMSE PIC self-iterations can be understood as a concatenation of MMSE PICdetectors from[CST2011], which forward intrinsic LLRs to the nextself-iteration.

Compared to[CST2011], this implementation also accepts priors on theconstellation symbols as an alternative to priors on the bits.

This block assumes the following channel model:

\[\mathbf{y} = \mathbf{H}\mathbf{x} + \mathbf{n}\]

where\(\mathbf{y}\in\mathbb{C}^M\) is the received signal vector,\(\mathbf{x}\in\mathcal{C}^S\) is the vector of transmitted symbols whichare uniformly and independently drawn from the constellation\(\mathcal{C}\),\(\mathbf{H}\in\mathbb{C}^{M\times S}\) is the known channel matrix,and\(\mathbf{n}\in\mathbb{C}^M\) is a complex Gaussian noise vector.It is assumed that\(\mathbb{E}\left[\mathbf{n}\right]=\mathbf{0}\) and\(\mathbb{E}\left[\mathbf{n}\mathbf{n}^{\mathsf{H}}\right]=\mathbf{S}\),where\(\mathbf{S}\) has full rank.

The algorithm starts by computing the soft symbols\(\bar{x}_s=\mathbb{E}\left[ x_s \right]\) andvariances\(v_s=\mathbb{E}\left[ |e_s|^2\right]\) from the priors,where\(e_s = x_s - \bar{x}_s\), for all\(s=1,\dots,S\).

Next, for each stream, the interference caused by all other streams is cancelledfrom the observation\(\mathbf{y}\), leading to

\[\hat{\mathbf{y}}_s = \mathbf{y} - \sum_{j\neq s} \mathbf{h}_j x_j = \mathbf{h}_s x_s + \tilde{\mathbf{n}}_s,\quad s=1,\dots,S\]

where\(\tilde{\mathbf{n}}_s=\sum_{j\neq s} \mathbf{h}_j e_j + \mathbf{n}\).

Then, a linear MMSE filter\(\mathbf{w}_s\) is computed to reduce the resdiual noisefor each observation\(\hat{\mathbf{y}}_s\), which is given as

\[\mathbf{w}_s = \mathbf{h}_s^{\mathsf{H}}\left( \mathbf{H} \mathbf{D}_s\mathbf{H}^{\mathsf{H}} +\mathbf{S} \right)^{-1}\]

where\(\mathbf{D}_s \in \mathbb{C}^{S\times S}\) is diagonal with entries

\[\begin{split}\left[\mathbf{D}_s\right]_{i,i} = \begin{cases} v_i & i\neq s \\ 1 & i=s. \end{cases}\end{split}\]

The filtered observations

\[\tilde{z}_s = \mathbf{w}_s^{\mathsf{H}} \hat{\mathbf{y}}_s = \tilde{\mu}_s x_s + \mathbf{w}_s^{\mathsf{H}}\tilde{\mathbf{n}}_s\]

where\(\tilde{\mu}_s=\mathbf{w}_s^{\mathsf{H}} \mathbf{h}_s\), are then demapped to either symbol logits or LLRs, assuming that the remaining noise is Gaussian with variance

\[\nu_s^2 = \mathop{\text{Var}}\left[\tilde{z}_s\right] = \mathbf{w}_s^{\mathsf{H}} \left(\sum_{j\neq s} \mathbf{h}_j \mathbf{h}_j^{\mathsf{H}} v_j +\mathbf{S} \right)\mathbf{w}_s.\]

The resulting soft-symbols can then be used for the next self-iteration of the algorithm.

Note that this algorithm can be substantially simplified as described in[CST2011] to avoidthe computation of different matrix inverses for each stream. This is the version which isimplemented.

Parameters:
  • output ("bit" |"symbol") – Type of output, either LLRs on bits or logits on constellation symbols

  • demapping_method ("maxlog" (default)|"app") – Demapping method to be used

  • num_iter (int, (default 1)) – Number of MMSE PIC iterations

  • constellation_type ("qam" |"pam" |"custom") – For “custom”, an instance ofConstellationmust be provided.

  • num_bits_per_symbol (int) – Number of bits per constellation symbol, e.g., 4 for QAM16.Only required forconstellation_type in [“qam”, “pam”].

  • constellation (None (default) |Constellation) – IfNone,constellation_typeandnum_bits_per_symbol must be provided.

  • hard_out (bool, (defaultFalse)) – IfTrue, the detector computes hard-decided bit values orconstellation point indices instead of soft-values.

  • precision (None (default) | “single” | “double”) – Precision used for internal calculations and outputs.If set toNone,precision is used.

Input:
  • y ([…,M],tf.complex) – Received signals

  • h ([…,M,num_streams],tf.complex) – Channel matrices

  • s ([…,M,M],tf.complex) – Noise covariance matrices

  • prior ([…,num_streams,num_bits_per_symbol] or […,num_streams,num_points],tf.float) – Prior of the transmitted signals.Ifoutput equals “bit”, then LLRs of the transmitted bits are expected.Ifoutput equals “symbol”, then logits of the transmitted constellation points are expected.

Output:
  • One of

  • […, num_streams, num_bits_per_symbol],tf.float – LLRs or hard-decisions for every bit of every stream, ifoutput equals“bit”.

  • […, num_streams, num_points], tf.float or […, num_streams],tf.int32 – Logits or hard-decisions for constellation symbols for every stream, ifoutput equals“symbol”.Hard-decisions correspond to the symbol indices.

Utility Functions

classsionna.phy.mimo.List2LLR(precision=None,**kwargs)[source]

Abstract class defining a callable to compute LLRs from a list ofcandidate vectors (or paths) provided by a MIMO detector

The following channel model is assumed

\[\bar{\mathbf{y}} = \mathbf{R}\bar{\mathbf{x}} + \bar{\mathbf{n}}\]

where\(\bar{\mathbf{y}}\in\mathbb{C}^S\) are the channel outputs,\(\mathbf{R}\in\mathbb{C}^{S\times S}\) is an upper-triangular matrix,\(\bar{\mathbf{x}}\in\mathbb{C}^S\) is the transmitted vector whose entriesare uniformly and independently drawn from the constellation\(\mathcal{C}\),and\(\bar{\mathbf{n}}\in\mathbb{C}^S\) is white noisewith\(\mathbb{E}\left[\bar{\mathbf{n}}\right]=\mathbf{0}\) and\(\mathbb{E}\left[\bar{\mathbf{n}}\bar{\mathbf{n}}^{\mathsf{H}}\right]=\mathbf{I}\).

It is assumed that a MIMO detector such asKBestDetectorproduces\(K\) candidate solutions\(\bar{\mathbf{x}}_k\in\mathcal{C}^S\)and their associated distance metrics\(d_k=\lVert \bar{\mathbf{y}} - \mathbf{R}\bar{\mathbf{x}}_k \rVert^2\)for\(k=1,\dots,K\). This layer can also be used with the real-valued representation of the channel.

Parameters:

precision (None (default) | “single” | “double”) – Precision used for internal calculations and outputs.If set toNone,precision is used.

Input:
  • y ([…,M],tf.complex ortf.float) – Channel outputs of the whitened channel

  • r ([…,num_streams, num_streams], samedtype asy) – Upper triangular channel matrix of the whitened channel

  • dists ([…,num_paths],tf.float) – Distance metric for each path (or candidate)

  • path_inds ([…,num_paths,num_streams],tf.int32) – Symbol indices for every stream of every path (or candidate)

  • path_syms ([…,num_path,num_streams], samedtype asy) – Constellation symbol for every stream of every path (or candidate)

Output:

llr ([…num_streams,num_bits_per_symbol],tf.float) – LLRs for all bits of every stream

Note

An implementation of this class does not need to make use of all ofthe provided inputs which enable various different implementations.

classsionna.phy.mimo.List2LLRSimple(num_bits_per_symbol,llr_clip_val=20.0,precision=None,**kwargs)[source]

Computes LLRs from a list of candidate vectors (or paths) provided by a MIMO detector

The following channel model is assumed:

\[\bar{\mathbf{y}} = \mathbf{R}\bar{\mathbf{x}} + \bar{\mathbf{n}}\]

where\(\bar{\mathbf{y}}\in\mathbb{C}^S\) are the channel outputs,\(\mathbf{R}\in\mathbb{C}^{S\times S}\) is an upper-triangular matrix,\(\bar{\mathbf{x}}\in\mathbb{C}^S\) is the transmitted vector whose entriesare uniformly and independently drawn from the constellation\(\mathcal{C}\),and\(\bar{\mathbf{n}}\in\mathbb{C}^S\) is white noisewith\(\mathbb{E}\left[\bar{\mathbf{n}}\right]=\mathbf{0}\) and\(\mathbb{E}\left[\bar{\mathbf{n}}\bar{\mathbf{n}}^{\mathsf{H}}\right]=\mathbf{I}\).

It is assumed that a MIMO detector such asKBestDetectorproduces\(K\) candidate solutions\(\bar{\mathbf{x}}_k\in\mathcal{C}^S\)and their associated distance metrics\(d_k=\lVert \bar{\mathbf{y}} - \mathbf{R}\bar{\mathbf{x}}_k \rVert^2\)for\(k=1,\dots,K\). This layer can also be used with the real-valued representation of the channel.

The LLR for the\(i\text{th}\) bit of the\(k\text{th}\) stream is computed as

\[\begin{split}\begin{align} LLR(k,i) &= \log\left(\frac{\Pr(b_{k,i}=1|\bar{\mathbf{y}},\mathbf{R})}{\Pr(b_{k,i}=0|\bar{\mathbf{y}},\mathbf{R})}\right)\\ &\approx \min_{j \in \mathcal{C}_{k,i,0}}d_j - \min_{j \in \mathcal{C}_{k,i,1}}d_j\end{align}\end{split}\]

where\(\mathcal{C}_{k,i,1}\) and\(\mathcal{C}_{k,i,0}\) are the set of indicesin the list of candidates for which the\(i\text{th}\) bit of the\(k\text{th}\)stream is equal to 1 and 0, respectively. The LLRs are clipped to\(\pm LLR_\text{clip}\)which can be configured through the parameterllr_clip_val.

If\(\mathcal{C}_{k,i,0}\) is empty,\(LLR(k,i)=LLR_\text{clip}\);if\(\mathcal{C}_{k,i,1}\) is empty,\(LLR(k,i)=-LLR_\text{clip}\).

Parameters:
  • num_bits_per_symbol (int) – Number of bits per constellation symbol

  • llr_clip_val (float, (default 20.0)) – The absolute values of LLRs are clipped to this value.

  • precision (None (default) | “single” | “double”) – Precision used for internal calculations and outputs.If set toNone,precision is used.

Input:
  • y ([…,M],tf.complex ortf.float) – Channel outputs of the whitened channel

  • r ([…,num_streams, num_streams], samedtype asy) – Upper triangular channel matrix of the whitened channel

  • dists ([…,num_paths],tf.float) – Distance metric for each path (or candidate)

  • path_inds ([…,num_paths,num_streams],tf.int32) – Symbol indices for every stream of every path (or candidate)

  • path_syms ([…,num_path,num_streams], samedtype asy) – Constellation symbol for every stream of every path (or candidate)

Output:

llr ([…num_streams,num_bits_per_symbol],tf.float) – LLRs for all bits of every stream

propertyllr_clip_val

Get/set the value to which the absolute values of LLRsare clipped

Type:

float

sionna.phy.mimo.complex2real_vector(z)[source]

Transforms a complex-valued vector into its real-valued equivalent

Transforms the last dimension of a complex-valued tensor intoits real-valued equivalent by stacking the real and imaginaryparts on top of each other.

For a vector\(\mathbf{z}\in \mathbb{C}^M\) with real and imaginaryparts\(\mathbf{x}\in \mathbb{R}^M\) and\(\mathbf{y}\in \mathbb{R}^M\), respectively, this function returnsthe vector\(\left[\mathbf{x}^{\mathsf{T}}, \mathbf{y}^{\mathsf{T}} \right ]^{\mathsf{T}}\in\mathbb{R}^{2M}\).

Input:

[…,M],tf.complex

Output:

[…,2M],tf.complex.real_dtype

sionna.phy.mimo.real2complex_vector(z)[source]

Transforms a real-valued vector into its complex-valued equivalent

Transforms the last dimension of a real-valued tensor intoits complex-valued equivalent by interpreting the first halfas the real and the second half as the imaginary part.

For a vector\(\mathbf{z}=\left[\mathbf{x}^{\mathsf{T}}, \mathbf{y}^{\mathsf{T}} \right ]^{\mathsf{T}}\in \mathbb{R}^{2M}\)with\(\mathbf{x}\in \mathbb{R}^M\) and\(\mathbf{y}\in \mathbb{R}^M\),this function returnsthe vector\(\mathbf{x}+j\mathbf{y}\in\mathbb{C}^M\).

Input:

[…,2M],tf.float

Output:

[…,M],tf.complex

sionna.phy.mimo.complex2real_matrix(z)[source]

Transforms a complex-valued matrix into its real-valued equivalent

Transforms the last two dimensions of a complex-valued tensor intotheir real-valued matrix equivalent representation.

For a matrix\(\mathbf{Z}\in \mathbb{C}^{M\times K}\) with real and imaginaryparts\(\mathbf{X}\in \mathbb{R}^{M\times K}\) and\(\mathbf{Y}\in \mathbb{R}^{M\times K}\), respectively, this function returnsthe matrix\(\tilde{\mathbf{Z}}\in \mathbb{R}^{2M\times 2K}\), given as

\[\begin{split}\tilde{\mathbf{Z}} = \begin{pmatrix} \mathbf{X} & -\mathbf{Y}\\ \mathbf{Y} & \mathbf{X} \end{pmatrix}.\end{split}\]
Input:

[…,M,K],tf.complex

Output:

[…,2M, 2K],tf.complex.real_dtype

sionna.phy.mimo.real2complex_matrix(z)[source]

Transforms a real-valued matrix into its complex-valued equivalent

Transforms the last two dimensions of a real-valued tensor intotheir complex-valued matrix equivalent representation.

For a matrix\(\tilde{\mathbf{Z}}\in \mathbb{R}^{2M\times 2K}\),satisfying

\[\begin{split}\tilde{\mathbf{Z}} = \begin{pmatrix} \mathbf{X} & -\mathbf{Y}\\ \mathbf{Y} & \mathbf{X} \end{pmatrix}\end{split}\]

with\(\mathbf{X}\in \mathbb{R}^{M\times K}\) and\(\mathbf{Y}\in \mathbb{R}^{M\times K}\), this function returnsthe matrix\(\mathbf{Z}=\mathbf{X}+j\mathbf{Y}\in\mathbb{C}^{M\times K}\).

Input:

[…,2M,2K],tf.float

Output:

[…,M, 2],tf.complex

sionna.phy.mimo.complex2real_covariance(r)[source]

Transforms a complex-valued covariance matrix to its real-valued equivalent

Assume a proper complex random variable\(\mathbf{z}\in\mathbb{C}^M\)[ProperRV]with covariance matrix\(\mathbf{R}= \in\mathbb{C}^{M\times M}\)and real and imaginary parts\(\mathbf{x}\in \mathbb{R}^M\) and\(\mathbf{y}\in \mathbb{R}^M\), respectively.This function transforms the given\(\mathbf{R}\) into the covariance matrix of the real-valued equivalentvector\(\tilde{\mathbf{z}}=\left[\mathbf{x}^{\mathsf{T}}, \mathbf{y}^{\mathsf{T}} \right ]^{\mathsf{T}}\in\mathbb{R}^{2M}\), whichis computed as[CovProperRV]

\[\begin{split}\mathbb{E}\left[\tilde{\mathbf{z}}\tilde{\mathbf{z}}^{\mathsf{H}} \right] =\begin{pmatrix} \frac12\Re\{\mathbf{R}\} & -\frac12\Im\{\mathbf{R}\}\\ \frac12\Im\{\mathbf{R}\} & \frac12\Re\{\mathbf{R}\}\end{pmatrix}.\end{split}\]
Input:

[…,M,M],tf.complex

Output:

[…,2M, 2M],tf.complex.real_dtype

sionna.phy.mimo.real2complex_covariance(q)[source]

Transforms a real-valued covariance matrix to its complex-valued equivalent

Assume a proper complex random variable\(\mathbf{z}\in\mathbb{C}^M\)[ProperRV]with covariance matrix\(\mathbf{R}= \in\mathbb{C}^{M\times M}\)and real and imaginary parts\(\mathbf{x}\in \mathbb{R}^M\) and\(\mathbf{y}\in \mathbb{R}^M\), respectively.This function transforms the given covariance matrix of the real-valued equivalentvector\(\tilde{\mathbf{z}}=\left[\mathbf{x}^{\mathsf{T}}, \mathbf{y}^{\mathsf{T}} \right ]^{\mathsf{T}}\in\mathbb{R}^{2M}\), whichis given as[CovProperRV]

\[\begin{split}\mathbb{E}\left[\tilde{\mathbf{z}}\tilde{\mathbf{z}}^{\mathsf{H}} \right] =\begin{pmatrix} \frac12\Re\{\mathbf{R}\} & -\frac12\Im\{\mathbf{R}\}\\ \frac12\Im\{\mathbf{R}\} & \frac12\Re\{\mathbf{R}\}\end{pmatrix},\end{split}\]

into is complex-valued equivalent\(\mathbf{R}\).

Input:

[…,2M,2M],tf.float

Output:

[…,M, M],tf.complex

sionna.phy.mimo.complex2real_channel(y,h,s)[source]

Transforms a complex-valued MIMO channel into its real-valued equivalent

Assume the canonical MIMO channel model

\[\mathbf{y} = \mathbf{H}\mathbf{x} + \mathbf{n}\]

where\(\mathbf{y}\in\mathbb{C}^M\) is the received signal vector,\(\mathbf{x}\in\mathbb{C}^K\) is the vector of transmitted symbols,\(\mathbf{H}\in\mathbb{C}^{M\times K}\) is the known channel matrix,and\(\mathbf{n}\in\mathbb{C}^M\) is a noise vector with covariancematrix\(\mathbf{S}\in\mathbb{C}^{M\times M}\).

This function returns the real-valued equivalent representations of\(\mathbf{y}\),\(\mathbf{H}\), and\(\mathbf{S}\),which are used by a wide variety of MIMO detection algorithms (Section VII)[YH2015].These are obtained by applyingcomplex2real_vector() to\(\mathbf{y}\),complex2real_matrix() to\(\mathbf{H}\),andcomplex2real_covariance() to\(\mathbf{S}\).

Input:
  • y ([…,M],tf.complex) – Complex-valued received signals

  • h ([…,M,K],tf.complex) – Complex-valued channel matrices

  • s ([…,M,M], tf.complex) – Complex-valued noise covariance matrices

Output:
  • […,2M],tf.complex.real_dtype – Real-valued equivalent received signals

  • […,2M,2K],tf.complex.real_dtype – Real-valued equivalent channel matrices

  • […,2M,2M],tf.complex.real_dtype – Real-valued equivalent noise covariance matrices

sionna.phy.mimo.real2complex_channel(y,h,s)[source]

Transforms a real-valued MIMO channel into its complex-valued equivalent

Assume the canonical MIMO channel model

\[\mathbf{y} = \mathbf{H}\mathbf{x} + \mathbf{n}\]

where\(\mathbf{y}\in\mathbb{C}^M\) is the received signal vector,\(\mathbf{x}\in\mathbb{C}^K\) is the vector of transmitted symbols,\(\mathbf{H}\in\mathbb{C}^{M\times K}\) is the known channel matrix,and\(\mathbf{n}\in\mathbb{C}^M\) is a noise vector with covariancematrix\(\mathbf{S}\in\mathbb{C}^{M\times M}\).

This function transforms the real-valued equivalent representations of\(\mathbf{y}\),\(\mathbf{H}\), and\(\mathbf{S}\), as, e.g.,obtained with the functioncomplex2real_channel(),back to their complex-valued equivalents (Section VII)[YH2015].

Input:
  • y ([…,2M],tf.float) – Real-valued received signals

  • h ([…,2M,2K],tf.float) – Real-valued channel matrices

  • s ([…,2M,2M],tf.float) – Real-valued noise covariance matrices

Output:
  • […,M],tf.complex – Complex-valued equivalent received signals

  • […,M,K],tf.complex – Complex-valued equivalent channel matrices

  • […,M,M],tf.complex – Complex-valued equivalent noise covariance matrices

sionna.phy.mimo.whiten_channel(y,h,s,return_s=True)[source]

Whitens a canonical MIMO channel

Assume the canonical MIMO channel model

\[\mathbf{y} = \mathbf{H}\mathbf{x} + \mathbf{n}\]

where\(\mathbf{y}\in\mathbb{C}^M(\mathbb{R}^M)\) is the received signal vector,\(\mathbf{x}\in\mathbb{C}^K(\mathbb{R}^K)\) is the vector of transmitted symbols,\(\mathbf{H}\in\mathbb{C}^{M\times K}(\mathbb{R}^{M\times K})\) is the known channel matrix,and\(\mathbf{n}\in\mathbb{C}^M(\mathbb{R}^M)\) is a noise vector with covariancematrix\(\mathbf{S}\in\mathbb{C}^{M\times M}(\mathbb{R}^{M\times M})\).

This function whitens this channel by multiplying\(\mathbf{y}\) and\(\mathbf{H}\) from the left by\(\mathbf{S}^{-\frac{1}{2}}=\mathbf{L}^{-1}\), where\(\mathbf{L}\in \mathbb{C}^{M\times M}\) is the Choleskydecomposition of\(\mathbf{S}\).Optionally, the whitened noise covariance matrix\(\mathbf{I}_M\)can be returned.

Input:
  • y ([…,M],tf.float ortf.complex) – Received signals

  • h ([…,M,K],tf.float ortf.complex) – Channel matrices

  • s ([…,M,M],tf.float ortf.complex) – Noise covariance matrices

  • return_s (bool, (defaultTrue)) – IfTrue, the whitened covariance matrix is returned.

Output:
  • […,M],tf.float ortf.complex – Whitened received signals

  • […,M,K],tf.float ortf.complex – Whitened channel matrices

  • […,M,M],tf.float ortf.complex – Whitened noise covariance matrices.Only returned ifreturn_s isTrue.

References:
[ProperRV](1,2)

Proper complex random variables,Wikipedia, accessed 11 September, 2022.

[CovProperRV](1,2)

Covariance matrices of real and imaginary parts,Wikipedia, accessed 11 September, 2022.

[YH2015](1,2)

S. Yang and L. Hanzo,“Fifty Years of MIMO Detection: The Road to Large-Scale MIMOs”,IEEE Communications Surveys & Tutorials, vol. 17, no. 4, pp. 1941-1988, 2015.

[FT2015]

W. Fu and J. S. Thompson,“Performance analysis of K-best detection with adaptive modulation”, IEEE Int. Symp. Wirel. Commun. Sys. (ISWCS), 2015.

[EP2014]

J. Céspedes, P. M. Olmos, M. Sánchez-Fernández, and F. Perez-Cruz,“Expectation Propagation Detection for High-Order High-Dimensional MIMO Systems”,IEEE Trans. Commun., vol. 62, no. 8, pp. 2840-2849, Aug. 2014.

[CST2011](1,2,3,4)

C. Studer, S. Fateh, and D. Seethaler,“ASIC Implementation of Soft-Input Soft-Output MIMO Detection Using MMSE Parallel Interference Cancellation”,IEEE Journal of Solid-State Circuits, vol. 46, no. 7, pp. 1754–1765, July2011.