class documentation

abstract base class for an Object Oriented Optimizer interface.

Relevant methods are __init__, ask, tell, optimize and stop, and property result. Only optimize is fully implemented in this base class.

Examples

All examples minimize the function elli, the output is not shown. (A preferred environment to execute all examples is ipython.)

First we need:

# CMAEvolutionStrategy derives from the OOOptimizer class
from cma import CMAEvolutionStrategy
from cma.fitness_functions import elli

The shortest example uses the inherited method OOOptimizer.optimize:

es = CMAEvolutionStrategy(8 * [0.1], 0.5).optimize(elli)

The input parameters to CMAEvolutionStrategy are specific to this inherited class. The remaining functionality is based on interface defined by OOOptimizer. We might have a look at the result:

print(es.result[0])  # best solution and
print(es.result[1])  # its function value

Virtually the same example can be written with an explicit loop instead of using optimize. This gives the necessary insight into the OOOptimizer class interface and entire control over the iteration loop:

# a new CMAEvolutionStrategy instance
optim = CMAEvolutionStrategy(9 * [0.5], 0.3)

# this loop resembles optimize()
while not optim.stop():  # iterate
    X = optim.ask()      # get candidate solutions
    f = [elli(x) for x in X]  # evaluate solutions
    #  in case do something else that needs to be done
    optim.tell(X, f)     # do all the real "update" work
    optim.disp(20)       # display info every 20th iteration
    optim.logger.add()   # log another "data line", non-standard

# final output
print('termination by', optim.stop())
print('best f-value =', optim.result[1])
print('best solution =', optim.result[0])
optim.logger.plot()  # if matplotlib is available

Details

Most of the work is done in the methods tell or ask. The property result provides more useful output.

Method __init__ xstart is a mandatory argument
Method ask abstract method, AKA "get" or "sample_distribution", deliver new candidate solution(s), a list of "vectors"
Method disp abstract method, display some iteration info when self.iteration_counter % modulo < 1, using a reasonable default for modulo if modulo is None.
Method initialize (re-)set to the initial state
Method optimize find minimizer of objective_fct.
Method stop abstract method, return satisfied termination conditions in a dictionary like {'termination reason': value, ...} or {}.
Method tell abstract method, AKA "update", pass f-values and prepare for next iteration
Instance Variable countiter Undocumented
Instance Variable more_mandatory_args Undocumented
Instance Variable optional_kwargs Undocumented
Instance Variable xcurrent Undocumented
Instance Variable xstart Undocumented
Property result abstract property, contain (x, f(x), ...), that is, the minimizer, its function value, ...
Method _force_final_logging try force the logger to log NOW
Method _prepare_callback_list return a list of callbacks including self.logger.add.
def __init__(self, xstart, *more_mandatory_args, **optional_kwargs):

xstart is a mandatory argument

def ask(self, **optional_kwargs):

abstract method, AKA "get" or "sample_distribution", deliver new candidate solution(s), a list of "vectors"

def disp(self, modulo=None):

abstract method, display some iteration info when self.iteration_counter % modulo < 1, using a reasonable default for modulo if modulo is None.

def initialize(self):

(re-)set to the initial state

def optimize(self, objective_fct, maxfun=None, iterations=None, min_iterations=1, args=(), verb_disp=None, callback=None, n_jobs=0, **kwargs):

find minimizer of objective_fct.

CAVEAT: the return value for optimize has changed to self, allowing for a call like:

solver = OOOptimizer(x0).optimize(f)

and investigate the state of the solver.

Arguments

objective_fct: f(x: array_like) -> float
function be to minimized
maxfun: number
maximal number of function evaluations
iterations: number
number of (maximal) iterations, while not self.stop(), it can be useful to conduct only one iteration at a time.
min_iterations: number
minimal number of iterations, even if not self.stop()
args: sequence_like
arguments passed to objective_fct
verb_disp: number
print to screen every verb_disp iteration, if None the value from self.logger is "inherited", if available.
callback: callable or list of callables
callback function called like callback(self) or a list of call back functions called in the same way. If available, self.logger.add is added to this list. TODO: currently there is no way to prevent this other than changing the code of _prepare_callback_list.
n_jobs=0: number of processes to be acquired for
multiprocessing to parallelize calls to objective_fct. Must be >1 to expect any speed-up or None or -1, which both default to the number of available CPUs. The default n_jobs=0 avoids the use of multiprocessing altogether.

return self, that is, the OOOptimizer instance.

Example

>>> import cma
>>> es = cma.CMAEvolutionStrategy(7 * [0.1], 0.1
...              ).optimize(cma.ff.rosen, verb_disp=100)
...                   #doctest: +ELLIPSIS
(4_w,9)-aCMA-ES (mu_w=2.8,w_1=49%) in dimension 7 (seed=...)
Iterat #Fevals   function value  axis ratio  sigma ...
    1      9 ...
    2     18 ...
    3     27 ...
  100    900 ...
>>> cma.s.Mh.vequals_approximately(es.result[0], 7 * [1], 1e-5)
True
def stop(self):

abstract method, return satisfied termination conditions in a dictionary like {'termination reason': value, ...} or {}.

For example {'tolfun': 1e-12}, or the empty dictionary {}.

TODO: this should rather be a property!? Unfortunately, a change would break backwards compatibility.

def tell(self, solutions, function_values):

abstract method, AKA "update", pass f-values and prepare for next iteration

countiter: int =

Undocumented

more_mandatory_args =

Undocumented

optional_kwargs =

Undocumented

xcurrent =

Undocumented

xstart =

Undocumented

@property
result =

abstract property, contain (x, f(x), ...), that is, the minimizer, its function value, ...

def _force_final_logging(self):

try force the logger to log NOW

def _prepare_callback_list(self, callback):

return a list of callbacks including self.logger.add.

callback can be a callable or a list (or iterable) of callables. Otherwise a ValueError exception is raised.