.. :html_theme.sidebar_secondary.remove:

:py:mod:`comyx.network`
=======================

.. py:module:: comyx.network


Package Summary
----------------

Classes
~~~~~~~

.. autoapisummary::

   comyx.network.BaseStation
   comyx.network.Link
   comyx.network.RIS
   comyx.network.STAR_RIS
   comyx.network.Transceiver
   comyx.network.UserEquipment



Functions
~~~~~~~~~

.. autoapisummary::

   comyx.network.cascaded_channel_gain
   comyx.network.effective_channel_gain




Reference
---------

.. py:class:: BaseStation(id_: str, n_antennas: int, position: Union[List[float], None] = None, t_power: Union[float, None] = None, r_sensitivity: Union[float, None] = None, radius: Union[float, None] = None)


   Bases: :py:obj:`comyx.network.transceiver.Transceiver`

   Represents a base station in the modelled environment.

   Identifiers may be of the form "BSx", where x is a positive integer. The
   first two characters indicate the type of transceiver, i.e., "BS" for base
   station. The remaining characters are the unique identifier of the base
   station. For example, "BS1" is a base station with identifier 1.

   .. py:property:: radius
      :type: float

      Return the radius of the base station.


.. py:class:: Link(tx: comyx.network.transceiver.Transceiver | comyx.network.ris.RIS, rx: comyx.network.transceiver.Transceiver | comyx.network.ris.RIS, fading_args: dict[str, Any], pathloss_args: dict[str, Any], shape: Tuple[int, Ellipsis], rician_args: Union[dict[str, Any], None] = None, custom_rvs: Union[NDArrayComplex, None] = None, distance: Union[float, None] = None, seed: Union[int, None] = None)


   Represents a link in the modelled environment.

   A link is a connection between two transceivers. It is characterized by the
   distance between the two transceivers, the path loss, and the channel gain.

   If rician_args are provided, the fading_args are used for the NLOS component
   and the rician_args are used for the LOS component.

   Mathematically, the channel gain is given by

   .. math::
       h_{t,r} = g_{t,r} \sqrt{PL(d_{t,r})},

   where :math:`g_{t,r}` is the small-scale fading (sampled from a
   distribution), :math:`PL(d_{t,r})` is the path loss, and
   :math:`d_{t,r}` is the distance between the transceivers.

   .. attribute:: tx

      Transmitter of the link.

   .. attribute:: rx

      Receiver of the link.

   .. attribute:: shape

      Number of shape for the channel gain.

   .. py:property:: channel_gain
      :type: NDArrayComplex

      Channel gain between the transceivers.

   .. py:property:: distance
      :type: float

      Distance between the transceivers.

   .. py:property:: magnitude
      :type: NDArrayFloat

      Magnitude of the channel

   .. py:property:: pathloss
      :type: NDArrayFloat

      Path loss between the transceivers.

   .. py:property:: phase
      :type: NDArrayFloat

      Phase of the channel

   .. py:method:: generate_rvs(custom_rvs: NDArrayComplex | None = None, seed: int = None) -> None

      Generate random variables for the channel gain.

      Not private to allow for the generation of new channel gains for more
      flexible simulations.


   .. py:method:: rician_fading(K: float, order: str = 'post', ris: bool = True) -> NDArrayComplex

      Generate Rician fading channel gain between the transceivers.

      :param K: Rician K-factor.
      :param pos_a: Position of the first transceiver.
      :param pos_b: Position of the second transceiver.
      :param order: Order of RIS in the link.
                    Possible values are 'post' and 'pre'.
      :param ris: Whether to consider the RIS in the link.

      :returns: Rician fading channel gain.


   .. py:method:: update_channel(distance: Union[float, None] = None, custom_rvs: NDArrayComplex | None = None, ex_pathloss: bool = False, ex_rvs: bool = False, seed: Union[int, None] = None) -> None

      Update the channel gain.

      :param distance: New distance between the transceivers.
      :param custom_rvs: New random variables for the channel gain.
      :param ex_pathloss: Whether to exclude distance-based params from the update.
      :param ex_rvs: Whether to exclude the random variables from the update.
      :param seed: Seed for the random number generator.


   .. py:method:: update_params(distance: Union[float, None] = None) -> None

      Update the parameters of the link.

      :param distance: New distance between the transceivers.



