class documentation

two point adaptation for step-size sigma.

Relies on a specific sampling of the first two offspring, whose objective function value ranks are used to decide on the step-size change, see update for the specifics.

Example

>>> import cma
>>> cma.CMAOptions('adapt').pprint()  # doctest: +ELLIPSIS
 AdaptSigma='True...
>>> es = cma.CMAEvolutionStrategy(10 * [0.2], 0.1,
...     {'AdaptSigma': cma.sigma_adaptation.CMAAdaptSigmaTPA,
...      'ftarget': 1e-8})  # doctest: +ELLIPSIS
(5_w,10)-aCMA-ES (mu_w=3.2,w_1=45%) in dimension 10 (seed=...
>>> es.optimize(cma.ff.rosen)  # doctest: +ELLIPSIS
Iter...
>>> assert 'ftarget' in es.stop()
>>> assert es.result[1] <= 1e-8  # should coincide with the above
>>> assert es.result[2] < 6500  # typically < 5500

References: loosely based on Hansen 2008, CMA-ES with Two-Point Step-Size Adaptation, more tightly reflecting Hansen et al. 2014, How to Assess Step-Size Adaptation Mechanisms in Randomized Search and Akimoto & Hansen 2020, Diagonal Acceleration for Covariance...

TODO: collect data for ._last_z and/or .s distributions, namely on the stationary sphere with sigma in [sigma_opt, 2 * sigma_opt] or as a function of the convergence rate and depending on popsize: is |s| decreasing with increasing popsize and how? Can we compute hsig based on s instead ps?

Method __init__ popsize is a valid kwargs
Method check_consistency make consistency checks with a CMAEvolutionStrategy instance as input
Method initialize late initialization based on CMAEvolutionStrategy.
Method initialize_settings set parameters in .sp based on an CMAEvolutionStrategy instance
Method update update es.sigma *= self.update2(...).
Method update2 update state variables and return the step-size multiplier.
Instance Variable delta all sigma changes multiplied
Instance Variable dimension with the default averaging coefficient, the first two entries dominate all others: c = 1/2 <==> 1/c * 1/2 == 1 meaning the first entry == 1 takes half of the weight c = 0.29289 = 1 - sqrt(1/2) <==> 1/c * 1/2 == 1 + 1-c meaning the first two entries take half of the weight, where "the full" weight is 1/c = sum_{i=0}^infty (1-c)^i...
Instance Variable initialized Undocumented
Instance Variable s the state/summation variable
Instance Variable sp parameter settings
Instance Variable _es_opts Undocumented
Instance Variable _last_multiplier Undocumented
Instance Variable _last_z Undocumented
Instance Variable _popsize Undocumented

Inherited from CMAAdaptSigmaBase:

Method hsig return "OK-signal" for rank-one update.
Method initialize_base set parameters and state variable based on dimension, mueff and possibly further options.
Instance Variable cs Undocumented
Instance Variable is_initialized_base Undocumented
Instance Variable ps Undocumented
Method _update_ps update the isotropic evolution path.
Instance Variable _ps_updated_iteration Undocumented
def __init__(self, dimension=None, opts=None, **kwargs):

popsize is a valid kwargs

def check_consistency(self, es):

make consistency checks with a CMAEvolutionStrategy instance as input

def initialize(self, N=None, opts=None, popsize=None, reset=False, **kwargs):

late initialization based on CMAEvolutionStrategy.

Argument N is either the dimension (for backward compatibility) or a CMAEvolutionStrategy instance. opts and popsize are ignored in the latter case.

Argument opts is equivalent with N.opts, used for 'TPA_dampfac', verbosity behavior and hacking (very versatile).

Unless bool(reset) is True, initialize does not overwrite parameters or state variables unless their value is None or they are in the _attributes_to_not_recover_on_init list.

The following mainly tests the (new) reset behavior:

>>> import cma  # test sp.damp value and reset behavior (minor)
>>> es = cma.CMAEvolutionStrategy(2 * [1], 1, {'verbose':-9,
...               'AdaptSigma': cma.sigma_adaptation.CMAAdaptSigmaTPA})
>>> assert 4.85888 < es.adapt_sigma.sp.damp < 4.85889, es.adapt_sigma.sp.__dict__
>>> es.adapt_sigma.sp.damp = 1.234
>>> _ = es.adapt_sigma.initialize(es)
>>> assert es.adapt_sigma.sp.damp == 1.234, es.adapt_sigma.sp.__dict__
>>> _ = es.adapt_sigma.initialize(es)
>>> assert es.adapt_sigma.sp.damp == 1.234, es.adapt_sigma.sp.__dict__
>>> es.adapt_sigma.is_initialized = False
>>> _ = es.adapt_sigma.initialize(es)
>>> assert es.adapt_sigma.sp.damp == 1.234, es.adapt_sigma.sp.__dict__
>>> _ = es.adapt_sigma.initialize(es, reset=True)  # reset everything
>>> assert 4.85888 < es.adapt_sigma.sp.damp < 4.85889, es.adapt_sigma.sp.__dict__
>>> es.adapt_sigma.sp.damp = 1.234
>>> _ = es.optimize(cma.ff.elli, iterations = 4)
>>> assert es.adapt_sigma.sp.damp == 1.234, es.adapt_sigma.sp.__dict__
def initialize_settings(self, es=None, reset=False):

set parameters in .sp based on an CMAEvolutionStrategy instance

or on the previously stored .dimension, ._es_opts, ._popsize. These attributes could be modified to compute a respective setting. Any existing setting is overwritten only if bool(reset) is True or the respective parameter value in .sp is None.

def update(self, es, function_values, **kwargs):

update es.sigma *= self.update2(...).

The first and second value in function_values must reflect two mirrored solutions.

Legacy method replaced by update2.

def update2(self, es, function_values, **kwargs):

update state variables and return the step-size multiplier.

The first and second value in function_values must reflect two mirrored solutions sampled, respectively, in direction and in opposite direction of the previous mean shift.

delta: int =

all sigma changes multiplied

dimension =

with the default averaging coefficient, the first two entries dominate all others: c = 1/2 <==> 1/c * 1/2 == 1 meaning the first entry == 1 takes half of the weight c = 0.29289 = 1 - sqrt(1/2) <==> 1/c * 1/2 == 1 + 1-c meaning the first two entries take half of the weight, where "the full" weight is 1/c = sum_{i=0}^infty (1-c)^i

initialized: bool =

Undocumented

s: int =

the state/summation variable

sp =

parameter settings

_es_opts =

Undocumented

_last_multiplier =

Undocumented

_last_z =

Undocumented

_popsize =

Undocumented