Module cma :: Class CMAEvolutionStrategy
[hide private]
[frames] | no frames]

Class CMAEvolutionStrategy

source code

 object --+    
          |    
OOOptimizer --+
              |
             CMAEvolutionStrategy

CMA-ES stochastic optimizer class with ask-and-tell interface.

Calling Sequences

es = CMAEvolutionStrategy(x0, sigma0)

es = CMAEvolutionStrategy(x0, sigma0, opts)

es = CMAEvolutionStrategy(x0, sigma0).optimize(objective_fct)

res = CMAEvolutionStrategy(x0, sigma0,
opts).optimize(objective_fct).result()

Arguments

x0

initial solution, starting point. x0 is given as "phenotype" which means, if:

opts = {'transformation': [transform, inverse]}

is given and inverse is None, the initial mean is not consistent with x0 in that transform(mean) does not equal to x0 unless transform(mean) equals mean.

sigma0
initial standard deviation. The problem variables should have been scaled, such that a single standard deviation on all variables is useful and the optimum is expected to lie within about x0 +- 3*sigma0. See also options scaling_of_variables. Often one wants to check for solutions close to the initial point. This allows, for example, for an easier check of consistency of the objective function and its interfacing with the optimizer. In this case, a much smaller sigma0 is advisable.
opts
options, a dictionary with optional settings, see class CMAOptions.

Main interface / usage

The interface is inherited from the generic OOOptimizer class (see also there). An object instance is generated from

es = cma.CMAEvolutionStrategy(8 * [0.5], 0.2)

The least verbose interface is via the optimize method:

es.optimize(objective_func)
res = es.result()

More verbosely, the optimization is done using the methods stop, ask, and tell:

while not es.stop():
    solutions = es.ask()
    es.tell(solutions, [cma.fcts.rosen(s) for s in solutions])
    es.disp()
es.result_pretty()

where ask delivers new candidate solutions and tell updates the optim instance by passing the respective function values (the objective function cma.fcts.rosen can be replaced by any properly defined objective function, see cma.fcts for more examples).

To change an option, for example a termination condition to continue the optimization, call

es.opts.set({'tolfacupx': 1e4})

The class CMAEvolutionStrategy also provides:

(solutions, func_values) = es.ask_and_eval(objective_func)

and an entire optimization can also be written like:

while not es.stop():
    es.tell(*es.ask_and_eval(objective_func))

Besides for termination criteria, in CMA-ES only the ranks of the func_values are relevant.

Attributes and Properties

Examples

Super-short example, with output shown:

>>> import cma
>>> # construct an object instance in 4-D, sigma0=1:
>>> es = cma.CMAEvolutionStrategy(4 * [1], 1, {'seed':234})
(4_w,8)-CMA-ES (mu_w=2.6,w_1=52%) in dimension 4 (seed=234)
>>>
>>> # optimize the ellipsoid function
>>> es.optimize(cma.fcts.elli, verb_disp=1)
Iterat #Fevals   function value     axis ratio  sigma   minstd maxstd min:sec
    1       8 2.093015112685775e+04 1.0e+00 9.27e-01  9e-01  9e-01 0:0.0
    2      16 4.964814235917688e+04 1.1e+00 9.54e-01  9e-01  1e+00 0:0.0
    3      24 2.876682459926845e+05 1.2e+00 1.02e+00  9e-01  1e+00 0:0.0
  100     800 6.809045875281943e-01 1.3e+02 1.41e-02  1e-04  1e-02 0:0.2
  200    1600 2.473662150861846e-10 8.0e+02 3.08e-05  1e-08  8e-06 0:0.5
  233    1864 2.766344961865341e-14 8.6e+02 7.99e-07  8e-11  7e-08 0:0.6
>>>
>>> cma.pprint(es.result())
(array([ -1.98546755e-09,  -1.10214235e-09,   6.43822409e-11,
        -1.68621326e-11]),
 4.5119610261406537e-16,
 1666,
 1672,
 209,
 array([ -9.13545269e-09,  -1.45520541e-09,  -6.47755631e-11,
        -1.00643523e-11]),
 array([  3.20258681e-08,   3.15614974e-09,   2.75282215e-10,
         3.27482983e-11]))
