Subclasses:  Hybrid Digital/Analog Transmitter

The transmitter object captures the properties and responsibilities of transmission. Its primary responsibility lay in MIMO precoding and applying a transmit power to produce the signal that departs from its antennas.

The $N_{\mathrm{t}} \times 1$ signal vector $\mathrm{x}$ leaving the transmitter and entering the channel can be written as

where $\mathbf{s}$ is the $N_{\mathrm{s}} \times 1$ complex transmit symbol vector, $\mathbf{F}$ is the $N_{\mathrm{t}} \times N_{\mathrm{s}}$ precoding matrix, and $P_{\mathrm{tx}}$ is the transmit energy per symbol, all of which are housed by and the responsibility of the transmitter object. While not strictly followed by MFM, we maintain this notation throughout this documentation to better communicate the material.

The transmitter object represents a fully-digital precoder, in contrast to a hybrid digital/analog precoder. As such, this page will focus specifically on the transmitter object while further documentation can be found on the hybrid digital/analog transmitter on its page.

### Creating a Transmitter

To create a transmitter object tx, a convenient way is to use

tx = transmitter.create();


### Key Properties

A transmitter’s precoding matrix is captured by the property

tx.precoder


Its transmit symbol is captured by

tx.transmit_symbol


Its transmit power (in watts) is captured by

tx.transmit_power


The symbol bandwidth (in Hz) and symbol period (in seconds) are captured by

tx.symbol_bandwidth
tx.symbol_period


### Setting the Transmit Symbol

To set the $N_{\mathrm{s}} \times 1$ complex transmit symbol vector $\mathbf{s}$, one can use

tx.set_transmit_symbol(s)


where s is an $N_{\mathrm{s}} \times 1$ column vector.

### Setting the Number of Transmit Streams

To set the number of streams multiplexed at the transmitter $N_{\mathrm{s}}$, one can use

tx.set_num_streams(Ns)


where Ns should be a positive integer.

### Setting the Transmit Array

Every transmitter object has its own array object, capturing—at the very least—how many antennas the transmitter has. To set the transmit array, simply use

tx.set_array(a)


where a is an array object.

It may be important to note that MFM performs a deep copy of the array before setting it at the transmitter.

### Setting the Transmit Power

The transmit power is a critical component of any transmitter. Typically, engineers regard transmit power in terms of watts (joules per second) or decibel milliwatts (dBm).

The variable $P_{\mathrm{tx}}$ is often used in single-letter (symbol-level) MIMO equations captures the transmit “power” in units joules per symbol rather than joules per second; note that this is also often termed the energy per symbol, joules being a unit of energy and not of power.

Let us define $B$ as the symbol bandwidth (in Hz). Then, it is common to take $T = 1 / B$ as the symbol period (in seconds).

Thus, expending $P_{\mathrm{tx}}$ joules per symbol reduces to expending $P_{\mathrm{tx}} / T$ or $P_{\mathrm{tx}} \times B$ watts (joules per second).

From this, it is clear that setting the transmit “power” at the symbol level requires defining a symbol bandwidth/period. Therefore, it is critical that users set a symbol bandwidth when setting the transmit power in terms of watts.

For example, if the bandwidth is 50 MHz and we want to transmit with 1 watt, we can achieve the desired transmit energy per symbol via

tx.set_symbol_bandwidth(50e6)
tx.set_transmit_power(1)


Note that setting the symbol bandwidth also sets the symbol period.

The set_transmit_power() function also accepts input arguments of the form

tx.set_transmit_power(P,'dBm')


where P is in units of dBm.

Note that the transmit energy per symbol is stored in the property

tx.transmit_energy_per_symbol


and is automatically updated anytime the transmit power or the symbol bandwidth change.

### Example Setup

A typical transmitter setup looks something similar to

tx = transmitter.create()
tx.set_symbol_bandwidth(B)
tx.set_num_streams(Ns)
tx.set_set_array(a)
tx.set_transmit_power(Ptx,'dBm')


where B is the bandwidth in Hz, Ns is the number of streams to multiplex, a is an array object, and Ptx is the transmit power in dBm.

After this initial setup, the transmitter tx can be configured to transmit symbol vectors using its precoder.

### Precoding Power Budget

MFM supports the enforcement of a precoding power budget, as is ubiquitous in MIMO literature to limit and abstract out the transmit power.

A precoding power budget takes the form

By default, the transmitter sets $P = N_{\mathrm{s}}$ to ensure that the average power of the transmitted vector $\mathbf{x}$ is in fact $P_{\mathrm{tx}}$ joules per symbol when the covariance of the transmit symbols is

via

tx.set_precoder_power_budget(P)


### Setting the Precoder

There are multiple routes to setting a transmitter’s precoding matrix $\mathbf{F}$. The most straightforward within the scope of this transmitter documentation is to simply use

tx.set_precoder(F)


where F is an $N_{\mathrm{t}} \times N_{\mathrm{s}}$ precoding matrix; if the precoding matrix is not of appropriate size based on the current array or number of streams, MFM will alert the user and it will not set the precoder.

