# Path: jr/utils.py
# def product_matrix_vector(X, v, axis=0):
#     """
#     Computes product between a matrix and a vector
#     Input:
#     ------
#     X : np.array, shape[axis] = n
#         The matrix
#     v : np.array, shape (n)
#         The vector
#     axis : int
#         The axis.
#     Returns
#     -------
#     Y : np.array, shape == X.shape
#     """
#     # ensure numpy array
#     X = np.array(X)
#     v = np.squeeze(v)
#     # ensure axis = 0
#     if axis != 0:
#         X = np.transpose(X, [[axis] + range(axis) + range(axis + 1, X.ndim)])
#     if X.shape[0] != v.shape[0]:
#         raise ValueError('X and v shapes must be identical on the chosen axis')
#     # from nD to 2D
#     dims = X.shape
#     if X.ndim != 2:
#         X = np.reshape(X, [X.shape[0], -1])
#     # product
#     # rows, columns = X.shape
#     # Y = np.zeros((rows, columns))
#     # for jj, m in enumerate(X.T):
#     #     Y[:, jj] = m * v
#     Y = X * v[:, np.newaxis]
#     # from 2D to nD
#     if X.ndim != 2:
#         Y = np.reshape(Y, dims)
#     # transpose axes back to original
#     if axis != 0:
#         Y = Y.transpose([range(1, axis) + [axis] + range(axis + 1, X.ndim)])
#     return Y


import numpy as np
    import numpy as np
    import numpy as np
    import numpy as np
from ..utils import product_matrix_vector
    from mne.parallel import parallel_func
    from scipy.stats import wilcoxon
    from scipy.stats import chi2
    from scipy.stats import chi2
    from jr.utils import pairwise
    from scipy.stats import rankdata
    from mne.parallel import parallel_func
    from scipy.stats import norm
    from math import exp, sqrt
    from scipy.stats import rankdata, tiecorrect
    from scipy.stats import distributions
    from numpy import asarray
    from jr.utils import pairwise
    from jr.stats import fast_mannwhitneyu
    from scipy import signal
    from numpy.lib.stride_tricks import as_strided
        from sklearn.metrics import roc_auc_score
    from sklearn.model_selection import cross_val_score, KFold
    from sklearn.linear_model import LogisticRegression, RidgeClassifier
    from sklearn.svm import LinearSVC
    from sklearn.preprocessing import LabelBinarizer
    alpha2 : np.array, shape (n), or shape == ALPHA1.shape
        Vector or matrix
    axis : int
        The axis used to estimate correlation
    Returns
    -------
    Y : np.array, shape == X.shape

    Adapted from pycircstat by Jean-Remi King :
    1. Less memory consuming than original
    2. supports ALPHA1 as matrix and alpha2 as vector
    https://github.com/circstat/pycircstat
    References: [Jammalamadaka2001]_
    """

    # center data on circular mean
    def sin_center(alpha):
        m = np.arctan2(np.mean(np.sin(alpha), axis=axis),
                       np.mean(np.cos(alpha), axis=axis))
        return np.sin((alpha - m) % (2 * np.pi))

    sin_alpha1 = sin_center(ALPHA1)
    sin_alpha2 = sin_center(alpha2)

    # compute correlation coeffcient from p. 176
    if sin_alpha1.ndim == sin_alpha2.ndim:
        num = np.sum(sin_alpha1 * sin_alpha2, axis=axis)
        den = np.sqrt(np.sum(sin_alpha1 ** 2, axis=axis) *
                      np.sum(sin_alpha2 ** 2, axis=axis))
    else:

# Path: jr/utils.py
# def product_matrix_vector(X, v, axis=0):
#     """
#     Computes product between a matrix and a vector
#     Input:
#     ------
#     X : np.array, shape[axis] = n
#         The matrix
#     v : np.array, shape (n)
#         The vector
#     axis : int
#         The axis.
#     Returns
#     -------
#     Y : np.array, shape == X.shape
#     """
#     # ensure numpy array
#     X = np.array(X)
#     v = np.squeeze(v)
#     # ensure axis = 0
#     if axis != 0:
#         X = np.transpose(X, [[axis] + range(axis) + range(axis + 1, X.ndim)])
#     if X.shape[0] != v.shape[0]:
#         raise ValueError('X and v shapes must be identical on the chosen axis')
#     # from nD to 2D
#     dims = X.shape
#     if X.ndim != 2:
#         X = np.reshape(X, [X.shape[0], -1])
#     # product
#     # rows, columns = X.shape
#     # Y = np.zeros((rows, columns))
#     # for jj, m in enumerate(X.T):
#     #     Y[:, jj] = m * v
#     Y = X * v[:, np.newaxis]
#     # from 2D to nD
#     if X.ndim != 2:
#         Y = np.reshape(Y, dims)
#     # transpose axes back to original
#     if axis != 0:
#         Y = Y.transpose([range(1, axis) + [axis] + range(axis + 1, X.ndim)])
#     return Y


# Path: jr/stats/base.py
import numpy as np
    import numpy as np
    import numpy as np
    import numpy as np
from ..utils import product_matrix_vector
    from mne.parallel import parallel_func
    from scipy.stats import wilcoxon
    from scipy.stats import chi2
    from scipy.stats import chi2
    from jr.utils import pairwise
    from scipy.stats import rankdata
    from mne.parallel import parallel_func
    from scipy.stats import norm
    from math import exp, sqrt
    from scipy.stats import rankdata, tiecorrect
    from scipy.stats import distributions
    from numpy import asarray
    from jr.utils import pairwise
    from jr.stats import fast_mannwhitneyu
    from scipy import signal
    from numpy.lib.stride_tricks import as_strided
        from sklearn.metrics import roc_auc_score
    from sklearn.model_selection import cross_val_score, KFold
    from sklearn.linear_model import LogisticRegression, RidgeClassifier
    from sklearn.svm import LinearSVC
    from sklearn.preprocessing import LabelBinarizer

    alpha2 : np.array, shape (n), or shape == ALPHA1.shape
        Vector or matrix
    axis : int
        The axis used to estimate correlation
    Returns
    -------
    Y : np.array, shape == X.shape

    Adapted from pycircstat by Jean-Remi King :
    1. Less memory consuming than original
    2. supports ALPHA1 as matrix and alpha2 as vector
    https://github.com/circstat/pycircstat
    References: [Jammalamadaka2001]_
    """

    # center data on circular mean
    def sin_center(alpha):
        m = np.arctan2(np.mean(np.sin(alpha), axis=axis),
                       np.mean(np.cos(alpha), axis=axis))
        return np.sin((alpha - m) % (2 * np.pi))

    sin_alpha1 = sin_center(ALPHA1)
    sin_alpha2 = sin_center(alpha2)

    # compute correlation coeffcient from p. 176
    if sin_alpha1.ndim == sin_alpha2.ndim:
        num = np.sum(sin_alpha1 * sin_alpha2, axis=axis)
        den = np.sqrt(np.sum(sin_alpha1 ** 2, axis=axis) *
                      np.sum(sin_alpha2 ** 2, axis=axis))
    else:

        num = np.sum(product_matrix_vector(sin_alpha1, sin_alpha2, axis=axis))