<commit_before>"""
created on May 6, 2015

@author: <NAME>, jajcay(at)cs.cas.cz

last update on Sep 22, 2017
"""

import numpy as np


def get_time_series_condition(ts, tau = 1, reversed = False, dim_of_condition = 1, eta = 0, close_condition = False, phase_diff = False):
    """
    Returns time series for CMI as list in the sense
        I(x; y | z), where x = x(t); y = y(t+tau) | z = [y(t), y(t-eta), y(t-2eta), ...] up to dim_of_condition
    so x -- master time series, y -- slave time series, z -- list of condtions (slave time series in the past)
    tau and eta are forward and backward time lags, respectively.
    If reversed is True, the master (ts[0, :]) and the slave (ts[1, :]) are reversed (for CMI in other direction).
    If close_condition is True, the conditions are returned as
        z = [y(t+tau-1), y(t+tau-1-eta), y(t+tau-1-2eta), ...] up to dim_of_condition,
    so the conditions are closer in temporal sense to the slave time series.
    If phase_diff is True, as y, the phase differences (future - first cond.) will be used (use only with phase data, not raw).
    """

    if isinstance(ts, list) and len(ts) > 1:
        if len(ts) != 2:
            raise Exception("Input must be a list of 1D arrays (or a 2 x length array).")
        if ts[0].shape != ts[1].shape:
            raise Exception("Both time series must be the same length.") 
        master = ts[1].copy() if reversed else ts[0].copy()
        slave = ts[0].copy() if reversed else ts[1].copy()
    elif isinstance(ts, np.ndarray):
        if np.squeeze(ts).ndim != 2:
            raise Exception("Input must be 2 x length array (or a list of 1D arrays).")
        master = ts[1, :].copy() if reversed else ts[0, :].copy()
        slave = ts[0, :].copy() if reversed else ts[1, :].copy()
    else:
        raise Exception("Input not understood. Use either list of 1D arrays or 2 x length array.")

    if dim_of_condition > 4:
        print("** WARNING -- for %d dimensional condition the estimation might be biased." % (dim_of_condition))
    if (dim_of_condition > 1 and eta == 0):
        raise Exception("For multidimensional condition the backward lag eta must be chosen.")

    n_eta = dim_of_condition - 1
    n = master.shape[0] - tau - n_eta*eta
    if eta is None:
        eta = 0
    else:
        eta = int(eta)

    x = master[n_eta*eta : -tau] # "now"
    if x.shape[0] != n:
        raise Exception("Something went wrong! Check input data.")

    y = slave[n_eta*eta+tau :] # "tau future"
    if y.shape[0] != n:
        raise Exception("Something went wrong! Check input data.")

    z = []
    for i in range(dim_of_condition):
        if close_condition:
            cond = slave[(n_eta-i)*eta+tau-1 : -1-i*eta] # "almost future" until ...
        else:    
            cond = slave[(n_eta-i)*eta : -tau-i*eta] # "now" until "n_eta eta past"
        if cond.shape[0] != n:
            raise Exception("Something went wrong! Check input data.")
        z.append(cond)

    if phase_diff:
        y = y - z[0]
        y[y < -np.pi] += 2*np.pi

    return (x, y, z)



def mutual_information(x, y, algorithm = 'EQQ', bins = 8, log2 = True):
    """<commit_msg>added extra conditions to mutual inf<commit_after>"""
created on May 6, 2015

@author: <NAME>, jajcay(at)cs.cas.cz

last update on Sep 22, 2017
"""

import numpy as np


def get_time_series_condition(ts, tau=1, reversed=False, dim_of_condition=1, eta=0, 
        close_condition=False, phase_diff=False, add_cond = None):
    """
    Returns time series for CMI as list in the sense
        I(x; y | z), where x = x(t); y = y(t+tau) | z = [y(t), y(t-eta), y(t-2eta), ...] up to dim_of_condition
    so x -- master time series, y -- slave time series, z -- list of condtions (slave time series in the past)
    tau and eta are forward and backward time lags, respectively.
    If reversed is True, the master (ts[0, :]) and the slave (ts[1, :]) are reversed (for CMI in other direction).
    If close_condition is True, the conditions are returned as
        z = [y(t+tau-1), y(t+tau-1-eta), y(t+tau-1-2eta), ...] up to dim_of_condition,
    so the conditions are closer in temporal sense to the slave time series.
    If phase_diff is True, as y, the phase differences (future - first cond.) will be used (use only with phase data, not raw).
    add_cond if None, is time series of shape [x, len] where x is number of additional time series to be put into the
        condition as of 'now', thus without any backward lag. These additional conditions are NOT counted in the dimension
        of condition parameter.
    """

    if isinstance(ts, list) and len(ts) > 1:
        if len(ts) != 2:
            raise Exception("Input must be a list of 1D arrays (or a 2 x length array).")
        if ts[0].shape != ts[1].shape:
            raise Exception("Both time series must be the same length.") 
        master = ts[1].copy() if reversed else ts[0].copy()
        slave = ts[0].copy() if reversed else ts[1].copy()
    elif isinstance(ts, np.ndarray):
        if np.squeeze(ts).ndim != 2:
            raise Exception("Input must be 2 x length array (or a list of 1D arrays).")
        master = ts[1, :].copy() if reversed else ts[0, :].copy()
        slave = ts[0, :].copy() if reversed else ts[1, :].copy()
    else:
        raise Exception("Input not understood. Use either list of 1D arrays or 2 x length array.")

    if add_cond is not None:
        add_cond = np.atleast_2d(add_cond)
        assert add_cond.shape[1] == master.shape[0]

    if dim_of_condition > 4:
        print("** WARNING -- for %d dimensional condition the estimation might be biased." % (dim_of_condition))
    if (dim_of_condition > 1 and eta == 0):
        raise Exception("For multidimensional condition the backward lag eta must be chosen.")

    n_eta = dim_of_condition - 1
    n = master.shape[0] - tau - n_eta*eta
    if eta is None:
        eta = 0
    else:
        eta = int(eta)

    x = master[n_eta*eta : -tau] # "now"
    if x.shape[0] != n:
        raise Exception("Something went wrong! Check input data.")

    y = slave[n_eta*eta+tau :] # "tau future"
    if y.shape[0] != n:
        raise Exception("Something went wrong! Check input data.")

    z = []
    for i in range(dim_of_condition):
        if close_condition:
            cond = slave[(n_eta-i)*eta+tau-1 : -1-i*eta] # "almost future" until ...
        else:    
            cond = slave[(n_eta-i)*eta : -tau-i*eta] # "now" until "n_eta eta past"
        if cond.shape[0] != n:
            raise Exception("Something went wrong! Check input data.")
        z.append(cond)

    if add_cond is not None:
        for condextra in range(add_cond.shape[0]):
            extra_cond = add_cond[condextra, n_eta*eta : -tau] # "now"
            if extra_cond.shape[0] != n:
                raise Exception("Something went wrong! Check input data.")
            z.append(extra_cond) 

    if phase_diff:
        y = y - z[0]
        y[y < -np.pi] += 2*np.pi

    return (x, y, z)



def mutual_information(x, y, algorithm='EQQ', bins=8, log2=True):
    """
{'fraction_non_alphanumeric': 0.1268540754343834, 'fraction_numerical': 0.01624523237745444, 'mean_word_length': 2.515392254220457, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 11, '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': '5286174', 'n_tokens_mistral': 2377, 'n_tokens_neox': 2255, 'n_words': 849}