Source code for sionna.phy.utils.linalg

#
# SPDX-FileCopyrightText: Copyright (c) 2021-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
#
"""Linear algebra utilities."""

from __future__ import annotations

import torch

__all__ = ["inv_cholesky", "matrix_pinv"]


[docs] def inv_cholesky(tensor: torch.Tensor) -> torch.Tensor: r"""Inverse of the Cholesky decomposition of a matrix Given a batch of :math:`M \times M` Hermitian positive definite matrices :math:`\mathbf{A}`, this function computes :math:`\mathbf{L}^{-1}`, where :math:`\mathbf{L}` is the Cholesky decomposition, such that :math:`\mathbf{A}=\mathbf{L}\mathbf{L}^{\textsf{H}}`. :param tensor: [..., M, M], `torch.float` | `torch.complex`. Input tensor of rank greater than one. :output inv_chol: [..., M, M], `torch.float` | `torch.complex`. A tensor of the same shape and type as ``tensor`` containing the inverse of the Cholesky decomposition of its last two dimensions. .. rubric:: Examples >>> import torch >>> from sionna.phy.utils.linalg import inv_cholesky >>> a = torch.eye(2) >>> inv_cholesky(a) tensor([[1., 0.], [0., 1.]]) """ chol_factor = torch.linalg.cholesky_ex(tensor, check_errors=False)[0] dim = chol_factor.shape[-1] identity = torch.eye(dim, dtype=chol_factor.dtype, device=chol_factor.device) identity = identity.expand(*chol_factor.shape[:-2], dim, dim) return torch.linalg.solve_triangular(chol_factor, identity, upper=False)
[docs] def matrix_pinv(tensor: torch.Tensor) -> torch.Tensor: r"""Computes the Moore–Penrose (or pseudo) inverse of a matrix Given a batch of :math:`M \times K` matrices :math:`\mathbf{A}` with rank :math:`K` (i.e., linearly independent columns), the function returns :math:`\mathbf{A}^+`, such that :math:`\mathbf{A}^{+}\mathbf{A}=\mathbf{I}_K`. The two inner dimensions are assumed to correspond to the matrix rows and columns, respectively. :param tensor: [..., M, K], `torch.float` | `torch.complex`. Input tensor of rank greater than or equal to two. :output pinv: [..., K, M], `torch.float` | `torch.complex`. A tensor containing the matrix pseudo inverse of the last two dimensions of ``tensor``. .. rubric:: Examples >>> import torch >>> from sionna.phy.utils.linalg import matrix_pinv >>> a = torch.randn(4, 2) >>> matrix_pinv(a).shape torch.Size([2, 4]) """ tensor_h = tensor.mH # conjugate transpose gram = tensor_h @ tensor chol = torch.linalg.cholesky_ex(gram, check_errors=False)[0] # Solve (L L^H) X^T = A^H via two triangular solves y = torch.linalg.solve_triangular(chol, tensor_h, upper=False) return torch.linalg.solve_triangular(chol.mH, y, upper=True)