Quick start

60-second example

import numpy as np
from gloss import GLOSS

# A candidate pool of 10,000 points in 5 dimensions
rng = np.random.default_rng(0)
candidates = rng.random((10_000, 5))

def oracle(X):
    """Your evaluation function — typically an experiment or simulation."""
    return -np.linalg.norm(X - 0.7, axis=1)   # peak at x = (0.7, 0.7, ..., 0.7)

g = GLOSS(
    space={"candidates": candidates},
    direction="maximize",
    ratio={"global_best": 4, "local_best": 2, "unexplored": 2},
    ucb_kappa=2.0,
    diversity_radius=0.02,
)

# Bootstrap from 8 random points
init_idx = rng.choice(len(candidates), size=8, replace=False)
X_obs = candidates[init_idx]
y_obs = oracle(X_obs)

# Run 20 batches of 8 recommendations each
for r in range(20):
    batch = g.recommend(X_obs, y_obs, n_points=8)
    y_new = oracle(batch)
    X_obs = np.vstack([X_obs, batch])
    y_obs = np.concatenate([y_obs, y_new])
    print(f"round {r:2d}: best so far = {y_obs.max():.4f}")

Key parameters

Parameter

Default

Meaning

ratio

{4, 2, 2}

Per-stream batch size \(\{n_g, n_l, n_u\}\). The sum is the batch size.

ucb_kappa

2.0

UCB exploration weight \(\kappa\) in \(s \cdot \mu(x) + \kappa \sigma(x)\).

diversity_radius

0.02

Greedy batch-diversity filter radius (unit-normalized space).

local_top_k

500

Top-\(K\) truncation for the Local stream (\(\mathcal{O}(K)\) per round).

distance_metric

"euclidean"

Distance for Unexplored and Local. Use "jaccard" for binary ECFP fingerprints.

direction

"maximize"

Use "minimize" if your objective is to find the smallest value.

Discrete vs. continuous search spaces

GLOSS supports both. The space argument decides which.

g = GLOSS(space={"candidates": X_pool}, ...)
g = GLOSS(
    space={"bounds": [(0.0, 1.0), (0.0, 1.0), (-5.0, 5.0)]},
    ...,
)

Next