Example #1
0
def gccmi_nd_ccc(x,
                 y,
                 z,
                 mvaxis=None,
                 traxis=-1,
                 shape_checking=True,
                 gcrn=True):
    """GCCMI between two continuous variables conditioned on a third.

    Parameters
    ----------
    x, y, z : array_like
        Continuous variables. z is the continuous variable that is considered
        as the condition
    mvaxis : int | None
        Spatial location of the axis to consider if multi-variate analysis
        is needed
    traxis : int | -1
        Spatial location of the trial axis. By default the last axis is
        considered
    shape_checking : bool | True
        Perform a reshape and check that x and y shapes are consistents. For
        high performances and to avoid extensive memory usage, it's better to
        already have x and y with a shape of (..., mvaxis, traxis) and to set
        this parameter to False
    gcrn : bool | True
        Apply a Gaussian Copula rank normalization. This operation is
        relatively slow for big arrays.

    Returns
    -------
    mi : array_like
        The mutual information with the same shape as x and y, without the
        mvaxis and traxis
    """
    # Multi-dimentional shape checking
    if shape_checking:
        x = nd_reshape(x, mvaxis=mvaxis, traxis=traxis)
        y = nd_reshape(y, mvaxis=mvaxis, traxis=traxis)
        z = nd_reshape(z, mvaxis=mvaxis, traxis=traxis)
        nd_shape_checking(x, y, mvaxis, traxis)
        nd_shape_checking(x, z, mvaxis, traxis)

    # x.shape == y.shape == z.shape (..., x_mvaxis, traxis)
    if gcrn:
        cx, cy = copnorm_nd(x, axis=-1), copnorm_nd(y, axis=-1)
        cz = copnorm_nd(z, axis=-1)
    else:
        cx, cy, cz = x, y, z
    return cmi_nd_ggg(cx,
                      cy,
                      cz,
                      mvaxis=-2,
                      traxis=-1,
                      biascorrect=True,
                      demeaned=True,
                      shape_checking=False)
Example #2
0
def _cond_gccovgc(data, s, t, ind_tx, t0, conditional=True):
    """Compute the Gaussian-Copula based covGC for a single pair.

    This function computes the covGC for a single pair, across multiple trials,
    at different time indices.
    """
    conditional = conditional if data.shape[1] > 2 else False
    kw = CONFIG["KW_GCMI"]
    d_s, d_t = data[:, s, :], data[:, t, :]
    n_lags, n_dt = ind_tx.shape
    n_trials, n_times = d_s.shape[0], len(t0)
    gc = np.empty((n_trials, n_times, 3), dtype=d_s.dtype, order='C')
    # define z past
    roi_range = np.array([k for k in range(data.shape[1]) if k not in [s, t]])
    z_roi = data[:, roi_range, :]  # other roi selection
    rsh = int(len(roi_range) * (n_lags - 1))
    for n_ti, ti in enumerate(t0):
        # force starting indices at t0 + force row-major slicing
        ind_t0 = np.ascontiguousarray(ind_tx + ti)
        x = d_s[:, ind_t0]
        y = d_t[:, ind_t0]
        # temporal selection
        x_pres, x_past = x[:, [0], :], x[:, 1:, :]
        y_pres, y_past = y[:, [0], :], y[:, 1:, :]
        xy_past = np.concatenate((x[:, 1:, :], y[:, 1:, :]), axis=1)
        # conditional granger causality case
        if conditional:
            # condition by the past of every other possible sources
            z_past = z_roi[..., ind_t0[1:, :]]  # (lag_past, dt) selection
            z_past = z_past.reshape(n_trials, rsh, n_dt)
            # cat with past
            yz_past = np.concatenate((y_past, z_past), axis=1)
            xz_past = np.concatenate((x_past, z_past), axis=1)
            xyz_past = np.concatenate((xy_past, z_past), axis=1)
        else:
            yz_past, xz_past, xyz_past = y_past, x_past, xy_past
        # copnorm over the last axis (avoid copnorming several times)
        x_pres = copnorm_nd(x_pres, axis=-1)
        x_past = copnorm_nd(x_past, axis=-1)
        y_pres = copnorm_nd(y_pres, axis=-1)
        y_past = copnorm_nd(y_past, axis=-1)
        yz_past = copnorm_nd(yz_past, axis=-1)
        xz_past = copnorm_nd(xz_past, axis=-1)
        xyz_past = copnorm_nd(xyz_past, axis=-1)

        # -----------------------------------------------------------------
        # Granger Causality measures
        # -----------------------------------------------------------------
        # gc(pairs(:,1) -> pairs(:,2))
        gc[:, n_ti, 0] = cmi_nd_ggg(y_pres, x_past, yz_past, **kw)
        # gc(pairs(:,2) -> pairs(:,1))
        gc[:, n_ti, 1] = cmi_nd_ggg(x_pres, y_past, xz_past, **kw)
        # gc(pairs(:,2) . pairs(:,1))
        gc[:, n_ti, 2] = cmi_nd_ggg(x_pres, y_pres, xyz_past, **kw)

    return gc
