Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement a shorter function boundary wrapper based on transformations.BoxConstraintsLinQuadTransformation #265

Open
nikohansen opened this issue Sep 18, 2024 · 2 comments

Comments

@nikohansen
Copy link
Contributor

such that the boundaries are not passed as options anymore and the BoundTransform boundary handling can be used easily with any other algorithm. Also, fmin2 could use the function wrapper instead of passing bounds to the GenoPheno transformation.

This wrapper is just a shortcut for

    >>> bounded_sphere = ComposedFunction([
    ...         cma.ff.sphere,
    ...         BoundTransform([[], 5 * [-1] + [np.inf]]).transform
    ...     ])

where the docstring of BoundTransform should be improved.

@nikohansen nikohansen changed the title Implement a shorter function wrapper based on transformations.BoxConstraintsLinQuadTransformation Implement a shorter function boundary wrapper based on transformations.BoxConstraintsLinQuadTransformation Sep 18, 2024
@nikohansen
Copy link
Contributor Author

nikohansen commented Sep 18, 2024

Class definition:

import cma

class WrapBoundaryTransform(cma.fitness_transformations.ComposedFunction):
    def __init__(self, objective_function, boundaries):
        # could in principle be done with BoundPenalty too
        self.boundary_handler = cma.boundary_handler.BoundTransform(boundaries)
        self.transform = self.boundary_handler.transform
        super(WrapBoundaryTransform, self).__init__(
              [objective_function, self.transform])

Usecase:

fun = WrapBoundaryTransform(cma.ff.sphere, [0.01, 2])
x, es = cma.fmin2(fun, 5 * [0.5], 0.5)
print("best solution = {}".format(fun.transform(x)))
es.plot();

Output:
Screenshot 2024-09-19 at 08 07 58

The output of fmin2 is the untransformed solution, hence the optimal x-values are negative, which is a little confusing and somewhat mitigated by the bounds option.

@nikohansen
Copy link
Contributor Author

A more explicit class definition that does not depend on ComposedFunction:

class WrapBoundaryTransform(object):
    def __init__(self, objective_function, boundaries,
                 outer_wrapper=cma.fitness_transformations.Function):
        self.objective_function = outer_wrapper(objective_function) if outer_wrapper else objective_function
        self.boundary_handler = cma.boundary_handler.BoundTransform(boundaries)
        self.transform = self.boundary_handler.transform
    def __call__(self, x, *args, **kwargs):
        return self.objective_function(self.transform(x), *args, **kwargs)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant