class ScaleCoordinates(ComposedFunction):
Constructor: ScaleCoordinates(fitness_function, multipliers, zero, upper, ...)
compose a (fitness) function with a preceding scaling and offset.
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).
Domain interface (lower and upper variable values)
Let u and l be vectors (or a scalar) of (approximate) lower and upper variable values, respectively. After fun2 = cma.ScaleCoordinates(fun, upper=u, lower=l) we have 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.
Examples and Doctest
>>> import numpy as np >>> import cma >>> fun = cma.ScaleCoordinates(cma.ff.sphere, upper=[30, 1]) >>> bool(fun([1, 1]) == 30**2 + 1**2) True >>> fun.transform([1, 1]).tolist(), fun.transform([0.2, 0.2]).tolist() ([30.0, 1.0], [6.0, 0.2]) >>> fun.inverse(fun.transform([0.1, 0.3])).tolist() [0.1, 0.3] >>> fun = cma.ScaleCoordinates(cma.ff.sphere, upper=[31, 3], lower=[1, 2]) >>> bool(-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 >>> bool(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 |
Undocumented |
Instance Variable | from |
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 |
Undocumented |
Inherited from Function
(via ComposedFunction
):
Method | initialize |
initialization of Function |
Instance Variable | evaluations |
Undocumented |
Instance Variable | ftarget |
Undocumented |
Instance Variable | target |
Undocumented |
Property | function |
attributes which are searched for to be called if no function was given to __init__ . |
Class Variable | _function |
Undocumented |
Instance Variable | __callable |
Undocumented |
Instance Variable | __initialized |
Undocumented |
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 | a callable object |
multipliers | coordinate-wise multipliers. |
zero | defines a new zero in preimage space, that is,
calling the ScaleCoordinates instance returns
fitness_function(multipliers * (x - zero)). |
upper | variable value to which from_lower_upper[1] maps. |
lower | variable value to which from_lower_upper[0] maps. |
from | Undocumented |