2. Generator

Introduction || 1. Getting started || 2. Generator || 3. Simulator || 4. Script || 5. Next steps

Let’s begin the coding portion of this tutorial by writing our generator.

An available libEnsemble worker will call this generator’s .suggest() method to obtain new values to evaluate.

For now, create a new Python file named sine_gen.py. Write the following:

examples/tutorials/simple_sine/sine_gen_std.py
 1import numpy as np
 2from gest_api import Generator
 3
 4
 5class RandomSample(Generator):
 6    """
 7    This sampler accepts a gest-api VOCS object for configuration and returns random samples.
 8    """
 9
10    def __init__(self, vocs):
11        self.variables = vocs.variables
12        self.rng = np.random.default_rng(1)
13        self._validate_vocs(vocs)
14
15    def _validate_vocs(self, vocs):
16        if not len(vocs.variables) > 0:
17            raise ValueError("vocs must have at least one variable")
18
19    def suggest(self, num_points):
20        output = []
21        for _ in range(num_points):
22            trial = {}
23            for key in self.variables.keys():
24                trial[key] = self.rng.uniform(self.variables[key].domain[0], self.variables[key].domain[1])
25            output.append(trial)
26        return output

libEnsemble accepts generators that implement the gest-api interface. These generators accept a gest_api.VOCS object for configuration, and contain a .suggest(num_points) method that returns num_points points. Points consist of a list of dictionaries with keys that match the variable names from the gest_api.VOCS object.

Our generator’s suggest() method creates num_points dictionaries. For each key in the generator’s self.variables, it creates a random number uniformly distributed between the corresponding lower and upper bounds of its domain.

Our generator must implement a _validate_vocs() method. Here, we implement a simple check that ensures the VOCS object has at least one variable.