LMMSEChannelEstimator#

class sionna.phy.ofdm.LMMSEChannelEstimator(resource_grid: sionna.phy.ofdm.resource_grid.ResourceGrid, cov_mat_time: torch.Tensor, cov_mat_freq: torch.Tensor, cov_mat_space: torch.Tensor | None = None, order: str = 't-f', precision: Literal['single', 'double'] | None = None, device: str | None = None, **kwargs)[source]#

Bases: sionna.phy.ofdm.channel_estimation.BaseChannelEstimator

LMMSE channel estimation for MIMO OFDM systems, where LMMSE filtering (interpolation and smoothing) is applied across time, frequency, and (optionally) spatial dimensions. Here, interpolation refers to estimating the channel at resource elements without an input estimate, while smoothing refers to updating existing estimates using channel statistics and error variances. The frequency and time passes perform both interpolation and smoothing, whereas the optional spatial pass performs smoothing only. We use filtering as an umbrella term for both operations.

Depending on the value of order, the filtering is carried out across time (t), i.e., OFDM symbols, frequency (f), i.e., subcarriers, and optionally space (s), i.e., receive antennas, in any desired order.

For simplicity, we describe the underlying algorithm assuming that filtering across the sub-carriers is performed first, followed by filtering across OFDM symbols, and finally by smoothing across receive antennas. The algorithm is similar if filtering is performed in a different order. For clarity, antenna indices are omitted when describing frequency and time filtering, as the same process is applied to all the antennas.

From the input y, we start by extracting the observations at the non-zero positions of the PilotPattern and arranging them in a resource grid with the following model: \(\mathbf{Y} = \mathbf{H} \odot \mathbf{P} + \mathbf{N} \in \mathbb{C}^{N \times M}\), where \(\mathbf{Y}\) are the observations, \(\mathbf{H} \in \mathbb{C}^{N \times M}\) is the channel matrix, \(\mathbf{P} \in \mathbb{C}^{N \times M}\) is the matrix of non-zero pilots, and \(\mathbf{N} \in \mathbb{C}^{N \times M}\) is the noise matrix. \(N\) denotes the number of OFDM symbols and \(M\) the number of sub-carriers.

A least-squares (LS) estimate and corresponding error variances are first computed as:

\[\begin{split}\hat{\mathbf{H}} &= \mathbf{Y} \odot \frac{\mathbf{P}^\star}{\left|\mathbf{P}\right|^2} = \mathbf{H} + \tilde{\mathbf{H}}\\ \sigma^2_{n,m} &= \mathbb{E}\left[\tilde{h}_{n,m} \tilde{h}_{n,m}^\star \right] = \frac{N_0}{\left|p_{n,m}\right|^2}.\end{split}\]

The first pass then consists in filtering across the sub-carriers:

\[\hat{\mathbf{h}}_n^{(1)} = \mathbf{A}_n \hat{\mathbf{h}}_n\]

where \(1 \leq n \leq N\) is the OFDM symbol index and \(\hat{\mathbf{h}}_n\) is the \(n^{\text{th}}\) (transposed) row of \(\hat{\mathbf{H}}\). \(\mathbf{A}_n\) is the \(M \times M\) matrix such that:

\[\mathbf{A}_n = \bar{\mathbf{A}}_n \mathbf{\Pi}_n^\intercal\]

where

\[\bar{\mathbf{A}}_n = \underset{\mathbf{Z} \in \mathbb{C}^{M \times K_n}}{\text{argmin}} \left\lVert \mathbf{Z}\left( \mathbf{\Pi}_n^\intercal \mathbf{R^{(f)}} \mathbf{\Pi}_n + \mathbf{\Sigma}_n \right) - \mathbf{R^{(f)}} \mathbf{\Pi}_n \right\rVert_{\text{F}}^2\]

