# Path: pyphysim/channels/fading.py
#     _MATPLOTLIB_AVAILABLE = True
#     _MATPLOTLIB_AVAILABLE = False
# class TdlChannelProfile:
# class TdlImpulseResponse:
# class TdlChannel:
# class TdlMimoChannel(TdlChannel):
#     def __init__(self,
#                  tap_powers_dB: Optional[np.ndarray] = None,
#                  tap_delays: Optional[np.ndarray] = None,
#                  name: str = 'custom') -> None:
#     def mean_excess_delay(self) -> float:
#     def rms_delay_spread(self) -> float:
#     def name(self) -> str:
#     def tap_powers_dB(self) -> np.ndarray:
#     def tap_powers_linear(self) -> np.ndarray:
#     def tap_delays(self) -> np.ndarray:
#     def num_taps(self) -> int:
#     def num_taps_with_padding(self) -> int:
#     def Ts(self) -> Optional[float]:
#     def is_discretized(self) -> bool:
#     def get_discretize_profile(self, Ts: float) -> "TdlChannelProfile":
#     def _calc_discretized_tap_powers_and_delays(
#             self, Ts: float) -> Tuple[np.ndarray, np.ndarray]:
#     def __repr__(self) -> str:  # pragma: no cover
#     def __init__(self, tap_values: np.ndarray,
#                  channel_profile: TdlChannelProfile) -> None:
#     def tap_values_sparse(self) -> np.ndarray:
#     def tap_indexes_sparse(self) -> np.ndarray:
#     def Ts(self) -> Optional[float]:
#     def tap_delays_sparse(self) -> np.ndarray:
#     def tap_values(self) -> np.ndarray:
#     def num_samples(self) -> int:
#     def channel_profile(self) -> TdlChannelProfile:
#     def _get_samples_including_the_extra_zeros(self) -> np.ndarray:
#     def get_freq_response(self, fft_size: int) -> np.ndarray:
#     def __mul__(self, value: float) -> "TdlImpulseResponse":
#     def __rmul__(self, value: float) -> "TdlImpulseResponse":
#     def plot_impulse_response(self) -> None:  # pragma: no cover
#     def plot_frequency_response(self,
#                                 fft_size: int) -> None:  # pragma: no cover
#     def concatenate_samples(
#             impulse_responses: List["TdlImpulseResponse"]
#     ) -> "TdlImpulseResponse":
#     def __init__(self,
#                  fading_generator: FadingGenerator,
#                  channel_profile: Optional[TdlChannelProfile] = None,
#                  tap_powers_dB: Optional[np.ndarray] = None,
#                  tap_delays: Optional[np.ndarray] = None,
#                  Ts: Optional[float] = None) -> None:
#     def switched_direction(self) -> bool:
#     def switched_direction(self, value: bool) -> None:
#     def set_num_antennas(self, num_rx_antennas: int,
#                          num_tx_antennas: int) -> None:
#     def _set_fading_generator_shape(self, new_shape: Optional[Shape]) -> None:
#     def channel_profile(self) -> TdlChannelProfile:
#     def num_taps(self) -> int:
#     def num_taps_with_padding(self) -> int:
#     def generate_impulse_response(self, num_samples: int = 1) -> None:
#     def num_tx_antennas(self) -> int:
#     def num_rx_antennas(self) -> int:
#     def get_last_impulse_response(self) -> TdlImpulseResponse:
#     def __prepare_transmit_signal_shape(self,
#                                         signal: np.ndarray) -> np.ndarray:
#     def corrupt_data(self, signal: np.ndarray) -> np.ndarray:
#     def corrupt_data_in_freq_domain(
#             self,
#             signal: np.ndarray,
#             fft_size: int,
#             carrier_indexes: Optional[Indexes] = None) -> np.ndarray:
#     def __init__(self,
#                  fading_generator: FadingGenerator,
#                  channel_profile: Optional[TdlChannelProfile] = None,
#                  tap_powers_dB: Optional[np.ndarray] = None,
#                  tap_delays: Optional[np.ndarray] = None,
#                  Ts: Optional[float] = None) -> None:


