module documentation

Utility classes and functionalities loosely related to optimization

Class BestFeasibleSolution No class docstring; 0/2 instance variable, 1/2 method documented
Class BestSolution container to keep track of the best solution seen.
Class BestSolution2 minimal tracker of a smallest f-value with variable meta-info
Class BinaryEvolutionPath No class docstring; 2/2 properties, 1/1 method documented
Class EvalParallel2 A class and context manager for parallel evaluations.
Class EvaluationsIterator return iteratively evals, fval, successes
Class EvolutionPath not in use (yet)
Class ExponentialSmoothing not in use (yet)
Class NoiseHandler Noise handling according to [Hansen et al 2009, A Method for Handling Uncertainty in Evolutionary Optimization...]
Class OldEvolutionPath not in use (yet)
Class Sections plot sections through an objective function.
Function contour_data generate x,y,z-data for contour plot.
Function ei_copy_arrays Needed when the array evals or successes is kept for later use, because
Function ei_ert expected runtime = average runtime over all runs / success_rate from EI data line
Function ei_median return median evaluations to reach fval.
Function ei_sp1 like ERT but disregarding the runtime values of unsuccessful runs by
Function ei_xy_data return a function that creates xy-values from a single EvaluationsIterator element.
Function id Undocumented
Function semilogy_signed signed semilogy plot.
Function step_data return x, y ECDF data for ECDF plot. Smoothing may look strange in a semilogx plot.
def contour_data(fct, x_range, y_range=None):

generate x,y,z-data for contour plot.

fct is a 2-D function. x- and y_range are iterable (e.g. list or arrays) to define the meshgrid.

CAVEAT: this function calls fct len(list(x_range)) * len(list(y_range)) times. Hence using Sections may be the better first choice to investigate an expensive function.

Examples:

from cma import optimization_tools
import numpy as np

def plt_contour():  # def avoids doctest execution
    from matplotlib import pyplot as plt

    X, Y, Z = optimization_tools.contour_data(
                  lambda x: sum([xi**2 for xi in x]),
                  np.arange(0.90, 1.10, 0.02),
                  np.arange(-0.10, 0.10, 0.02))
    CS = plt.contour(X, Y, Z)
    plt.gca().set_aspect('equal')
    plt.clabel(CS)
def plt_surface():  # def avoids doctest execution
    from matplotlib import pyplot as plt
    from mpl_toolkits import mplot3d

    X, Y, Z = optimization_tools.contour_data(
                  lambda x: sum([xi**2 for xi in x]),
                  np.arange(-1, 1.1, 0.02))
    ax = plt.axes(projection='3d')
    ax.plot_surface(X, Y, Z, cmap='viridis', edgecolor='none')

See cma.fitness_transformations.FixVariables to create a 2-D function from a d-D function, e.g. like

>>> import cma
...
>>> fd = cma.ff.elli
>>> x0 = 22 * [0]
>>> indices_to_vary = [2, 4]
>>> f2 = cma.fitness_transformations.FixVariables(fd,
...          dict((i, x0[i]) for i in range(len(x0))
...                          if i not in indices_to_vary))
>>> isinstance(f2, cma.fitness_transformations.FixVariables)
True
>>> isinstance(f2, cma.fitness_transformations.ComposedFunction)
True
>>> f2[0] is fd, len(f2) == 2
(True, True)
def ei_copy_arrays(evals, fval, successes):

Needed when the array evals or successes is kept for later use, because

internally the arrays change in place over the iterations.

return_filter=ei_copy_arrays is the default for EvaluationIterator to avoid unexpected results in that:

ert1 = [ei_ert(d) for d in list(EvaluationIterator(data))]
ert2 = [ei_ert(d) for d in EvaluationIterator(data)]

give the same result, as to be desired, whereas:

ert3 = [ei_ert(d) for d in list(EvaluationIterator(data, return_filter=None))]

is wrong unless the list call is omitted.

For efficiency, we should use return_filter=None with a for loop like:

for evals, fval, successes in ot.EvaluationIterator(data, return_filter=None)

when evals and successes are never used after the iterator advances (unless copied).

def ei_ert(evals, fval, successes):

expected runtime = average runtime over all runs / success_rate from EI data line

def ei_median(evals, fval, successes):

return median evaluations to reach fval.

Unsuccessful runs are sorted to the end and the median is taken over all runs. Hence, return nan when half or more runs were unsuccessful and hence fval doesn't map to any median evaluations.

When plotting fval versus this median, the graph stops after the last improvement, even when the true median run continues (flat).

Details: the median of only successful trials is not monotonuous in fval, hence seems semantically not always meaningful.

def ei_sp1(evals, fval, successes):

like ERT but disregarding the runtime values of unsuccessful runs by

replacing them with the average runtime of successful runs. When unsuccessful runs terminate on a timeout max budget, SP1 is usually a better performance indicator than ERT.

def ei_xy_data(xvalues=(ei_ert)):

return a function that creates xy-values from a single EvaluationsIterator element.

Argument xvalues is a list or sequence of functions, each used to create one "x-column".

The return value of ei_xy_data can be passed to EvaluationsIterator as return_filter argument, thereby internally computing the given xvalues and the f-value as last column.

Example:

import numpy as np
import cma.optimization_tools as ot

xy = np.asarray(list(ot.EvaluationsIterator(data, return_filter=ot.ei_xy_data())))
assert xy.shape[1] == 2  # x=ERT and y=fval
def id(*args):

Undocumented

def semilogy_signed(x=None, y=None, yoffset=0, minabsy=None, iabscissa=1, **kwargs):

signed semilogy plot.

plt.yscale('symlog', linthreshy=min(abs(data[data != 0]))) should do the same job at least as good.

y (or x if y is None) is a data array, by default read from outcmaesxmean.dat or (first) from the default logger output file like:

xy = cma.logger.CMADataLogger().load().data['xmean']
x, y = xy[:, iabscissa], xy[:, 5:]
semilogy_signed(x, y)

Plotted is y - yoffset vs x for positive values as a semilogy plot and for negative values as a semilogy plot of absolute values with inverted axis.

minabsy controls the minimum shown value away from zero, which can be useful if extremely small non-zero values occur in the data.

def step_data(data, smooth_corners=0.1):

return x, y ECDF data for ECDF plot. Smoothing may look strange in a semilogx plot.