Generates solutions by first applying a genetic operator, then applying a gradient arborescence with coefficients parameterized by a fixed Gaussian.

This emitter is from Fontaine 2021. It proceeds in two stages. The first stage samples a batch of intermediate solutions from the archive and (optionally) applies Gaussian perturbation with zero mean and fixed standard deviation sigma. If the archive is empty and no initial solutions are provided, the sampled solutions will be from a Gaussian centered at x0.

Optionally, an additional operator, Iso+LineDD (Vassiliades 2018), can be applied to the intermediate solutions in the first stage by setting operator_type='iso_line_dd'. The operator samples an additional batch of archive solutions to form a line in parameter space starting from the intermediate solutions. A zero-mean Gaussian interpolation along the line is then applied to the intermediate solutions, with standard deviation line_sigma.

The second stage creates new solutions by branching from each of the intermediate solutions. It leverages the gradient information of the objective and measure functions, generating a new solution from each solution point $$\boldsymbol{\theta_i}$$ using gradient arborescence. The gradient coefficients $$\boldsymbol{c_i}$$ are drawn from a zero-centered Gaussian distribution with standard deviation sigma_g. Note that the objective gradient coefficient is forced to be non-negative by taking its absolute value $$|c_{i,0}|$$.

Essentially, this means that the emitter samples coefficients $$\boldsymbol{c_i} \sim \mathcal{N}(\boldsymbol{0}, \boldsymbol{\sigma_g}I)$$ and creates new solutions $$\boldsymbol{\theta'_i}$$ by updating the intermediate solutions $$\boldsymbol{\theta_i}$$ from the first stage according to:

$\boldsymbol{\theta'_i} \gets \boldsymbol{\theta_i} + |c_{i,0}| \boldsymbol{\nabla} f(\boldsymbol{\theta_i}) + \sum_{j=1}^k c_{i,j}\boldsymbol{\nabla}m_j(\boldsymbol{\theta_i})$

Where $$k$$ is the number of measures, and $$\boldsymbol{\nabla} f(\boldsymbol{\theta})$$ and $$\boldsymbol{\nabla} m_j(\boldsymbol{\theta})$$ are the objective and measure gradients of the solution point $$\boldsymbol{\theta}$$, respectively.

Parameters
• archive (ribs.archives.ArchiveBase) – An archive to use when creating and inserting solutions. For instance, this can be ribs.archives.GridArchive.

• sigma (float or array-like) – Standard deviation of the Gaussian perturbation used to generate new solutions in ask_dqd(). Note we assume the Gaussian is diagonal, so if this argument is an array, it must be 1D.

• sigma_g (float) – Step size used for gradient arborescence in ask(), branching from the parents generated by ask_dqd(). If measure gradients are used, this acts as the standard deviation of the Gaussian from which to sample the step size. Otherwise, this acts as the step size itself.

• initial_solutions (array-like) – An (n, solution_dim) array of solutions to be used when the archive is empty. If this argument is None, then solutions will be sampled from a Gaussian distribution centered at x0 with standard deviation sigma.

• x0 (array-like) – Center of the Gaussian distribution from which to sample solutions when the archive is empty.

• line_sigma (float) – the standard deviation of the line Gaussian for Iso+LineDD operator.

• epsilon (float) – For numerical stability, we add a small epsilon when normalizing gradients in tell_dqd() – refer to the implementation here. Pass this parameter to configure that epsilon.

• operator_type (str) – Either ‘isotropic’ or ‘iso_line_dd’ to mark the operator type for intermediate operations. Defaults to ‘isotropic’.

• bounds (None or array-like) – Bounds of the solution space. Solutions are clipped to these bounds. Pass None to indicate there are no bounds. Alternatively, pass an array-like to specify the bounds for each dim. Each element in this array-like can be None to indicate no bound, or a tuple of (lower_bound, upper_bound), where lower_bound or upper_bound may be None to indicate no bound.

• batch_size (int) – Number of solutions to return in ask().

• seed (int) – Value to seed the random number generator. Set to None to avoid a fixed seed.

Raises

ValueError – There is an error in the bounds configuration.

Methods

 Samples new solutions from a gradient arborescence parameterized by a multivariate Gaussian distribution. Create new solutions by sampling elites from the archive with (optional) Gaussian perturbation. tell(solution, objective, measures, ...) Gives the emitter results from evaluating solutions. tell_dqd(solution, objective, measures, ...) Gives the emitter results of evaluating solutions from ask_dqd().

Attributes

 archive The archive which stores solutions generated by this emitter. batch_size Number of solutions to return in ask(). batch_size_dqd Number of solutions to return in ask_dqd(). epsilon The epsilon added for numerical stability when normalizing gradients in tell_dqd(). initial_solutions The initial solutions which are returned when the archive is empty (if x0 is not set). lower_bounds (solution_dim,) array with lower bounds of solution space. sigma Standard deviation of the (diagonal) Gaussian distribution. solution_dim The dimension of solutions produced by this emitter. upper_bounds (solution_dim,) array with upper bounds of solution space. x0 Center of the Gaussian distribution from which to sample solutions when the archive is empty (if initial_solutions is not set).

Samples new solutions from a gradient arborescence parameterized by a multivariate Gaussian distribution.

If measure_gradients is used, the multivariate Gaussian is parameterized by sigma_g, and the arboresecence coefficient is sampled from the multivariate Gaussian, with the objective coefficient being always non-negative. If measure_gradients is not used, the arboresecence coefficient is just sigma_g itself.

This method returns batch_size solutions by branching with gradient arborescence based on the solutions returned by ask_dqd().

Returns

(batch_size, solution_dim) array – a batch of new solutions to evaluate.

Raises

RuntimeError – This method was called without first passing gradients with calls to ask_dqd() and tell_dqd().

Create new solutions by sampling elites from the archive with (optional) Gaussian perturbation.

If the archive is empty and initial_solutions is given, this method returns no solutions. Otherwise, this method will sample elites from the archive.

Call :meth:ask_dqd and :meth:tell_dqd (in this order) before calling :meth:ask and :meth:tell.

Returns

(batch_size, solution_dim) array – contains batch_size new solutions to evaluate.

Gives the emitter results from evaluating solutions.

This base class implementation (in EmitterBase) needs to be overriden.

Parameters
• solution (numpy.ndarray) – Array of solutions generated by this emitter’s ask() method.

• objective (numpy.ndarray) – 1D array containing the objective function value of each solution.

• measures (numpy.ndarray) – (n, <measure space dimension>) array with the measure space coordinates of each solution.

• add_info (dict) – Data returned from the archive add() method.

• fields (keyword arguments) – Additional data for each solution. Each argument should be an array with batch_size as the first dimension.

tell_dqd(solution, objective, measures, jacobian, add_info, **fields)[source]

Gives the emitter results of evaluating solutions from ask_dqd().

Parameters
• solution (array-like) – (batch_size, solution_dim) array of solutions generated by this emitter’s ask() method.

• objective (array-like) – 1D array containing the objective function value of each solution.

• measures (array-like) – (batch_size, measure space dimension) array with the measure space coordinates of each solution.

• jacobian (array-like) – (batch_size, 1 + measure_dim, solution_dim) array consisting of Jacobian matrices of the solutions obtained from ask_dqd(). Each matrix should consist of the objective gradient of the solution followed by the measure gradients.

• add_info (dict) – Data returned from the archive add() method.

• fields (keyword arguments) – Additional data for each solution. Each argument should be an array with batch_size as the first dimension.

property archive

The archive which stores solutions generated by this emitter.

Type

ribs.archives.ArchiveBase

property batch_size

Number of solutions to return in ask().

Type

int

property batch_size_dqd

Number of solutions to return in ask_dqd().

Type

int

property epsilon

The epsilon added for numerical stability when normalizing gradients in tell_dqd().

Type

int

property initial_solutions

The initial solutions which are returned when the archive is empty (if x0 is not set).

Type

numpy.ndarray

property lower_bounds

(solution_dim,) array with lower bounds of solution space.

For instance, [-1, -1, -1] indicates that every dimension of the solution space has a lower bound of -1.

Type

numpy.ndarray

property sigma

Standard deviation of the (diagonal) Gaussian distribution.

Type
property solution_dim

The dimension of solutions produced by this emitter.

Type

int

property upper_bounds

(solution_dim,) array with upper bounds of solution space.

For instance, [1, 1, 1] indicates that every dimension of the solution space has an upper bound of 1.

Type

numpy.ndarray

property x0

Center of the Gaussian distribution from which to sample solutions when the archive is empty (if initial_solutions is not set).

Type

numpy.ndarray