Source code for hermespy.channel.ideal

# -*- coding: utf-8 -*-

from __future__ import annotations
from h5py import Group

import numpy as np

from hermespy.channel.channel import InterpolationMode
from hermespy.core import Device, ChannelStateInformation, ChannelStateFormat, Signal

from .channel import Channel, ChannelRealization

__author__ = "Jan Adler"
__copyright__ = "Copyright 2023, Barkhausen Institut gGmbH"
__credits__ = ["Andre Noll Barreto", "Tobias Kronauer", "Jan Adler"]
__license__ = "AGPLv3"
__version__ = "1.2.0"
__maintainer__ = "Jan Adler"
__email__ = "jan.adler@barkhauseninstitut.org"
__status__ = "Prototype"


[docs] class IdealChannelRealization(ChannelRealization): """Realization of an ideal channel. Generated by the :meth:`realize()<IdealChannel.realize>` routine of :class:`IdealChannels<IdealChannel>`. """
[docs] def state( self, transmitter: Device, receiver: Device, delay: float, sampling_rate: float, num_samples: int, num_taps: int, ) -> ChannelStateInformation: # MISO case if receiver.num_receive_antennas == 1: spatial_response = np.ones((1, transmitter.num_receive_antennas), dtype=np.complex_) # SIMO case elif transmitter.num_transmit_antennas == 1: spatial_response = np.ones((receiver.num_receive_antennas, 1), dtype=np.complex_) # MIMO case else: spatial_response = np.eye( receiver.num_receive_antennas, transmitter.num_transmit_antennas, dtype=np.complex_ ) # Scale response by channel gain spatial_response *= np.sqrt(self.gain) sampled_state = np.expand_dims( np.repeat(spatial_response[:, :, np.newaxis], num_samples, 2), axis=3 ) return ChannelStateInformation(ChannelStateFormat.IMPULSE_RESPONSE, sampled_state)
def _propagate( self, signal: Signal, transmitter: Device, receiver: Device, interpolation: InterpolationMode, ) -> Signal: # Single antenna transmitter case if transmitter.num_transmit_antennas == 1: propagated_samples = np.repeat( signal.samples[[0], :], receiver.num_receive_antennas, axis=0 ) # Single antenna receiver case elif receiver.num_receive_antennas == 1: propagated_samples = np.sum(signal.samples, axis=0, keepdims=True) # No receiving antenna case elif receiver.num_receive_antennas == 0: propagated_samples = np.empty((0, signal.num_samples), dtype=np.complex_) # MIMO case else: propagated_samples = signal.samples if transmitter.num_transmit_antennas < receiver.num_receive_antennas: propagated_samples = np.append( propagated_samples, np.zeros( ( receiver.num_receive_antennas - transmitter.num_transmit_antennas, signal.num_samples, ), dtype=np.complex_, ), axis=0, ) return Signal( propagated_samples, signal.sampling_rate, signal.carrier_frequency, signal.delay, signal.noise_power, )
[docs] class IdealChannel(Channel[IdealChannelRealization]): """An ideal distortion-less channel. Refer to :doc:`/api/channel.ideal` for further information. For MISO systems, the received signal is the addition of the signal transmitted at all antennas. For SIMO systems, the received signal is the signal transmitted at the single antenna. For MIMO systems, the received signal is the signal transmitted at all antennas. """ yaml_tag: str = "Channel" def _realize(self) -> IdealChannelRealization: return IdealChannelRealization(self.alpha_device, self.beta_device, self.gain)
[docs] def recall_realization(self, group: Group) -> IdealChannelRealization: return IdealChannelRealization.From_HDF(group, self.alpha_device, self.beta_device)