import torch
from typing import Optional


def lower_vector_to_matrix(
    lower_flat: torch.Tensor, matrix_dim: Optional[int] = None
) -> torch.Tensor:
    """Convert a valid vector to a lower triangular matrix.

    Parameters
    ----------
    vector : torch.Tensor
        vector
    matix_dim : Optional[int]
        matix_dim

    Returns
    -------
    torch.Tensor

    """
    shape = lower_flat.shape

    if matrix_dim is None:
        # (N, N) matrix has L =  N * (N + 1) / 2 values in its
        # lower triangular region (including diagonals).

        # N = 0.5 * sqrt(8 * L + 1)**0.5 - 0.5
        matrix_dim = int(0.5 * (8 * shape[-1] + 1) ** 0.5 - 0.5)

    matrix_shape = shape[:-1] + (matrix_dim, matrix_dim)

    lower = torch.zeros(matrix_shape)
    lower_idx = torch.tril_indices(matrix_dim, matrix_dim)
    lower[..., lower_idx[0], lower_idx[1]] = lower_flat
    return lower