pyphysim.mimo package¶
Submodules¶
pyphysim.mimo.mimo module¶
Module implementing different MIMO schemes.
Each MIMO scheme is implemented as a class inheriting from
MimoBase
and implements at least the methods encode, decode
and getNumberOfLayers.
-
class
pyphysim.mimo.mimo.
Alamouti
(channel: Optional[numpy.ndarray] = None)[source]¶ Bases:
pyphysim.mimo.mimo.MimoBase
MIMO class for the Alamouti scheme.
- Parameters
channel (np.ndarray) – MIMO channel matrix.
-
static
_calc_precoder
(channel: numpy.ndarray) → numpy.ndarray[source]¶ Not defined.
There is no linear precoder for the Almost scheme and thus an exception is called if this method is ever called.
-
static
_calc_receive_filter
(channel: numpy.ndarray, noise_var: Optional[float] = None) → numpy.ndarray[source]¶ Not defined.
There is no linear receive filter for the Alamouti scheme that can be directly applied to the received data. Thus, an exception is called if this method is ever called.
-
static
_decode
(received_data: numpy.ndarray, channel: numpy.ndarray) → numpy.ndarray[source]¶ Perform the decoding of the received_data for the Alamouti scheme with the channel channel, but does not compensate for the power division among transmit antennas.
The idea is that the decode method will call _decode and perform the power compensation. This separation allows better code reuse.
- Parameters
received_data (np.ndarray) – Received data, which was encoded with the Alamouti scheme and corrupted by the channel channel.
channel (np.ndarray) – MIMO channel matrix.
- Returns
decoded_data – The decoded data (without power compensating the power division performed during transmission).
- Return type
np.ndarray
See also
-
static
_encode
(transmit_data: numpy.ndarray) → numpy.ndarray[source]¶ Perform the Alamouti encoding, but without dividing the power among the transmit antennas.
The idea is that the encode method will call _encode and perform the power division. This separation allows better code reuse.
- Parameters
transmit_data (np.ndarray) – Data to be encoded by the Alamouti scheme.
- Returns
encoded_data – The encoded transmit_data (without dividing the power among transmit antennas).
- Return type
np.ndarray
See also
-
calc_linear_SINRs
(noise_var: float) → numpy.ndarray[source]¶ Calculate the SINRs (in linear scale) of the multiple streams.
- Parameters
noise_var (float) – The noise variance.
- Returns
sinrs – The sinrs (in linear scale) of the multiple streams.
- Return type
np.ndarray
-
decode
(received_data: numpy.ndarray) → numpy.ndarray[source]¶ Perform the decoding of the received_data for the Alamouti scheme with the channel channel.
- Parameters
received_data (np.ndarray) – Received data, which was encoded with the Alamouti scheme and corrupted by the channel channel.
- Returns
decoded_data – The decoded data.
- Return type
np.ndarray
-
encode
(transmit_data: numpy.ndarray) → numpy.ndarray[source]¶ Perform the Alamouti encoding.
- Parameters
transmit_data (np.ndarray) – Data to be encoded by the Alamouti scheme.
- Returns
encoded_data – The encoded transmit_data.
- Return type
np.ndarray
-
getNumberOfLayers
() → int[source]¶ Get the number of layers of the Alamouti scheme.
The number of layers in the Alamouti scheme is always equal to one.
- Returns
Nl – Number of layers of the Alamouti scheme, which is always one.
- Return type
-
set_channel_matrix
(channel: numpy.ndarray) → None[source]¶ Set the channel matrix.
- Parameters
channel (np.ndarray) – MIMO channel matrix.
- Returns
- Return type
-
class
pyphysim.mimo.mimo.
Blast
(channel: Optional[numpy.ndarray] = None)[source]¶ Bases:
pyphysim.mimo.mimo.MimoBase
MIMO class for the BLAST scheme.
The receive filter used will depend on the noise variance (see the
set_noise_var()
method). If the noise variance is positive the MMSE filter will be used, otherwise noise variance will be ignored and the Zero-Forcing filter will be used.- Parameters
channel (np.ndarray) – MIMO channel matrix.
-
static
_calc_precoder
(channel: numpy.ndarray) → numpy.ndarray[source]¶ Calculate the linear precoder for the BLAST scheme.
The BLAST scheme simple send the data through the multiple streams without any particular precoding. Therefore, its linear precoder is equivalent to an identity matrix.
- Parameters
channel (np.ndarray) – MIMO channel matrix.
- Returns
W – The precoder that can be applied to the input data.
- Return type
np.ndarray
-
static
_calc_receive_filter
(channel: numpy.ndarray, noise_var: Optional[float] = None) → numpy.ndarray[source]¶ Calculate the receive filter for the MIMO scheme, if there is any.
- Parameters
channel (np.ndarray) – MIMO channel matrix.
noise_var (float) – The noise variance. If a value is provided then MMSE filter will be used. If it is not provided (or None is passes) then Zero Force filter will be used.
- Returns
G_H – The receive_filter that can be applied to the input data.
- Return type
np.ndarray
-
decode
(received_data: numpy.ndarray) → numpy.ndarray[source]¶ Decode the received data array.
- Parameters
received_data (np.ndarray) – Received data, which was encoded with the Blast scheme and corrupted by the channel channel.
- Returns
decoded_data – The decoded data.
- Return type
np.ndarray
-
encode
(transmit_data: numpy.ndarray) → numpy.ndarray[source]¶ Encode the transmit data array to be transmitted using the BLAST scheme.
- Parameters
transmit_data (np.ndarray) – A numpy array with a number of elements which is a multiple of the number of transmit antennas.
- Returns
encoded_data – The encoded transmit_data.
- Return type
np.ndarray
- Raises
ValueError – If the number of elements in transmit_data is not multiple of the number of transmit antennas.
-
getNumberOfLayers
() → int[source]¶ Get the number of layers of the Blast scheme.
- Returns
Nl – Number of layers of the MIMO scheme.
- Return type
-
set_channel_matrix
(channel: numpy.ndarray) → None[source]¶ Set the channel matrix.
- Parameters
channel (np.ndarray) – MIMO channel matrix.
-
set_noise_var
(noise_var: Optional[float]) → None[source]¶ Set the noise variance for the MMSE receive filter.
If noise_var is non-positive then the Zero-Force filter will be used instead.
- Parameters
noise_var (float | None) – Noise variance for the MMSE filter (if noise_var is positive). If noise_var is 0.0 or None then the Zero-Forcing filter will be used.
- Returns
- Return type
-
class
pyphysim.mimo.mimo.
GMDMimo
(channel: Optional[numpy.ndarray] = None)[source]¶ Bases:
pyphysim.mimo.mimo.Blast
MIMO class for the GMD based MIMO scheme.
- Parameters
channel (np.ndarray) – MIMO channel matrix.
-
static
_calc_precoder
(channel: numpy.ndarray) → numpy.ndarray[source]¶ Calculate the linear precoder for the GMD scheme.
- Parameters
channel (np.ndarray) – MIMO channel matrix with dimension (1, Nt).
- Returns
W – The precoder that can be applied to the input data.
- Return type
np.ndarray
-
static
_calc_receive_filter
(channel: numpy.ndarray, noise_var: Optional[float] = None) → numpy.ndarray[source]¶ Calculate the receive filter for the MRT scheme.
- Parameters
channel (np.ndarray) – MIMO channel matrix.
noise_var (float) – The noise variance.
- Returns
G_H – The receive_filter that can be applied to the input data.
- Return type
np.ndarray
-
decode
(received_data: numpy.ndarray) → numpy.ndarray[source]¶ Perform the decoding of the received_data for the GMD MIMO.
- Parameters
received_data (np.ndarray) – Received data, which was encoded with the Alamouti scheme and corrupted by the channel channel.
- Returns
decoded_data – The decoded data.
- Return type
np.ndarray
-
encode
(transmit_data: numpy.ndarray) → numpy.ndarray[source]¶ Encode the transmit data array to be transmitted using the GMD MIMO scheme.
The GMD MIMO scheme is based on the Geometric Mean Decomposition (GMD) of the channel. The channel is decomposed into H = Q R P^H, where R is an upper triangular matrix with all diagonal elements being equal to the geometric mean of the singular values of the channel matrix H.
corresponds to using the ‘U’ and ‘V’ matrices from the SVD decomposition of the channel as the precoder and receive filter.
- Parameters
transmit_data (np.ndarray) – A numpy array with the data to be transmitted.
- Returns
encoded_data – The encoded transmit_data.
- Return type
np.ndarray
-
class
pyphysim.mimo.mimo.
MRC
(channel: Optional[numpy.ndarray] = None)[source]¶ Bases:
pyphysim.mimo.mimo.Blast
MIMO class for the MRC scheme.
The receive filter used will depend on the noise variance (see the
set_noise_var()
method). If the noise variance is positive the MMSE filter will be used, otherwise noise variance will be ignored and the Zero-Forcing filter will be used.The receive filter in the Blast class already does the maximum ratio combining. Therefore, this MRC class simply inherits from the Blast class and only exists for completion.
- Parameters
channel (np.ndarray) – MIMO channel matrix.
-
set_channel_matrix
(channel: numpy.ndarray) → None[source]¶ Set the channel matrix.
- Parameters
channel (np.ndarray) – MIMO channel matrix. The MRC MIMO scheme is defined for the scenario with multiple receive antennas and a single receive antenna. If channel is 1D assume that the number of transmit antennas is equal to 1.
-
class
pyphysim.mimo.mimo.
MRT
(channel: Optional[numpy.ndarray] = None)[source]¶ Bases:
pyphysim.mimo.mimo.MisoBase
MIMO class for the MRT scheme.
The number of streams for the MRT scheme is always equal to one, but it still employs multiple transmit antennas.
If channel is not provided you need to call the set_channel_matrix method before calling the other methods.
- Parameters
channel (np.ndarray) – MISO channel vector. It must be a 1D numpy array, where the number of receive antennas is assumed to be equal to 1.
-
static
_calc_precoder
(channel: numpy.ndarray) → numpy.ndarray[source]¶ Calculate the linear precoder for the MRT scheme.
The MRT scheme corresponds to multiplying the symbol from each transmit antenna with a complex number corresponding to the inverse of the phase of the channel so as to ensure that the signals add constructively at the receiver. This also means that the MRT scheme only be applied to scenarios with a single receive antenna.
- Parameters
channel (np.ndarray) – MIMO channel matrix with dimension (1, Nt).
- Returns
W – The precoder that can be applied to the input data.
- Return type
np.ndarray
-
static
_calc_receive_filter
(channel: numpy.ndarray, noise_var: Optional[float] = None) → numpy.ndarray[source]¶ Calculate the receive filter for the MRT scheme.
- Parameters
channel (np.ndarray) – MIMO channel matrix.
noise_var (float) – The noise variance.
- Returns
G_H – The receive_filter that can be applied to the input data.
- Return type
np.ndarray
-
decode
(received_data: numpy.ndarray) → numpy.ndarray[source]¶ Decode the received data array.
- Parameters
received_data (np.ndarray) – Received data, which was encoded with the MRT scheme and corrupted by the channel channel.
- Returns
decoded_data – The decoded data.
- Return type
np.ndarray
-
encode
(transmit_data: numpy.ndarray) → numpy.ndarray[source]¶ Encode the transmit data array to be transmitted using the MRT scheme.
The MRT scheme corresponds to multiplying the symbol from each transmit antenna with a complex number corresponding to the inverse of the phase of the channel so as to ensure that the signals add constructively at the receiver. This also means that the MRT scheme only be applied to scenarios with a single receive antenna.
- Parameters
transmit_data (np.ndarray) – A numpy array with the data to be transmitted.
- Returns
encoded_data – The encoded transmit_data.
- Return type
np.ndarray
-
class
pyphysim.mimo.mimo.
MimoBase
(channel: Optional[numpy.ndarray] = None)[source]¶ Bases:
object
Base Class for MIMO schemes.
All subclasses must implement at least the following methods:
getNumberOfLayers()
: Should return the number of layers of that specific MIMO schemeencode()
: The encode method must perform everything executed at the transmitter for that specific MIMO scheme. This also include the power division among the transmit antennas.decode()
: Analogous to the encode method, the decode method must perform everything performed at the receiver.
If possible, subclasses should implement the _calc_precoder and _calc_receive_filter static methods and use them in the implementation of encode and decode. This will allow using the calc_linear_SINRs and calc_SINRs methods to calculate the post processing SINRs. Note that calling the _calcZeroForceFilter and _calcMMSEFilter methods in the implementation of the receive filter calculation can be useful.
If you can’t implement the _calc_precoder and _calc_receive_filter static methods` (because there is no linear precoder or receive filter for the MIMO scheme in the subclass, for instance), then you should implement the calc_linear_SINRs method in the subclass instead.
- Parameters
channel (np.ndarray | None) – MIMO channel matrix. This should be a 1D or 2D numpy array. The allowed dimensions will depend on the particular MIMO scheme implemented in a subclass.
-
property
Nr
¶ Get the number of receive antennas
- Returns
The number of receive antennas.
- Return type
-
property
Nt
¶ Get the number of transmit antennas
- Returns
The number of transmit antennas.
- Return type
-
static
_calcMMSEFilter
(channel: numpy.ndarray, noise_var: float) → numpy.ndarray[source]¶ Calculates the MMSE filter to cancel the inter-stream interference.
- Parameters
channel (np.ndarray) – MIMO channel matrix.
noise_var (float) – Noise variance.
- Returns
W – The MMSE receive filter.
- Return type
np.ndarray
-
static
_calcZeroForceFilter
(channel: numpy.ndarray) → numpy.ndarray[source]¶ Calculates the Zero-Force filter to cancel the inter-stream interference.
- Parameters
channel (np.ndarray) – MIMO channel matrix.
- Returns
W – The Zero-Forcing receive filter.
- Return type
np.ndarray
Notes
The Zero-Force filter basically corresponds to the pseudo-inverse of the channel matrix.
-
static
_calc_precoder
(channel: numpy.ndarray) → numpy.ndarray[source]¶ Calculate the linear precoder for the MIMO scheme, if there is any.
- Parameters
channel (np.ndarray) – MIMO channel matrix.
- Returns
W – The precoder that can be applied to the input data.
- Return type
np.ndarray
-
static
_calc_receive_filter
(channel: numpy.ndarray, noise_var: Optional[float] = None) → numpy.ndarray[source]¶ Calculate the receive filter for the MIMO scheme, if there is any.
- Parameters
channel (np.ndarray) – MIMO channel matrix.
noise_var (float) – The noise variance.
- Returns
G_H – The receive_filter that can be applied to the input data.
- Return type
np.ndarray
-
calc_SINRs
(noise_var: float) → numpy.ndarray[source]¶ Calculate the SINRs (in dB) of the multiple streams.
- Parameters
noise_var (float) – The noise variance.
- Returns
SINRs – The SINRs (in dB) of the multiple streams.
- Return type
np.ndarray
-
calc_linear_SINRs
(noise_var: float) → numpy.ndarray[source]¶ Calculate the SINRs (in linear scale) of the multiple streams.
- Parameters
noise_var (float) – The noise variance.
- Returns
sinrs – The sinrs (in linear scale) of the multiple streams.
- Return type
np.ndarray
-
abstract
decode
(received_data: numpy.ndarray) → numpy.ndarray[source]¶ Method to decode the transmit data array to be transmitted using some MIMO scheme. This method must be implemented in a subclass.
- Parameters
received_data (np.ndarray) – The received data.
- Returns
decoded_data – The decoded data.
- Return type
np.ndarray
-
abstract
encode
(transmit_data: numpy.ndarray) → numpy.ndarray[source]¶ Method to encode the transmit data array to be transmitted using some MIMO scheme. This method must be implemented in a subclass.
- Parameters
transmit_data (np.ndarray) – The data to be transmitted.
- Returns
encoded_data – The encoded transmit_data.
- Return type
np.ndarray
-
abstract
getNumberOfLayers
() → int[source]¶ Get the number of layers of the MIMO scheme.
Notes
This method must be implemented in each subclass of MimoBase.
- Returns
The number of layers.
- Return type
-
set_channel_matrix
(channel: numpy.ndarray) → None[source]¶ Set the channel matrix.
- Parameters
channel (np.ndarray) – MIMO channel matrix. This should be a 1D or 2D numpy array. The allowed dimensions will depend on the particular MIMO scheme implemented in a subclass.
-
class
pyphysim.mimo.mimo.
MisoBase
(channel: Optional[numpy.ndarray] = None)[source]¶ Bases:
pyphysim.mimo.mimo.MimoBase
Base Class for MISO schemes.
All subclasses must implement at least the following methods:
MimoBase.encode()
: The encode method must perform everything executed at the transmitter for that specific MIMO scheme. This also include the power division among the transmit antennas.MimoBase.decode()
: Analogous to the encode method, the decode method must perform everything performed at the receiver.
Other optional methods that might be useful implementing in subclasses are the _calc_precoder and _calc_receive_filter methods.
- Parameters
channel (np.ndarray) – MISO channel matrix/vector. MISO schemes are defined for scenarios with multiple transmit antennas and a single receive antenna. If channel is 2D, then the first dimension size must be equal to 1.
-
getNumberOfLayers
() → int[source]¶ Get the number of layers of the MISO scheme.
Because a MISO scheme only has one receive antenna then then number of layers is always equal to 1.
- Returns
The number of layers.
- Return type
-
set_channel_matrix
(channel: numpy.ndarray) → None[source]¶ Set the channel matrix.
- Parameters
channel (np.ndarray) – MISO channel vector. A MISO scheme is defined for the scenario with multiple transmit antennas and a single receive antenna. If channel is 2D then the first dimension size must be equal to 1.
- Returns
- Return type
-
class
pyphysim.mimo.mimo.
SVDMimo
(channel: Optional[numpy.ndarray] = None)[source]¶ Bases:
pyphysim.mimo.mimo.Blast
MIMO class for the SVD MIMO scheme.
- Parameters
channel (np.ndarray) – MIMO channel matrix.
-
static
_calc_precoder
(channel: numpy.ndarray) → numpy.ndarray[source]¶ Calculate the linear precoder for the SVD MIMO scheme.
The SVD MIMO scheme employs as precoder the right singular matrix from SVD (Singular Value Decomposition) of the channel.
- Parameters
channel (np.ndarray) – MIMO channel matrix with dimension (1, Nt).
- Returns
W – The precoder that can be applied to the input data.
- Return type
np.ndarray
-
static
_calc_receive_filter
(channel: numpy.ndarray, noise_var: Optional[float] = None) → numpy.ndarray[source]¶ Calculate the receive filter for the SVD MIMO scheme.
- Parameters
channel (np.ndarray) – MIMO channel matrix.
noise_var (float) – The noise variance.
- Returns
G_H – The receive_filter that can be applied to the input data.
- Return type
np.ndarray
-
decode
(received_data: numpy.ndarray) → numpy.ndarray[source]¶ Perform the decoding of the received_data for the SVD MIMO scheme with the channel channel.
- Parameters
received_data (np.ndarray) – Received data, which was encoded with the Alamouti scheme and corrupted by the channel channel.
- Returns
decoded_data – The decoded data.
- Return type
np.ndarray
-
encode
(transmit_data: numpy.ndarray) → numpy.ndarray[source]¶ Encode the transmit data array to be transmitted using the SVD MIMO scheme.
The SVD MIMO scheme corresponds to using the ‘U’ and ‘V’ matrices from the SVD decomposition of the channel as the precoder and receive filter.
- Parameters
transmit_data (np.ndarray) – A numpy array with the data to be transmitted.
- Returns
encoded_data – The encoded transmit_data.
- Return type
np.ndarray