Project Name: Dreem-Organization+benderopt
Language: Python
Statement Type: API

Source Code:
def parzen_estimator_build_posterior_parameter(parameter, observations):
    """TPE algorith transform a prior parameter into a posterior parameters using observations
    to build posterior.
    """
    posterior_parameter = None
    parameter_values = [observation.sample[parameter.name] for observation in observations]
    search_space = parameter.search_space
    if parameter.category == "categorical":
        """ TODO Compare mean (current implem) vs hyperopt approach."""
        prior_probabilities = np.array(search_space["probabilities"])
        posterior_probabilities = prior_probabilities
        if len(parameter_values) != 0:
            observed_probabilities = np.array([parameter_values.count(value)
                                               for value in search_space["values"]])
            observed_probabilities = observed_probabilities / np.sum(observed_probabilities)
            posterior_probabilities += observed_probabilities
        posterior_probabilities /= sum(posterior_probabilities)

        # Build param
        posterior_parameter = Parameter.from_dict(
            {
                "name": parameter.name,
                "category": "categorical",
                "search_space": {
                    "values": search_space["values"],
                    "probabilities": list(posterior_probabilities),
                }
            }
        )

    if parameter.category in ("uniform", "normal", "loguniform", "lognormal"):
        if parameter.category in ("uniform", "loguniform"):
            prior_mu = 0.5 * (search_space["high"] + search_space["low"])
            prior_sigma = (search_space["high"] - search_space["low"])
        elif parameter.category in ("normal", "lognormal"):
            prior_mu = search_space["mu"]
            prior_sigma = search_space["sigma"]

        # Mus
        mus = np.sort(parameter_values + [prior_mu])

        # Sigmas
        # Trick to get for each mu the greater distance from left and right neighbor
        # when low and high are not defined we use inf to get the only available distance
        # (right neighbor for sigmas[0] and left for sigmas[-1])
        tmp = np.concatenate(
            (
                [search_space.get("low", np.inf)],
                mus,
                [search_space.get("high", -np.inf)],
            )
        )
        sigmas = np.maximum(tmp[1:-1] - tmp[0:-2], tmp[2:] - tmp[1:-1])

        # Use formulas from hyperopt to clip sigmas
        sigma_max_value = prior_sigma
        sigma_min_value = prior_sigma / min(100.0, (1.0 + len(mus)))
        sigmas = np.clip(sigmas, sigma_min_value, sigma_max_value)

        # Fix prior sigma with correct value
        sigmas[np.where(mus == prior_mu)[0]] = prior_sigma

        posterior_parameter = Parameter.from_dict(
            {
                "name": parameter.name,
                "category": "mixture",
                "search_space": {
                    "parameters": [
                        {
                            "category": "normal",
                            "search_space": {
                                "mu": mu.tolist(),
                                "sigma": sigma.tolist(),
                                "low": search_space["low"],
                                "high": search_space["high"],
                                "step": search_space.get("step", None)
                            }
                        } if parameter.category[:3] != "log" else
                        {
                            "category": "lognormal",
                            "search_space": {
                                "mu": mu.tolist(),
                                "sigma": sigma.tolist(),
                                "low": search_space["low"],
                                "high": search_space["high"],
                                "step": search_space["step"],
                                "base": search_space["base"],
                            }
                        } for mu, sigma in zip(mus, sigmas)
                    ],
                    "weights": [1 / len(mus) for _ in range(len(mus))]
                }
            }
        )

    return posterior_parameter

parzen_estimator_build_posterior_parameter(parameter=x, observations=[])

Selected Statement: sigma_min_value = prior_sigma / min(100.0, (1.0 + len(mus)))

Function Input:
parameter: x

Variable Values Before Statement:
mus: array([1.57079633])

Value After Statement Execution: 1.5707963267948966

Variable States During Runtime (line, value):
parameter: 1
x
observations: 1
posterior_parameter: 5
None
63
x
parameter_values: 6
search_space: 7
low: 0
high: 3.141592653589793
prior_mu: 33
1.5707963267948966
prior_sigma: 34
3.141592653589793
mus: 40
array([1.57079633])
tmp: 46
array([0.        , 1.57079633, 3.14159265])
sigmas: 53
array([1.57079633])
61
array([3.14159265])
sigma_max_value: 56
3.141592653589793
sigma_min_value: 57
1.5707963267948966