>>> assert es.result()[1] < 1e-9
>>> help(es.result)
Help on method result in module cma:
result(self) method of cma.CMAEvolutionStrategy instance
return (xbest, f(xbest), evaluations_xbest, evaluations, iterations, pheno(xmean), effective_stds)

The optimization loop can also be written explicitly.

>>> import cma
>>> es = cma.CMAEvolutionStrategy(4 * [1], 1)
>>> while not es.stop():
...    X = es.ask()
...    es.tell(X, [cma.fcts.elli(x) for x in X])
...    es.disp()
<output omitted>

achieving the same result as above.

An example with lower bounds (at zero) and handling infeasible solutions:

>>> import cma
>>> import numpy as np
>>> es = cma.CMAEvolutionStrategy(10 * [0.2], 0.5, {'bounds': [0, np.inf]})
>>> while not es.stop():
...     fit, X = [], []
...     while len(X) < es.popsize:
...         curr_fit = None
...         while curr_fit in (None, np.NaN):
...             x = es.ask(1)[0]
...             curr_fit = cma.fcts.somenan(x, cma.fcts.elli) # might return np.NaN
...         X.append(x)
...         fit.append(curr_fit)
...     es.tell(X, fit)
...     es.logger.add()
...     es.disp()
<output omitted>
>>>
>>> assert es.result()[1] < 1e-9
>>> assert es.result()[2] < 9000  # by internal termination
>>> # es.logger.plot()  # will plot data
>>> # cma.show()  # display plot window

An example with user-defined transformation, in this case to realize a lower bound of 2.

>>> es = cma.CMAEvolutionStrategy(5 * [3], 1,
...                 {"transformation": [lambda x: x**2+2, None]})
>>> es.optimize(cma.fcts.rosen)
<output omitted>
>>> assert cma.fcts.rosen(es.result()[0]) < 1e-6 + 5.530760944396627e+02
>>> assert es.result()[2] < 3300

The inverse transformation is (only) necessary if the BoundPenalty boundary handler is used at the same time.

The CMAEvolutionStrategy class also provides a default logger (cave: files are overwritten when the logger is used with the same filename prefix):

>>> import cma
>>> es = cma.CMAEvolutionStrategy(4 * [0.2], 0.5, {'verb_disp': 0})
>>> es.logger.disp_header()  # to understand the print of disp
Iterat Nfevals  function value    axis ratio maxstd   minstd
>>> while not es.stop():
...     X = es.ask()
...     es.tell(X, [cma.fcts.sphere(x) for x in X])
...     es.logger.add()  # log current iteration
...     es.logger.disp([-1])  # display info for last iteration
1      8 2.72769793021748e+03 1.0e+00 4.05e-01 3.99e-01
2     16 6.58755537926063e+03 1.1e+00 4.00e-01 3.39e-01
<output ommitted>
193   1544 3.15195320957214e-15 1.2e+03 3.70e-08 3.45e-11
>>> es.logger.disp_header()
Iterat Nfevals  function value    axis ratio maxstd   minstd
>>> # es.logger.plot() # will make a plot

Example implementing restarts with increasing popsize (IPOP), output is not displayed:

>>> import cma, numpy as np
>>>
>>> # restart with increasing population size (IPOP)
>>> bestever = cma.BestSolution()
>>> for lam in 10 * 2**np.arange(8):  # 10, 20, 40, 80, ..., 10 * 2**7
...     es = cma.CMAEvolutionStrategy('6 - 8 * np.random.rand(9)',  # 9-D
...                                   5,  # initial std sigma0
...                                   {'popsize': lam,  # options
...                                    'verb_append': bestever.evalsall})
...     logger = cma.CMADataLogger().register(es, append=bestever.evalsall)
...     while not es.stop():
...         X = es.ask()    # get list of new solutions
...         fit = [cma.fcts.rastrigin(x) for x in X]  # evaluate each solution
...         es.tell(X, fit) # besides for termination only the ranking in fit is used
...
...         # display some output
...         logger.add()  # add a "data point" to the log, writing in files
...         es.disp()  # uses option verb_disp with default 100
...
...     print('termination:', es.stop())
...     cma.pprint(es.best.__dict__)
...
...     bestever.update(es.best)
...
...     # show a plot
...     # logger.plot();
...     if bestever.f < 1e-8:  # global optimum was hit
...         break
<output omitted>
>>> assert es.result()[1] < 1e-8