Example #3
0
def gcmi_model_nd_cd(x,
                     y,
                     mvaxis=None,
                     traxis=-1,
                     shape_checking=True,
                     gcrn=True):
    """GCMI between a continuous and discret variables.

    The only difference with `mi_gg` is that a normalization is performed for
    each continuous variable.

    Parameters
    ----------
    x : array_like
        Continuous variable
    y : array_like
        Discret variable of shape (n_trials,)
    mvaxis : int | None
        Spatial location of the axis to consider if multi-variate analysis
        is needed
    traxis : int | -1
        Spatial location of the trial axis. By default the last axis is
        considered
    shape_checking : bool | True
        Perform a reshape and check that x is consistents. For high
        performances and to avoid extensive memory usage, it's better to
        already have x with a shape of (..., mvaxis, traxis) and to set this
        parameter to False
    gcrn : bool | True
        Apply a Gaussian Copula rank normalization. This operation is
        relatively slow for big arrays.

    Returns
    -------
    mi : array_like
        The mutual information with the same shape as x, without the mvaxis and
        traxis
    """
    # Multi-dimentional shape checking
    if shape_checking:
        x = nd_reshape(x, mvaxis=mvaxis, traxis=traxis)

    # x.shape (..., x_mvaxis, traxis)
    # y.shape (traxis)
    cx = copnorm_nd(x, axis=-1) if gcrn else x
    return mi_model_nd_gd(cx,
                          y,
                          mvaxis=-2,
                          traxis=-1,
                          biascorrect=True,
                          demeaned=True,
                          shape_checking=False)
Example #4
0
def _gccovgc(d_s, d_t, ind_tx, t0):
    """Compute the Gaussian-Copula based covGC for a single pair.

    This function computes the covGC for a single pair, across multiple trials,
    at different time indices.
    """
    kw = CONFIG["KW_GCMI"]
    n_trials, n_times = d_s.shape[0], len(t0)
    gc = np.empty((n_trials, n_times, 3), dtype=d_s.dtype, order='C')
    for n_ti, ti in enumerate(t0):
        # force starting indices at t0 + force row-major slicing
        ind_t0 = np.ascontiguousarray(ind_tx + ti)
        x = d_s[:, ind_t0]
        y = d_t[:, ind_t0]
        # temporal selection
        x_pres, x_past = x[:, [0], :], x[:, 1:, :]
        y_pres, y_past = y[:, [0], :], y[:, 1:, :]
        xy_past = np.concatenate((x[:, 1:, :], y[:, 1:, :]), axis=1)
        # copnorm over the last axis (avoid copnorming several times)
        x_pres = copnorm_nd(x_pres, axis=-1)
        x_past = copnorm_nd(x_past, axis=-1)
        y_pres = copnorm_nd(y_pres, axis=-1)
        y_past = copnorm_nd(y_past, axis=-1)
        xy_past = copnorm_nd(xy_past, axis=-1)

        # -----------------------------------------------------------------
        # Granger Causality measures
        # -----------------------------------------------------------------
        # gc(pairs(:,1) -> pairs(:,2))
        gc[:, n_ti, 0] = cmi_nd_ggg(y_pres, x_past, y_past, **kw)
        # gc(pairs(:,2) -> pairs(:,1))
        gc[:, n_ti, 1] = cmi_nd_ggg(x_pres, y_past, x_past, **kw)
        # gc(pairs(:,2) . pairs(:,1))
        gc[:, n_ti, 2] = cmi_nd_ggg(x_pres, y_pres, xy_past, **kw)

    return gc
Example #5
0
def gccmi_model_nd_cdnd(x,
                        y,
                        *z,
                        mvaxis=None,
                        traxis=-1,
                        gcrn=True,
                        shape_checking=True):
    """Conditional GCMI between a continuous and a discret variable.

    This function performs a GC-CMI between a continuous and a discret
    variable conditioned with multiple discrete variables.

    Parameters
    ----------
    x : array_like
        Continuous variable
    y : array_like
        Discret variable
    z : list | array_like
        Array that describes the conditions across the trial axis. Should be a
        list of arrays of shape (n_trials,) of integers
        (e.g. [0, 0, ..., 1, 1, 2, 2])
    mvaxis : int | None
        Spatial location of the axis to consider if multi-variate analysis
        is needed
    traxis : int | -1
        Spatial location of the trial axis. By default the last axis is
        considered
    gcrn : bool | True
        Apply a Gaussian Copula rank normalization. This operation is
        relatively slow for big arrays.
    shape_checking : bool | True
        Perform a reshape and check that x and y shapes are consistents. For
        high performances and to avoid extensive memory usage, it's better to
        already have x and y with a shape of (..., mvaxis, traxis) and to set
        this parameter to False

    Returns
    -------
    cmi : array_like
        Conditional mutual-information with the same shape as x and y without
        the mvaxis and traxis
    """
    # Multi-dimentional shape checking
    if shape_checking:
        x = nd_reshape(x, mvaxis=mvaxis, traxis=traxis)
    assert isinstance(y, np.ndarray) and (y.ndim == 1)
    assert x.shape[-1] == len(y)
    ntrl = x.shape[-1]

    # Find unique values of each discret array
    prod_idx = discret_to_index(*z)
    # sh = x.shape[:-3] if isinstance(mvaxis, int) else x.shape[:-2]
    sh = x.shape[:-2]
    zm_shape = list(sh) + [len(prod_idx)]

    # calculate gcmi for each z value
    pz = np.zeros((len(prod_idx), ), dtype=float)
    icond = np.zeros(zm_shape, dtype=float)
    for num, idx in enumerate(prod_idx):
        pz[num] = idx.sum()
        if gcrn:
            thsx = copnorm_nd(x[..., idx], axis=-1)
        else:
            thsx = x[..., idx]
        thsy = y[idx]
        icond[..., num] = mi_model_nd_gd(thsx,
                                         thsy,
                                         mvaxis=-2,
                                         traxis=-1,
                                         biascorrect=True,
                                         demeaned=True,
                                         shape_checking=False)
    pz /= ntrl

    # conditional mutual information
    cmi = np.sum(pz * icond, axis=-1)
    return cmi