Source code for evox.operators.sampling.uniform
import itertools
from math import comb
from typing import Tuple
import torch
[docs]
def uniform_sampling(n: int, m: int) -> Tuple[torch.Tensor, int]:
"""Uniform sampling using Das and Dennis's method, Deb and Jain's method.
Inspired by PlatEMO's NBI algorithm.
:param n: Number of points to generate.
:param m: Dimensionality of the grid.
:return: The generated points, and the number of samples.
"""
h1 = 1
while comb(h1 + m, m - 1) <= n:
h1 += 1
# Generate combinations and scale them
w = (
torch.tensor(list(itertools.combinations(range(1, h1 + m), m - 1)))
- torch.tile(torch.tensor(range(m - 1)), (comb(h1 + m - 1, m - 1), 1))
- 1
)
w = (
torch.cat([w, torch.zeros((w.size(0), 1), dtype=w.dtype) + h1], dim=1)
- torch.cat([torch.zeros((w.size(0), 1), dtype=w.dtype), w], dim=1)
) / h1
if h1 < m:
h2 = 0
while comb(h1 + m - 1, m - 1) + comb(h2 + m, m - 1) <= n:
h2 += 1
if h2 > 0:
w2 = (
torch.tensor(list(itertools.combinations(range(1, h2 + m), m - 1)))
- torch.tile(torch.tensor(range(m - 1)), (comb(h2 + m - 1, m - 1), 1))
- 1
)
w2 = (
torch.cat([w2, torch.zeros((w2.size(0), 1), dtype=w2.dtype) + h2], dim=1)
- torch.cat([torch.zeros((w2.size(0), 1), dtype=w2.dtype), w2], dim=1)
) / h2
w = torch.cat([w, w2 / 2.0 + 1.0 / (2.0 * m)], dim=0)
w = torch.maximum(w, torch.tensor(1e-6))
n_samples = w.size(0)
return w, n_samples