and \(\mathbf{R^{(f)}}\) is the \(M \times M\) channel frequency covariance matrix, \(\mathbf{\Pi}_n\) the \(M \times K_n\) matrix that spreads \(K_n\) values to a vector of size \(M\) according to the pilot_pattern for the \(n^{\text{th}}\) OFDM symbol, and \(\mathbf{\Sigma}_n \in \mathbb{R}^{K_n \times K_n}\) is the channel estimation error covariance built from err_var and assumed to be diagonal. Computation of \(\bar{\mathbf{A}}_n\) uses a diagonally loaded Cholesky factorization followed by triangular solves. The diagonal loading improves numerical stability for badly conditioned covariance matrices.

The channel estimation error variances after the first filtering pass are computed as

\[\mathbf{\Sigma}^{(1)}_n = \text{diag} \left( \mathbf{R^{(f)}} - \mathbf{A}_n \mathbf{\Xi}_n \mathbf{R^{(f)}} \right)\]

where \(\mathbf{\Xi}_n\) is the diagonal matrix of size \(M \times M\) that zeros the columns corresponding to sub-carriers not carrying any pilots. Note that interpolation is not performed for OFDM symbols which do not carry pilots.

Remark: The filter matrix differs across OFDM symbols as different OFDM symbols may carry pilots on different sub-carriers and/or have different estimation error variances.

Scaling of the estimates is then performed to ensure that their variances match the ones expected by the next filtering step, and the error variances are updated accordingly:

\[\begin{split}\begin{aligned} \left[\hat{\mathbf{h}}_n^{(2)}\right]_m &= s_{n,m} \left[\hat{\mathbf{h}}_n^{(1)}\right]_m\\ \left[\mathbf{\Sigma}^{(2)}_n\right]_{m,m} &= s_{n,m}\left( s_{n,m}-1 \right) \left[\hat{\mathbf{\Sigma}}^{(1)}_n\right]_{m,m} + \left( 1 - s_{n,m} \right) \left[\mathbf{R^{(f)}}\right]_{m,m} + s_{n,m} \left[\mathbf{\Sigma}^{(1)}_n\right]_{m,m} \end{aligned}\end{split}\]

where the scaling factor \(s_{n,m}\) is such that:

\[\mathbb{E} \left\{ \left\lvert s_{n,m} \left[\hat{\mathbf{h}}_n^{(1)}\right]_m \right\rvert^2 \right\} = \left[\mathbf{R^{(f)}}\right]_{m,m} + \mathbb{E} \left\{ \left\lvert s_{n,m} \left[\hat{\mathbf{h}}^{(1)}_n\right]_m - \left[\mathbf{h}_n\right]_m \right\rvert^2 \right\}\]

which leads to:

\[\begin{split}\begin{aligned} s_{n,m} &= \frac{2 \left[\mathbf{R^{(f)}}\right]_{m,m}}{\left[\mathbf{R^{(f)}}\right]_{m,m} - \left[\mathbf{\Sigma}^{(1)}_n\right]_{m,m} + \left[\hat{\mathbf{\Sigma}}^{(1)}_n\right]_{m,m}}\\ \hat{\mathbf{\Sigma}}^{(1)}_n &= \mathbf{A}_n \mathbf{R^{(f)}} \mathbf{A}_n^{\mathrm{H}}. \end{aligned}\end{split}\]

The second pass consists in filtering across the OFDM symbols:

\[\hat{\mathbf{h}}_m^{(3)} = \mathbf{B}_m \tilde{\mathbf{h}}^{(2)}_m\]

where \(1 \leq m \leq M\) is the sub-carrier index and \(\tilde{\mathbf{h}}^{(2)}_m\) is the \(m^{\text{th}}\) column of

\[\begin{split}\hat{\mathbf{H}}^{(2)} = \begin{bmatrix} {\hat{\mathbf{h}}_1^{(2)}}^\intercal\\ \vdots\\ {\hat{\mathbf{h}}_N^{(2)}}^\intercal \end{bmatrix}\end{split}\]

and \(\mathbf{B}_m\) is the \(N \times N\) LMMSE filter matrix:

\[\mathbf{B}_m = \bar{\mathbf{B}}_m \tilde{\mathbf{\Pi}}_m^\intercal\]

where