.. py:class:: RIS(id_: str, n_elements: int, position: Union[List[float], None] = None)


   Represents a reconfigurable intelligent surface (RIS).

   An RIS is a surface with a large number of elements that can be
   electronically controlled to reflect the incoming signal in a desired
   direction.

   Mathematically, the reflection matrix of the RIS is given by

   .. math::
       \mathbf{R} = \text{diag}(\mathbf{a} \odot \exp(j \mathbf{\Phi})),

   where :math:`\mathbf{a}` is the vector of amplitudes, :math:`\mathbf{\Phi}`
   is the vector of phase shifts, and :math:`\odot` is the Hadamard product.

   .. py:property:: amplitudes
      :type: NDArrayFloat

      Return the amplitudes of the RIS.

   .. py:property:: id
      :type: str

      Return the unique identifier of the RIS.

   .. py:property:: n_elements
      :type: int

      Return the number of elements of the RIS.

   .. py:property:: phase_shifts
      :type: NDArrayFloat

      Return the phase shifts of the RIS.

   .. py:property:: position
      :type: List[float]

      Return the position of the RIS in the environment.

   .. py:property:: reflection_matrix
      :type: NDArrayComplex

      Return the reflection matrix of the RIS.

      The reflection matrix is a diagonal matrix with the phase shifts and
      amplitudes as its diagonal elements. The phase shifts and amplitudes
      must be set before accessing the reflection matrix.

      The diagonality of the reflection matrix is due to the fact that the
      each element of the RIS reflects the incoming signal independently of
      the other elements.

      :returns: The reflection matrix of the RIS.


.. py:class:: STAR_RIS(id_: str, n_elements: int, position: Union[List[float], None] = None)


   Represents a STAR-RIS (Simultaneously Transmitting and Reflecting RIS).

   An STAR-RIS is a surface with a large number of elements that can be
   electronically controlled to reflect and transmit the incoming signal in a
   both spaces.

   Mathematically, the characteristic matrices of the STAR-RIS is given by

   .. math::
       \mathbf{R}^{n} = \text{diag}(\mathbf{a}^{n} \odot \exp(j \mathbf{\Phi}^{n})),

   where :math:`n \in \{t, r\}` and represents the transmission and reflection
   mode, respectively. Furthermore, $\mathbf{a}^{n}$ is the vector of
   amplitudes, :math:`\mathbf{\Phi}^{n}` is the vector of phase shifts, and $\odot$
   is the Hadamard product.

   Note that STAR-RIS must satisfy the law of conservation of energy, that is,
   :math:`\forall i \in \{1, \ldots, N\}` (where :math:`N` is the number of
   elements of the STAR-RIS), :math:`(a^{t}_{i})^2 + (a^{r}_{i})^2 = 1`.

   .. py:property:: id
      :type: str

      Return the unique identifier of the STAR-RIS.

   .. py:property:: n_elements
      :type: int

      Return the number of antennas of the STAR-RIS.

   .. py:property:: position
      :type: List[float]

      Return the position of the STAR-RIS in the environment.

   .. py:property:: reflection_amplitudes
      :type: NDArrayFloat

      Return the reflection amplitudes of the STAR-RIS.

   .. py:property:: reflection_matrix
      :type: NDArrayComplex

      Return the reflection matrix of the STAR-RIS.

      The reflection matrix is a diagonal matrix with the phase shifts and
      amplitudes as its diagonal elements. The phase shifts and amplitudes
      must be set before accessing the reflection matrix.

      The diagonality of the reflection matrix is due to the fact that the
      each element of the RIS reflects the incoming signal independently of
      the other elements.

      :returns: The reflection matrix of the RIS.

   .. py:property:: reflection_phases
      :type: NDArrayFloat

      Return the reflection phase shifts of the STAR-RIS.

   .. py:property:: transmission_amplitudes
      :type: NDArrayFloat

      Return the transmission amplitudes of the STAR-RIS.

   .. py:property:: transmission_matrix
      :type: NDArrayComplex

      Return the transmission matrix of the STAR-RIS.

      The transmission matrix is a diagonal matrix with the phase shifts and
      amplitudes as its diagonal elements. The phase shifts and amplitudes
      must be set before accessing the transmission matrix.

      The diagonality of the transmission matrix is due to the fact that the
      each element of the RIS reflects the incoming signal independently of
      the other elements.

      :returns: The transmission matrix of the STAR-RIS.

   .. py:property:: transmission_phases
      :type: NDArrayFloat

      Return the transmission phase shifts of the STAR-RIS.


.. py:class:: Transceiver(id_: str, n_antennas: int, position: Union[List[float], None] = None, t_power: Union[float, None] = None, r_sensitivity: Union[float, None] = None)


   Represents a transceiver in the modelled environment.

   Fundamental class of Comyx environments; can be used to model both the base
   stations and the mobile stations/users.

   All transceivers have a unique identifier, a position in the environment, number
   of antennas, and optionally a transmit power and a sensitivity. The transmit power
   is the power at which a transceiver transmits signals, and the sensitivity is the
   minimum power at which a transceiver can receive signals.

   .. py:property:: id
      :type: str

      Return the unique identifier of the transceiver.

   .. py:property:: n_antennas
      :type: int

      Return the number of antennas of the transceiver.

   .. py:property:: position
      :type: List[float]

      Return the position of the transceiver in the environment.

   .. py:property:: r_sensitivity
      :type: Union[float, None]

      Return the sensitivity of the transceiver.

   .. py:property:: t_power
      :type: Union[float, NDArrayFloat, None]

      Return the transmit power of the transceiver.


