def _update_lims(self, swarm, X: numpy.ndarray): backup_bounds = swarm.env.bounds if swarm is not None else Bounds.from_array( X) bounds = (swarm.critic.bounds if has_embedding(swarm) and self.use_embeddings else backup_bounds) self.xlim, self.ylim = bounds.to_tuples()[:2] self.xlim = judo.to_numpy(self.xlim[0]), judo.to_numpy(self.xlim[1]) self.ylim = judo.to_numpy(self.ylim[0]), judo.to_numpy(self.ylim[1])
def get_z_coords(self, swarm: Swarm, X: numpy.ndarray = None): """Get the values assigned by the :class:`Critic` to the regions of the state space.""" if swarm is None: return numpy.ones(self.n_points**self.n_points) if swarm.critic.bounds is None: swarm.critic.bounds = Bounds.from_array(X, scale=1.1) # target grid to interpolate to xi = numpy.linspace(swarm.critic.bounds.low[0], swarm.critic.bounds.high[0], self.n_points) yi = numpy.linspace(swarm.critic.bounds.low[1], swarm.critic.bounds.high[1], self.n_points) xx, yy = numpy.meshgrid(xi, yi) grid = numpy.c_[xx.ravel(), yy.ravel()] if swarm.swarm.critic.warmed: memory_values = swarm.swarm.critic.predict(grid) memory_values = relativize(-memory_values) else: memory_values = numpy.arange(grid.shape[0]) return judo.to_numpy(memory_values)
def from_bounds_params( cls, function: Callable, shape: tuple = None, high: Union[int, float, typing.Tensor] = numpy.inf, low: Union[int, float, typing.Tensor] = numpy.NINF, custom_domain_check: Callable[[typing.Tensor], typing.Tensor] = None, ) -> "Function": """ Initialize a function defining its shape and bounds without using a :class:`Bounds`. Args: function: Callable that takes a batch of vectors (batched across \ the first dimension of the array) and returns a vector of \ typing.Scalar. This function is applied to a batch of walker \ observations. shape: Input shape of the solution vector without taking into account \ the batch dimension. For example, a two dimensional function \ applied to a batch of 5 walkers will have shape=(2,), even though the observations will have shape (5, 2) high: Upper bound of the function domain. If it's an typing.Scalar it will \ be the same for all dimensions. If its a numpy array it will \ be the upper bound for each dimension. low: Lower bound of the function domain. If it's an typing.Scalar it will \ be the same for all dimensions. If its a numpy array it will \ be the lower bound for each dimension. custom_domain_check: Callable that checks points inside the bounds \ to know if they are in a custom domain when it is not just \ a set of rectangular bounds. Returns: :class:`Function` with its :class:`Bounds` created from the provided arguments. """ if (not (judo.is_tensor(high) or isinstance(high, (list, tuple))) and not (judo.is_tensor(low) or isinstance(low, (list, tuple))) and shape is None): raise TypeError( "Need to specify shape or high or low must be a numpy array.") bounds = Bounds(high=high, low=low, shape=shape) return Function(function=function, bounds=bounds, custom_domain_check=custom_domain_check)
def mapper(): def potential_well(x): return judo.sum((x - 1)**2, 1) - 1 bounds = Bounds.from_tuples([(-10, 10), (-5, 5)]) def model(x): return NormalContinuous(bounds=bounds, env=x) return FunctionMapper.from_function( n_vectors=5, function=potential_well, bounds=bounds, model=model, shape=(2, ), n_walkers=10, reward_scale=1, accumulate_rewards=False, )
def get_z_coords(self, swarm: Swarm, X: numpy.ndarray = None) -> numpy.ndarray: """Extract the memory values of the :class:`Critic`'s grid.""" if swarm is None: return numpy.ones(self.n_points**self.n_points) if swarm.critic.bounds is None: swarm.critic.bounds = Bounds.from_array(X, scale=1.1) # target grid to interpolate to xi = numpy.linspace(swarm.critic.bounds.low[0], swarm.critic.bounds.high[0], self.n_points) yi = numpy.linspace(swarm.critic.bounds.low[1], swarm.critic.bounds.high[1], self.n_points) xx, yy = numpy.meshgrid(xi, yi) grid = numpy.c_[xx.ravel(), yy.ravel()] if swarm.swarm.critic.warmed: memory_values = swarm.swarm.critic.model.transform(grid) memory_values = numpy.array([ swarm.swarm.critic.memory[ix[0], ix[1]].astype(numpy.float32) for ix in memory_values.astype(int) ]) else: memory_values = numpy.arange(grid.shape[0]) return judo.to_numpy(memory_values)
def custom_domain_function(): bounds = Bounds(shape=(2, ), high=10, low=-5, dtype=judo.float) env = Function(function=sphere, bounds=bounds, custom_domain_check=lambda x, *args: judo.norm(x, 1) < 5.0) return env
def local_minimizer(): bounds = Bounds(shape=(2, ), high=10, low=-5, dtype=judo.float) env = Function(function=sphere, bounds=bounds) return MinimizerWrapper(env)
def test_minimizer_getattr(self): bounds = Bounds(shape=(2, ), high=10, low=-5, dtype=float) env = Function(function=sphere, bounds=bounds) minim = MinimizerWrapper(env) assert minim.shape == env.shape
def det_cmaes(): bs = Bounds(low=-10, high=10, shape=(5, )) return DeterministicCMAES(bounds=bs, sigma=0.3)
def cmaes(): bs = Bounds(low=-10, high=10, shape=(5, )) return CMAES(bounds=bs, sigma=0.3)
def create_model(name="es_model"): if name == "es_model": bs = Bounds(low=-10, high=10, shape=(BATCH_SIZE, )) return lambda: ESModel(bounds=bs) raise ValueError("Invalid param `name`.")