### Shorthand Methods

To provide convenient ways to retrieve common MIMO-related quantities from a transmitter object tx, there exist the following so-called shorthand methods.

• tx.F — Returns the precoding matrix.
• tx.Ns — Returns the number of streams.
• tx.Nt — Returns the number of transmit antennas.
• tx.Ptx — Returns the transmit energy per symbol (joules per symbol).
• tx.Rs — Returns the transmit symbol covariance matrix.
• tx.s — Returns the transmit symbol.
• tx.x — Returns the signal vector transmitted from the transmitter.

### List of Properties

The transmitter object contains the following properties:

• transmitter.name
• transmitter.type
• transmitter.array
• transmitter.num_antennas
• transmitter.num_streams
• transmitter.symbol_bandwidth
• transmitter.symbol_period
• transmitter.transmit_power
• transmitter.transmit_energy_per_symbol
• transmitter.transmitted_signal
• transmitter.transmit_symbol
• transmitter.transmit_symbol_covariance
• transmitter.precoder
• transmitter.precoder_power_budget
• transmitter.channel_state_information
• transmitter.transmit_strategy
• transmitter.destination

### List of Methods

The transmitter object contains the following methods:

### Methods Documentation

#### F()

Returns the precoding matrix.

Usage:
val = F()
Return Values:
val — the precoding matrix

Back to methods

#### Ns()

Returns the number of streams.

Usage:
val = Ns()
Return Values:
val — the number of streams

Back to methods

#### Nt()

Returns the number of transmit antennas.

Usage:
val = Nt()
Return Values:
val — the number of transmit antennas

Back to methods

#### P()

Returns the transmit energy per symbol (joules per symbol).

Usage:
val = P()
Return Values:
val — the transmit energy per symbol

Back to methods

#### Ptx()

Returns the transmit energy per symbol (joules per symbol).

Usage:
val = Ptx()
Return Values:
val — the transmit energy per symbol

Back to methods

#### Rs()

Returns the transmit symbol covariance matrix.

Usage:
val = Rs()
Return Values:
val — the transmit symbol covariance matrix

Back to methods

#### check_precoder_dimensions(F)

Checks to see if the precoding matrix has dimensions appropriate for the current number of antennas and streams.

Usage:
out = check_precoder_dimensions()
out = check_precoder_dimensions(F)
Input Arguments:
F — (optional) a precoding matrix; if not passed, the transmitter’s current precoder will be assessed
Return Values:
out — a boolean indicating if the precoder is of appropriate dimension

Back to methods

#### check_precoder_power_budget(F)

Checks to see if the precoding matrix meets the allotted precoding power budget.

Usage:
out = check_precoder_power_budget()
out = check_precoder_power_budget(F)
Input Arguments:
F — (optional) a precoding matrix; if not passed, the transmitter’s current precoding matrix will be assessed
Return Values:
out — a boolean indicating if the precoding power budget is met by the current precoding matrix (returns true if met)

Back to methods

#### check_transmit_strategy(strategy)

Returns a boolean indicating if a transmit strategy is valid.

Usage:
out = check_transmit_strategy(strategy)
Input Arguments:
strategy — a string indentifying a specific transmit strategy
Return Values:
out — a boolean

Back to methods

#### configure_transmitter(strategy)

Configures the transmitter’s precoder according to the current/specified transmit strategy, incorporating channel state information as applicable.

Usage:
configure_transmitter()
configure_transmitter(strategy)
Input Arguments:
strategy — (optional) transmit strategy to use; if not passed, the current transmit strategy will be used

Back to methods

#### configure_transmitter_eigen()

Configures the transmitter to transmit along the strongest components of the desired channel, neglecting interference, etc.

Usage:
configure_transmitter_eigen()

Back to methods

#### configure_transmitter_identity()

Configures the transmit precoder to an identity matrix.

Usage:
configure_transmitter_identity()

Back to methods

#### create(type)

Creates a transmitter.

Usage:
obj = transmitter.create()
obj = transmitter.create(type)
Input Arguments:
type — (optional) a string specifying the type of transmitter to create; either ‘digital’ or ‘hybrid’
Return Values:
obj — a transmitter object

Back to methods

#### enforce_precoder_power_budget()

Scales the precoding matrix to ensure that it satisfies the precoding power budget.

Usage:
enforce_precoder_power_budget()

Back to methods

#### get_destination_channel_state_information_index()

Returns the index of the transmit CSI entry whose receive device corresponds to the transmitter’s destination device.

Usage:
idx = get_destination_channel_state_information_index()
Return Values:
idx — an index; if zero, the CSI entry was not found

Back to methods

#### get_valid_transmit_strategies()

Returns a cell containing all valid transmit strategy strings.

Usage:
out = get_valid_transmit_strategies()
Return Values:
out — a cell of strings
Notes:
This function will differ between a fully-digital transmitter and hybrid digital/analog transmitter to account for transmit strategies that are specific to each.
This function will need to be updated anytime a custom/new transmit strategy is added.
The strings should be all lowercase.

Back to methods

#### initialize()

Executes initializations for a transmitter.

