<commit_before># Author: <NAME>

# Provides some universal statistical utilities and stats comparison tools

import numpy as np
import pandas as pd
from threeML.io.rich_display import display
import copy

import warnings


def li_and_ma(total, background, alpha=1.):
    """"Li and Ma (1983) signal to noise significance"""

    a = total / (total + background)
    b = background / (total + background)
    S = np.sqrt(2) * np.sqrt((total * np.log(((1. + alpha) / alpha) * a) + background * np.log((1 + alpha) * b)))

    return S


def aic(log_like, n_parameters, n_data_points):
    """
    The Aikake information criterion.
    A model comparison tool based of infomormation theory. It assumes that N is large i.e.,
    that the model is approaching the CLT.


    """

    val = -2. * log_like + 2 * n_parameters
    val += 2 * n_parameters * (n_parameters + 1) / (n_data_points - n_parameters - 1)

    return val


def bic(log_like, n_parameters, n_data_points):
    """
    The Bayesian information criterion.


    Returns:

    """
    val = -2. * log_like + n_parameters * np.log(n_data_points)

    return val


def waic(bayesian_trace):
    raise NotImplementedError("Coming soon to a theater near you.")


def effective_number_of_parameters(bayesian_trace):
    raise NotImplementedError("Coming soon to a theater near you.")


def dic(bayesian_trace):
    """
    The Deviance information criteria derived from MCMC traces
    Read more:  dx.doi.org/10.1111/1467-9868.00353

    Args:
        bayesian_trace: an instance of Bayesian Analysis

    Returns: deviance information criteria

    """

    mean_deviance = -2. * np.mean(bayesian_trace.log_probability_values)

    mean_of_free_parameters = np.mean(bayesian_trace.raw_samples, axis=0)

    deviance_at_mean = -2. * bayesian_trace.log_probability(mean_of_free_parameters)[0]

    return 2 * mean_deviance - deviance_at_mean


class ModelComparison(object):
    def __init__(self, *analyses):
        self._analysis_container = analyses

        # First make sure that it is all bayesian or all MLE
        if (np.unique([a._analysis_type for a in analyses])).shape[0] > 1:
            raise RuntimeError("Only all Bayesian or all MLE analyses are allowed. Not a mixture!")

        self._analysis_type = analyses[0].analysis_type

        if self._analysis_type == 'mle':

            self._stat_df = self._compute_mle_statistics()



        elif self._analysis_type == 'bayesian':

            self._stat_df = self._compute_bayes_statistics()

    def report(self, sort=None, normalized=True, precision=1):

        pd.options.display.float_format = ('{:.%df}' % (precision)).format

        this_df = self._stat_df.copy()

        if self._analysis_type == 'bayesian':

            # Remember to add WAIC in later

            display_order = ['Model',
                             '-2 ln(like)',
                             'AIC',
                             'BIC',
                             'DIC',
                             'log10 (Z)',
                             'N. Free Parameters',
                             #                  'Eff. N. Free Parameters',
                             'dof']

            min_stat = ['-2 ln(like)',<commit_msg>fixed doc string<commit_after># Author: <NAME>

# Provides some universal statistical utilities and stats comparison tools

import numpy as np
import pandas as pd
from threeML.io.rich_display import display
import copy

import warnings


def li_and_ma(total, background, alpha=1.):
    """"Li and Ma (1983) signal to noise significance"""

    a = total / (total + background)
    b = background / (total + background)
    S = np.sqrt(2) * np.sqrt((total * np.log(((1. + alpha) / alpha) * a) + background * np.log((1 + alpha) * b)))

    return S


def aic(log_like, n_parameters, n_data_points):
    """
    The Aikake information criterion.
    A model comparison tool based of infomormation theory. It assumes that N is large i.e.,
    that the model is approaching the CLT.


    """

    val = -2. * log_like + 2 * n_parameters
    val += 2 * n_parameters * (n_parameters + 1) / (n_data_points - n_parameters - 1)

    return val


def bic(log_like, n_parameters, n_data_points):
    """
    The Bayesian information criterion.
    """
    val = -2. * log_like + n_parameters * np.log(n_data_points)

    return val


def waic(bayesian_trace):
    raise NotImplementedError("Coming soon to a theater near you.")


def effective_number_of_parameters(bayesian_trace):
    raise NotImplementedError("Coming soon to a theater near you.")


def dic(bayesian_trace):
    """
    The Deviance information criteria derived from MCMC traces
    Read more:  dx.doi.org/10.1111/1467-9868.00353


    :param bayesian_trace: an instance of Bayesian Analysis

    :return: deviance information criteria

    """

    mean_deviance = -2. * np.mean(bayesian_trace.log_probability_values)

    mean_of_free_parameters = np.mean(bayesian_trace.raw_samples, axis=0)

    deviance_at_mean = -2. * bayesian_trace.log_probability(mean_of_free_parameters)[0]

    return 2 * mean_deviance - deviance_at_mean


class ModelComparison(object):
    def __init__(self, *analyses):
        self._analysis_container = analyses

        # First make sure that it is all bayesian or all MLE
        if (np.unique([a._analysis_type for a in analyses])).shape[0] > 1:
            raise RuntimeError("Only all Bayesian or all MLE analyses are allowed. Not a mixture!")

        self._analysis_type = analyses[0].analysis_type

        if self._analysis_type == 'mle':

            self._stat_df = self._compute_mle_statistics()



        elif self._analysis_type == 'bayesian':

            self._stat_df = self._compute_bayes_statistics()

    def report(self, sort=None, normalized=True, precision=1):
        """
        Create a statistical report for multiple fits
        :param sort: (optional) which statistic to sort (str)
        :param normalized: (optional) normalize the stats to the best fit
        :param precision: (optional) precision of the table
        :return: stats DataFrame
        """

        pd.options.display.float_format = ('{:.%df}' % (precision)).format

        this_df = self._stat_df.copy()

        if self._analysis_type == 'bayesian':

            # Remember to add WAIC in later

            display_order = ['Model',
                             '-2 ln(like)',
                             'AIC',
                             'BIC',
                             'DIC',
                             'log10 (Z)',
                             'N. Free Parameters',
                             #                  'Eff. N. Free Parameters',
                             'dof']

            min_stat = ['-2 ln(like)',
{'fraction_non_alphanumeric': 0.1, 'fraction_numerical': 0.013609467455621301, 'mean_word_length': 2.309348996573666, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5297746', 'n_tokens_mistral': 2104, 'n_tokens_neox': 1917, 'n_words': 571}