import torch


def latin_hypercube(n_pts, dim, dtype=None, device=None):
    """Latin hypercube with center perturbation."""
    X = torch.zeros(n_pts, dim, dtype=dtype, device=device)
    centers = (1.0 + 2.0 * torch.arange(0.0, n_pts, dtype=dtype, device=device)) / float(2 * n_pts)
    for i in range(dim):  # Shuffle the center locataions for each dimension.
        X[:, i] = centers[torch.randperm(n_pts)]

    # Add some perturbations within each box
    pert = (-1.0 + 2.0 * torch.rand(n_pts, dim, dtype=dtype, device=device)) / float(2 * n_pts)
    X += pert
    return X