A function to find the maximum of the acquisition function

        It uses a combination of random sampling (cheap) and the 'L-BFGS-B' optimization method.

        First by sampling `n_warmup` (1e5) points at random,
        and then running L-BFGS-B from `n_iter` (250) random starting points.

        Params:
            y_max: The current maximum known value of the target function.
            bounds: The variables bounds to limit the search of the acq max.
            n_warmup: The number of times to randomly sample the acquisition function
            n_iter: The number of times to run scipy.minimize

        Returns
            x_max: The arg max of the acquisition function.

def max_compute(self, y_max, bounds, n_warmup=100000, n_iter=250):
        """A function to find the maximum of the acquisition function

        It uses a combination of random sampling (cheap) and the 'L-BFGS-B' optimization method.

        First by sampling `n_warmup` (1e5) points at random,
        and then running L-BFGS-B from `n_iter` (250) random starting points.

        Params:
            y_max: The current maximum known value of the target function.
            bounds: The variables bounds to limit the search of the acq max.
            n_warmup: The number of times to randomly sample the acquisition function
            n_iter: The number of times to run scipy.minimize

        Returns
            x_max: The arg max of the acquisition function.
        """
        # Warm up with random points
        x_tries = self.random_generator.uniform(bounds[:, 0], bounds[:, 1],
                                                size=(n_warmup, bounds.shape[0]))
        ys = self.compute(x_tries, y_max=y_max)
        x_max = x_tries[ys.argmax()]
        max_acq = ys.max()

        # Explore the parameter space more throughly
        x_seeds = self.random_generator.uniform(bounds[:, 0], bounds[:, 1],
                                                size=(n_iter, bounds.shape[0]))
        for x_try in x_seeds:
            # Find the minimum of minus the acquisition function
            res = minimize(lambda x: -self.compute(x.reshape(1, -1), y_max=y_max),
                           x_try.reshape(1, -1),
                           bounds=bounds,
                           method="L-BFGS-B")

            # See if success
            if not res.success:
                continue

            # Store it if better than previous minimum(maximum).
            if max_acq is None or -res.fun[0] >= max_acq:
                x_max = res.x
                max_acq = -res.fun[0]

        # Clip output to make sure it lies within the bounds. Due to floating
        # point technicalities this is not always the case.
        return np.clip(x_max, bounds[:, 0], bounds[:, 1])