<commit_before>"""
Acquisition functions for Bayesian optimization with GPs.
"""

# future imports
from __future__ import division
from __future__ import absolute_import
from __future__ import print_function

# global imports
import numpy as np
import scipy.stats as ss
import functools
import operator

# exported symbols
__all__ = ['ei']


def _integrate(models, index):
    if hasattr(models, '__iter__'):
        def index2(X, grad=False):
            indices = [index(model, X, grad) for model in models]
            if grad:
                return tuple([np.sum(_, axis=0) for _ in zip(*indices)])
            else:
                return np.sum(indices, axis=0)
    else:
        def index2(X, grad=False):
            return index(models, X, grad)
    return index2


def ei(models, fbest, xi=0.0):
    # FIXME (Matt): Before Bobak had added a target value that was either given
    # by `fbest + xi` or was given by the target. This allows us to enter a
    # 'max' value, but I'm not sure that's right. IE: doesn't that mean we're
    # trying to compute the expected improvement over the max? Which should be
    # zero? I took this out because it deserves more thought.
    target = fbest + xi

    # define the index wrt a single model (that should act like a GP model, ie
    # in that it is marginally Gaussian and defines the posterior method).
    def index(model, X, grad=False):
        posterior = model.posterior(X, grad=grad)
        mu, s2 = posterior[:2]
        s = np.sqrt(s2)
        d = mu - target
        z = d / s
        pdfz = ss.norm.pdf(z)
        cdfz = ss.norm.cdf(z)
        ei = d * cdfz + s * pdfz

        if grad:
            # get the derivative of ei. The mu/s2/etc. components are vectors
            # collecting n scalar points, whereas dmu and ds2 are (n,d)-arrays.
            # The indexing tricks just interpret the "scalar" quantities as
            # (n,1)-arrays so that we can use numpy's broadcasting rules.
            dmu, ds2 = posterior[2:]
            dei = 0.5 * ds2 / s2[:,None]
            dei *= (ei - s * z * cdfz)[:,None]
            dei += cdfz[:,None] * dmu
            return ei, dei
        else:<commit_msg>Have the index being integrated over always take grad.<commit_after>"""
Acquisition functions for Bayesian optimization with GPs.
"""

# future imports
from __future__ import division
from __future__ import absolute_import
from __future__ import print_function

# global imports
import numpy as np
import scipy.stats as ss
import functools
import operator

# exported symbols
__all__ = ['ei']


def _integrate(models, index):
    if hasattr(models, '__iter__'):
        def index2(X, grad=False):
            indices = [index(model, grad, X) for model in models]
            if grad:
                return tuple([np.sum(_, axis=0) for _ in zip(*indices)])
            else:
                return np.sum(indices, axis=0)
    else:
        def index2(X, grad=False):
            return index(models, grad, X)
    return index2


def ei(models, fbest, xi=0.0):
    # FIXME (Matt): Before Bobak had added a target value that was either given
    # by `fbest + xi` or was given by the target. This allows us to enter a
    # 'max' value, but I'm not sure that's right. IE: doesn't that mean we're
    # trying to compute the expected improvement over the max? Which should be
    # zero? I took this out because it deserves more thought.
    target = fbest + xi

    # define the index wrt a single model (that should act like a GP model, ie
    # in that it is marginally Gaussian and defines the posterior method).
    def index(model, grad, X):
        posterior = model.posterior(X, grad=grad)
        mu, s2 = posterior[:2]
        s = np.sqrt(s2)
        d = mu - target
        z = d / s
        pdfz = ss.norm.pdf(z)
        cdfz = ss.norm.cdf(z)
        ei = d * cdfz + s * pdfz

        if grad:
            # get the derivative of ei. The mu/s2/etc. components are vectors
            # collecting n scalar points, whereas dmu and ds2 are (n,d)-arrays.
            # The indexing tricks just interpret the "scalar" quantities as
            # (n,1)-arrays so that we can use numpy's broadcasting rules.
            dmu, ds2 = posterior[2:]
            dei = 0.5 * ds2 / s2[:,None]
            dei *= (ei - s * z * cdfz)[:,None]
            dei += cdfz[:,None] * dmu
            return ei, dei
        else:
{'fraction_non_alphanumeric': 0.0928750284543592, 'fraction_numerical': 0.008650125199180514, 'mean_word_length': 2.2404129793510323, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7295672', 'n_tokens_mistral': 1337, 'n_tokens_neox': 1294, 'n_words': 529}