On the Rastrigin function, usually after five restarts the global optimum is located.

Using the multiprocessing module, we can evaluate the function in parallel with a simple modification of the example (however multiprocessing seems not always reliable):

try:
    import multiprocessing as mp
    import cma
    es = cma.CMAEvolutionStrategy(22 * [0.0], 1.0, {'maxiter':10})
    pool = mp.Pool(es.popsize)
    while not es.stop():
        X = es.ask()
        f_values = pool.map_async(cma.felli, X).get()
        # use chunksize parameter as es.popsize/len(pool)?
        es.tell(X, f_values)
        es.disp()
        es.logger.add()
except ImportError:
    pass

The final example shows how to resume:

>>> import cma, pickle
>>>
>>> es = cma.CMAEvolutionStrategy(12 * [0.1],  # a new instance, 12-D
...                               0.5)         # initial std sigma0
>>> es.optimize(cma.fcts.rosen, iterations=100)
>>> pickle.dump(es, open('saved-cma-object.pkl', 'wb'))
>>> print('saved')
>>> del es  # let's start fresh
>>>
>>> es = pickle.load(open('saved-cma-object.pkl', 'rb'))
>>> print('resumed')
>>> es.optimize(cma.fcts.rosen, verb_disp=200)
>>> assert es.result()[2] < 15000
>>> cma.pprint(es.result())

Details

The following two enhancements are implemented, the latter is turned on by default only for very small population size.

Active CMA is implemented with option CMA_active and conducts an update of the covariance matrix with negative weights. The negative update is implemented, such that positive definiteness is guarantied. The update is applied after the default update and only before the covariance matrix is decomposed, which limits the additional computational burden to be at most a factor of three (typically smaller). A typical speed up factor (number of f-evaluations) is between 1.1 and two.

References: Jastrebski and Arnold, CEC 2006, Glasmachers et al, GECCO 2010.

Selective mirroring is implemented with option CMA_mirrors in the method get_mirror(). Only the method ask_and_eval() (used by fmin) will then sample selectively mirrored vectors. In selective mirroring, only the worst solutions are mirrored. With the default small number of mirrors, pairwise selection (where at most one of the two mirrors contribute to the update of the distribution mean) is implicitly guarantied under selective mirroring and therefore not explicitly implemented.

References: Brockhoff et al, PPSN 2010, Auger et al, GECCO 2011.


See Also: fmin(), OOOptimizer, CMAOptions, plot(), ask(), tell(), ask_and_eval()

Instance Methods [hide private]
 
stop(self, check=True)
return a dictionary with the termination status. With check==False, the termination conditions are not checked and the status might not reflect the current situation.
source code
 
copy_constructor(self, es) source code
 
__init__(self, x0, sigma0, inopts={})
see class CMAEvolutionStrategy
source code
 
_set_x0(self, x0) source code
 
ask(self, number=None, xmean=None, sigma_fac=1, gradf=None, args=())
get new candidate solutions, sampled from a multi-variate normal distribution and transformed to f-representation (phenotype) to be evaluated.
source code
 
ask_geno(self, number=None, xmean=None, sigma_fac=1)
get new candidate solutions in genotyp, sampled from a multi-variate normal distribution.
source code
 
random_rescale_to_mahalanobis(self, x)
change x like for injection, all on genotypic level
source code
 
random_rescaling_factor_to_mahalanobis_size(self, y)
self.mean + self.random_rescaling_factor_to_mahalanobis_size(y) is guarantied to appear like from the sample distribution.
source code
 
get_mirror(self, x, preserve_length=False)
return pheno(self.mean - (geno(x) - self.mean)).
source code
 