import math
import numpy as np
from typing import Optional, Tuple
from ..channels import fading
        channel compensation.

        Parameters
        ----------
        data_reshaped : np.ndarray
            The data to be equalized. If must be a 2D numpy array, where
            different rows correspond to different OFDM symbols and the
            different columns correspond to the USED
            subcarriers.
            Dimension: `num OFDM symbols x num Used subcarriers`
        mean_freq_response : np.ndarray
            The frequency response for each OFDM symbol.
            Dimension: `num OFDM symbols x FFT size`

        Returns
        -------
        np.ndarray
            The received `data` after the one-tap equalization to
            compensate the channel effect.
            Dimension: `num OFDM symbols x num Used subcarriers`
        """
        used_subcarriers_idx = self._ofdm_obj.get_used_subcarrier_indexes()

        equalized_ofdm_demodulated_data = \
            data_reshaped / mean_freq_response[:, used_subcarriers_idx]

        return equalized_ofdm_demodulated_data

    def equalize_data(
            self, data: np.ndarray,

# Path: pyphysim/channels/fading.py
#     _MATPLOTLIB_AVAILABLE = True
#     _MATPLOTLIB_AVAILABLE = False
# class TdlChannelProfile:
# class TdlImpulseResponse:
# class TdlChannel:
# class TdlMimoChannel(TdlChannel):
#     def __init__(self,
#                  tap_powers_dB: Optional[np.ndarray] = None,
#                  tap_delays: Optional[np.ndarray] = None,
#                  name: str = 'custom') -> None:
#     def mean_excess_delay(self) -> float:
#     def rms_delay_spread(self) -> float:
#     def name(self) -> str:
#     def tap_powers_dB(self) -> np.ndarray:
#     def tap_powers_linear(self) -> np.ndarray:
#     def tap_delays(self) -> np.ndarray:
#     def num_taps(self) -> int:
#     def num_taps_with_padding(self) -> int:
#     def Ts(self) -> Optional[float]:
#     def is_discretized(self) -> bool:
#     def get_discretize_profile(self, Ts: float) -> "TdlChannelProfile":
#     def _calc_discretized_tap_powers_and_delays(
#             self, Ts: float) -> Tuple[np.ndarray, np.ndarray]:
#     def __repr__(self) -> str:  # pragma: no cover
#     def __init__(self, tap_values: np.ndarray,
#                  channel_profile: TdlChannelProfile) -> None:
#     def tap_values_sparse(self) -> np.ndarray:
#     def tap_indexes_sparse(self) -> np.ndarray:
#     def Ts(self) -> Optional[float]:
#     def tap_delays_sparse(self) -> np.ndarray:
#     def tap_values(self) -> np.ndarray:
#     def num_samples(self) -> int:
#     def channel_profile(self) -> TdlChannelProfile:
#     def _get_samples_including_the_extra_zeros(self) -> np.ndarray:
#     def get_freq_response(self, fft_size: int) -> np.ndarray:
#     def __mul__(self, value: float) -> "TdlImpulseResponse":
#     def __rmul__(self, value: float) -> "TdlImpulseResponse":
#     def plot_impulse_response(self) -> None:  # pragma: no cover
#     def plot_frequency_response(self,
#                                 fft_size: int) -> None:  # pragma: no cover
#     def concatenate_samples(
#             impulse_responses: List["TdlImpulseResponse"]
#     ) -> "TdlImpulseResponse":
#     def __init__(self,
#                  fading_generator: FadingGenerator,
#                  channel_profile: Optional[TdlChannelProfile] = None,
#                  tap_powers_dB: Optional[np.ndarray] = None,
#                  tap_delays: Optional[np.ndarray] = None,
#                  Ts: Optional[float] = None) -> None:
#     def switched_direction(self) -> bool:
#     def switched_direction(self, value: bool) -> None:
#     def set_num_antennas(self, num_rx_antennas: int,
#                          num_tx_antennas: int) -> None:
#     def _set_fading_generator_shape(self, new_shape: Optional[Shape]) -> None:
#     def channel_profile(self) -> TdlChannelProfile:
#     def num_taps(self) -> int:
#     def num_taps_with_padding(self) -> int:
#     def generate_impulse_response(self, num_samples: int = 1) -> None:
#     def num_tx_antennas(self) -> int:
#     def num_rx_antennas(self) -> int:
#     def get_last_impulse_response(self) -> TdlImpulseResponse:
#     def __prepare_transmit_signal_shape(self,
#                                         signal: np.ndarray) -> np.ndarray:
#     def corrupt_data(self, signal: np.ndarray) -> np.ndarray:
#     def corrupt_data_in_freq_domain(
#             self,
#             signal: np.ndarray,
#             fft_size: int,
#             carrier_indexes: Optional[Indexes] = None) -> np.ndarray:
#     def __init__(self,
#                  fading_generator: FadingGenerator,
#                  channel_profile: Optional[TdlChannelProfile] = None,
#                  tap_powers_dB: Optional[np.ndarray] = None,
#                  tap_delays: Optional[np.ndarray] = None,
#                  Ts: Optional[float] = None) -> None:


# Path: pyphysim/modulators/ofdm.py
import math
import numpy as np
from typing import Optional, Tuple
from ..channels import fading

        channel compensation.

        Parameters
        ----------
        data_reshaped : np.ndarray
            The data to be equalized. If must be a 2D numpy array, where
            different rows correspond to different OFDM symbols and the
            different columns correspond to the USED
            subcarriers.
            Dimension: `num OFDM symbols x num Used subcarriers`
        mean_freq_response : np.ndarray
            The frequency response for each OFDM symbol.
            Dimension: `num OFDM symbols x FFT size`

        Returns
        -------
        np.ndarray
            The received `data` after the one-tap equalization to
            compensate the channel effect.
            Dimension: `num OFDM symbols x num Used subcarriers`
        """
        used_subcarriers_idx = self._ofdm_obj.get_used_subcarrier_indexes()

        equalized_ofdm_demodulated_data = \
            data_reshaped / mean_freq_response[:, used_subcarriers_idx]

        return equalized_ofdm_demodulated_data

    def equalize_data(
            self, data: np.ndarray,

            impulse_response: fading.TdlImpulseResponse) -> np.ndarray: