pyphysim.channels package¶
Submodules¶
pyphysim.channels.antennagain module¶
-
class
pyphysim.channels.antennagain.
AntGainBS3GPP25996
(number_of_sectors: int = 3)[source]¶ Bases:
pyphysim.channels.antennagain.AntGainBase
Class for antenna model defined by 3GPP in the 25996 norm for sectorized Base Stations.
The antenna gain (in dBi) will depend on the number of sectors of the Base Station.
NOTE: The antenna pattern here is targeted for diversity-oriented implementations (i.e. large inter-element spacings). For beamforming applications that require small spacings, alternative antenna designs may have to be considered leading to a different antenna pattern.
- Parameters
number_of_sectors (int) – The number of sectors of the base station. It can be either 3 or 6.
-
get_antenna_gain
(angle: NumberOrArray) → NumberOrArray[source]¶ Get the antenna gain for the given angle.
- Parameters
angle (float | np.ndarray) – Angle between the direction of interest and the boresight of the antenna. This can also be a numpy array with angles.
- Returns
The gain (in linear scale) for the provided angle.
- Return type
float | np.ndarray
-
class
pyphysim.channels.antennagain.
AntGainBase
[source]¶ Bases:
object
Base class for antenna models.
-
get_antenna_gain
(angle: NumberOrArray) → NumberOrArray[source]¶ Get the antenna gain for the given angle.
- Parameters
angle (float | np.ndarray) – Angle between the direction of interest and the boresight of the antenna. This can also be a numpy array with angles.
- Returns
The gain (in linear scale) for the provided angle.
- Return type
float | np.ndarray
-
-
class
pyphysim.channels.antennagain.
AntGainOmni
(ant_gain: Optional[float] = None)[source]¶ Bases:
pyphysim.channels.antennagain.AntGainBase
Class for Omnidirectional antenna gain model.
- Parameters
ant_gain (float, optional) – The antenna gain (in dBi). If not provided then 0dBi will be assumed.
-
get_antenna_gain
(angle: NumberOrArray) → NumberOrArray[source]¶ Get the antenna gain for the given angle.
- Parameters
angle (float | np.ndarray) – Angle between the direction of interest and the boresight of the antenna. This can also be a numpy array with angles.
- Returns
The gain (in linear scale) for the provided angle.
- Return type
float | np.ndarray
pyphysim.channels.fading module¶
-
class
pyphysim.channels.fading.
TdlChannel
(fading_generator: Union[pyphysim.channels.fading_generators.JakesSampleGenerator, pyphysim.channels.fading_generators.RayleighSampleGenerator], channel_profile: Optional[pyphysim.channels.fading.TdlChannelProfile] = None, tap_powers_dB: Optional[numpy.ndarray] = None, tap_delays: Optional[numpy.ndarray] = None, Ts: Optional[float] = None)[source]¶ Bases:
object
Tapped Delay Line channel model, which corresponds to a multipath channel.
You can create a new TdlChannel object either specifying the channel profile or specifying both the channel tap powers and delays.
- Parameters
fading_generator (FadingGenerator) – The instance of a fading generator in the fading_generators module. It should be a subclass of FadingSampleGenerator. The fading generator will be used to generate the channel samples. If the shape of the fading_generator is not None, then it must contain two positive integers, and a MIMO transmission will be employed, where the first integer in shape corresponds to the number of receive antennas while the second integer corresponds to the number of transmit antennas
channel_profile (TdlChannelProfile) – The channel profile, which specifies the tap powers and delays.
tap_powers_dB (np.ndarray) – The powers of each tap (in dB). Dimension: L x 1 Note: The power of each tap will be a negative number (in dB).
tap_delays (np.ndarray) – The delay of each tap (in seconds). Dimension: L x 1
-
_TdlChannel__prepare_transmit_signal_shape
(signal: numpy.ndarray) → numpy.ndarray¶ Helper method called in corrupt_data and corrupt_data_in_freq_domain methods to prepare the shape of transmit signal.
It there is only one transmit antenna but signal is 1D, then an extra dimension will be added to signal. Otherwise the signal will be just returned.
- Parameters
signal (np.ndarray) – The signal to be transmitted. This should be 1D for SISO systems (or SIMO systems) and 2D for MIMO systems.
- Returns
Either the same signal of signal with an added dimension.
- Return type
np.ndarray
-
_set_fading_generator_shape
(new_shape: Optional[Tuple[int, …]]) → None[source]¶ Set the shape of the fading generator.
-
property
channel_profile
¶ Return the channel profile.
- Returns
The channel profile.
- Return type
-
corrupt_data
(signal: numpy.ndarray) → numpy.ndarray[source]¶ Transmit the signal though the TDL channel.
- Parameters
signal (np.ndarray) – The signal to be transmitted. This should be 1D for SISO systems (or SIMO systems) and 2D for MIMO systems.
- Returns
The received signal after transmission through the TDL channel
- Return type
np.ndarray
-
corrupt_data_in_freq_domain
(signal: numpy.ndarray, fft_size: int, carrier_indexes: Optional[Union[numpy.ndarray, List[int], slice]] = None) → numpy.ndarray[source]¶ Transmit the signal through the TDL channel, but in the frequency domain.
This is ROUGHLY equivalent to modulating signal with OFDM using fft_size subcarriers, transmitting through a regular TdlChannel, and then demodulating with OFDM to recover the received signal.
One important difference is that here the channel is considered constant during the transmission of fft_size elements in signal, and then it is varied by the equivalent of the variation for that number of elements. That is, the channel is block static.
- Parameters
signal (np.ndarray) – The signal to be transmitted. This should be 1D for SISO systems (or SIMO systems) and 2D for MIMO systems.
fft_size (int) – The size of the Fourier transform to get the frequency response.
carrier_indexes (slice | np.ndarray | list[int]) – The indexes of the subcarriers where signal is to be transmitted. If it is None assume all subcarriers will be used. This can be a slice object or a numpy array of integers.
- Returns
The received signal after transmission through the TDL channel
- Return type
np.ndarray
-
generate_impulse_response
(num_samples: int = 1) → None[source]¶ Generate a new impulse response of all discretized taps (not including possible zero padding) for num_samples channel realizations.
NOTE: This method is automatically called in the corrupt_data and corrupt_data_in_freq_domain methods and you don’t need to call it befortransmitting data. After one of them has been called the generated impulse response can ge get with the get_last_impulse_response method.
The number of discretized taps of the generated impulse response will depend on the channel delay profile (the tap_delays passed during creation of the TdlChannel object) as well as on the sampling interval.
As an example, the COST259 TU channel profile has 20 different taps where the last one has a delay equal to 2.14 microseconds. If the sampling interval is configured as 3.25e-08 then the discretized channel will have more than 60 taps ( including the zeros padding), where only 15 taps are different from zero. These 15 taps are what is returned by this method.
Alternatively, with a sampling time of 1e-6 you will end up with only 3 discretized taps.
- Parameters
num_samples (int) – The number of samples to generate (for each tap).
-
get_last_impulse_response
() → pyphysim.channels.fading.TdlImpulseResponse[source]¶ Get the last generated impulse response.
A new impulse response is generated when the method corrupt_data is called. You can use the get_last_impulse_response method to get the impulse response used to corrupt the last data.
- Returns
The impulse response of the channel that was used to corrupt the last data.
- Return type
-
property
num_rx_antennas
¶ Get the number of receive antennas.
- Returns
The number of receive antennas.
- Return type
-
property
num_taps
¶ Number of taps not including zero taps after discretization.
- Returns
The number of taps (not including padding)
- Return type
-
property
num_taps_with_padding
¶ Number of taps including zero taps after discretization.
- Returns
The number of taps (including padding)
- Return type
-
property
num_tx_antennas
¶ Get the number of transmit antennas.
- Returns
The number of transmit antennas.
- Return type
-
class
pyphysim.channels.fading.
TdlChannelProfile
(tap_powers_dB: Optional[numpy.ndarray] = None, tap_delays: Optional[numpy.ndarray] = None, name: str = 'custom')[source]¶ Bases:
object
Channel Profile class.
This class is just a nice way to present known profiles from the norm or the literature, which are represented as instances of this class.
A TDL channel profile store information about the TDL taps. That is, it stores the power and delay of each tap. The power and delay of each tap can be accessed through the tap_powers_* and tap_delays properties.
Some profiles are defined as objects of this class, such as
COST259_TUx
,COST259_RAx
andCOST259_HTx
. These can be used when instantiating aTdlChannel
object.Note that the tap powers and delays are not necessarily discretized to some sampling interval.
- Parameters
tap_powers_dB (np.ndarray) – The tap powers (in dB). If both tap_powers_dB and tap_delays are None then a single tap with 0dB power will be assumed at delay 0.
tap_delays (np.ndarray) – The tap delays.
name (str) – A name for the channel profile
Examples
>>> jakes_generator = fading_generators.JakesSampleGenerator(Ts=3.25e-8) >>> tdlchannel = TdlChannel(jakes_generator, channel_profile=COST259_TUx)
-
property
Ts
¶ Get the sampling interval used for discretizing this channel profile object.
If it is not discretized then this returns None.
-
_calc_discretized_tap_powers_and_delays
(Ts: float) → Tuple[numpy.ndarray, numpy.ndarray][source]¶ Discretize the taps according to the sampling time.
The discretized taps will be equally spaced and the delta time from two taps corresponds to the sampling time.
- Parameters
Ts (float) – The sampling time.
- Returns
A tuple with the discretized powers and delays.
- Return type
np.ndarray, np.ndarray
-
get_discretize_profile
(Ts: float) → pyphysim.channels.fading.TdlChannelProfile[source]¶ Compute the discretized taps (power and delay) and return a new discretized TdlChannelProfile object.
The tap powers and delays of the returned TdlChannelProfile object correspond to the taps and delays of the TdlChannelProfile object used to call get_discretize_profile after discretizing with the sampling interval Ts.
- Parameters
Ts (float) – The sampling time for the discretization of the tap powers and delays.
- Returns
The discretized channel profile
- Return type
-
property
is_discretized
¶ Returns True if the channel profile is discretized
-
property
mean_excess_delay
¶ The mean excess delay is the first moment of the power delay profile and is defined to be
\[\overline{\tau} = \frac{\sum_k P(\tau_k)\tau_k}{\sum_k P(\tau_k)}\]- Returns
The mean excess delay.
- Return type
-
property
num_taps
¶ Get the number of taps in the profile.
- Returns
Number of taps before discretization (does not count possible padding).
- Return type
-
property
num_taps_with_padding
¶ Get the number of taps in the profile including zero-padding when the profile is discretized.
If the profile is not discretized an exception is raised.
- Returns
Number of taps after discretization (it counts possible any added padding).
- Return type
-
property
rms_delay_spread
¶ The RMS delay spread is the square root of the second central moment of the power delay profile. It is defined to be
\[\sigma_t = \sqrt{\overline{t^2} - \overline{\tau}^2}\]where
\[\overline{\tau^2}=\frac{\sum_k P(\tau_k)\tau_k^2}{\sum_k P(\tau_k)}\]Typically, when the symbol time period is greater than 10 times the RMS delay spread, no ISI equalizer is needed in the receiver.
- Returns
The RMS delay spread.
- Return type
-
property
tap_delays
¶ Get the tap delays.
- Returns
The tap delays.
- Return type
np.ndarray
-
property
tap_powers_dB
¶ Get the tap powers (in dB).
- Returns
The tap powers (in dB).
- Return type
np.ndarray
-
property
tap_powers_linear
¶ Get the tap powers (in linear scale).
- Returns
The tap powers (in linear scale).
- Return type
np.ndarray
-
class
pyphysim.channels.fading.
TdlImpulseResponse
(tap_values: numpy.ndarray, channel_profile: pyphysim.channels.fading.TdlChannelProfile)[source]¶ Bases:
object
Class that represents impulse response for a TdlChannel object.
This impulse response corresponds to the generated samples for one or more channel realization of the TdlChannel with the configured fading generator.
- Parameters
tap_values (np.ndarray) – The tap_values (not including zero padded taps) of a TDL channel generated for the non-zero taps. Dimension: Num sparse taps x SHAPE x num_samples. The value SHAPE here is the shape of the fading generator and corresponds to independent impulse responses. Often the shape of the used fading generator is None and thus the dimension of tap_values is just Num sparse taps x num_samples
channel_profile (TdlChannelProfile) – The channel profile that was considering to generate this impulse response.
-
property
Ts
¶ Return the sampling interval of this impulse response.
If the impulse response is not discretized this returns None.
- Returns
The sampling interval.
- Return type
-
_get_samples_including_the_extra_zeros
() → numpy.ndarray[source]¶ Return the samples including the zeros for the zero taps.
- Returns
samples_with_zeros – The samples including the extra delays containing zeros.
- Return type
np.ndarray
-
property
channel_profile
¶ Return the channel profile.
- Returns
The channel profile.
- Return type
-
static
concatenate_samples
(impulse_responses: List[TdlImpulseResponse]) → pyphysim.channels.fading.TdlImpulseResponse[source]¶ Concatenate multiple TdlImpulseResponse objects and return the new concatenated TdlImpulseResponse.
This concatenation is performed in the “samples” dimension.
- Parameters
impulse_responses (list[TdlImpulseResponse]) – A list of TdlImpulseResponse objects to be concatenated.
- Returns
The new concatenated TdlImpulseResponse.
- Return type
-
get_freq_response
(fft_size: int) → numpy.ndarray[source]¶ Get the frequency response for this impulse response.
- Parameters
fft_size (int) – The size of the FFT to be applied.
- Returns
The frequency response. Dimension: fft_size x num_samples for SISO impulse response or fft_size x num_rx x num_tx x num_samples for MIMO impulse response.
- Return type
np.ndarray
-
property
num_samples
¶ Get the number of samples (different, “neighbor” impulse responses) stored here.
- Returns
The number of samples in the TdlImpulseResponse object.
- Return type
-
plot_frequency_response
(fft_size: int) → None[source]¶ Plot the frequency response.
- Parameters
fft_size (int) – The size of the FFT to be applied.
-
property
tap_delays_sparse
¶ Return the tap delays (which are multiples of the sampling interval).
- Returns
The tap delays.
- Return type
np.ndarray
-
property
tap_indexes_sparse
¶ Return the (sparse) tap indexes.
- Returns
- Return type
The indexes of the non-zero taps.
-
property
tap_values
¶ Return the tap values (including zero padding) as a numpy array.
- Returns
The tap values (including zero padding).
- Return type
np.ndarray
-
property
tap_values_sparse
¶ Return the tap values (not including zero padding) as a numpy array.
- Returns
The tap values (not including possible zero padding).
- Return type
np.ndarray
-
class
pyphysim.channels.fading.
TdlMimoChannel
(fading_generator: Union[pyphysim.channels.fading_generators.JakesSampleGenerator, pyphysim.channels.fading_generators.RayleighSampleGenerator], channel_profile: Optional[pyphysim.channels.fading.TdlChannelProfile] = None, tap_powers_dB: Optional[numpy.ndarray] = None, tap_delays: Optional[numpy.ndarray] = None, Ts: Optional[float] = None)[source]¶ Bases:
pyphysim.channels.fading.TdlChannel
Tapped Delay Line channel model, which corresponds to a multipath channel.
You can create a new TdlMimoChannel object either specifying the channel profile or specifying both the channel tap powers and delays.
Note that the TdlChannel class can already work with multiple antennas if provided fading_generator has a shape with two elements (number of receive antennas and number of transmit antennas). The TdlMimoChannel only adds a slight better interface over TdlChannel class for working with MIMO. This class is also useful to test MIMO transmission, with the added num_tx_antennas and num_rx_antennas properties.
- Parameters
fading_generator (FadingGenerator) – The instance of a fading generator in the fading_generators module. It should be a subclass of FadingSampleGenerator. The fading generator will be used to generate the channel samples. The shape of the fading_generator will be ignored and replaced by provided number of antennas.
channel_profile (TdlChannelProfile) – The channel profile, which specifies the tap powers and delays.
tap_powers_dB (np.ndarray) – The powers of each tap (in dB). Dimension: L x 1 Note: The power of each tap will be a negative number (in dB).
tap_delays (np.ndarray) – The delay of each tap (in seconds). Dimension: L x 1
pyphysim.channels.fading_generators module¶
-
class
pyphysim.channels.fading_generators.
FadingSampleGenerator
(shape: Optional[Union[int, Tuple[int, …]]] = None)[source]¶ Bases:
object
Base class for fading generators.
- Parameters
shape (tuple[int] | int, optional) – The shape of the sample generator. Each time generate_more_samples(num_samples) method is called it will generate samples with this shape as the first dimensions.
-
generate_more_samples
(num_samples: Optional[int] = None) → None[source]¶ Generate next samples.
When implementing this method in a subclass you must take the value of the self._shape attribute into account.
- Parameters
num_samples (int, optional) – Number of samples (with the provided shape) to generate. If not provided it will be assumed to be 1.
-
get_samples
() → numpy.ndarray[source]¶ Get the last generated sample.
- Returns
- Return type
np.ndarray
-
get_similar_fading_generator
() → Any[source]¶ Get a similar fading generator with the same configuration, but that generates independent samples.
-
property
shape
¶ Get the shape of the sampling generator
This is the shape of the samples that will be generated (not including num_samples).
-
skip_samples_for_next_generation
(num_samples: int) → None[source]¶ Advance sample generation process by num_samples similarly to what would happen if you call generate_more_samples( num_samples=num_samples), but without actually generating the samples.
- Parameters
num_samples (int) – How many samples to skip.
-
class
pyphysim.channels.fading_generators.
JakesSampleGenerator
(Fd: float = 100, Ts: float = 0.001, L: int = 8, shape: Optional[Union[int, Tuple[int, …]]] = None, RS: Optional[numpy.random.mtrand.RandomState] = None)[source]¶ Bases:
pyphysim.channels.fading_generators.FadingSampleGenerator
Class that generated fading samples according to the Jakes model given by
\[h(t) = \frac{1}{\sqrt{L}}\sum_{l=0}^{L-1}\exp\{j[2\pi f_D \cos(\phi_l)t+\psi_l]\}\]- Parameters
Fd (float) – The Doppler frequency (in Hertz).
Ts (float) – The sample interval (in seconds).
L (int) – The number of rays for the Jakes model.
shape (int | tuple[int], optional) – The shape of the sample generator. Each time the generate_jakes_samples method is called it will generate samples with this shape. If not provided, then 1 will be assumed. This could be used to generate MIMO channels. For instance, in order to generate channels samples for a MIMO scenario with 3 receive antennas and 2 transmit antennas use a shape of (3, 2).
RS (np.random.RandomState) – The RandomState object used to generate the random values. If not provided, the global RandomState in numpy will be used.
See also
-
property
Fd
¶ The Doppler frequency (in Hertz)
-
property
L
¶ The number of rays for the Jakes model
-
property
Ts
¶ The sample interval (in seconds)
-
_generate_time_samples
(num_samples: Optional[int] = None) → numpy.ndarray[source]¶ Generate the time samples that will be used internally in generate_more_samples method.
- Parameters
num_samples (int, optional) – Number of samples to be generated.
- Returns
The numpy array with the time samples. The shape of the generated time variable is “(1, A, num_samples)”, where ‘A’ has as many ‘1’s as the length of self._shape. Ex: If self._shape is None then the shape of the returned ‘t’ variable is (1, num_samples). If self._shape is (2,3) then the shape of the returned ‘t’ variable is (1, 1, 1, num_samples)
- Return type
np.ndarray
Notes
Each time _generate_time_samples is called it will update _current_time to reflect the advance of the time after generating the new samples.
-
_set_phi_and_psi_according_to_shape
() → None[source]¶ This will update the phi and psi attributes used to generate the jakes samples to reflect the current value of self._shape.
-
generate_more_samples
(num_samples: Optional[int] = None) → None[source]¶ Generate next samples.
Note that any subsequent call to this method continues from the point where the last call stopped. That is, if you generate 10 samples and then 15 more samples, you will get the same samples you would have got if you had generated 25 samples.
- Parameters
num_samples (int, optional) – Number of samples (with the provided shape) to generate. If not provided it will be assumed to be 1.
Notes
This method will update the self._current_time variable.
-
get_similar_fading_generator
() → Any[source]¶ Get a similar fading generator with the same configuration, but that generates independent samples.
- Returns
Another JakesSampleGenerator object with the same configuration of this object.
- Return type
-
property
shape
¶ Get the shape of the sampling generator
This is the shape of the samples that will be generated (not including num_samples).
-
skip_samples_for_next_generation
(num_samples: int) → None[source]¶ Advance sample generation process by num_samples similarly to what would happen if you call generate_more_samples( num_samples=num_samples), but without actually generating the samples.
This has the effect of advancing the internal time using by JakesSampleGenerator without generating any samples.
- Parameters
num_samples (int) – How many samples to skip.
-
class
pyphysim.channels.fading_generators.
RayleighSampleGenerator
(shape: Optional[Union[int, Tuple[int, …]]] = None)[source]¶ Bases:
pyphysim.channels.fading_generators.FadingSampleGenerator
Class that generates fading samples from a Raleigh distribution.
- Parameters
shape (int | tuple[int] | None) – The shape of the sample generator. Each time the generate_jakes_samples method is called it will generate samples with this shape. If not provided, then 1 will be assumed.
-
generate_more_samples
(num_samples: Optional[int] = None) → None[source]¶ Generate next samples.
- Parameters
num_samples (int, optional) – Number of samples (with the provided shape) to generate. If not provided it will be assumed to be 1.
-
get_similar_fading_generator
() → Any[source]¶ Get a similar fading generator with the same configuration, but that generates independent samples.
- Returns
Another RayleighSampleGenerator object with the same configuration of this object.
- Return type
-
skip_samples_for_next_generation
(num_samples: int) → None[source]¶ Advance sample generation process by num_samples similarly to what would happen if you call generate_more_samples( num_samples=num_samples), but without actually generating the samples.
Since the samples generated by RayleighSampleGenerator are independent, calling this method has no effect.
- Parameters
num_samples (int) – How many samples to skip. This is ignored in the RayleighSampleGenerator. Since the different samples are uncorrelated then calling skip_samples_for_next_generation does not do anything.
-
pyphysim.channels.fading_generators.
generate_jakes_samples
(Fd: float, Ts: float = 0.001, NSamples: int = 100, L: int = 8, shape: Optional[Tuple[int, …]] = None, current_time: float = 0, phi_l: Optional[numpy.ndarray] = None, psi_l: Optional[numpy.ndarray] = None) → Tuple[float, numpy.ndarray][source]¶ Generates channel samples according to the Jakes model.
This functions generates channel samples for a single tap according to the Jakes model given by
(1)¶\[h(t) = \frac{1}{\sqrt{L}}\sum_{l=0}^{L-1}\exp\{j[2\pi f_D \cos(\phi_l)t+\psi_l]\}\]- Parameters
Fd (float) – The Doppler frequency (in Hertz).
Ts (float) – The sample interval (in seconds).
NSamples (int) – The number of samples to generate.
L (int) – The number of rays for the Jakes model.
shape (tuple[int]) – The shape of the generated channel. This is used to generate MIMO channels. For instance, in order to generate channels samples for a MIMO scenario with 3 receive antennas and 2 transmit antennas use a shape of (3, 2).
current_time (float) – The current start time
phi_l (np.ndarray) – The “phi” part in Jakes model
psi_l (np.ndarray) – The “psi” part in Jakes model
- Returns
The first element in the returned tuple is the new current time (that should be used the next time this function is called to ‘continue’ the fading).
The second element in the returned tuple is the generated channel. If shape is None the the shape of the returned h is equal to ( NSamples,). That is, h is a 1-dimensional numpy array. If shape was provided then the shape of h is the provided shape with an additional dimension for the time (the last dimension). For instance, if a shape of (3, 2) was provided then the shape of the returned h will be (3, 2, NSamples).
- Return type
(float, np.ndarray)
pyphysim.channels.multiuser module¶
Module containing multiuser channels.
The MultiUserChannelMatrix
and
MultiUserChannelMatrixExtInt
classes implement the MIMO
Interference Channel (MIMO-IC) model, where the first one does not include
an external interference source while the last one includes it. The MIMO-IC
model is shown in the Figure below.
-
class
pyphysim.channels.multiuser.
MuChannel
(N: Union[int, Tuple[int, int]], fading_generator: Optional[Union[pyphysim.channels.fading_generators.JakesSampleGenerator, pyphysim.channels.fading_generators.RayleighSampleGenerator]] = None, channel_profile: Optional[pyphysim.channels.fading.TdlChannelProfile] = None, tap_powers_dB: Optional[numpy.ndarray] = None, tap_delays: Optional[numpy.ndarray] = None, Ts: Optional[float] = None)[source]¶ Bases:
object
SISO multiuser channel.
Each transmitter sends data to its own receiver while interfering to other receivers.
Note that noise is NOT added.
- Parameters
N (int | tuple[int,int]) – The number of transmit/receive pairs.
fading_generator (T <= fading_generators.FadingSampleGenerator) – The instance of a fading generator in the fading_generators module. It should be a subclass of FadingSampleGenerator. The fading generator will be used to generate the channel samples. However, since we have multiple links, the provided fading generator will actually be used to create similar (but independent) fading generators. If not provided then RayleighSampleGenerator will be used
channel_profile (TdlChannelProfile) – The channel profile, which specifies the tap powers and delays.
tap_powers_dB (np.ndarray) – The powers of each tap (in dB). Dimension: L x 1 Note: The power of each tap will be a negative number (in dB).
tap_delays (np.ndarray) – The delay of each tap (in seconds). Dimension: L x 1
- Returns
The created object.
- Return type
-
property
channel_profile
¶ Return the channel profile.
- Returns
The channel profile.
- Return type
-
corrupt_data
(signal: numpy.ndarray) → numpy.ndarray[source]¶ Corrupt data passed through the TDL channels of each link.
Note that noise is NOT added in corrupt_data.
- Parameters
signal (np.ndarray) – Signal to be transmitted through the channel. This should be a 2D numpy array (1D array if there is only one transmitter), where each row corresponds to the transmit data of one transmitter.
- Returns
Received signal at each receiver. Each row corresponds to one receiver.
- Return type
np.ndarray
-
corrupt_data_in_freq_domain
(signal: numpy.ndarray, fft_size: int, carrier_indexes: Union[numpy.ndarray, List[int], slice] = None) → numpy.ndarray[source]¶ Corrupt data passed through the TDL channels of each link, but in the frequency domain..
For each link, this is ROUGHLY equivalent to modulating signal with OFDM using fft_size subcarriers, transmitting through a regular TdlChannel, and then demodulating with OFDM to recover the received signal.
One important difference is that here the channel is considered constant during the transmission of fft_size elements in signal, and then it is varied by the equivalent of the variation for that number of elements. That is, the channel is block static.
Note that noise is NOT added in corrupt_data.
- Parameters
signal (np.ndarray | list[np.ndarray]) – Signal to be transmitted through the channel. This should be a 2D numpy array where each row corresponds to the transmit data of one transmitter. It can also be a list of numpy arrays or, if there is only one transmitter, a single 1D numpy array.
fft_size (int) – The size of the Fourier transform to get the frequency response.
carrier_indexes (slice | np.ndarray | list[int]) – The indexes of the subcarriers where signal is to be transmitted (all users will use the same indexes). If it is None assume all subcarriers will be used.
- Returns
Received signal at each receiver. Each row corresponds to one receiver.
- Return type
np.ndarray
-
get_last_impulse_response
(rx_idx: int, tx_idx: int) → pyphysim.channels.fading.TdlImpulseResponse[source]¶ Get the last generated impulse response.
A new impulse response is generated when the method corrupt_data is called. You can use the get_last_impulse_response method to get the impulse response used to corrupt the last data.
- Parameters
- Returns
The impulse response of the channel that was used to corrupt the last data for the link from transmitter tx_idx to receiver rx_idx.
- Return type
-
property
num_rx_antennas
¶ Get the number of receive antennas.
- Returns
The number of receive antennas.
- Return type
-
property
num_taps
¶ Get the number of taps in the profile.
Note that all links have the same channel profile.
- Returns
The number of taps in the channel (not including any zero padding).
- Return type
-
property
num_taps_with_padding
¶ Get the number of taps in the profile including zero-padding when the profile is discretized.
If the profile is not discretized an exception is raised.
Note that all links have the same channel profile.
- Returns
The number of taps in the channel (including any zero padding).
- Return type
-
property
num_tx_antennas
¶ Get the number of transmit antennas.
- Returns
The number of transmit antennas.
- Return type
np.ndarray
-
property
pathloss_matrix
¶ Get the matrix with the pathloss from each transmitter to each receiver.
- Returns
The pathloss matrix, if it was set, or None if there is no pathloss.
- Return type
np.ndarray
-
set_pathloss
(pathloss_matrix: numpy.ndarray) → None[source]¶ Set the path loss (IN LINEAR SCALE) from each transmitter to each receiver.
The path loss will be accounted when calling the corrupt_data method.
If you want to disable the path loss, set pathloss_matrix to None.
- Parameters
pathloss_matrix (np.ndarray) – A matrix with dimension “K x K”, where K is the number of users, with the path loss (IN LINEAR SCALE) from each transmitter (columns) to each receiver (rows). If you want to disable the path loss then set it to None.
Notes
Note that path loss is a power relation, which means that the channel coefficients will be multiplied by the square root of elements in pathloss_matrix.
-
class
pyphysim.channels.multiuser.
MuMimoChannel
(N: Union[int, Tuple[int, int]], num_rx_antennas: int, num_tx_antennas: int, fading_generator: Optional[Union[pyphysim.channels.fading_generators.JakesSampleGenerator, pyphysim.channels.fading_generators.RayleighSampleGenerator]] = None, channel_profile: Optional[pyphysim.channels.fading.TdlChannelProfile] = None, tap_powers_dB: Optional[numpy.ndarray] = None, tap_delays: Optional[numpy.ndarray] = None, Ts: Optional[float] = None)[source]¶ Bases:
pyphysim.channels.multiuser.MuChannel
MIMO multiuser channel.
Each transmitter sends data to its own receiver while interfering to other receivers.
Note that noise is NOT added.
- Parameters
N (int | tuple[int, int]) – The number of transmit/receive pairs.
num_rx_antennas (int) – Number of receive antennas of each user.
num_tx_antennas (int) – Number of transmit antennas of each user.
fading_generator (T <= fading_generators.FadingSampleGenerator) – The instance of a fading generator in the fading_generators module. It should be a subclass of FadingSampleGenerator. The fading generator will be used to generate the channel samples. However, since we have multiple links, the provided fading generator will actually be used to create similar (but independent) fading generators. If not provided then RayleighSampleGenerator will be used
channel_profile (TdlChannelProfile) – The channel profile, which specifies the tap powers and delays.
tap_powers_dB (np.ndarray) – The powers of each tap (in dB). Dimension: L x 1 Note: The power of each tap will be a negative number (in dB).
tap_delays (np.ndarray) – The delay of each tap (in seconds). Dimension: L x 1
-
class
pyphysim.channels.multiuser.
MultiUserChannelMatrix
[source]¶ Bases:
object
Stores the (fast fading) channel matrix of a multi-user scenario. The path-loss from each transmitter to each receiver is also be accounted if the set_pathloss is called to set the path-loss matrix.
This channel matrix can be seem as an concatenation of blocks (of non-uniform size) where each block is a channel from one transmitter to one receiver and the block size is equal to the number of receive antennas of the receiver times the number of transmit antennas of the transmitter.
For instance, in a 3-users scenario the block (1,0) corresponds to the channel between the transmit antennas of user 0 and the receive antennas of user 1 (indexing staring at zero). If the number of receive antennas and transmit antennas of the three users are [2, 4, 6] and [2, 3, 5], respectively, then the block (1,0) would have a dimension of 4x2. Likewise, the channel matrix would look similar to the block structure below.
2 x 2
2 x 3
2 x 5
4 x 2
4 x 3
4 x 5
6 x 2
6 x 3
6 x 5
It is possible to initialize the channel matrix randomly by calling the randomize method, or from a given matrix by calling the init_from_channel_matrix method.
In order to get the channel matrix of a specific user k to another user l, call the get_Hkl method.
-
property
H
¶ Get method for the H property.
- Returns
The channel from all transmitters to all receivers. This is a numpy array of numpy arrays.
- Return type
np.ndarray
-
property
K
¶ Get method for the K property.
- Returns
The number of users (transmit-receive pairs).
- Return type
-
property
Nr
¶ Get method for the Nr property.
- Returns
The number of receive antennas of all users.
- Return type
np.ndarray
-
property
Nt
¶ Get method for the Nt property.
- Returns
The number of transmit antennas of all users.
- Return type
np.ndarray
-
property
W
¶ Post processing filters (a list of 2D numpy arrays) for each user.
- Returns
The Post processing filters for each user.
- Return type
list[np.ndarray]
-
_calc_Bkl_cov_matrix_all_l
(F_all_users: numpy.ndarray, k: int, N0_or_Rek: NumberOrArray = 0.0) → numpy.ndarray[source]¶ Calculates the interference-plus-noise covariance matrix for all streams at receiver \(k\) according to equation (28) in [ Cadambe2008]_.
The interference-plus-noise covariance matrix for stream \(l\) of user \(k\) is given by Equation (28) in [Cadambe2008], which is reproduced below
\(\mtB^{[kl]} = \sum_{j=1}^{K} \frac{P^{[j]}}{d^{[j]}} \sum_{d=1}^{d^{[j]}} \mtH^{[kj]}\mtV_{\star l}^{[j]} \mtV_{\star l}^{[j]\dagger} \mtH^{[kj]\dagger} - \frac{P^{[k]}}{d^{[k]}} \mtH^{[kk]} \mtV_{\star l}^{[k]} \mtV_{\star l}^{[k]\dagger} \mtH^{[kk]\dagger} + \mtI_{N^{[k]}}\)
where \(P^{[k]}\) is the transmit power of transmitter \(k\), \(d^{[k]}\) is the number of degrees of freedom of user \(k\), \(\mtH^{[kj]}\) is the channel between transmitter \(j\) and receiver \(k\), \(\mtV_{\star l}\) is the \(l\)-th column of the precoder of user \(k\) and \(\mtI_{N^{k}}\) is an identity matrix with size equal to the number of receive antennas of receiver \(k\).
- Parameters
F_all_users (list[np.ndarray] | np.ndarray) – The precoder of all users (already taking into account the transmit power). This can be a list of numpy arrays or a 1D numpy array of numpy arrays.
k (int) – Index of the desired user.
N0_or_Rek (float | np.ndarray) – If this is a 2D numpy array, it is interpreted as the covariance matrix of any external interference plus noise. If this is a number, it is interpreted as the noise power, in which case the covariance matrix will be an identity matrix times this noise power.
- Returns
Bkl – Covariance matrix of all streams of user k. Each element of the returned 1D numpy array is a 2D numpy complex array corresponding to the covariance matrix of one stream of user k.
- Return type
np.ndarray
Notes
To be simple, a function that returns the covariance matrix of only a single stream “l” of the desired user “k” could be implemented, but in the order to calculate the max SINR algorithm we need the covariance matrix of all streams and returning them in single function as is done here allows us to calculate the first part in equation (28) of [Cadambe2008] only once, since it is the same for all streams.
-
_calc_Bkl_cov_matrix_first_part
(F_all_users: numpy.ndarray, k: int, N0_or_Rek: NumberOrArray = 0.0) → numpy.ndarray[source]¶ Calculates the first part in the equation of the Blk covariance matrix in equation (28) of [Cadambe2008].
The first part is given by
\(\sum_{j=1}^{K} \frac{P^{[j]}}{d^{[j]}} \sum_{d=1}^{d^{[j]}} \mtH^{[kj]}\mtV_{\star d}^{[j]} \mtV_{\star d}^{[j]\dagger} \mtH^{[kj]\dagger} + \mtI_{Nk}\)
Note that it only depends on the value of \(k\).
- Parameters
F_all_users (list[np.ndarray] | np.ndarray) – The precoder of all users (already taking into account the transmit power). It can be a list of numpy arrays or a numpy array of numpy arrays.
k (int) – Index of the desired user.
N0_or_Rek (float | np.ndarray) – If this is a 2D numpy array, it is interpreted as the covariance matrix of any external interference plus noise. If this is a number, it is interpreted as the noise power, in which case the covariance matrix will be an identity matrix times this noise power.
- Returns
first_part
- Return type
np.ndarray
-
_calc_Bkl_cov_matrix_second_part
(Fk: numpy.ndarray, k: int, l: int) → numpy.ndarray[source]¶ Calculates the second part in the equation of the Blk covariance matrix in equation (28) of [Cadambe2008] (note that it does not include the identity matrix).
The second part is given by
\(\frac{P^{[k]}}{d^{[k]}} \mtH^{[kk]} \mtV_{\star l}^{[k]} \mtV_{\star l}^{[k]\dagger} \mtH^{[kk]\dagger}\)
- Parameters
- Returns
second_part – Second part in equation (28) of [Cadambe2008].
- Return type
np.ndarray
-
_calc_JP_Bkl_cov_matrix_all_l
(F_all_users: numpy.ndarray, k: int, N0_or_Rek: NumberOrArray = 0.0) → numpy.ndarray[source]¶ Calculates the interference-plus-noise covariance matrix for all streams at receiver \(k\) according to equation (28) in [ Cadambe2008]_.
The interference-plus-noise covariance matrix for stream \(l\) of user \(k\) is given by Equation (28) in [Cadambe2008], which is reproduced below
\(\mtB^{[kl]} = \sum_{j=1}^{K} \frac{P^{[j]}}{d^{[j]}} \sum_{d=1}^{d^{[j]}} \mtH^{[kj]}\mtV_{\star l}^{[j]} \mtV_{\star l}^{[j]\dagger} \mtH^{[kj]\dagger} - \frac{P^{[k]}}{d^{[k]}} \mtH^{[kk]} \mtV_{\star l}^{[k]} \mtV_{\star l}^{[k]\dagger} \mtH^{[kk]\dagger} + \mtI_{N^{[k]}}\)
where \(P^{[k]}\) is the transmit power of transmitter \(k\), \(d^{[k]}\) is the number of degrees of freedom of user \(k\), \(\mtH^{[kj]}\) is the channel between transmitter \(j\) and receiver \(k\), \(\mtV_{\star l}\) is the \(l\)-th column of the precoder of user \(k\) and \(\mtI_{N^{k}}\) is an identity matrix with size equal to the number of receive antennas of receiver \(k\).
- Parameters
F_all_users (list[np.ndarray] | np.ndarray) – The precoder of all users (already taking into account the transmit power). This can be either a 1D numpy array of numpy arrays or a list of numpy arrays.
k (int) – Index of the desired user.
N0_or_Rek (float | np.ndarray) – If this is a 2D numpy array, it is interpreted as the covariance matrix of any external interference plus noise. If this is a number, it is interpreted as the noise power, in which case the covariance matrix will be an identity matrix times this noise power.
- Returns
Bkl – Covariance matrix of all streams of user k. Each element of the returned 1D numpy array is a 2D numpy complex array corresponding to the covariance matrix of one stream of user k.
- Return type
np.ndarray
Notes
To be simple, a function that returns the covariance matrix of only a single stream “l” of the desired user “k” could be implemented, but in the order to calculate the max SINR algorithm we need the covariance matrix of all streams and returning them in single function as is done here allows us to calculate the first part in equation (28) of [Cadambe2008] only once, since it is the same for all streams.
-
_calc_JP_Bkl_cov_matrix_first_part
(F_all_users: numpy.ndarray, k: int, noise_power: float = 0.0) → numpy.ndarray[source]¶ Calculates the first part in the equation of the Blk covariance matrix in equation (28) of [Cadambe2008] when joint process is employed.
The first part is given by
\(\sum_{j=1}^{K} \frac{P^{[j]}}{d^{[j]}} \sum_{d=1}^{d^{[j]}} \mtH^{[kj]}\mtV_{\star d}^{[j]} \mtV_{\star d}^{[j]\dagger} \mtH^{[kj]\dagger} + \mtI_{Nk}\)
Note that it only depends on the value of \(k\).
- Parameters
- Returns
- Return type
np.ndarray
-
_calc_JP_Bkl_cov_matrix_first_part_impl
(Hk: numpy.ndarray, F_all_users: numpy.ndarray, Rek: NumberOrArray) → numpy.ndarray[source]¶ Common implementation of the _calc_JP_Bkl_cov_matrix_first_part.
- Parameters
Hk (np.ndarray) – The channel from all transmitters (not including external interference source, if any) to receiver k.
F_all_users (list[np.ndarray]) – The precoder of all users (already taking into account the transmit power).
Rek (np.ndarray | float) – Covariance matrix of the external interference (if there is any) plus noise.
- Returns
The first_part for the Bkl matrix computation.
- Return type
np.ndarray
-
_calc_JP_Bkl_cov_matrix_second_part
(Fk: numpy.ndarray, k: int, l: int) → numpy.ndarray[source]¶ Calculates the second part in the equation of the Blk covariance matrix in equation (28) of [Cadambe2008] (note that it does not include the identity matrix).
The second part is given by
\(\frac{P^{[k]}}{d^{[k]}} \mtH^{[kk]} \mtV_{\star l}^{[k]} \mtV_{\star l}^{[k]\dagger} \mtH^{[kk]\dagger}\)
- Parameters
- Returns
second_part – Second part in equation (28) of [Cadambe2008].
- Return type
np.ndarray.
-
static
_calc_JP_Bkl_cov_matrix_second_part_impl
(Hk: numpy.ndarray, Fk: numpy.ndarray, l: int) → numpy.ndarray[source]¶ Common implementation of the _calc_JP_Bkl_cov_matrix_second_part method.
- Parameters
Hk (np.ndarray) –
Fk (np.ndarray) –
l (int) –
- Returns
- Return type
np.ndarray
-
_calc_JP_Q_impl
(k: int, F_all_users: numpy.ndarray) → numpy.ndarray[source]¶ Calculates the interference covariance matrix (without any noise) at the \(k\)-th receiver with a joint processing scheme.
See the documentation of the calc_JP_Q method.
-
_calc_JP_SINR_k
(k: int, Fk: numpy.ndarray, Uk: numpy.ndarray, Bkl_all_l: numpy.ndarray) → numpy.ndarray[source]¶ Calculates the SINR of all streams of user ‘k’.
- Parameters
k (int) – Index of the desired user.
Fk (np.ndarray) – The precoder of user k.
Uk (np.ndarray) – The receive filter of user k (before applying the conjugate transpose).
Bkl_all_l (list[np.ndarray] | np.ndarray) – A sequence (1D numpy array, a list, etc) of 2D numpy arrays corresponding to the Bkl matrices for all ‘l’s.
- Returns
SINR_k – The SINR for the different streams of user k.
- Return type
np.ndarray
-
static
_calc_JP_SINR_k_impl
(Hk: numpy.ndarray, Fk: numpy.ndarray, Uk: numpy.ndarray, Bkl_all_l: numpy.ndarray) → numpy.ndarray[source]¶ Implementation of the
_calc_JP_SINR_k()
method.- Parameters
Hk (np.ndarray) – Channel from all transmitters to receiver k.
Fk (np.ndarray) – The precoder of user k.
Uk (np.ndarray) – The receive filter of user k (before applying the conjugate transpose).
Bkl_all_l (list[np.ndarray]) – A sequence (1D numpy array, a list, etc) of 2D numpy arrays corresponding to the Bkl matrices for all ‘l’s.
- Returns
SINR_k – The SINR for the different streams of user k.
- Return type
np.ndarray
Notes
The implementation of the _calc_JP_SINR_k method is almost the same for the MultiuserChannelMatrix and MultiuserChannelMatrixExtint class, except for the Hk argument. Therefore, the common code was put here and in each class the
_calc_JP_SINR_k()
is implemented as simply getting the correct Hk argument and then calling_calc_JP_SINR_k_impl()
.
-
_calc_Q_impl
(k: int, F_all_users: numpy.ndarray) → numpy.ndarray[source]¶ Calculates the interference covariance matrix (without any noise) at the \(k\)-th receiver.
See the documentation of the calc_Q method.
- Parameters
k (int) – Index of the desired receiver.
F_all_users (np.ndarray) – The precoder of all users (already taking into account the transmit power). This should be a 1D numpy array of 2D numpy arrays.
- Returns
- Return type
np.ndarray
-
_calc_SINR_k
(k: int, Fk: numpy.ndarray, Uk: numpy.ndarray, Bkl_all_l: numpy.ndarray) → numpy.ndarray[source]¶ Calculates the SINR of all streams of user ‘k’.
- Parameters
k (int) – Index of the desired user.
Fk (np.ndarray) – The precoder of user k.
Uk (np.ndarray) – The receive filter of user k (before applying the conjugate transpose).
Bkl_all_l (list[np.ndarray] | np.ndarray) – A sequence (1D numpy array, a list, etc) of 2D numpy arrays corresponding to the Bkl matrices for all ‘l’s.
- Returns
SINR_k – The SINR for the different streams of user k.
- Return type
np.ndarray
-
static
_from_small_matrix_to_big_matrix
(small_matrix: numpy.ndarray, Nr: numpy.ndarray, Nt: numpy.ndarray, Kr: int, Kt: Optional[int] = None) → numpy.ndarray[source]¶ Convert from a small matrix to a big matrix by repeating elements according to the number of receive and transmit antennas.
- Parameters
small_matrix (np.ndarray) – Any 2D numpy array
Nr (np.ndarray) – Number of antennas at each receiver. This should be a 1D numpy array.
Nt (np.ndarray) – Number of antennas at each transmitter. This should be a 1D numpy array.
Kr (int) – Number of receivers to consider.
Kt (int, optional) – Number of transmitters to consider. It not provided the value of Kr will be used.
- Returns
big_matrix – The converted matrix. This is a 2D numpy array
- Return type
np.ndarray
Notes
Since a ‘user’ is a transmit/receive pair then the small_matrix will be a square matrix and Kr must be equal to Kt. However, in the
MultiUserChannelMatrixExtInt
class we will only have the ‘transmitter part’ for the external interference sources. That means that small_matrix will have more columns then rows and Kt will be greater then Kr.Examples
>>> K = 3 >>> Nr = np.array([2, 4, 6]) >>> Nt = np.array([2, 3, 5]) >>> small_matrix = np.array([[1,2,3],[4,5,6],[7,8,9]]) >>> MultiUserChannelMatrix._from_small_matrix_to_big_matrix( small_matrix, Nr, Nt, K) array([[1, 1, 2, 2, 2, 3, 3, 3, 3, 3], [1, 1, 2, 2, 2, 3, 3, 3, 3, 3], [4, 4, 5, 5, 5, 6, 6, 6, 6, 6], [4, 4, 5, 5, 5, 6, 6, 6, 6, 6], [4, 4, 5, 5, 5, 6, 6, 6, 6, 6], [4, 4, 5, 5, 5, 6, 6, 6, 6, 6], [7, 7, 8, 8, 8, 9, 9, 9, 9, 9], [7, 7, 8, 8, 8, 9, 9, 9, 9, 9], [7, 7, 8, 8, 8, 9, 9, 9, 9, 9], [7, 7, 8, 8, 8, 9, 9, 9, 9, 9], [7, 7, 8, 8, 8, 9, 9, 9, 9, 9], [7, 7, 8, 8, 8, 9, 9, 9, 9, 9]])
-
property
big_H
¶ Get method for the big_H property.
- Returns
The channel from all transmitters to all receivers as a single big matrix (numpy complex array)
- Return type
np.ndarray
-
property
big_W
¶ Post processing filters (a block diagonal matrix) for each user.
- Returns
The big block diagonal matrix with the post processing filters for each user.
- Return type
np.ndarray
-
calc_JP_Q
(k: int, F_all_users: numpy.ndarray) → numpy.ndarray[source]¶ Calculates the interference plus noise covariance matrix at the \(k\)-th receiver with a joint processing scheme.
The interference covariance matrix at the \(k\)-th receiver, \(\mtQ k\), is given by
\(\mtQ k = \sum_{j=1, j \neq k}^{K} \frac{P_j}{Ns_j} \mtH_{k} \mtF_j \mtF_j^H \mtH_{k}^H\)
where \(P_j\) is the transmit power of transmitter \(j\), and \(Ns_j\) is the number of streams for user \(j\).
- Parameters
k (int) – Index of the desired receiver.
F_all_users (np.ndarray | list[np.ndarray]) – The precoder of all users (already taking into account the transmit power).
- Returns
Qk – The interference covariance matrix at receiver \(k\).
- Return type
np.ndarray
-
calc_JP_SINR
(F: numpy.ndarray, U: numpy.ndarray) → numpy.ndarray[source]¶ Calculates the SINR values (in linear scale) of all streams of all users with the current IA solution.
The noise variance used will be the value of the noise_var property.
- Parameters
F (np.ndarray) – The precoders of all users. This should be a 1D numpy array of 2D numpy arrays.
U (np.ndarray) – The receive filters of all users. This should be a 1D numpy array of 2D numpy arrays.
- Returns
SINRs – The SINR (in linear scale) of all streams of all users. This is a 1D numpy array of 1D numpy arrays (of floats).
- Return type
np.ndarray
-
calc_Q
(k: int, F_all_users: numpy.ndarray) → numpy.ndarray[source]¶ Calculates the interference plus noise covariance matrix at the \(k\)-th receiver.
The interference covariance matrix at the \(k\)-th receiver, \(\mtQ k\), is given by
\(\mtQ k = \sum_{j=1, j \neq k}^{K} \frac{P_j}{Ns_j} \mtH_{kj} \mtF_j \mtF_j^H \mtH_{kj}^H\)
where \(P_j\) is the transmit power of transmitter \(j\), and \(Ns_j\) is the number of streams for user \(j\).
- Parameters
k (int) – Index of the desired receiver.
F_all_users (np.ndarray) – The precoder of all users (already taking into account the transmit power). This should be a 1D numpy array of 2D numpy arrays.
- Returns
Qk – The interference covariance matrix at receiver \(k\) (a 2D numpy complex array).
- Return type
np.ndarray
-
calc_SINR
(F: numpy.ndarray, U: numpy.ndarray) → numpy.ndarray[source]¶ Calculates the SINR values (in linear scale) of all streams of all users with the current IA solution.
The noise variance used will be the value of the noise_var property.
- Parameters
F (np.ndarray) – The precoders of all users. This should be a 1D numpy array of 2D numpy arrays.
U (np.ndarray) – The receive filters of all users. This should be a 1D numpy array of 2D numpy arrays.
- Returns
SINRs – The SINR (in linear scale) of all streams of all users. This is a 1D numpy array of 1D numpy arrays (of floats)
- Return type
np.ndarray
-
corrupt_concatenated_data
(data: numpy.ndarray) → numpy.ndarray[source]¶ Corrupt data passed through the channel.
If self.noise_var is set to some scalar number then white noise will also be added.
- Parameters
data (np.ndarray) – A bi-dimensional numpy array with the concatenated data of all transmitters. The dimension of data is sum(self.Nt) x NSymb. That is, the number of rows corresponds to the sum of the number of transmit antennas of all users and the number of columns correspond to the number of transmitted symbols.
- Returns
A bi-dimension numpy array where the number of rows corresponds to the sum of the number of receive antennas of all users and the number of columns correspond to the number of transmitted symbols.
- Return type
np.ndarray
-
corrupt_data
(data: numpy.ndarray) → numpy.ndarray[source]¶ Corrupt data passed through the channel.
If the noise_var is supplied then an white noise will also be added.
- Parameters
data (np.ndarray) – An array of numpy matrices with the data of the multiple users. The k-th element in data is a numpy array with dimension Nt_k x NSymbs, where Nt_k is the number of transmit antennas of the k-th user and NSymbs is the number of transmitted symbols.
- Returns
A numpy array where each element contains the received data (a 2D numpy array) of a user.
- Return type
np.ndarray
-
get_Hk
(k: int) → numpy.ndarray[source]¶ Get the channel from all transmitters to receiver k.
- Parameters
k (int) – Receiving user.
- Returns
channel_k – Channel from all transmitters to receiver k. This is a 2D numpy array.
- Return type
np.ndarray
See also
Examples
>>> multiH = MultiUserChannelMatrix() >>> H = np.reshape(np.r_[0:16], [4,4]) >>> Nt = np.array([2, 2]) >>> Nr = np.array([2, 2]) >>> multiH.init_from_channel_matrix(H, Nr, Nt, 2) >>> print(multiH.big_H) [[ 0 1 2 3] [ 4 5 6 7] [ 8 9 10 11] [12 13 14 15]] >>> print(multiH.get_Hk(0)) [[0 1 2 3] [4 5 6 7]] >>> print(multiH.get_Hk(1)) [[ 8 9 10 11] [12 13 14 15]]
-
get_Hkl
(k: int, l: int) → numpy.ndarray[source]¶ Get the channel matrix from user l to user k.
- Parameters
- Returns
channel – Channel from transmitter l to receiver k. This is a 2D numpy array.
- Return type
np.ndarray
See also
Examples
>>> multiH = MultiUserChannelMatrix() >>> H = np.reshape(np.r_[0:16], [4,4]) >>> Nt = np.array([2, 2]) >>> Nr = np.array([2, 2]) >>> multiH.init_from_channel_matrix(H, Nr, Nt, 2) >>> print(multiH.big_H) [[ 0 1 2 3] [ 4 5 6 7] [ 8 9 10 11] [12 13 14 15]] >>> print(multiH.get_Hkl(0, 0)) [[0 1] [4 5]] >>> print(multiH.get_Hkl(1, 0)) [[ 8 9] [12 13]]
-
init_from_channel_matrix
(channel_matrix: numpy.ndarray, Nr: Union[numpy.ndarray, int], Nt: Union[numpy.ndarray, int], K: int) → None[source]¶ Initializes the multiuser channel matrix from the given channel_matrix.
- Parameters
channel_matrix (np.ndarray) – A matrix concatenating the channel of all users (from each transmitter to each receiver). This is a 2D numpy array.
Nr (int | np.ndarray) – Number of antennas at each receiver.
Nt (int | np.ndarray) – Number of antennas at each transmitter.
K (int) – Number of transmit/receive pairs.
- Raises
ValueError – If the arguments are invalid.
-
property
last_noise
¶ Get method for the last_noise property.
- Returns
The last AWGN noise array added to corrupt the data.
- Return type
None | np.ndarray
-
property
noise_var
¶ Get method for the noise_var property.
- Returns
The noise variance, if noise is being added in “corrupt_*data” methods.
- Return type
None | float
-
property
pathloss
¶ Get method for the pathloss property.
- Returns
The pathloss matrix (if one was set).
- Return type
None | np.ndarray
-
randomize
(Nr: Union[numpy.ndarray, int], Nt: Union[numpy.ndarray, int], K: int) → None[source]¶ Generates a random channel matrix for all users.
- Parameters
Nr (int | np.ndarray) – Number of receive antennas of each user. If an integer is specified, all users will have that number of receive antennas.
Nt (int | np.ndarray) – Number of transmit antennas of each user. If an integer is specified, all users will have that number of receive antennas.
K (int) – Number of users.
-
re_seed
() → None[source]¶ Re-seed the channel and noise RandomState objects randomly.
If you want to specify the seed for each of them call the set_channel_seed and set_noise_seed methods and pass the desired seed for each of them.
-
set_channel_seed
(seed: Optional[Union[int, List[int], numpy.ndarray]] = None) → None[source]¶ Set the seed of the RandomState object used to generate the random elements of the channel (when self.randomize is called).
- Parameters
seed (None | int | array_like) – Random seed initializing the pseudo-random number generator. See np.random.RandomState help for more info.
-
set_noise_seed
(seed: Optional[Union[int, List[int], numpy.ndarray]] = None) → None[source]¶ Set the seed of the RandomState object used to generate the random noise elements (when the corrupt data function is called).
- Parameters
seed (None | int | array_like) – Random seed initializing the pseudo-random number generator. See np.random.RandomState help for more info.
-
set_pathloss
(pathloss_matrix: Optional[numpy.ndarray] = None) → None[source]¶ Set the path loss (IN LINEAR SCALE) from each transmitter to each receiver.
The path loss will be accounted when calling the get_Hkl, get_Hk, the corrupt_concatenated_data and the corrupt_data methods.
If you want to disable the path loss, set pathloss_matrix to None.
- Parameters
pathloss_matrix (np.ndarray) – A matrix with dimension “K x K”, where K is the number of users, with the path loss (IN LINEAR SCALE) from each transmitter (columns) to each receiver (rows). If you want to disable the path loss then set it to None.
Notes
Note that path loss is a power relation, which means that the channel coefficients will be multiplied by the square root of elements in pathloss_matrix.
-
set_post_filter
(filters: numpy.ndarray) → None[source]¶ Set the post-processing filters.
The post-processing filters will be applied to the data after if has been corrupted by the channel in either the corrupt_data or the corrupt_concatenated_data methods.
- Parameters
filters (list[np.ndarray] | np.ndarray) – The post processing filters of each user. This should be a list of 2D np arrays or a 1D np array of 2D np arrays.
-
property
-
class
pyphysim.channels.multiuser.
MultiUserChannelMatrixExtInt
[source]¶ Bases:
pyphysim.channels.multiuser.MultiUserChannelMatrix
Very similar to the MultiUserChannelMatrix class, but the MultiUserChannelMatrixExtInt also includes the effect of an external interference.
This channel matrix can be seem as an concatenation of blocks (of non-uniform size) where each block is a channel from one transmitter to one receiver and the block size is equal to the number of receive antennas of the receiver times the number of transmit antennas of the transmitter. The difference compared with MultiUserChannelMatrix is that in the MultiUserChannelMatrixExtInt class the interference user counts as one more user, but with zero receive antennas.
For instance, in a 3-users scenario the block (1,0) corresponds to the channel between the transmit antennas of user 0 and the receive antennas of user 1 (indexing staring at zero). If the number of receive antennas and transmit antennas of the three users are [2, 4, 6] and [2, 3, 5], respectively, then the block (1,0) would have a dimension of 4x2. The external interference will count as one more block where the number of columns of this block corresponds to the rank of the external interference. If the external interference has a rank 2 then the complete channel matrix would look similar to the block structure below.
2 x 2
2 x 3
2 x 5
2 x 2
4 x 2
4 x 3
4 x 5
4 x 2
6 x 2
6 x 3
6 x 5
6 x 2
The methods from the MultiUserChannelMatrix class that makes sense were reimplemented here to include information regarding the external interference.
-
property
H
¶ Get method for the H property.
-
property
H_no_ext_int
¶ Get method for the H_no_ext_int property.
-
property
K
¶ Get method for the K property.
-
property
Nr
¶ Get method for the Nr property.
-
property
Nt
¶ Get method for the Nt property.
-
_calc_JP_Bkl_cov_matrix_first_part
(F_all_users: numpy.ndarray, k: int, Rek: NumberOrArray) → numpy.ndarray[source]¶ Calculates the first part in the equation of the Blk covariance matrix in equation (28) of [Cadambe2008] when joint process is employed.
The first part is given by
\(\sum_{j=1}^{K} \frac{P^{[j]}}{d^{[j]}} \sum_{d=1}^{d^{[j]}} \mtH^{[kj]}\mtV_{\star d}^{[j]} \mtV_{\star d}^{[j]\dagger} \mtH^{[kj]\dagger} + \mtI_{Nk}\)
Note that it only depends on the value of \(k\).
- Parameters
F_all_users (list[np.ndarray] | np.ndarray) – The precoder of all users (already taking into account the transmit power). This can be either a 1D numpy array of numpy arrays or a list of numpy arrays.
k (int) – Index of the desired user.
Rek (np.ndarray | float) – Covariance matrix of the external interference plus noise.
- Returns
The first part in the equation of the Blk covariance matrix.
- Return type
np.ndarray
-
_calc_JP_Bkl_cov_matrix_second_part
(Fk: numpy.ndarray, k: int, l: int) → numpy.ndarray[source]¶ Calculates the second part in the equation of the Blk covariance matrix in equation (28) of [Cadambe2008] (note that it does not include the identity matrix).
The second part is given by
\(\frac{P^{[k]}}{d^{[k]}} \mtH^{[kk]} \mtV_{\star l}^{[k]} \mtV_{\star l}^{[k]\dagger} \mtH^{[kk]\dagger}\)
- Parameters
- Returns
second_part – Second part in equation (28) of [Cadambe2008].
- Return type
np.ndarray
-
_calc_JP_Q
(k: int, F_all_users: numpy.ndarray) → numpy.ndarray[source]¶ Calculates the interference covariance matrix at the \(k\)-th receiver with a joint processing scheme (not including the covariance matrix of the external interference plus noise)
- Parameters
k (int) – Index of the desired receiver.
F_all_users (np.ndarray) – The precoder of all users (already taking into account the transmit power). This is a 1D numpy array of 2D numpy array.
See also
-
_calc_JP_SINR_k
(k: int, Fk: numpy.ndarray, Uk: numpy.ndarray, Bkl_all_l: numpy.ndarray) → numpy.ndarray[source]¶ Calculates the SINR of all streams of user ‘k’.
- Parameters
Fk (np.ndarray) – The precoder of user k.
Uk (np.ndarray) – The receive filter of user k (before applying the conjugate transpose).
k (int) – Index of the desired user.
Bkl_all_l (list[np.ndarray] | np.ndarray) – A sequence (1D numpy array, a list, etc) of 2D numpy arrays corresponding to the Bkl matrices for all ‘l’s.
- Returns
The SINR for the different streams of user k.
- Return type
np.ndarray
-
static
_prepare_input_parans
(Nr: numpy.ndarray, Nt: numpy.ndarray, K: int, NtE: Iterable[int]) → Tuple[numpy.ndarray, numpy.ndarray, int, int, numpy.ndarray][source]¶ Helper method used in the init_from_channel_matrix and randomize method definitions.
- Parameters
Nr (np.ndarray) – Number of antennas at each receiver.
Nt (np.ndarray) – Number of antennas at each transmitter.
K (int) – Number of transmit/receive pairs.
NtE (int | list[int] | np.ndarray) – Number of transmit antennas of the external interference source(s). If NtE is an iterable, the number of external interference sources will be the len(NtE).
- Returns
output – The tuple (full_Nr, full_Nt, full_K, extIntK, extIntNt).
- Return type
-
property
big_H_no_ext_int
¶ Get method for the big_H_no_est_int property.
big_H_no_est_int is similar to big_H, but does not include the last column(s) corresponding to the external interference channel.
-
calc_JP_Q
(k: int, F_all_users: numpy.ndarray, pe: float = 1.0) → numpy.ndarray[source]¶ Calculates the interference covariance matrix at the \(k\)-th receiver with a joint processing scheme.
The interference covariance matrix at the \(k\)-th receiver, \(\mtQ k\), is given by
\(\mtQ k = \sum_{j=1, j \neq k}^{K} \frac{P_j}{Ns_j} \mtH_{k} \mtF_j \mtF_j^H \mtH_{k}^H\)
where \(P_j\) is the transmit power of transmitter \(j\), and \(Ns_j\) is the number of streams for user \(j\).
- Parameters
- Returns
Qk – The interference covariance matrix at receiver \(k\).
- Return type
np.ndarray
-
calc_JP_SINR
(F: numpy.ndarray, U: numpy.ndarray, pe: float = 1.0) → numpy.ndarray[source]¶ Calculates the SINR values (in linear scale) of all streams of all users with the current IA solution.
The noise variance used will be the value of the noise_var property.
- Parameters
F (np.ndarray) – The precoders of all users. This is a 1D numpy array of 2D numpy arrays.
U (np.ndarray) – The receive filters of all users. This is a 1D numpy array of 2D numpy arrays.
pe (float) – The external interference power.
- Returns
The SINR (in linear scale) of all streams of all users. This is a 1D numpy array of 1D numpy arrays (of floats).
- Return type
np.ndarray
-
calc_Q
(k: int, F_all_users: numpy.ndarray, pe: float = 1.0) → numpy.ndarray[source]¶ Calculates the interference covariance matrix at the \(k\)-th receiver.
The interference covariance matrix at the \(k\)-th receiver, \(\mtQ k\), is given by
\(\mtQ k = \sum_{j=1, j \neq k}^{K} \frac{P_j}{Ns_j} \mtH_{kj} \mtF_j \mtF_j^H \mtH_{kj}^H\)
where \(P_j\) is the transmit power of transmitter \(j\), and \(Ns_j\) is the number of streams for user \(j\).
- Parameters
k (int) – Index of the desired receiver.
F_all_users (list[np.ndarray] | np.ndarray) – The precoder of all users (already taking into account the transmit power). This should be either a list of numpy 2D arrays or a 1D numpy array of 2D numpy arrays.
pe (float) – The power of the external interference source(s).
- Returns
Qk – The interference covariance matrix at receiver \(k\).
- Return type
np.ndarray
-
calc_SINR
(F: numpy.ndarray, U: numpy.ndarray, pe: float = 1.0) → numpy.ndarray[source]¶ Calculates the SINR values (in linear scale) of all streams of all users with the current IA solution.
The noise variance used will be the value of the noise_var property.
- Parameters
F (list[np.ndarray] | np.ndarray) – The precoders of all users. This should be either a list of numpy 2D arrays or a 1D numpy array of 2D numpy arrays.
U (list[np.ndarray] | np.ndarray) – The receive filters of all users. This should be either a list of numpy 2D arrays or a 1D numpy array of 2D numpy arrays.
pe (float) – Power of the external interference source.
- Returns
SINRs – The SINR (in linear scale) of all streams of all users. This is a 1D numpy array of 1D numpy arrays (of floats)
- Return type
np.ndarray
-
calc_cov_matrix_extint_plus_noise
(pe: float = 1.0) → numpy.ndarray[source]¶ Calculates the covariance matrix of the external interference plus noise.
- Parameters
pe (float, optional [default=1]) – External interference power (in linear scale)
- Returns
R_all_k – Return a numpy array, where each element is the covariance matrix of the external interference plus noise at one receiver.
- Return type
np.ndarray
-
calc_cov_matrix_extint_without_noise
(pe: float = 1.0) → numpy.ndarray[source]¶ Calculates the covariance matrix of the external interference without include the noise.
- Parameters
pe (float, optional) – External interference power (in linear scale)
- Returns
R_all_k – Return a numpy array, where each element is the covariance matrix of the external interference at one receiver.
- Return type
np.ndarray
-
corrupt_concatenated_data
(data: numpy.ndarray) → numpy.ndarray[source]¶ Corrupt data passed through the channel.
If the noise_var member variable is not None then an white noise will also be added.
- Parameters
data (np.ndarray) – A bi-dimensional numpy array with the concatenated data of all transmitters as well as the data from all external interference sources. The dimension of data is (sum(self._Nt) + sum(self.extIntNt)) x NSymb. That is, the number of rows corresponds to the sum of the number of transmit antennas of all users and external interference sources and the number of columns correspond to the number of transmitted symbols.
- Returns
output – A bi-dimension numpy array where the number of rows corresponds to the sum of the number of receive antennas of all users and the number of columns correspond to the number of transmitted symbols.
- Return type
np.ndarray
-
corrupt_data
(data: numpy.ndarray, ext_int_data: numpy.ndarray) → numpy.ndarray[source]¶ Corrupt data passed through the channel.
If the noise_var member variable is not None then an white noise will also be added.
- Parameters
data (np.ndarray) – An array of numpy matrices with the data of the multiple users. The k-th element in data is a numpy array with dimension Nt_k x NSymbs, where Nt_k is the number of transmit antennas of the k-th user and NSymbs is the number of transmitted symbols.
ext_int_data (list[np.ndarray] | np.ndarray) – An array of numpy matrices with the data of the external interference sources. The l-th element is the data transmitted by the l-th external interference source, which must have a dimension of NtEl x NSymbs, where NtEl is the number of transmit antennas of the l-th external interference source.
- Returns
output – A numpy array where each element contains the received data (a 2D numpy array) of a user.
- Return type
np.ndarray
-
property
extIntK
¶ Get method for the extIntK property.
-
property
extIntNt
¶ Get method for the extIntNt property.
-
get_Hk_with_ext_int
(k: int) → numpy.ndarray[source]¶ Get the channel from all transmitters (including the external interference sources) to receiver k.
This method is essentially the same as the get_Hk method.
- Parameters
k (int) – Receiving user.
- Returns
channel_k – Channel from all transmitters to receiver k.
- Return type
np.ndarray
See also
Examples
>>> multiH = MultiUserChannelMatrixExtInt() >>> H = np.reshape(np.r_[0:20], [4,5]) >>> Nt = np.array([2, 2]) >>> Nr = np.array([2, 2]) >>> NextInt = np.array([1]) >>> multiH.init_from_channel_matrix(H, Nr, Nt, 2, 1) >>> # Note that the last column of multiH.big_H corresponds to the >>> # external interference source >>> print(multiH.big_H) [[ 0 1 2 3 4] [ 5 6 7 8 9] [10 11 12 13 14] [15 16 17 18 19]] >>> print(multiH.get_Hk_with_ext_int(0)) [[0 1 2 3 4] [5 6 7 8 9]] >>> print(multiH.get_Hk_with_ext_int(1)) [[10 11 12 13 14] [15 16 17 18 19]]
-
get_Hk_without_ext_int
(k: int) → numpy.ndarray[source]¶ Get the channel from all transmitters (without including the external interference sources) to receiver k.
- Parameters
k (int) – Receiving user.
- Returns
channel_k – Channel from all transmitters to receiver k (2D numpy array).
- Return type
np.ndarray
See also
Examples
>>> multiH = MultiUserChannelMatrixExtInt() >>> H = np.reshape(np.r_[0:20], [4,5]) >>> Nt = np.array([2, 2]) >>> Nr = np.array([2, 2]) >>> NextInt = np.array([1]) >>> multiH.init_from_channel_matrix(H, Nr, Nt, 2, 1) >>> # Note that the last column of multiH.big_H corresponds to the >>> # external interference source >>> print(multiH.big_H) [[ 0 1 2 3 4] [ 5 6 7 8 9] [10 11 12 13 14] [15 16 17 18 19]] >>> print(multiH.get_Hk_without_ext_int(0)) [[0 1 2 3] [5 6 7 8]] >>> print(multiH.get_Hk_without_ext_int(1)) [[10 11 12 13] [15 16 17 18]]
-
init_from_channel_matrix
(channel_matrix: numpy.ndarray, Nr: numpy.ndarray, Nt: numpy.ndarray, K: int, NtE: Iterable[int]) → None[source]¶ Initializes the multiuser channel matrix from the given channel_matrix.
Note that channel_matrix must also include the channel terms for the external interference, which must be the last NtE columns of channel_matrix. The number of rows in channel_matrix must be equal to np.sum(Nr), while the number of columns must be np.sum(Nt) + NtE.
- Parameters
channel_matrix (np.ndarray) – A matrix concatenating the channel of all transmitters (including the external interference sources) to all receivers.
Nr (np.ndarray) – Number of antennas at each receiver.
Nt (np.ndarray) – Number of antennas at each transmitter.
K (int) – Number of transmit/receive pairs.
NtE (int | list[int] | np.ndarray) – Number of transmit antennas of the external interference source(s). If NtE is an iterable, the number of external interference sources will be the len(NtE).
- Raises
ValueError – If the arguments are invalid.
-
randomize
(Nr: Union[numpy.ndarray, int], Nt: Union[numpy.ndarray, int], K: int, NtE: Iterable[int]) → None[source]¶ Generates a random channel matrix for all users as well as for the external interference source(s).
- Parameters
Nr (int | np.ndarray) – Number of receive antennas of each user. If an integer is specified, all users will have that number of receive antennas.
Nt (int | np.ndarray) – Number of transmit antennas of each user. If an integer is specified, all users will have that number of receive antennas.
K (int) – Number of users.
NtE (int | list[int] | np.ndarray) – Number of transmit antennas of the external interference source(s). If NtE is an iterable, the number of external interference sources will be the len(NtE).
-
set_pathloss
(pathloss_matrix: Optional[numpy.ndarray] = None, ext_int_pathloss: Optional[numpy.ndarray] = None) → None[source]¶ Set the path loss (IN LINEAR SCALE) from each transmitter to each receiver, as well as the path loss from the external interference source(s) to each receiver.
The path loss will be accounted when calling the get_Hkl, get_Hk, the corrupt_concatenated_data and the corrupt_data methods.
Note that path loss is a power relation, which means that the channel coefficients will be multiplied by the square root of elements in pathloss_matrix.
If you want to disable the path loss, set pathloss_matrix to None.
- Parameters
pathloss_matrix (np.ndarray) – A matrix with dimension “K x K”, where K is the number of users, with the path loss (IN LINEAR SCALE) from each transmitter (columns) to each receiver (rows). If you want to disable the path loss then set it to None. ext_int_pathloss : 2D numpy array The path loss from each interference source to each receiver. The number of rows of ext_int_pathloss must be equal to the number of receives, while the number of columns must be equal to the number of external interference sources.
ext_int_pathloss (np.ndarray) – The external interference path loss.
-
property
pyphysim.channels.noise module¶
pyphysim.channels.pathloss module¶
Implement classes for several Path loss models.
The PathLossBase
class implements the common code to every path loss model and
only two methods need to be implemented in subclasses: the
PathLossBase.which_distance_dB()
and the
PathLossBase._calc_deterministic_path_loss_dB()
methods. However, instead
of inheriting directly from PathLossBase
, inherit from either
PathLossIndoorBase
or PathLossOutdoorBase
.
The most common usage of a path loss class is to instantiate an object of the desired path loss model and then call the calc_path_loss_dB or the calc_path_loss methods to actually calculate the path loss.
-
class
pyphysim.channels.pathloss.
PathLoss3GPP1
[source]¶ Bases:
pyphysim.channels.pathloss.PathLossGeneral
Class to calculate the Path Loss according to the model from 3GPP (scenario 1). That is, the Path Loss (in dB) is equal to
\[PL = 128.1 + 37.6*\log10(d)\]This model is valid for LTE assumptions and at 2GHz frequency, where the distance is in Km.
Examples
Determining the path loss in the free space for a distance of 1Km (without considering shadowing).
>>> pl = PathLoss3GPP1() >>> pl.calc_path_loss(1) # linear scale 1.5488166189124858e-13 >>> pl.calc_path_loss_dB(1) # log scale 128.1
Determining the distance (in Km) that yields a path loss of 130dB.
>>> pl.which_distance_dB(130) 1.1233935211892188
-
class
pyphysim.channels.pathloss.
PathLossBase
[source]¶ Bases:
object
Base class for the different Path Loss models.
The common interface for the path loss classes is provided by the
calc_path_loss_dB()
or thecalc_path_loss()
methods to actually calculate the path loss for a given distance, as well as thewhich_distance_dB()
orwhich_distance()
methods to determine the distance that yields the given path loss.Each subclass of PathLossBase NEED TO IMPLEMENT only the
which_distance_dB()
and the_calc_deterministic_path_loss_dB()
functions.If the use_shadow_bool attribute is set to True then calling
calc_path_loss_dB()
orcalc_path_loss()
will take the shadowing specified in the sigma_shadow attribute into account. However, shadowing is not taken into account in thewhich_distance_dB()
andwhich_distance()
functions, regardless of the value of the use_shadow_bool variable.-
handle_small_distances_bool
¶ If this is True then any negative path loss (in dB) that appears because a distance is too small will considered as 0dB. If this s False then an exception will be raised instead.
- Type
-
_TYPE
= 'base'¶
-
abstract
_calc_deterministic_path_loss_dB
(d: NumberOrArray, **kargs: Any) → NumberOrArray[source]¶ Calculates the Path Loss (in dB) for a given distance (in Km) without including the shadowing.
- Parameters
d (float | np.ndarray) – Distance (in Km)
kargs (dict, optional) – Optional parameters for use in subclasses if required.
- Other Parameters
kwargs (dict) – Additional keywords that might be necessary in a subclass.
- Returns
PL – Path loss (in dB).
- Return type
float | np.ndarray
- Raises
NotImplementedError – If the _calc_deterministic_path_loss_dB method of the PathLossBase class is called.
-
_plot_deterministic_path_loss_in_dB_impl
(d: numpy.ndarray, ax: Optional[Any] = None, extra_args: Optional[Any] = None, distance_unit: str = 'Km') → None[source]¶ Plot the path loss (in dB) for the distance values in d (in Km).
- Parameters
d (np.ndarray) – Distance (in correct unit)
ax (A matplotlib ax, optional) – The ax where the path loss will be plotted. If not provided, a new figure (and ax) will be created.
extra_args (dict) – Extra arguments that will be passed to the ax.plot command as
**extra_args
(see Matplotlib documentation). Ex: {‘label’: ‘curve name’, ‘linewidth’: 2}
-
calc_path_loss
(d: NumberOrArray, **kargs: Any) → NumberOrArray[source]¶ Calculates the path loss (linear scale) for a given distance (in Km).
- Parameters
d (float | np.ndarray) – Distance (in Km)
kargs (dict) – Extra named parameters. This is used in subclasses for extra parameters for the path loss calculation.
- Other Parameters
kwargs (dict) – Additional keywords that might be necessary in a subclass.
- Returns
pl – Path loss (in linear scale) for the given distance(s).
- Return type
float | np.ndarray
-
calc_path_loss_dB
(d: NumberOrArray, **kargs: Any) → NumberOrArray[source]¶ Calculates the Path Loss (in dB) for a given distance (in Km).
Note that the returned value is positive, but should be understood as “a loss”.
- Parameters
d (float | np.ndarray) – Distance (in Km)
kargs (dict) – Optional parameters for use in subclasses if required.
- Other Parameters
kwargs (dict) – Additional keywords that might be necessary in a subclass.
- Returns
PL – Path loss (in dB) for the given distance(s).
- Return type
float | np.ndarray
-
plot_deterministic_path_loss_in_dB
(d: numpy.ndarray, ax: Optional[Any] = None, extra_args: Optional[Any] = None) → None[source]¶ Plot the path loss (in dB) for the distance values in d (in Km).
- Parameters
d (np.ndarray) – Distance (in Km)
ax (A matplotlib ax, optional) – The ax where the path loss will be plotted. If not provided, a new figure (and ax) will be created.
extra_args (dict) – Extra arguments that will be passed to the ax.plot command as
**extra_args
(see Matplotlib documentation). Ex: {‘label’: ‘curve name’, ‘linewidth’: 2}
-
property
type
¶ Get method for the type property.
-
which_distance
(pl: NumberOrArray) → NumberOrArray[source]¶ Calculates the required distance (in Km) to achieve the given path loss. It is the inverse of the calc_path_loss function.
- Parameters
pl (float | np.ndarray) – Path loss (in linear scale).
- Returns
d – Distance(s) that will yield the path loss pl.
- Return type
float | np.ndarray
-
abstract
which_distance_dB
(PL: NumberOrArray) → NumberOrArray[source]¶ Calculates the distance that yields the given path loss (in dB).
- Parameters
PL (float | np.ndarray) – Path Loss (in dB)
- Returns
d – Distance to get the desired path loss PL.
- Return type
float | np.ndarray
- Raises
NotImplementedError – If the which_distance_dB method of the PathLossBase class is called.
-
-
class
pyphysim.channels.pathloss.
PathLossFreeSpace
(n: float = 2.0, fc: float = 900.0)[source]¶ Bases:
pyphysim.channels.pathloss.PathLossGeneral
Class to calculate the Path Loss in the free space.
The common interface for the path loss classes is provided by the
PathLossOutdoorBase.calc_path_loss_dB()
or thePathLossOutdoorBase.calc_path_loss()
methods to actually calculate the path loss for a given distance, as well as thePathLossGeneral.which_distance_dB()
orPathLossBase.which_distance()
methods to determine the distance that yields the given path loss.For the path loss in free space you also need to set the n variable, corresponding to the path loss coefficient, and the fc variable, corresponding to the frequency. The n variable defaults to 2 and fc defaults to 900 (that is, 900MHz).
The path loss (in dB) in free space is calculated as:
\[PL = 10 n ( \log_{10}(d)+\log_{10}(fc * 1e6) - 4.3779113907)\]Likewise, the
PathLossGeneral.which_distance_dB()
function calculates the value of\[10^{(PL/(10n) - \log_{10}(fc) + 4.377911390697565)}\]Examples
Determining the path loss in the free space for a distance of 1Km (without considering shadowing).
>>> pl = PathLossFreeSpace() >>> pl.calc_path_loss(1) # linear scale 7.036193308495632e-10 >>> pl.calc_path_loss_dB(1) # log scale 91.5266223748352
Determining the distance (in Km) that yields a path loss of 90dB.
>>> pl.which_distance_dB(90) 0.8388202017414481
-
static
_calculate_C_from_fc_and_n
(fc: float, n: float) → float[source]¶ Calculate the value of the constant C for the frequency value fc and path loss exponent n.
-
_repr_latex_
() → str[source]¶ Get a Latex representation of the PathLossFreeSpace class.
This is useful for representing the path loss object in an IPython notebook.
- Returns
The Latex representation of the path loss object.
- Return type
-
property
fc
¶ Get the central carrier frequency.
- Returns
The central carrier frequency.
- Return type
-
static
-
class
pyphysim.channels.pathloss.
PathLossGeneral
(n: float, C: float)[source]¶ Bases:
pyphysim.channels.pathloss.PathLossOutdoorBase
Class to calculate the path loss given the path loss for a reference distance.
In its simplest form, the path loss can be calculated using the formula
\(PL = 10 n \log_{10} (d) + C\)
where PL is in dB, n is the path loss exponent (usually in the range of 2 to 4) and d is the distance between the transmitter and the receiver.
-
_calc_deterministic_path_loss_dB
(d: NumberOrArray, **kargs: Any) → NumberOrArray[source]¶ Calculates the Path Loss (in dB) for a given distance (in Km).
Note that the returned value is positive, but should be understood as “a loss”.
For d in Km and self.fc in MHz, the free space Path Loss is given by
\[PL = 10 n \log_{10}(d) + C\]- Parameters
d (float | np.ndarray) – Distance (in Km).
- Returns
pl_dB – Path loss in dB.
- Return type
float | np.ndarray
-
_get_latex_repr
() → str[source]¶ Get the Latex representation (equation) for the PathLossGeneral class.
The general equation is given by
\[PL = 10 n \log_{10} (d) + C\]- Returns
The Latex representation of the path loss object.
- Return type
-
_repr_latex_
() → str[source]¶ Get a Latex representation of the PathLossGeneral class.
This is useful for representing the path loss object in an IPython notebook.
- Returns
The Latex representation of the path loss object.
- Return type
-
which_distance_dB
(PL: NumberOrArray) → NumberOrArray[source]¶ Calculates the required distance (in Km) to achieve the given path loss (in dB).
It is the inverse of the calc_path_loss function.
\[10^{(PL/(10n) - C)}\]d = obj.whichDistance(dB2Linear(-PL));
- Parameters
PL (float | np.ndarray) – Path Loss (in dB).
- Returns
d – Distance (in Km).
- Return type
float | np.ndarray
-
-
class
pyphysim.channels.pathloss.
PathLossIndoorBase
[source]¶ Bases:
pyphysim.channels.pathloss.PathLossBase
Base class for the different Indoor Path Loss models.
The common interface for the path loss classes is provided by the
calc_path_loss_dB()
or thecalc_path_loss()
methods to actually calculate the path loss for a given distance, as well as thewhich_distance_dB()
or which_distance methods to determine the distance that yields the given path loss.Each subclass of PathLossBase NEED TO IMPLEMENT only the
which_distance_dB()
and the_calc_deterministic_path_loss_dB()
functions.If the use_shadow_bool is set to True then calling
calc_path_loss_dB()
orcalc_path_loss()
will take the shadowing specified in the sigma_shadow variable into account. However, shadowing is not taken into account in thewhich_distance_dB()
andwhich_distance()
functions, regardless of the value of the use_shadow_bool variable.-
_TYPE
= 'indoor'¶
-
abstract
_calc_deterministic_path_loss_dB
(d: NumberOrArray, **kargs: Any) → NumberOrArray[source]¶ Calculates the Path Loss (in dB) for a given distance (in meters) without including the shadowing.
- Parameters
d (float | np.ndarray) – Distance (in meters)
- Other Parameters
kwargs (dict) – Additional keywords that might be necessary in a subclass.
- Returns
PL – The calculated path loss.
- Return type
float | np.ndarray
- Raises
NotImplementedError – If the _calc_deterministic_path_loss_dB method of the PathLossBase class is called.
-
calc_path_loss
(d: NumberOrArray, **kargs: Any) → NumberOrArray[source]¶ Calculates the path loss (linear scale) for a given distance (in meters).
- Parameters
d (float | np.ndarray) – Distance (in meters)
kargs (dict) – Additional keywords that might be necessary in a subclass.
- Returns
pl – Path loss (in linear scale) for the given distance(s).
- Return type
float | np.ndarray
-
calc_path_loss_dB
(d: NumberOrArray, **kargs: Any) → NumberOrArray[source]¶ Calculates the Path Loss (in dB) for a given distance (in meters).
Note that the returned value is positive, but should be understood as “a loss”.
- Parameters
d (float | np.ndarray) – Distance (in meters)
kargs (dict) – Additional keywords that might be necessary in a subclass.
- Returns
PL – Path loss (in dB) for the given distance(s).
- Return type
float | np.ndarray
-
plot_deterministic_path_loss_in_dB
(d: NumberOrArray, ax: Optional[Any] = None, extra_args: Optional[Any] = None) → None[source]¶ Plot the path loss (in dB) for the distance values in d (in meters).
- Parameters
d (np.ndarray) – Distance (in meters)
ax (A matplotlib ax, optional) – The ax where the path loss will be plotted. If not provided, a new figure (and ax) will be created.
extra_args (dict) – Extra arguments that will be passed to the ax.plot command as
**extra_args
(see Matplotlib documentation). Ex: {‘label’: ‘curve name’, ‘linewidth’: 2}
-
which_distance
(pl: NumberOrArray) → NumberOrArray[source]¶ Calculates the required distance (in meters) to achieve the given path loss. It is the inverse of the calc_path_loss function.
- Parameters
pl (float | np.ndarray) – Path loss (in linear scale).
- Returns
d – Distance(s) that will yield the path loss pl.
- Return type
float | np.ndarray
-
abstract
which_distance_dB
(PL: NumberOrArray) → NumberOrArray[source]¶ Calculates the distance that yields the given path loss (in dB).
- Parameters
PL (float | np.ndarray) – Path Loss (in dB)
- Returns
d – The distance to yield the given path loss.
- Return type
float | np.ndarray
- Raises
NotImplementedError – If the which_distance_dB method of the PathLossBase class is called.
-
-
class
pyphysim.channels.pathloss.
PathLossMetisPS7
(fc: float = 900.0)[source]¶ Bases:
pyphysim.channels.pathloss.PathLossIndoorBase
Class to calculate the Path Loss (indoor) according to the model described for the Propagation Scenario (PS) 7 of the METIS project.
This model is an indoor-2-indoor model.
-
_calc_PS7_path_loss_dB_LOS_same_floor
(d: NumberOrArray) → NumberOrArray[source]¶ Calculate the deterministic path loss according to the Propagation Scenario (PS) 7 of the METIS project for the LOS case.
The path loss (in dB) is calculated as
\[PL = A \log_{10}(d) + B + C \log_{10}(f_c/5)\]The distance \(d\) is in meters, while the frequency \(f_c\) is in GHz.
The other variables (NLOS case) are:
\[A = 18.7 B = 46.8, C = 20\]where \(n_w\) is the number of walls between the transmitter and receiver.
- Parameters
d (float | np.ndarray) – Distance (in meters).
- Returns
pl_dB – Path loss in dB.
- Return type
float | np.ndarray
-
_calc_PS7_path_loss_dB_NLOS_same_floor
(d: NumberOrArray, num_walls: int = 1) → NumberOrArray[source]¶ Calculate the deterministic path loss according to the Propagation Scenario (PS) 7 of the METIS project for the NLOS case.
The path loss (in dB) is calculated as
\[PL = A \log_{10}(d) + B + C \log_{10}(f_c/5) + X\]The distance \(d\) is in meters, while the frequency \(f_c\) is in Hz.
The other variables (NLOS case) are:
\[A = 36.8 B = 43.8, C = 20, X = 5 ( n_w - 1 )\]where \(n_w\) is the number of walls between the transmitter and receiver.
- Parameters
d (float | np.ndarray) – Distance (in meters).
num_walls (int | np.ndarray) – Number of walls between the transmitter and the receiver. If it is an int array it must have the same dimension as d.
- Returns
pl_dB – Path loss in dB.
- Return type
float | np.ndarray
-
_calc_PS7_path_loss_dB_same_floor
(d: NumberOrArray, num_walls: int = 0) → NumberOrArray[source]¶ Calculate the deterministic path loss according to the Propagation Scenario (PS) 7 of the METIS project.
The path loss (in dB) is calculated as
\[PL = A \log_{10}(d) + B + C \log_{10}(f_c/5) + X\]The distance \(d\) is in meters, while the frequency \(f_c\) is in GHz. Na others variables a different for the LOS and NLOS cases.
For the LOS case we have:
\[A = 18.7 B = 46.8, C = 20, X = 0\]For the NLOS case we have:
\[A = 36.8 B = 43.8, C = 20, X = 5 ( n_w - 1 )\]where \(n_w\) is the number of walls between the transmitter and receiver.
- Parameters
d (float | np.ndarray) – Distance (in meters).
num_walls (int | np.ndarray) – Indicates how many walls the signal has to pass. If num_walls is zero, then Line-of-Sight parameters are used. If it is greater than zero then Non-Sign-of-Sight parameters are used. If num_walls is a numpy array then it must have the same dimension as d and it then specifies the number of walls for each individual value of d
- Returns
pl_dB – Path loss in dB.
- Return type
float | np.ndarray
-
_calc_deterministic_path_loss_dB
(d: NumberOrArray, num_walls: int = 0) → NumberOrArray[source]¶ Calculates the Path Loss (in dB) for a given distance (in meters) without including the shadowing.
- Parameters
d (float | np.ndarray) – Distance (in meters)
num_walls (int | np.ndarray) – Number of walls between the transmitter and the receiver. If it is an int array it must have the same dimension as d.
- Returns
PL – The calculated path loss.
- Return type
float | np.ndarray
-
_repr_latex_
() → str[source]¶ Get a Latex representation of the PathLossMetisPS7 class.
This is useful for representing the path loss object in an IPython notebook.
- Returns
The Latex representation of the path loss object.
- Return type
-
property
fc
¶ Get the central carrier frequency.
- Returns
The central carrier frequency.
- Return type
-
static
get_latex_repr
(num_walls: Optional[int] = None) → str[source]¶ Get the Latex representation (equation) for the PathLossGeneral class.
The general equation is given by
\[PL = A \log_{10}(d) + B + C \log_{10}(f_c/5) + X\]where the parameters A, B, C and X depend on the number of walls.
-
which_distance_dB
(PL: NumberOrArray) → NumberOrArray[source]¶ Calculates the distance that yields the given path loss (in dB).
- Parameters
PL (float | np.ndarray) – Path Loss (in dB)
- Returns
d – The distance to yield the given path loss.
- Return type
float | np.ndarray
- Raises
NotImplementedError – If the which_distance_dB method of the PathLossBase class is called.
-
-
class
pyphysim.channels.pathloss.
PathLossOkomuraHata
[source]¶ Bases:
pyphysim.channels.pathloss.PathLossOutdoorBase
Class to calculate the Path Loss according to the Okomura Hata model.
The exact formula depend on the area type, but in general the path loss is given by (in dB):
\[PL = 69.55 + 26.16 * \log(fc) - 13.82*\log(h_{bs}) - a(h_{ms}) + (44.9 - 6.55\log(h_{bs})) \log(d) - K\]The term \(a(h_{ms})\) is the mobile station correction factor (see
_calc_mobile_antenna_height_correction_factor()
).The term \(K\) is a correction factor that depends on the area type (see
_calc_K()
).The possible area types are (in ascending order): ‘open’, ‘suburban’, ‘medium city’ and ‘large city’.
-
_calc_K
() → float[source]¶ Calculates the “‘medium city’/’suburban’/’open area’” correction factor.
- Returns
K – The correction factor “K”.
- Return type
-
_calc_deterministic_path_loss_dB
(d: NumberOrArray, **kargs: Any) → NumberOrArray[source]¶ Calculates the Path Loss (in dB) for a given distance (in Km).
Note that the returned value is positive, but should be understood as “a loss”.
For d in Km and self.fc in Hz, the free space Path Loss is given by
\[PL = 10n ( \log_{10}(d) + \log_{10}(f) - 4.3779113907 )\]- Parameters
d (float | np.ndarray) – Distance (in Km). Can be between 1km and 20Km.
- Returns
PL – Path loss in dB.
- Return type
float | np.ndarray
-
_calc_mobile_antenna_height_correction_factor
() → float[source]¶ Calculates the mobile antenna height correction factor.
This factor is strongly impacted by surrounding buildings and is refined according to city sizes. For all area types, except ‘large city’, the mobile antenna correction factor is given by
\[a(h_{ms}) = (1.1 \log(f) - 0.7) h_{ms} - 1.56 \log(f) + 0.8\]For the ‘large city’ area type, the mobile antenna height correction is given by
\[a(h_{ms}) = 3.2 (\log(11.75*h_{ms})^2) - 4.97\]if the frequency is greater then 300MHz, or
\[a(h_{ms}) = 8.29 (\log(1.54 h_{ms}))^2 - 1.10\]if the frequency is lower than 300MHz (and greater than 150MHz where the Okomura Hata model is valid).
- Returns
The mobile antenna height correction.
- Return type
-
property
area_type
¶ Get method for the area_type property.
-
property
fc
¶ Get the central carrier frequency.
- Returns
The central carrier frequency.
- Return type
-
property
hbs
¶ Get the height of the Base Station property.
- Returns
Height of the Base Station (in meters).
- Return type
-
property
hms
¶ Get the height of the Mobile Station property.
- Returns
Height of the Mobile Station (in meters).
- Return type
-
which_distance_dB
(PL: NumberOrArray) → NumberOrArray[source]¶ Calculates the required distance (in Km) to achieve the given path loss (in dB).
It is the inverse of the calc_path_loss function.
- Parameters
PL (float | np.ndarray) – Path loss (in dB).
- Returns
d – Distance (in Km).
- Return type
float | np.ndarray
-
-
class
pyphysim.channels.pathloss.
PathLossOutdoorBase
[source]¶ Bases:
pyphysim.channels.pathloss.PathLossBase
Base class for the different Outdoor Path Loss models.
The common interface for the path loss classes is provided by the
calc_path_loss_dB()
or thecalc_path_loss()
methods to actually calculate the path loss for a given distance, as well as thewhich_distance_dB()
orPathLossBase.which_distance()
methods to determine the distance that yields the given path loss.Each subclass of PathLossBase NEED TO IMPLEMENT only the
which_distance_dB()
and the_calc_deterministic_path_loss_dB()
functions.If the use_shadow_bool is set to True then calling
calc_path_loss_dB()
orcalc_path_loss()
will take the shadowing specified in the sigma_shadow variable into account. However, shadowing is not taken into account in thewhich_distance_dB()
andPathLossBase.which_distance()
functions, regardless of the value of the use_shadow_bool variable.-
_TYPE
= 'outdoor'¶
-
abstract
_calc_deterministic_path_loss_dB
(d: NumberOrArray, **kargs: Any) → NumberOrArray[source]¶ Calculates the Path Loss (in dB) for a given distance (in Km) without including the shadowing.
- Parameters
d (float | np.ndarray) – Distance (in Km)
- Other Parameters
kwargs (dict) – Additional keywords that might be necessary in a subclass.
- Returns
PL – The calculated path loss (in dB).
- Return type
float | np.ndarray
- Raises
NotImplementedError – If the _calc_deterministic_path_loss_dB method of the PathLossBase class is called.
-
calc_path_loss
(d: NumberOrArray, **kargs: Any) → NumberOrArray[source]¶ Calculates the path loss (linear scale) for a given distance (in Km).
-
calc_path_loss_dB
(d: NumberOrArray, **kargs: Any) → NumberOrArray[source]¶ Calculates the Path Loss (in dB) for a given distance (in Km).
Note that the returned value is positive, but should be understood as “a loss”.
-
plot_deterministic_path_loss_in_dB
(d: NumberOrArray, ax: Optional[Any] = None, extra_args: Optional[Any] = None) → None[source]¶ Plot the path loss (in dB) for the distance values in
d
(in Km).- Parameters
d (np.ndarray) – Distance (in Km)
ax (A matplotlib ax, optional) – The ax where the path loss will be plotted. If not provided, a new figure (and ax) will be created.
extra_args (dict) – Extra arguments that will be passed to the ax.plot command as
**extra_args
(see Matplotlib documentation). Ex: {‘label’: ‘curve name’, ‘linewidth’: 2}
-
abstract
which_distance_dB
(PL: NumberOrArray) → NumberOrArray[source]¶ Calculates the distance that yields the given path loss (in dB).
- Parameters
PL (float | np.ndarray) – Path Loss (in dB)
- Returns
d – The distance that yields the given path loss.
- Return type
float | np.ndarray
- Raises
NotImplementedError – If the which_distance_dB method of the PathLossBase class is called.
-
pyphysim.channels.singleuser module¶
Module containing single user channels.
-
class
pyphysim.channels.singleuser.
SuChannel
(fading_generator: Optional[Union[pyphysim.channels.fading_generators.JakesSampleGenerator, pyphysim.channels.fading_generators.RayleighSampleGenerator]] = None, channel_profile: Optional[pyphysim.channels.fading.TdlChannelProfile] = None, tap_powers_dB: Optional[numpy.ndarray] = None, tap_delays: Optional[numpy.ndarray] = None, Ts: Optional[float] = None)[source]¶ Bases:
object
Single User channel corresponding to a Tapped Delay Line channel model, which corresponds to a multipath channel. You can use a single tap in order to get a flat fading channel.
You can create a new SuChannel object either specifying the channel profile or specifying both the channel tap powers and delays. If only the fading_generator is specified then a single tap with unitary power and delay zero will be assumed, which corresponds to a flat fading channel model.
- Parameters
fading_generator (FadingGenerator) – The instance of a fading generator in the fading_generators module. It should be a subclass of FadingSampleGenerator. The fading generator will be used to generate the channel samples. If not provided then RayleighSampleGenerator will be used
channel_profile (fading.TdlChannelProfile) – The channel profile, which specifies the tap powers and delays.
tap_powers_dB (np.ndarray) – The powers of each tap (in dB). Dimension: L x 1 Note: The power of each tap will be a negative number (in dB).
tap_delays (np.ndarray) – The delay of each tap (in seconds). Dimension: L x 1
Ts (float, optional) – The sampling interval.
-
property
channel_profile
¶ Return the channel profile.
- Returns
The channel profile.
- Return type
-
corrupt_data
(signal: numpy.ndarray) → numpy.ndarray[source]¶ Transmit the signal through the TDL channel.
- Parameters
signal (np.ndarray) – The signal to be transmitted.
- Returns
The received signal after transmission through the TDL channel.
- Return type
np.ndarray
-
corrupt_data_in_freq_domain
(signal: numpy.ndarray, fft_size: int, carrier_indexes: Optional[Union[numpy.ndarray, List[int], slice]] = None) → numpy.ndarray[source]¶ Transmit the signal through the TDL channel, but in the frequency domain.
This is ROUGHLY equivalent to modulating signal with OFDM using fft_size subcarriers, transmitting through a regular TdlChannel, and then demodulating with OFDM to recover the received signal.
One important difference is that here the channel is considered constant during the transmission of fft_size elements in signal, and then it is varied by the equivalent of the variation for that number of elements. That is, the channel is block static.
- Parameters
signal (np.ndarray) – The signal to be transmitted.
fft_size (int) – The size of the Fourier transform to get the frequency response.
carrier_indexes (slice | np.ndarray) – The indexes of the subcarriers where signal is to be transmitted. If it is None assume all subcarriers will be used. This can be a slice object or a numpy array of integers.
- Returns
The received signal after transmission through the TDL channel
- Return type
np.ndarray
-
get_last_impulse_response
() → pyphysim.channels.fading.TdlImpulseResponse[source]¶ Get the last generated impulse response.
A new impulse response is generated when the method corrupt_data is called. You can use the get_last_impulse_response method to get the impulse response used to corrupt the last data.
- Returns
The impulse response of the channel that was used to corrupt the last data.
- Return type
-
property
num_rx_antennas
¶ Get the number of receive antennas.
- Returns
The number of receive antennas.
- Return type
-
property
num_taps
¶ Get the number of taps in the profile.
- Returns
The number of taps in the channel (not including any zero padding).
- Return type
-
property
num_taps_with_padding
¶ Get the number of taps in the profile including zero-padding when the profile is discretized.
If the profile is not discretized an exception is raised.
- Returns
The number of taps in the channel (including any zero padding).
- Return type
-
property
num_tx_antennas
¶ Get the number of transmit antennas.
- Returns
The number of transmit antennas.
- Return type
-
set_num_antennas
(num_rx_antennas: int, num_tx_antennas: int) → None[source]¶ Set the number of transmit and receive antennas for MIMO transmission.
Set both num_rx_antennas and num_tx_antennas to None for SISO transmission
-
set_pathloss
(pathloss_value: Optional[float] = None) → None[source]¶ Set the path loss (IN LINEAR SCALE).
The path loss will be accounted when calling the corrupt_data method.
If you want to disable the path loss, set pathloss_value to None.
- Parameters
pathloss_value (float | None) – The path loss (IN LINEAR SCALE) from the transmitter to the receiver. If you want to disable the path loss then set it to None.
Notes
Note that path loss is a power relation, which means that the channel coefficients will be multiplied by the square root of elements in pathloss_value.
-
class
pyphysim.channels.singleuser.
SuMimoChannel
(num_antennas: int, fading_generator: Optional[Union[pyphysim.channels.fading_generators.JakesSampleGenerator, pyphysim.channels.fading_generators.RayleighSampleGenerator]] = None, channel_profile: Optional[pyphysim.channels.fading.TdlChannelProfile] = None, tap_powers_dB: Optional[numpy.ndarray] = None, tap_delays: Optional[numpy.ndarray] = None, Ts: Optional[float] = None)[source]¶ Bases:
pyphysim.channels.singleuser.SuChannel
Single User channel corresponding to a Tapped Delay Line channel model, which corresponds to a multipath channel. You can use a single tap in order to get a flat fading channel.
You can create a new SuMimoChannel object either specifying the channel profile or specifying both the channel tap powers and delays. If only the fading_generator is specified then a single tap with unitary power and delay zero will be assumed, which corresponds to a flat fading channel model.
- Parameters
num_antennas (int) – Number of transmit and receive antennas.
fading_generator (FadingGenerator) – The instance of a fading generator in the fading_generators module. It should be a subclass of FadingSampleGenerator. The fading generator will be used to generate the channel samples. If not provided then RayleighSampleGenerator will be used
channel_profile (fading.TdlChannelProfile) – The channel profile, which specifies the tap powers and delays.
tap_powers_dB (np.ndarray) – The powers of each tap (in dB). Dimension: L x 1 Note: The power of each tap will be a negative number (in dB).
tap_delays (np.ndarray) – The delay of each tap (in seconds). Dimension: L x 1
Ts (float, optional) – The sampling interval.
Module contents¶
Module with implementation of channel related classes.