import torch


def random_tensor(low, high, shape, dtype=torch.float, device='cpu'):
    """Generate a random tensor.

    Args:
        low (float): the lowest value to be drawn from the distribution.
        high (float): the highest value to be drawn from the distribution.
        shape (list, tuple or torch.LongTensor): the desired output shape.
        dtype (torch.dtype): the desired output dtype.
        device (torch.device): the desired output device.

    Return:
        (torch.Tensor): a random generated tensor.

    Example:
        >>> _ = torch.random.manual_seed(1)
        >>> random_tensor(4., 5., (3, 3), dtype=torch.float, device='cpu')
        tensor([[4.7576, 4.2793, 4.4031],
                [4.7347, 4.0293, 4.7999],
                [4.3971, 4.7544, 4.5695]])
    """
    if dtype in (torch.half, torch.float, torch.double):
        output = torch.rand(shape, dtype=dtype, device=device)
        if (low != 0.) or (high != 1.):
            output = output * (high - low) + low
    elif dtype == torch.bool:
        assert (low is None) or (low == 0)
        assert (high is None) or (high == 1)
        output = torch.randint(0, 2, size=shape, dtype=dtype, device=device)
    else:
        output = torch.randint(low, high + 1, size=shape, dtype=dtype, device=device)
    return output