.. py:class:: UserEquipment(id_: str, n_antennas: int, position: Union[List[float], None] = None, t_power: Union[float, None] = None, r_sensitivity: Union[float, None] = None)


   Bases: :py:obj:`comyx.network.transceiver.Transceiver`

   Represents a user equipment in the modelled environment.

   Identifiers may be of the form "UEx", where x is a positive integer. The
   first two characters indicate the type of transceiver, i.e., "UE" for user
   equipment. The remaining characters are the unique identifier of the user
   equipment. For example, "UE42" is a user equipment with identifier 42.

   .. py:property:: rate
      :type: NDArrayFloat

      Calculate the rate of the transceiver (Shannon formula)

      :param mean_axis: Axis along which the mean is calculated.
                        Default is -1 (last axis, i.e., over all realizations).

      :returns: Rate of the transceiver.

   .. py:method:: from_base_station(base_station: comyx.network.base_station.BaseStation, id_: str, n_antennas: int, t_power: Union[float, None] = None, r_sensitivity: Union[float, None] = None, height: float = 0, tolerance: float = 0) -> UserEquipment
      :classmethod:

      Create a user equipment within the coverage area of a base station.

      :param id_: Unique identifier of the user equipment.
      :param n_antennas: Number of antennas of the user equipment.
      :param base_station: Base station to create the user equipment from.
      :param height: Height of the user equipment. Defaults to 0.
      :param tolerance: Tolerance from the edge of the coverage area.
                        Defaults to 0.

      :returns: Randomly positioned user equipment.



.. py:function:: cascaded_channel_gain(tR_link: Link, Rr_link: Link, style: str = 'sum', ele_idx: int = 0) -> NDArrayComplex

   Calculate the cascaded channel gain.

   The cascaded channel gain is the channel gain between the transmitter and
   the receiver through the RIS. Mathematically, the cascaded channel gain
   through the RIS is given by

   .. math::
       h_{csc}= \mathbf{h}_{R,r}^T \mathbf{R} \mathbf{h}_{t,R},

   where :math:`\mathbf{h}_{t,R}` is the channel gain between the transmitter
   and the RIS, :math:`\mathbf{h}_{R,r}` is the channel gain between the RIS
   and the receiver, and :math:`\mathbf{R}` is the reflection matrix of the
   RIS. The superscript :math:`T` denotes the transpose operator.

   If channel_gain_tR is of shape (Nt, K, Mc), and channel_gain_Rr is of shape
   (K, Nr, Mc), where Nt is the number of transmit antennas, K is the number of
   RIS elements, Nr is the number of receive antennas, and Mc is the number of
   channel realizations, then the cascaded channel gain is of shape (Nt, Nr,
   Mc). For SISO links, the cascaded channel gain is of shape (1, 1, Mc).

   :param tR_link: Link between the transmitter and the RIS.
   :param Rr_link: Link between the RIS and the receiver.
   :param style: Formula used to calculate the cascaded channel gain.
                 Possible values are 'sum' and 'matrix'.
   :param ele_idx: Index of the elements of RIS in channel gain matrix.

   :returns: Cascaded channel gain.


.. py:function:: effective_channel_gain(tr_link: Link, tR_link: Link, Rr_link: Link, style: str = 'sum', ele_idx: int = 0) -> NDArrayComplex

   Calculate the effective channel gain.

   The effective channel gain is the channel gain between the transceiver and
   the receiver through the RIS. Mathematically, the effective channel gain
   through the RIS is given by

   .. math::
       h_{eff}= h_{t,r} + \mathbf{h}_{R,r}^T \mathbf{R} \mathbf{h}_{t,R},

   where :math:`\mathbf{h}_{t,R}` is the channel gain between the transmitter
   and the RIS, :math:`\mathbf{h}_{R,r}` is the channel gain between the RIS
   and the receiver, :math:`\mathbf{R}` is the reflection matrix of the RIS,
   and :math:`h_{t,r}` is the channel gain between the transmitter and the
   receiver. The superscript :math:`T` denotes the transpose operator.

   :param tr: Direct link.
   :param tR: Link between the transmitter and the RIS.
   :param Rr: Link between the RIS and the receiver.
   :param style: Formula used to calculate the cascaded channel gain.
                 Possible values are 'sum' and 'matrix'.
   :param ele_idx: Index of the elements of RIS in channel gain matrix.

   :returns: Effective channel gain.