_mirror_penalized(self, f_values, idx)
obsolete and subject to removal (TODO), return modified f-values such that for each mirror one becomes worst.
source code
 
_mirror_idx_cov(self, f_values, idx1)
obsolete and subject to removal (TODO), return indices for negative ("active") update of the covariance matrix assuming that f_values[idx1[i]] and f_values[-1-i] are the corresponding mirrored values
source code
 
eval_mean(self, func, args=())
evaluate the distribution mean, this is not (yet) effective in terms of termination or display
source code
 
ask_and_eval(self, func, args=(), gradf=None, number=None, xmean=None, sigma_fac=1, evaluations=1, aggregation=<function median at 0x10594d6e0>, kappa=1)
samples number solutions and evaluates them on func, where each solution s is resampled until self.is_feasible(s, func(s)) is True.
source code
 
prepare_injection_directions(self)
provide genotypic directions for TPA and selective mirroring, with no specific length normalization, to be used in the coming iteration.
source code
 
get_selective_mirrors(self, number=None, pop_sorted=None)
get mirror genotypic directions of the number worst solution, based on pop_sorted attribute (from last iteration).
source code
 
tell(self, solutions, function_values, check_points=None, copy=False)
pass objective function values to prepare for next iteration. This core procedure of the CMA-ES algorithm updates all state variables, in particular the two evolution paths, the distribution mean, the covariance matrix and a step-size.
source code
 
inject(self, solutions)
inject a genotypic solution. The solution is used as direction relative to the distribution mean to compute a new candidate solution returned in method ask_geno which in turn is used in method ask.
source code
 
result(self)
return::
source code
 
result_pretty(self, number_of_runs=0, time_str=None, fbestever=None)
pretty print result.
source code
 
clip_or_fit_solutions(self, pop, idx)
make sure that solutions fit to sample distribution, this interface will probably change.
source code
 
repair_genotype(self, x, copy_if_changed=False)
make sure that solutions fit to the sample distribution, this interface will probably change.
source code
 
decompose_C(self)
eigen-decompose self.C and update self.dC, self.C, self.B.
source code
 
updateBD(self)
update internal variables for sampling the distribution with the current covariance matrix C. This method is O(N^3), if C is not diagonal.
source code
 
multiplyC(self, alpha)
multiply C with a scalar and update all related internal variables (dC, D,...)
source code
 
update_exponential(self, Z, eta, BDpair=None)
exponential update of C that guarantees positive definiteness, that is, instead of the assignment C = C + eta * Z, we have C = C**.5 * exp(eta * C**-.5 * Z * C**-.5) * C**.5.
source code
 
feedForResume(self, X, function_values)
Given all "previous" candidate solutions and their respective function values, the state of a CMAEvolutionStrategy object can be reconstructed from this history. This is the purpose of function feedForResume.
source code
 
readProperties(self)
reads dynamic parameters from property file (not implemented)
source code
 
correlation_matrix(self) source code
 
mahalanobis_norm(self, dx)
compute the Mahalanobis norm that is induced by the adapted sample distribution, covariance matrix C times sigma**2, including sigma_vec. The expected Mahalanobis distance to the sample mean is about sqrt(dimension).
source code
 
_metric_when_multiplied_with_sig_vec(self, sig)
return D^-1 B^T diag(sig) B D as a measure for C^-1/2 diag(sig) C^1/2
source code
 
disp_annotation(self)
print annotation for disp()
source code
 
disp(self, modulo=None)
prints some single-line infos according to disp_annotation(), if iteration_counter % modulo == 0
source code
 
plot(self) source code

Inherited from OOOptimizer: initialize, optimize

Inherited from object: __delattr__, __format__, __getattribute__, __hash__, __new__, __reduce__, __reduce_ex__, __repr__, __setattr__, __sizeof__, __str__, __subclasshook__

Properties [hide private]
  popsize
number of samples by default returned by` ask()`

Inherited from object: __class__

Method Details [hide private]

stop(self, check=True)

