PostEqualizationSINR#

class sionna.phy.ofdm.PostEqualizationSINR(resource_grid: sionna.phy.ofdm.resource_grid.ResourceGrid, stream_management: sionna.phy.mimo.stream_management.StreamManagement, precision: Literal['single', 'double'] | None = None, device: str | None = None, **kwargs)[source]#

Bases: sionna.phy.block.Block

Abstract block that computes the SINR after equalization.

This function computes the post-equalization SINR for every transmitted stream from the PrecodedChannel. A stream goes from a specific transmitter to a specific receiver and is characterized by a precoding vector and an equalization vector.

Every transmitter is equipped with num_tx_ant antennas and every receiver is equipped with num_rx_ant antennas. All transmitters send the same number of streams \(S\). A transmitter can allocate different power to different streams.

Let \(\mathbf{H}_{i,j}\in\mathbb{C}^{\text{num\_rx\_ant}\times\text{num\_tx\_ant}}\) be the complex channel matrix between receiver \(i\) and transmitter \(j\). We denote by \(\mathbf{g}_{j_,s}\in\mathbb{C}^{\text{num\_tx\_ant}}\) the precoding vector for stream \(s\) sent by transmitter \(j\). Then, the received signal at receiver \(i\) can be expressed as:

\[\mathbf{y}_i = \sum_{j,s} \mathbf{H}_{i,j} \mathbf{g}_{j,s} \sqrt{p_{j,s}} x_{j,s} + \mathbf{n}_{i}\]

where \(x_{j,s}\) and \(p_{j,s}\) are the unit-power transmit symbol and associated transmission power for stream \(s\), respectively, and \(\mathbf{n}_{i}\) is the additive noise, distributed as \(\mathcal{C}\mathcal{N}(0,\sigma^2 \mathbf{I})\).

By stacking the precoding vectors into a matrix \(\mathbf{G}_j=\left[\mathbf{g}_{j,1}, \ldots, \mathbf{g}_{j,S}\right]\), and using the definition of the precoded channel \(\widetilde{\mathbf{H}}_{i,j}\) in (60), the received signal can be rewritten as:

\[\mathbf{y}_i = \sum_j \widetilde{\mathbf{H}}_{i,j} \mathop{\text{diag}}(x_{j,1},...,x_{j,S}) + \mathbf{n}_{i}\]

Next, let \(\mathbf{f}_{i,j,s} \in\mathbb{C}^{\text{num\_rx\_ant}}\) be the equalization vector for stream \(s\) of transmitter \(j\), applied by the intended receiver \(i\). Then, the useful signal power for stream \(s\) of transmitter \(j\) is:

\[u_{i,j,s} = p_{j,s} \left| \mathbf{f}_{i,j,s}^\mathsf{H} \mathbf{H}_{i,j} \mathbf{g}_{j, s} \right|^2.\]

We assume that the transmitted symbols \(x_{j,s}\) are uncorrelated among each other. Then, the interference power for this stream can be written as:

