class documentation

class ScaleCoordinates(ComposedFunction):

View In Hierarchy

compose a (fitness) function with a preceding scaling and offset.

Domain interface (lower and upper variable values)

Let u and l be vectors (or a scalar) of (approximate) lower and upper variable values, respectively. Assigning fun2 from fun like:

fun2 = cma.ScaleCoordinates(fun, upper=u, lower=l)

gets fun2(x) == fun(l + (u - l) * x). Now, passing 0 as x[i] to fun2 evaluates fun at l[i] while passing 1 evaluates fun at u[i].

To match the size of x, the sizes of u and l are shortened or their last entry is recycled if necessary.

The default value for lower is zero in which case upper just becomes a scaling multiplier.

Bounding the search domain of fun2 to [0, 1] now bounds fun to the domain [l, u]. The 'bounds' option of CMAOptions allows to set these bounds.

More general, the affine transformation is defined such that x[i]==from_lower_upper[0] evaluates fun at l[i] and x[i]==from_lower_upper[1] evaluates fun at u[i] where from_lower_upper == [0, 1] by default.

Scaling interface

After fun2 = cma.ScaleCoordinates(fun, multipliers, zero), we have fun2(x) == fun(multipliers * (x - zero)), where the vector size of multipliers and zero is adapated to the size of x, in case by recycling their last entry. This awkwardly asks to pass the zero argument of the preimage space where it has little meaning. Hence more conveniently, fun2 = cma.ScaleCoordinates(fun, multipliers, lower=lower) gets fun2(x) == fun(multipliers * x + lower)).

Examples and Doctest

>>> import numpy as np
>>> import cma
>>> fun = cma.ScaleCoordinates(cma.ff.sphere, upper=[30, 1])
>>> fun([1, 1]) == 30**2 + 1**2
True
>>> list(fun.transform([1, 1])), list(fun.transform([0.2, 0.2]))
([30.0, 1.0], [6.0, 0.2])
>>> list(fun.inverse(fun.transform([0.1, 0.3])))
[0.1, 0.3]
>>> fun = cma.ScaleCoordinates(cma.ff.sphere, upper=[31, 3], lower=[1, 2])
>>> -1e-9 < fun([1, -1]) - (31**2 + 1**2) < 1e-9
True
>>> f = cma.ScaleCoordinates(cma.ff.sphere, [100, 1])
>>> assert f[0] == cma.ff.sphere  # first element of f-composition
>>> assert f(range(1, 6)) == 100**2 + sum([x**2 for x in range(2, 6)])
>>> assert f([2.1]) == 210**2 == f(2.1)
>>> assert f(20 * [1]) == 100**2 + 19
>>> assert np.all(f.inverse(f.scale_and_offset([1, 2, 3, 4])) ==
...               np.asarray([1, 2, 3, 4]))
>>> f = cma.ScaleCoordinates(f, [-2, 7], [2, 3, 4]) # last is recycled
>>> f([5, 6]) == sum(x**2 for x in [100 * -2 * (5 - 2), 7 * (6 - 3)])
True

See also these [Practical Hints](https://cma-es.github.io/cmaes_sourcecode_page.html#practical) for encoding variables.

Method __init__ Only either multipliers or 'upper` can be passed. If zero is passed then upper and lower are ignored. The arguments multipliers, zero, upper and lower can be vectors or scalars, superfluous trailing elements are ignored and the last element is recycled if needed to fit the length of the later given input.
Method inverse inverse of coordinate-wise affine transformation y / multipliers + zero
Method scale_and_offset Undocumented
Instance Variable from_lower_upper Undocumented
Instance Variable lower Undocumented
Instance Variable multiplier Undocumented
Instance Variable transform Undocumented
Instance Variable upper Undocumented
Instance Variable zero Undocumented

Inherited from ComposedFunction:

Method __call__ Undocumented
Instance Variable list_of_inverses Undocumented

Inherited from Function (via ComposedFunction):

Method initialize initialization of Function
Instance Variable evaluations Undocumented
Instance Variable ftarget Undocumented
Instance Variable target_hit_at Undocumented
Property function_names_to_evaluate_first_found attributes which are searched for to be called if no function was given to __init__.
Class Variable _function_names_to_evaluate_first_found Undocumented
Instance Variable __callable Undocumented
Instance Variable __initialized Undocumented
def __init__(self, fitness_function, multipliers=None, zero=None, upper=None, lower=None, from_lower_upper=(0, 1)):

Only either multipliers or 'upper` can be passed. If zero is passed then upper and lower are ignored. The arguments multipliers, zero, upper and lower can be vectors or scalars, superfluous trailing elements are ignored and the last element is recycled if needed to fit the length of the later given input.

from_lower_upper is (0, 1) by default and defines the preimage values which are mapped to lower and upper, respectively (unless multipliers or zero are given). These two preimage values are always the same for all coordinates.

Details

The upper and lower and from_lower_upper parameters are used to assign multipliers and zero such that the transformation is then always computed from the latter two only.

Parameters
fitness_functiona callable object
multiplierscoordinate-wise multipliers.
zerodefines a new zero in preimage space, that is, calling the ScaleCoordinates instance returns fitness_function(multipliers * (x - zero)).
uppervariable value to which from_lower_upper[1] maps.
lowervariable value to which from_lower_upper[0] maps.
from_lower_upperUndocumented
def inverse(self, x):

inverse of coordinate-wise affine transformation y / multipliers + zero

def scale_and_offset(self, x):

Undocumented

from_lower_upper =

Undocumented

lower =

Undocumented

multiplier =

Undocumented

transform =

Undocumented

upper =

Undocumented

zero =

Undocumented