diff --git a/README.md b/README.md index fb2b482..38429a2 100644 --- a/README.md +++ b/README.md @@ -379,13 +379,29 @@ For C++, the `BaseSampler` enum should be provided to the `sampler` member of th ```python ... -modules.sampler = c_maes.options.BaseSampler.GAUSSIAN +modules.sampler = c_maes.options.BaseSampler.UNIFORM # or modules.sampler = c_maes.options.BaseSampler.SOBOL # or modules.sampler = c_maes.options.BaseSampler.HALTON ``` +Here, this works slightly different. The base sampler only defined the method for generating uniform sampling in a $[0,1)^d$ hyperbox. In order to define that a, for example, Gaussian distribution (this is default) should be used when running the algorithm, we need to specify the `sample_transformation` type: + +```python +modules.sample_transformation = c_maes.options.SampleTranformerType.GAUSSIAN +# or +modules.sample_transformation = c_maes.options.SampleTranformerType.SCALED_UNIFORM +# or +modules.sample_transformation = c_maes.options.SampleTranformerType.LAPLACE +# or +modules.sample_transformation = c_maes.options.SampleTranformerType.LOGISTIC +# or +modules.sample_transformation = c_maes.options.SampleTranformerType.CAUCHY +# or +modules.sample_transformation = c_maes.options.SampleTranformerType.DOUBLE_WEIBULL +``` + ### Recombination Weights We implemented three different variants of the recombination weights used in the update of the strategy parameters, default, equal and $1/2\lambda$. @@ -478,7 +494,27 @@ modules.restart_strategy = c_maes.options.RestartStrategy.NONE modules.restart_strategy = c_maes.options.RestartStrategy.IPOP ``` -Note that the C++ version has an addtional option here, `STOP`, which forces the algortihm to stop whenever a restart condition is met (not to be confused with a break condition). +Note that the C++ version has an addtional option here, `STOP`, which forces the algortihm to stop whenever a restart condition is met (not to be confused with a break condition). The C++ version also offers fine control over when a restart happens. The `Parameters` object has an `criteria` member, of which the `items` member defines a list of `Criterion` objects, which are triggers for when a restart should happen. This list can be freely changed, and default items can be deleted and modified if desired. For example, `cma.p.criteria.items = []`, clears this list entirely, and no restarts will happen. Several of the currently defined `Criterion` object can also be modified, often this can be controlled by setting the `tolerance` parameter. For example, for the `MinSigma` criterion, you can set `c_maes.restart.MinSigma.tolerance = 1` to ensure a parameter value of sigma below 1 triggers a restart. Note that this is a static varaible, so modifying it in this fashion sets this for all instances of `c_maes.restart.MinSigma`. Alternatively, it is possible to define a custom `Criterion` like so: + +```python +class MyCriterion(modcma.restart.Criterion): + def __init__(self): + super().__init__("MyCriterionName") + + def on_reset(self, par: modcma.Parameters): + """Called when a restart happens (also at the start)""" + + def update(self, par: modcma.Parameters): + """Called after each iteration, needs to modify self.met""" + self.met = True + +# Python needs a reference to this object, +# so you CANNOT create it in place, i.e. +# cma.p.criteria.items = [MyCriterion()] +# will produce an error +c = MyCriterion() +cma.p.criteria.items = [c] +``` ### Bound correction diff --git a/src/mutation.cpp b/src/mutation.cpp index d647a02..693d60a 100644 --- a/src/mutation.cpp +++ b/src/mutation.cpp @@ -220,7 +220,8 @@ namespace mutation default: case StepSizeAdaptation::CSA: cs = cs0.value_or((mueff + 2.0) / (d + mueff + 5.0)); - damps = 1.0 + (2.0 * std::max(Float{0.0}, sqrt((mueff - 1.0) / (d + 1)) - 1) + cs); + const Float rhs = std::sqrt((mueff - Float(1.0)) / (d + 1)) - 1; + damps = 1.0 + (2.0 * std::max(Float(0.0), rhs) + cs); return std::make_shared(tc, sq, ss, cs, damps, sigma, expected_z); } }