anomaly-detection-material-parameters-calibration

Sionna param calibration (research proj)
git clone https://git.ea.contact/anomaly-detection-material-parameters-calibration
Log | Files | Refs | README

time_channel.py (8505B)


      1 #
      2 # SPDX-FileCopyrightText: Copyright (c) 2021-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
      3 # SPDX-License-Identifier: Apache-2.0
      4 #
      5 """Layer for implementing the channel in the time domain"""
      6 
      7 import tensorflow as tf
      8 
      9 from . import GenerateTimeChannel, ApplyTimeChannel
     10 from .utils import time_lag_discrete_time_channel
     11 
     12 class TimeChannel(tf.keras.layers.Layer):
     13     # pylint: disable=line-too-long
     14     r"""TimeChannel(channel_model, bandwidth, num_time_samples, maximum_delay_spread=3e-6, l_min=None, l_max=None, normalize_channel=False, add_awgn=True, return_channel=False, dtype=tf.complex64, **kwargs)
     15 
     16     Generate channel responses and apply them to channel inputs in the time domain.
     17 
     18     This class inherits from the Keras `Layer` class and can be used as layer
     19     in a Keras model.
     20 
     21     The channel output consists of ``num_time_samples`` + ``l_max`` - ``l_min``
     22     time samples, as it is the result of filtering the channel input of length
     23     ``num_time_samples`` with the time-variant channel filter  of length
     24     ``l_max`` - ``l_min`` + 1. In the case of a single-input single-output link and given a sequence of channel
     25     inputs :math:`x_0,\cdots,x_{N_B}`, where :math:`N_B` is ``num_time_samples``, this
     26     layer outputs
     27 
     28     .. math::
     29         y_b = \sum_{\ell = L_{\text{min}}}^{L_{\text{max}}} x_{b-\ell} \bar{h}_{b,\ell} + w_b
     30 
     31     where :math:`L_{\text{min}}` corresponds ``l_min``, :math:`L_{\text{max}}` to ``l_max``, :math:`w_b` to
     32     the additive noise, and :math:`\bar{h}_{b,\ell}` to the
     33     :math:`\ell^{th}` tap of the :math:`b^{th}` channel sample.
     34     This layer outputs :math:`y_b` for :math:`b` ranging from :math:`L_{\text{min}}` to
     35     :math:`N_B + L_{\text{max}} - 1`, and :math:`x_{b}` is set to 0 for :math:`b < 0` or :math:`b \geq N_B`.
     36     The channel taps :math:`\bar{h}_{b,\ell}` are computed assuming a sinc filter
     37     is used for pulse shaping and receive filtering. Therefore, given a channel impulse response
     38     :math:`(a_{m}(t), \tau_{m}), 0 \leq m \leq M-1`, generated by the ``channel_model``,
     39     the channel taps are computed as follows:
     40 
     41     .. math::
     42         \bar{h}_{b, \ell}
     43         = \sum_{m=0}^{M-1} a_{m}\left(\frac{b}{W}\right)
     44             \text{sinc}\left( \ell - W\tau_{m} \right)
     45 
     46     for :math:`\ell` ranging from ``l_min`` to ``l_max``, and where :math:`W` is
     47     the ``bandwidth``.
     48 
     49     For multiple-input multiple-output (MIMO) links, the channel output is computed for each antenna of each receiver and by summing over all the antennas of all transmitters.
     50 
     51     Parameters
     52     ----------
     53     channel_model : :class:`~sionna.channel.ChannelModel` object
     54         An instance of a :class:`~sionna.channel.ChannelModel`, such as
     55         :class:`~sionna.channel.RayleighBlockFading` or
     56         :class:`~sionna.channel.tr38901.UMi`.
     57 
     58     bandwidth : float
     59         Bandwidth (:math:`W`) [Hz]
     60 
     61     num_time_samples : int
     62         Number of time samples forming the channel input (:math:`N_B`)
     63 
     64     maximum_delay_spread : float
     65         Maximum delay spread [s].
     66         Used to compute the default value of ``l_max`` if ``l_max`` is set to
     67         `None`. If a value is given for ``l_max``, this parameter is not used.
     68         It defaults to 3us, which was found
     69         to be large enough to include most significant paths with all channel
     70         models included in Sionna assuming a nominal delay spread of 100ns.
     71 
     72     l_min : int
     73         Smallest time-lag for the discrete complex baseband channel (:math:`L_{\text{min}}`).
     74         If set to `None`, defaults to the value given by :func:`time_lag_discrete_time_channel`.
     75 
     76     l_max : int
     77         Largest time-lag for the discrete complex baseband channel (:math:`L_{\text{max}}`).
     78         If set to `None`, it is computed from ``bandwidth`` and ``maximum_delay_spread``
     79         using :func:`time_lag_discrete_time_channel`. If it is not set to `None`,
     80         then the parameter ``maximum_delay_spread`` is not used.
     81 
     82     add_awgn : bool
     83         If set to `False`, no white Gaussian noise is added.
     84         Defaults to `True`.
     85 
     86     normalize_channel : bool
     87         If set to `True`, the channel is normalized over the block size
     88         to ensure unit average energy per time step. Defaults to `False`.
     89 
     90     return_channel : bool
     91         If set to `True`, the channel response is returned in addition to the
     92         channel output. Defaults to `False`.
     93 
     94     dtype : tf.DType
     95         Complex datatype to use for internal processing and output.
     96         Defaults to `tf.complex64`.
     97 
     98     Input
     99     -----
    100 
    101     (x, no) or x:
    102         Tuple or Tensor:
    103 
    104     x :  [batch size, num_tx, num_tx_ant, num_time_samples], tf.complex
    105         Channel inputs
    106 
    107     no : Scalar or Tensor, tf.float
    108         Scalar or tensor whose shape can be broadcast to the shape of the
    109         channel outputs: [batch size, num_rx, num_rx_ant, num_time_samples].
    110         Only required if ``add_awgn`` is set to `True`.
    111         The noise power ``no`` is per complex dimension. If ``no`` is a scalar,
    112         noise of the same variance will be added to the outputs.
    113         If ``no`` is a tensor, it must have a shape that can be broadcast to
    114         the shape of the channel outputs. This allows, e.g., adding noise of
    115         different variance to each example in a batch. If ``no`` has a lower
    116         rank than the channel outputs, then ``no`` will be broadcast to the
    117         shape of the channel outputs by adding dummy dimensions after the last
    118         axis.
    119 
    120     Output
    121     -------
    122     y : [batch size, num_rx, num_rx_ant, num_time_samples + l_max - l_min], tf.complex
    123         Channel outputs
    124         The channel output consists of ``num_time_samples`` + ``l_max`` - ``l_min``
    125         time samples, as it is the result of filtering the channel input of length
    126         ``num_time_samples`` with the time-variant channel filter  of length
    127         ``l_max`` - ``l_min`` + 1.
    128 
    129     h_time : [batch size, num_rx, num_rx_ant, num_tx, num_tx_ant, num_time_samples + l_max - l_min, l_max - l_min + 1], tf.complex
    130         (Optional) Channel responses. Returned only if ``return_channel``
    131         is set to `True`.
    132         For each batch example, ``num_time_samples`` + ``l_max`` - ``l_min`` time
    133         steps of the channel realizations are generated to filter the channel input.
    134     """
    135 
    136     def __init__(self, channel_model, bandwidth, num_time_samples,
    137                  maximum_delay_spread=3e-6, l_min=None, l_max=None,
    138                  normalize_channel=False, add_awgn=True, return_channel=False,
    139                  dtype=tf.complex64, **kwargs):
    140 
    141         super().__init__(trainable=False, dtype=dtype, **kwargs)
    142 
    143         # Setting l_min and l_max to default values if not given by the user
    144         l_min_default, l_max_default = time_lag_discrete_time_channel(bandwidth,
    145                                                             maximum_delay_spread)
    146         if l_min is None:
    147             l_min = l_min_default
    148         if l_max is None:
    149             l_max = l_max_default
    150 
    151         self._cir_sampler = channel_model
    152         self._bandwidth = bandwidth
    153         self._num_time_steps = num_time_samples
    154         self._l_min = l_min
    155         self._l_max = l_max
    156         self._l_tot = l_max-l_min+1
    157         self._normalize_channel = normalize_channel
    158         self._add_awgn = add_awgn
    159         self._return_channel = return_channel
    160 
    161     def build(self, input_shape): #pylint: disable=unused-argument
    162 
    163         self._generate_channel = GenerateTimeChannel(self._cir_sampler,
    164                                                      self._bandwidth,
    165                                                      self._num_time_steps,
    166                                                      self._l_min,
    167                                                      self._l_max,
    168                                                      self._normalize_channel)
    169         self._apply_channel = ApplyTimeChannel( self._num_time_steps,
    170                                                 self._l_tot,
    171                                                 self._add_awgn,
    172                                                 tf.as_dtype(self.dtype))
    173 
    174     def call(self, inputs):
    175 
    176         if self._add_awgn:
    177             x, no = inputs
    178         else:
    179             x = inputs
    180 
    181         h_time = self._generate_channel(tf.shape(x)[0])
    182         if self._add_awgn:
    183             y = self._apply_channel([x, h_time, no])
    184         else:
    185             y = self._apply_channel([x, h_time])
    186 
    187         if self._return_channel:
    188             return y, h_time
    189         else:
    190             return y