EyePrecodedChannel#

class sionna.phy.ofdm.EyePrecodedChannel(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.ofdm.precoding.PrecodedChannel

Compute the effective channel after power allocation without precoding.

The identity matrix precoder is used, meaning no spatial precoding is applied, only power allocation.

Parameters:
Inputs:
  • h – [batch_size, num_rx, num_rx_ant, num_tx, num_tx_ant, num_ofdm_symbols, fft_size], torch.complex. Actual channel realizations.

  • tx_power – [batch_size, num_tx, num_streams_per_tx, num_ofdm_symbols, fft_size] (or broadcastable), torch.float. Power of each stream for each transmitter. Also a lower-rank tensor is accepted if it is broadcastable to the requested shape.

Outputs:

h_eff – [batch_size, num_rx, num_rx_ant, num_tx, num_streams_per_tx, num_ofdm_symbols, num_effective_subcarriers], torch.complex. The effective channel after power allocation. Nulled subcarriers are automatically removed.

Examples

import numpy as np
import torch
from sionna.phy.ofdm import ResourceGrid, EyePrecodedChannel
from sionna.phy.mimo import StreamManagement

num_tx = 2
num_rx = 2
num_tx_ant = 4
num_streams_per_tx = num_tx_ant  # Must equal num_tx_ant for identity precoder

rx_tx_association = np.eye(num_rx, num_tx, dtype=np.int32)
sm = StreamManagement(rx_tx_association, num_streams_per_tx)
rg = ResourceGrid(num_ofdm_symbols=14, fft_size=64,
                  subcarrier_spacing=15e3, num_tx=num_tx,
                  num_streams_per_tx=num_streams_per_tx)

precoded_channel = EyePrecodedChannel(rg, sm)

batch_size = 16
h = torch.randn(batch_size, num_rx, 2, num_tx, num_tx_ant, 14, 64,
                dtype=torch.complex64)
tx_power = torch.rand(batch_size, num_tx, num_streams_per_tx, 14, 64)

h_eff = precoded_channel(h, tx_power)
print(h_eff.shape)
# torch.Size([16, 2, 2, 2, 4, 14, 64])