Source code for sionna.phy.channel.generate_ofdm_channel
## SPDX-FileCopyrightText: Copyright (c) 2021-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.# SPDX-License-Identifier: Apache-2.0#"""Class for generating channel frequency responses"""fromsionna.phy.blockimportObjectfromsionna.phy.channel.utilsimportsubcarrier_frequencies,cir_to_ofdm_channel
[docs]classGenerateOFDMChannel(Object):# pylint: disable=line-too-longr""" Generates channel frequency responses The channel impulse response is constant over the duration of an OFDM symbol. Given a channel impulse response :math:`(a_{m}(t), \tau_{m}), 0 \leq m \leq M-1`, generated by the ``channel_model``, the channel frequency response for the :math:`s^{th}` OFDM symbol and :math:`n^{th}` subcarrier is computed as follows: .. math:: \widehat{h}_{s, n} = \sum_{m=0}^{M-1} a_{m}(s) e^{-j2\pi n \Delta_f \tau_{m}} where :math:`\Delta_f` is the subcarrier spacing, and :math:`s` is used as time step to indicate that the channel impulse response can change from one OFDM symbol to the next in the event of mobility, even if it is assumed static over the duration of an OFDM symbol. Parameters ---------- channel_model : :class:`~sionna.phy.channel.ChannelModel` Channel model to be used. resource_grid : :class:`~sionna.phy.ofdm.ResourceGrid` Resource grid normalize_channel : `bool`, (default `False`) If set to `True`, the channel is normalized over the resource grid to ensure unit average energy per resource element. precision : `None` (default) | "single" | "double" Precision used for internal calculations and outputs. If set to `None`, :attr:`~sionna.phy.config.Config.precision` is used. Input ----- batch_size : `None` (default) | `int` Batch size. Defaults to `None` for channel models that do not require this parameter. Output ------- h_freq : [batch size, num_rx, num_rx_ant, num_tx, num_tx_ant, num_ofdm_symbols, num_subcarriers], `tf.complex` Channel frequency responses """def__init__(self,channel_model,resource_grid,normalize_channel=False,precision=None,**kwargs):super().__init__(precision=precision,**kwargs)# Callable used to sample channel input responsesself._cir_sampler=channel_model# We need those in call()self._num_ofdm_symbols=resource_grid.num_ofdm_symbolsself._subcarrier_spacing=resource_grid.subcarrier_spacingself._num_subcarriers=resource_grid.fft_sizeself._normalize_channel=normalize_channelself._sampling_frequency=1./resource_grid.ofdm_symbol_duration# Frequencies of the subcarriersself._frequencies=subcarrier_frequencies(self._num_subcarriers,self._subcarrier_spacing,self.precision)def__call__(self,batch_size=None):# Sample channel impulse responsesh,tau=self._cir_sampler(batch_size,self._num_ofdm_symbols,self._sampling_frequency)h_freq=cir_to_ofdm_channel(self._frequencies,h,tau,self._normalize_channel)returnh_freq