source code 
return a dictionary with the termination status. With check==False, the termination conditions are not checked and the status might not reflect the current situation.
Overrides: OOOptimizer.stop

__init__(self, x0, sigma0, inopts={})
(Constructor)

source code 
see class CMAEvolutionStrategy
Overrides: object.__init__

ask(self, number=None, xmean=None, sigma_fac=1, gradf=None, args=())

source code 

get new candidate solutions, sampled from a multi-variate normal distribution and transformed to f-representation (phenotype) to be evaluated.

Arguments

number
number of returned solutions, by default the population size popsize (AKA lambda).
xmean
distribution mean, phenotyp?
sigma_fac
multiplier for internal sample width (standard deviation)
gradf
gradient, len(gradf(x)) == len(x), if gradf is not None the third solution in the returned list is "sampled" in supposedly Newton direction dot(C, gradf(xmean, *args)).
args
additional arguments passed to gradf

Return

A list of N-dimensional candidate solutions to be evaluated

Example

>>> import cma
>>> es = cma.CMAEvolutionStrategy([0,0,0,0], 0.3)
>>> while not es.stop() and es.best.f > 1e-6:  # my_desired_target_f_value
...     X = es.ask()  # get list of new solutions
...     fit = [cma.fcts.rosen(x) for x in X]  # call function rosen with each solution
...     es.tell(X, fit)  # feed values
Overrides: OOOptimizer.ask

See Also: ask_and_eval, ask_geno, tell

ask_geno(self, number=None, xmean=None, sigma_fac=1)

source code 

get new candidate solutions in genotyp, sampled from a multi-variate normal distribution.

Arguments are
number
number of returned solutions, by default the population size popsize (AKA lambda).
xmean
distribution mean
sigma_fac
multiplier for internal sample width (standard deviation)

ask_geno returns a list of N-dimensional candidate solutions in genotyp representation and is called by ask.

Details: updates the sample distribution and might change the geno-pheno transformation during this update.

See Also: ask, ask_and_eval

get_mirror(self, x, preserve_length=False)

source code 

return pheno(self.mean - (geno(x) - self.mean)).

>>> import cma
>>> es = cma.CMAEvolutionStrategy(cma.np.random.randn(3), 1)
>>> x = cma.np.random.randn(3)
>>> assert cma.Mh.vequals_approximately(es.mean - (x - es.mean), es.get_mirror(x, preserve_length=True))
>>> x = es.ask(1)[0]
>>> vals = (es.get_mirror(x) - es.mean) / (x - es.mean)
>>> assert cma.Mh.equals_approximately(sum(vals), len(vals) * vals[0])

TODO: this implementation is yet experimental.

TODO: this implementation includes geno-pheno transformation, however in general GP-transformation should be separated from specific code.

Selectively mirrored sampling improves to a moderate extend but overadditively with active CMA for quite understandable reasons.

Optimal number of mirrors are suprisingly small: 1,2,3 for maxlam=7,13,20 where 3,6,10 are the respective maximal possible mirrors that must be clearly suboptimal.

_mirror_penalized(self, f_values, idx)

source code 

obsolete and subject to removal (TODO), return modified f-values such that for each mirror one becomes worst.

This function is useless when selective mirroring is applied with no more than (lambda-mu)/2 solutions.

Mirrors are leading and trailing values in f_values.

_mirror_idx_cov(self, f_values, idx1)

source code 

obsolete and subject to removal (TODO), return indices for negative ("active") update of the covariance matrix assuming that f_values[idx1[i]] and f_values[-1-i] are the corresponding mirrored values

computes the index of the worse solution sorted by the f-value of the better solution.

TODO: when the actual mirror was rejected, it is better to return idx1 instead of idx2.

Remark: this function might not be necessary at all: if the worst solution is the best mirrored, the covariance matrix updates cancel (cave: weights and learning rates), which seems what is desirable. If the mirror is bad, as strong negative update is made, again what is desirable. And the fitness--step-length correlation is in part addressed by using flat weights.

ask_and_eval(self, func, args=(), gradf=None, number=None, xmean=None, sigma_fac=1, evaluations=1, aggregation=<function median at 0x10594d6e0>, kappa=1)