Usage:
initialize()

Back to methods

#### parse_channel_state_information()

Splits the CSI into two components: (i) a struct containing CSI for transmitting to the destination and (ii) a cell of structs containing CSI for all other links (e.g., interference channels).

Usage:
[csi_des,csi_int] = parse_channel_state_information()
Return Values:
csi_des — a CSI struct
csi_int — a cell of one or more CSI structs

Back to methods

#### s()

Returns the transmit symbol vector.

Usage:
val = s()
Return Values:
val — the transmit symbol vector

Back to methods

#### set_array(array)

Sets the transmitter’s array object and updates the number of transmit antennas.

Usage:
set_array(array)
Input Arguments:
array — an array object
Notes:
Also updates number of antennas based on array.

Back to methods

#### set_channel_state_information(csi)

Sets the transmit channel state information (CSI).

Usage:
set_channel_state_information(csi)
Input Arguments:
csi — a cell of channel state information structs or a single struct of csi

Back to methods

#### set_destination(device_destination)

Sets the destination (device the transmitter aims to serve).

Usage:
set_destination(device_destination)
Input Arguments:
device_destination — a device object

Back to methods

#### set_name(name)

Sets the name of the transmitter.

Usage:
set_name()
set_name(name)
Input Arguments:
name — (optional) a string; if not passed, ‘transmitter’ is the default name used

Back to methods

#### set_num_streams(Ns)

Sets the number of data streams being transmitted.

Usage:
set_num_streams(Ns)
Input Arguments:
Ns — number of data streams
Notes:
Also updates the transmit symbol covariance to Rs = eye(Ns) ./ sqrt(Ns). This can be overwritten if needed using set_transmit_symbol_covariance().
Also updates the precoder power budget to the number of streams. This can be overwritten if needed.

Back to methods

#### set_precoder(F)

Sets the transmit precoding matrix.

Usage:
set_precoder()
set_precoder(F)
Input Arguments:
F — transmit precoding matrix; if not provided an identity matrix of size Nt-by-Ns will be used

Back to methods

#### set_precoder_power_budget(P)

Sets the precoding matrix power budget.

Usage:
set_precoder_power_budget(P)
Input Arguments:
P — total power budget (squared Frobenius norm) of effective precoding matrix

Back to methods

#### set_symbol_bandwidth(B)

Sets the transmit symbol bandwidth.

Usage:
set_symbol_bandwidth(B)
Input Arguments:
B — symbol bandwidth in Hertz
Notes:
Also updates the symbol period and transmit energy per symbol accordingly.

Back to methods

#### set_transmit_power(P,unit)

Sets the transmit power.

Usage:
set_transmit_power(P)
set_transmit_power(P,unit)
Input Arguments:
P — the transmit power
unit — an optional unit specifying the units of P (default of Watts)

Back to methods

#### set_transmit_strategy(strategy)

Sets the transmit strategy.

Usage:
set_transmit_strategy()
set_transmit_strategy(strategy)
Input Arguments:
strategy — (optional) a string specifying the transmit strategy; options vary depending on transmitter type (digital vs. hybrid); if not passed, identity transmission will be used

Back to methods

#### set_transmit_symbol(s)

Sets the symbol vector to be transmitted.

Usage:
set_transmit_symbol(s)
Input Arguments:
s — the symbol vector transmitted

Back to methods

#### set_transmit_symbol_covariance(Rs)

Sets the transmit symbol covariance matrix.

Usage:
set_transmit_symbol_covariance()
set_transmit_symbol_covariance(Rs)
Input Arguments:
Rs — (optional) the covariance matrix of the transmit symbols; if not passed, the default is an identity matrix normalized to unit power

Back to methods

#### set_transmitted_signal(x)

Sets the signal vector that is transmitted (i.e., the signal that exits the transmit array).

Usage:
set_transmitted_signal(x)
Input Arguments:
x — the vector leaving the transmit array (i.e., x = sqrt(Ptx) * F * s)

Back to methods

#### set_type(type)

Sets the type of the transmitter.

Usage:
set_type()
set_type(type)
Input Arguments:
type — (optional) a string; if not passed, ‘digital’ is the default type used

Back to methods

#### transmitter(name)

Creates an instance of a transmitter object.

Usage:
obj = transmitter()
obj = transmitter(name)
Input Arguments:
name — (optional) a name for the transmitter
Return Values:
obj — a transmitter object

Back to methods

#### turn_off()

Turns off the transmitter by setting its precoder to a zeros matrix.

Usage:
turn_off()

Back to methods

#### update_transmit_energy_per_symbol()

Updates the energy per symbol property.

Usage:
update_transmit_energy_per_symbol()
Notes:
Is automatically called when transmit power or symbol bandwidth is set.

Back to methods

#### update_transmitted_signal()

Recomputes the transmitted signal vector.

Usage:
update_transmitted_signal()
Notes:
Should be called anytime the transmit power, precoder, or transmit symbol are changed.

Back to methods

#### x()

Returns the transmitted signal vector.

Usage:
val = x()
Return Values:
val — the transmitted signal vector

Back to methods