Source code for olympus.surfaces.surface_discrete_ackley.wrapper_discrete_ackley

#!/usr/bin/env python

import numpy as np
from olympus.surfaces import AbstractSurface
from itertools import product
from olympus import Logger


[docs]class DiscreteAckley(AbstractSurface): def __init__(self, param_dim=2, noise=None): """Discrete Ackley function. Args: param_dim (int): Number of input dimensions. Default is 2. noise (Noise): Noise object that injects noise into the evaluations of the surface. Default is None. """ AbstractSurface.__init__(**locals()) @property def minima(self): # minimum at the centre params = [0.5] * self.param_dim value = self._run(params) return [{'params': params, 'value': value}] @property def maxima(self): message = 'DiscreteAckley has an infinite number of maxima' Logger.log(message, 'INFO') # some maxima maxima = [] params = product([0.05, 0.95], repeat=self.param_dim) for param in params: param = list(param) value = self._run(param) maxima.append({'params': param, 'value': value}) return maxima def _run(self, params): params = np.array(params) params = 100 * params - 50 bounds = [1.0, 2.0, 3.0, 4.0, 5.0] bounds = np.array(bounds) ** 2 result = 5 for bound in bounds[::-1]: if np.amax(np.abs(params)) < bound: result -= 1 bounds = [1.25, 2.0, 2.5] bounds = np.array(bounds) ** 2 domain = np.linspace(-50, 50, 10) dx = domain[1] - domain[0] imaged = np.array([np.amin(np.abs(element - domain)) for element in params]) new_res = 5 for bound in bounds[::-1]: if np.amax(np.abs(imaged)) < bound: new_res -= 1 result = np.amin([result, new_res]) result = np.amin([4, result]) if self.noise is None: return result else: return self.noise(result)