source code 

samples number solutions and evaluates them on func, where each solution s is resampled until self.is_feasible(s, func(s)) is True.

Arguments

func
objective function, func(x) returns a scalar
args
additional parameters for func
gradf
gradient of objective function, g = gradf(x, *args) must satisfy len(g) == len(x)
number
number of solutions to be sampled, by default population size popsize (AKA lambda)
xmean
mean for sampling the solutions, by default self.mean.
sigma_fac
multiplier for sampling width, standard deviation, for example to get a small perturbation of solution xmean
evaluations
number of evaluations for each sampled solution
aggregation
function that aggregates evaluations values to as single value.
kappa
multiplier used for the evaluation of the solutions, in that func(m + kappa*(x - m)) is the f-value for x.

Return

(X, fit), where
X -- list of solutions fit -- list of respective function values

Details

While not self.is_feasible(x, func(x))``new solutions are sampled. By default ``self.is_feasible == cma.feasible == lambda x, f: f not in (None, np.NaN). The argument to func can be freely modified within func.

Depending on the CMA_mirrors option, some solutions are not sampled independently but as mirrors of other bad solutions. This is a simple derandomization that can save 10-30% of the evaluations in particular with small populations, for example on the cigar function.

Example

>>> import cma
>>> x0, sigma0 = 8*[10], 1  # 8-D
>>> es = cma.CMAEvolutionStrategy(x0, sigma0)
>>> while not es.stop():
...     X, fit = es.ask_and_eval(cma.fcts.elli)  # handles NaN with resampling
...     es.tell(X, fit)  # pass on fitness values
...     es.disp(20) # print every 20-th iteration
>>> print('terminated on ' + str(es.stop()))
<output omitted>

A single iteration step can be expressed in one line, such that an entire optimization after initialization becomes

while not es.stop():
    es.tell(*es.ask_and_eval(cma.fcts.elli))

prepare_injection_directions(self)

source code 

provide genotypic directions for TPA and selective mirroring, with no specific length normalization, to be used in the coming iteration.

Details: This method is called in the end of tell. The result is assigned to self.pop_injection_directions and used in ask_geno.

TODO: should be rather appended?

get_selective_mirrors(self, number=None, pop_sorted=None)

source code 

get mirror genotypic directions of the number worst solution, based on pop_sorted attribute (from last iteration).

Details: Takes the last number=sp.lam_mirr entries in pop_sorted=self.pop_sorted as solutions to be mirrored.

tell(self, solutions, function_values, check_points=None, copy=False)

source code 

pass objective function values to prepare for next iteration. This core procedure of the CMA-ES algorithm updates all state variables, in particular the two evolution paths, the distribution mean, the covariance matrix and a step-size.

Arguments

solutions
list or array of candidate solution points (of type numpy.ndarray), most presumably before delivered by method ask() or ask_and_eval().
function_values
list or array of objective function values corresponding to the respective points. Beside for termination decisions, only the ranking of values in function_values is used.
check_points
If check_points is None, only solutions that are not generated by ask() are possibly clipped (recommended). False does not clip any solution (not recommended). If True, clips solutions that realize long steps (i.e. also those that are unlikely to be generated with ask()). check_points can be a list of indices to be checked in solutions.
copy
solutions can be modified in this routine, if copy is False

Details

tell() updates the parameters of the multivariate normal search distribution, namely covariance matrix and step-size and updates also the attributes countiter and countevals. To check the points for consistency is quadratic in the dimension (like sampling points).

Bugs

The effect of changing the solutions delivered by ask() depends on whether boundary handling is applied. With boundary handling, modifications are disregarded. This is necessary to apply the default boundary handling that uses unrepaired solutions but might change in future.

Example

import cma
func = cma.fcts.elli  # choose objective function
es = cma.CMAEvolutionStrategy(cma.np.random.rand(10), 1)
while not es.stop():
   X = es.ask()
   es.tell(X, [func(x) for x in X])
es.result()  # where the result can be found
Overrides: OOOptimizer.tell

result(self)

source code 
return::