\[\bar{\mathbf{B}}_m = \underset{\mathbf{Z} \in \mathbb{C}^{N \times L_m}}{\text{argmin}} \left\lVert \mathbf{Z} \left( \tilde{\mathbf{\Pi}}_m^\intercal \mathbf{R^{(t)}}\tilde{\mathbf{\Pi}}_m + \tilde{\mathbf{\Sigma}}^{(2)}_m \right) - \mathbf{R^{(t)}}\tilde{\mathbf{\Pi}}_m \right\rVert_{\text{F}}^2\]

where \(\mathbf{R^{(t)}}\) is the \(N \times N\) channel time covariance matrix, \(\tilde{\mathbf{\Pi}}_m\) the \(N \times L_m\) matrix that spreads \(L_m\) values to a vector of size \(N\) according to the pilot_pattern for the \(m^{\text{th}}\) sub-carrier, and \(\tilde{\mathbf{\Sigma}}^{(2)}_m \in \mathbb{R}^{L_m \times L_m}\) is the diagonal matrix of channel estimation error variances built by gathering the error variances from (\(\mathbf{\Sigma}^{(2)}_1,\dots,\mathbf{\Sigma}^{(2)}_N\)) corresponding to resource elements carried by the \(m^{\text{th}}\) sub-carrier. Computation of \(\bar{\mathbf{B}}_m\) uses a diagonally loaded Cholesky factorization followed by triangular solves. The diagonal loading improves numerical stability for badly conditioned covariance matrices.

The resulting channel estimate for the resource grid is

\[\hat{\mathbf{H}}^{(3)} = \left[ \hat{\mathbf{h}}_1^{(3)} \dots \hat{\mathbf{h}}_M^{(3)} \right]\]

The resulting channel estimation error variances are the diagonal coefficients of the matrices

\[\mathbf{\Sigma}^{(3)}_m = \mathbf{R^{(t)}} - \mathbf{B}_m \tilde{\mathbf{\Xi}}_m \mathbf{R^{(t)}}, 1 \leq m \leq M\]

where \(\tilde{\mathbf{\Xi}}_m\) is the diagonal matrix of size \(N \times N\) that zeros the columns corresponding to OFDM symbols not carrying any pilots.

Remark: The filter matrix differs across sub-carriers as different sub-carriers may have different estimation error variances computed by the first pass. However, all sub-carriers carry at least one channel estimate as a result of the first pass, ensuring that a channel estimate is computed for all the resource elements after the second pass.

Remark: LMMSE filtering requires knowledge of the time and frequency covariance matrices of the channel. The functions tdl_time_cov_mat() and tdl_freq_cov_mat() compute the expected time and frequency covariance matrices, respectively, for the TDL channel models.

Scaling of the estimates is then performed to ensure that their variances match the ones expected by the next smoothing step, and the error variances are updated accordingly:

\[\begin{split}\begin{aligned} \left[\hat{\mathbf{h}}_m^{(4)}\right]_n &= \gamma_{m,n} \left[\hat{\mathbf{h}}_m^{(3)}\right]_n\\ \left[\mathbf{\Sigma}^{(4)}_m\right]_{n,n} &= \gamma_{m,n}\left( \gamma_{m,n}-1 \right) \left[\hat{\mathbf{\Sigma}}^{(3)}_m\right]_{n,n} + \left( 1 - \gamma_{m,n} \right) \left[\mathbf{R^{(t)}}\right]_{n,n} + \gamma_{m,n} \left[\mathbf{\Sigma}^{(3)}_n\right]_{m,m} \end{aligned}\end{split}\]

where:

\[\begin{split}\begin{aligned} \gamma_{m,n} &= \frac{2 \left[\mathbf{R^{(t)}}\right]_{n,n}}{\left[\mathbf{R^{(t)}}\right]_{n,n} - \left[\mathbf{\Sigma}^{(3)}_m\right]_{n,n} + \left[\hat{\mathbf{\Sigma}}^{(3)}_n\right]_{m,m}}\\ \hat{\mathbf{\Sigma}}^{(3)}_m &= \mathbf{B}_m \mathbf{R^{(t)}} \mathbf{B}_m^{\mathrm{H}} \end{aligned}\end{split}\]