\[v_{i,j,s} = \sum_{(j',s') \ne (j,s)} p_{j',s'} \left| \mathbf{f}_{i,j,s}^\mathsf{H} \mathbf{H}_{i,j'} \mathbf{g}_{j', s'} \right|^2.\]

The post-equalization noise power can be expressed as:

\[n_{i,j,s} = \sigma^2 \| \mathbf{f}_{i,j,s} \|^2.\]

With these definitions, the SINR for this stream which is finally computed as:

\[\mathrm{SINR}_{i,j,s} = \frac{u_{i,j,s}}{v_{i,j,s} + n_{i,j,s}}.\]

Notes

The intended receiver \(i\) for a particular stream \((j,s)\) is defined by the StreamManagement object.

Parameters:
Inputs:
  • h_eff – [batch_size, num_rx, num_rx_ant, num_tx, num_streams_per_tx, num_ofdm_symbols, num_effective_subcarriers], torch.complex. Effective channel after precoding as defined in (60).

  • no – [batch_size, num_rx, num_rx_ant, num_ofdm_symbols, num_effective_subcarriers] (or only the first n dims), torch.float. Noise variance.

  • h_eff_hatNone (default) | [batch_size, num_rx, num_rx_ant, num_tx, num_streams_per_tx, num_ofdm_symbols, num_effective_subcarriers], torch.complex. Estimated effective channel after precoding. If set to None, the actual channel realizations are used.

Outputs:

sinr – [batch_size, num_ofdm_symbols, num_effective_subcarriers, num_rx, num_streams_per_rx], torch.float. SINR after equalization.

Methods

get_per_rx_channels(h_eff: torch.Tensor) Tuple[torch.Tensor, torch.Tensor][source]#

Extract desired and undesired channels for each receiver.

Parameters:

h_eff (torch.Tensor) – [batch_size, num_rx, num_rx_ant, num_tx, num_streams_per_tx, num_ofdm_symbols, num_effective_subcarriers], torch.complex. Effective precoded channel. Can be estimated or true.

Outputs:
  • h_eff_desired – [batch_size, num_rx, num_ofdm_symbols, num_effective_subcarriers, num_rx_ant, num_streams_per_rx], torch.complex. Desired effective channels.

  • h_eff_undesired – [batch_size, num_rx, num_ofdm_symbols, num_effective_subcarriers, num_rx_ant, num_interfering_streams_per_rx], torch.complex. Undesired effective channels.

compute_interference_covariance_matrix(no: torch.Tensor | None = None, h_eff_undesired: torch.Tensor | None = None) torch.Tensor[source]#

Compute the interference covariance matrix.

Parameters:
  • no (torch.Tensor | None) – None (default) | [batch_size, num_rx, num_ofdm_symbols, num_effective_subcarriers, num_rx_ant], torch.float. Noise variance.

  • h_eff_undesired (torch.Tensor | None) – None (default) | [batch_size, num_rx, num_ofdm_symbols, num_effective_subcarriers, num_rx_ant, num_interfering_streams_per_rx], torch.complex. Undesired effective channels. If set to None, the actual channel realizations are used.

Outputs:

s – [batch_size, num_rx, num_ofdm_symbols, num_effective_subcarriers, num_rx_ant, num_rx_ant], torch.complex. Interference covariance matrix.

compute_desired_signal_power(h_eff_desired: torch.Tensor, f: torch.Tensor) torch.Tensor[source]#

Compute the desired signal power.

Parameters:
  • h_eff_desired (torch.Tensor) – [batch_size, num_rx, num_ofdm_symbols, num_effective_subcarriers, num_rx_ant, num_streams_per_rx], torch.complex. Desired effective channels.

  • f (torch.Tensor) – [batch_size, num_rx, num_ofdm_symbols, num_effective_subcarriers, num_streams_per_rx, num_rx_ant], torch.complex. Receive combining vectors.

Outputs:

signal_power – [batch_size, num_rx, num_ofdm_symbols, num_effective_subcarriers, num_streams_per_rx], torch.float. Desired signal power.

compute_total_power(h_eff_desired: torch.Tensor, h_eff_undesired: torch.Tensor, f: torch.Tensor) torch.Tensor[source]#

Compute the total power from all transmitters.

Parameters:
  • h_eff_desired (torch.Tensor) – [batch_size, num_rx, num_ofdm_symbols, num_effective_subcarriers, num_rx_ant, num_streams_per_rx], torch.complex. Desired effective channels.

  • h_eff_undesired (torch.Tensor) – [batch_size, num_rx, num_ofdm_symbols, num_effective_subcarriers, num_rx_ant, num_interfering_streams_per_rx], torch.complex. Undesired effective channels.

  • f (torch.Tensor) – [batch_size, num_rx, num_ofdm_symbols, num_effective_subcarriers, num_streams_per_rx, num_rx_ant], torch.complex. Receive combining vectors.

Outputs:

total_power – [batch_size, num_rx, num_ofdm_symbols, num_effective_subcarriers, 1], torch.float. Total power.

compute_noise_power(no: torch.Tensor, f: torch.Tensor) torch.Tensor[source]#

Compute the noise power.

Parameters:
  • no (torch.Tensor) – [batch_size, num_rx, num_ofdm_symbols, num_effective_subcarriers, num_rx_ant], torch.float. Noise variance.

  • f (torch.Tensor) – [batch_size, num_rx, num_ofdm_symbols, num_effective_subcarriers, num_streams_per_rx, num_rx_ant], torch.complex. Receive combining vectors.

compute_sinr(h_eff_desired: torch.Tensor, h_eff_undesired: torch.Tensor, no: torch.Tensor, f: torch.Tensor) torch.Tensor[source]#

Compute the SINR.

Parameters:
  • h_eff_desired (torch.Tensor) – [batch_size, num_rx, num_ofdm_symbols, num_effective_subcarriers, num_rx_ant, num_streams_per_rx], torch.complex. Desired effective channels.

  • h_eff_undesired (torch.Tensor) – [batch_size, num_rx, num_ofdm_symbols, num_effective_subcarriers, num_rx_ant, num_interfering_streams_per_rx], torch.complex. Undesired effective channels.

  • no (torch.Tensor) – [batch_size, num_rx, num_ofdm_symbols, num_effective_subcarriers, num_rx_ant], torch.float. Noise variance.

  • f (torch.Tensor) – [batch_size, num_rx, num_ofdm_symbols, num_effective_subcarriers, num_rx_ant, num_streams_per_rx], torch.complex. Equalization matrix.

Outputs:

sinr – [batch_size, num_ofdm_symbols, num_effective_subcarriers, num_rx, num_streams_per_rx], torch.float. Post-equalization SINR.