rzf_precoder#

sionna.phy.mimo.rzf_precoder(x: torch.Tensor, h: torch.Tensor, alpha: float | torch.Tensor = 0.0, return_precoding_matrix: bool = False, precision: Literal['single', 'double'] | None = None) torch.Tensor | Tuple[torch.Tensor, torch.Tensor][source]#

Regularized Zero-Forcing (RZF) Precoder.

This function implements RZF precoding for a MIMO link, assuming the following model:

\[\mathbf{y} = \mathbf{H}\mathbf{G}\mathbf{x} + \mathbf{n}\]

where \(\mathbf{y}\in\mathbb{C}^K\) is the received signal vector, \(\mathbf{H}\in\mathbb{C}^{K\times M}\) is the known channel matrix, \(\mathbf{G}\in\mathbb{C}^{M\times K}\) is the precoding matrix, \(\mathbf{x}\in\mathbb{C}^K\) is the symbol vector to be precoded, and \(\mathbf{n}\in\mathbb{C}^K\) is a noise vector.

The precoding matrix \(\mathbf{G}\) is defined as (Eq. 4.37) [BHS2017]:

\[\mathbf{G} = \mathbf{V}\mathbf{D}\]

where

\[\begin{split}\mathbf{V} &= \mathbf{H}^{\mathsf{H}}\left(\mathbf{H} \mathbf{H}^{\mathsf{H}} + \alpha \mathbf{I} \right)^{-1}\\ \mathbf{D} &= \mathop{\text{diag}}\left( \lVert \mathbf{v}_{k} \rVert_2^{-1}, k=0,\dots,K-1 \right)\end{split}\]

where \(\alpha>0\) is the regularization parameter.

This ensures that each stream is precoded with a unit-norm vector, i.e., \(\mathop{\text{tr}}\left(\mathbf{G}\mathbf{G}^{\mathsf{H}}\right)=K\). The function returns the precoded vector \(\mathbf{G}\mathbf{x}\).

Parameters:
  • x (torch.Tensor) – Symbol vectors to be precoded with shape […, K]

  • h (torch.Tensor) – Channel matrices with shape […, K, M]

  • alpha (float | torch.Tensor) – Regularization parameter with shape […] or scalar

  • return_precoding_matrix (bool) – If True, the precoding matrices are also returned

  • precision (Literal['single', 'double'] | None) – Precision used for internal calculations and outputs. If set to None, precision is used.

Outputs:
  • x_precoded – […, M], torch.complex. Precoded symbol vectors.

  • g – […, M, K], torch.complex. Precoding matrices. Only returned if return_precoding_matrix=True.

Examples

x = torch.complex(torch.randn(4), torch.randn(4))
h = torch.complex(torch.randn(4, 8), torch.randn(4, 8))
x_precoded = rzf_precoder(x, h, alpha=0.1)
# x_precoded.shape = torch.Size([8])