Finally, if requested, a spatial smoothing step is applied to every resource element carrying a channel estimate. For clarity, we drop the resource element indexing \((n,m)\). We denote by \(L\) the number of receive antennas, and by \(\mathbf{R^{(s)}}\in\mathbb{C}^{L \times L}\) the spatial covariance matrix.

LMMSE spatial smoothing consists in the following computations:

\[\hat{\mathbf{h}}^{(5)} = \mathbf{C} \hat{\mathbf{h}}^{(4)}\]

where

\[\mathbf{C} = \mathbf{R^{(s)}} \left( \mathbf{R^{(s)}} + \mathbf{\Sigma}^{(4)} \right)^{-1}.\]

The estimation error variances are the diagonal coefficients of

\[\mathbf{\Sigma}^{(5)} = \mathbf{R^{(s)}} - \mathbf{C}\mathbf{R^{(s)}}\]

The smoothed channel estimate \(\hat{\mathbf{h}}^{(5)}\) and corresponding error variances \(\text{diag}\left( \mathbf{\Sigma}^{(5)} \right)\) are returned for every resource element \((m,n)\).

Remark: No scaling is performed after the last filtering step.

Remark: All passes assume that the estimation error covariance matrix (\(\mathbf{\Sigma}\), \(\tilde{\mathbf{\Sigma}}^{(2)}\), or \(\tilde{\mathbf{\Sigma}}^{(4)}\)) is diagonal, which may not be accurate. When this assumption does not hold, this estimator is only an approximation of LMMSE estimation.

Remark: The order in which frequency filtering, temporal filtering, and, optionally, spatial smoothing are applied, is controlled using the order parameter.

Parameters:
  • resource_grid (sionna.phy.ofdm.resource_grid.ResourceGrid) – Used resource grid.

  • cov_mat_time (torch.Tensor) – Time covariance matrix of the channel.

  • cov_mat_freq (torch.Tensor) – Frequency covariance matrix of the channel.

  • cov_mat_space (torch.Tensor | None) – Spatial covariance matrix of the channel. Only required if spatial smoothing is requested (see order).

  • order (str) – Order in which to perform filtering. For example, "t-f-s" means that filtering across the OFDM symbols is performed first ("t": time), followed by filtering across the sub-carriers ("f": frequency), and filtering across the receive antennas ("s": space). Similarly, "f-t" means filtering across the sub-carriers followed by filtering across the OFDM symbols, and no spatial filtering. The spatial covariance matrix (cov_mat_space) is only required when spatial filtering is requested. Time and frequency filtering are not optional to ensure that a channel estimate is computed for all resource elements.

  • precision (Literal['single', 'double'] | None)

  • device (str | None)

Inputs:
  • y – [batch_size, num_rx, num_rx_ant, num_ofdm_symbols, fft_size], torch.complex. Observed resource grid.

  • no – [batch_size, num_rx, num_rx_ant] or only the first n>=0 dims, torch.float. Variance of the AWGN.

Outputs:
  • h_hat – [batch_size, num_rx, num_rx_ant, num_tx, num_streams_per_tx, num_ofdm_symbols, num_effective_subcarriers], torch.complex. Channel estimates across the entire resource grid for all transmitters and streams.

  • err_var – Same shape as h_hat, torch.float. Channel estimation error variances across the entire resource grid for all transmitters and streams.

Examples

import torch
from sionna.phy.ofdm import (
    ResourceGrid, LMMSEChannelEstimator,
    tdl_freq_cov_mat, tdl_time_cov_mat
)

rg = ResourceGrid(num_ofdm_symbols=14,
                  fft_size=64,
                  subcarrier_spacing=30e3,
                  num_tx=1,
                  num_streams_per_tx=1,
                  pilot_pattern="kronecker",
                  pilot_ofdm_symbol_indices=[2, 11])

# Compute covariance matrices
cov_mat_freq = tdl_freq_cov_mat("A", 30e3, 64, 100e-9)
cov_mat_time = tdl_time_cov_mat("A", 3.0, 3.5e9, 35.7e-6, 14)

# Create LMMSE channel estimator
estimator = LMMSEChannelEstimator(
    rg, cov_mat_time, cov_mat_freq, order="f-t"
)