(xbest, f(xbest), evaluations_xbest, evaluations, iterations,
    pheno(xmean), effective_stds)

Overrides: OOOptimizer.result

result_pretty(self, number_of_runs=0, time_str=None, fbestever=None)

source code 

pretty print result.

Returns self.result()

clip_or_fit_solutions(self, pop, idx)

source code 

make sure that solutions fit to sample distribution, this interface will probably change.

In particular the frequency of long vectors appearing in pop[idx] - self.mean is limited.

repair_genotype(self, x, copy_if_changed=False)

source code 

make sure that solutions fit to the sample distribution, this interface will probably change.

In particular the frequency of x - self.mean being long is limited.

decompose_C(self)

source code 

eigen-decompose self.C and update self.dC, self.C, self.B.

Known bugs: this might give a runtime error with CMA_diagonal / separable option on.

update_exponential(self, Z, eta, BDpair=None)

source code 

exponential update of C that guarantees positive definiteness, that is, instead of the assignment C = C + eta * Z, we have C = C**.5 * exp(eta * C**-.5 * Z * C**-.5) * C**.5.

Parameter Z should have expectation zero, e.g. sum(w[i] * z[i] * z[i].T) - C if E z z.T = C.

Parameter eta is the learning rate, for eta == 0 nothing is updated.

This function conducts two eigendecompositions, assuming that B and D are not up to date, unless BDpair is given. Given BDpair, B is the eigensystem and D is the vector of sqrt(eigenvalues), one eigendecomposition is omitted.

Reference: Glasmachers et al 2010, Exponential Natural Evolution Strategies

feedForResume(self, X, function_values)

source code 

Given all "previous" candidate solutions and their respective function values, the state of a CMAEvolutionStrategy object can be reconstructed from this history. This is the purpose of function feedForResume.

Arguments

X
(all) solution points in chronological order, phenotypic representation. The number of points must be a multiple of popsize.
function_values
respective objective function values

Details

feedForResume can be called repeatedly with only parts of the history. The part must have the length of a multiple of the population size. feedForResume feeds the history in popsize-chunks into tell. The state of the random number generator might not be reconstructed, but this would be only relevant for the future.

Example

import cma

# prepare
(x0, sigma0) = ... # initial values from previous trial
X = ... # list of generated solutions from a previous trial
f = ... # respective list of f-values

# resume
es = cma.CMAEvolutionStrategy(x0, sigma0)
es.feedForResume(X, f)

# continue with func as objective function
while not es.stop():
   X = es.ask()
   es.tell(X, [func(x) for x in X])

Credits to Dirk Bueche and Fabrice Marchal for the feeding idea.

See Also: class CMAEvolutionStrategy for a simple dump/load to resume

mahalanobis_norm(self, dx)

source code 

compute the Mahalanobis norm that is induced by the adapted sample distribution, covariance matrix C times sigma**2, including sigma_vec. The expected Mahalanobis distance to the sample mean is about sqrt(dimension).

Argument

A genotype difference dx.

Example

>>> import cma, numpy
>>> es = cma.CMAEvolutionStrategy(numpy.ones(10), 1)
>>> xx = numpy.random.randn(2, 10)
>>> d = es.mahalanobis_norm(es.gp.geno(xx[0]-xx[1]))

d is the distance "in" the true sample distribution, sampled points have a typical distance of sqrt(2*es.N), where es.N is the dimension, and an expected distance of close to sqrt(N) to the sample mean. In the example, d is the Euclidean distance, because C = I and sigma = 1.

_metric_when_multiplied_with_sig_vec(self, sig)

source code 
return D^-1 B^T diag(sig) B D as a measure for C^-1/2 diag(sig) C^1/2
Parameters:
  • sig - a vector "used" as diagonal matrix

disp(self, modulo=None)

source code 
prints some single-line infos according to disp_annotation(), if iteration_counter % modulo == 0
Overrides: OOOptimizer.disp

Property Details [hide private]

popsize

number of samples by default returned by` ask()`
Get Method:
unreachable.popsize(self) - number of samples by default returned by` ask()`