# Path: jr/utils.py
# def tile_memory_free(y, shape):
#     """
#     XXX Will be deprecated
#     Tile vector along multiple dimension without allocating new memory.
# 
#     Parameters
#     ----------
#      y : np.array, shape (n,)
#         data
#     shape : np.array, shape (m),
#     Returns
#     -------
#     Y : np.array, shape (n, *shape)
#     """
#     import warnings
#     warnings.warn('Will be deprecated. Use np.newaxis instead')
#     for dim in range(len(shape)):
#         y = y[..., np.newaxis]
#     return y
# 
# def nandigitize(x, bins, right=None):
#     x = np.array(x)
#     dims = x.shape
#     x = np.reshape(x, [1, -1])
#     sel = ~ np.isnan(x)
#     x_ = x[sel]
#     x[sel] = np.digitize(x_, bins, right=right)
#     x[~sel] = np.nan
#     return x.reshape(dims)


import numpy as np
from ..utils import tile_memory_free, nandigitize
from nose.tools import assert_almost_equal
def circ_mean(alpha, axis=None):
    alpha = np.arctan2(np.nanmean(np.sin(alpha), axis=axis),
                       np.nanmean(np.cos(alpha), axis=axis))
    return alpha % (2 * np.pi)


def circ_cummean(alpha, axis=None):
    alpha = np.arctan2(np.cummean(np.sin(alpha), axis=axis),
                       np.cummean(np.cos(alpha), axis=axis))
    return alpha % (2 * np.pi)


def circ_std(alpha, axis=None):
    return np.sqrt(np.nanmean(np.sin(alpha), axis=axis) ** 2 +
                   np.nanmean(np.cos(alpha), axis=axis) ** 2)


def circ_digitize(x, bins=None, n_bins=None):
    if n_bins is None:
        n_bins = len(np.unique(x)) / 10
    if bins is None:
        bins = np.hstack((
            -np.pi, np.linspace(-np.pi + 2 * np.pi / n_bins / 2.,
                                np.pi - 2 * np.pi / n_bins / 2., n_bins),
            np.pi))
    # TODO: put in test
    # check that first and last bin wrap up
    assert_almost_equal(np.diff(bins)[0], np.diff(bins)[-1])
    # check that first and last bin are half size as the other ones
    assert_almost_equal(np.diff(bins)[0] * 2, np.diff(bins)[1])

# Path: jr/utils.py
# def tile_memory_free(y, shape):
#     """
#     XXX Will be deprecated
#     Tile vector along multiple dimension without allocating new memory.
# 
#     Parameters
#     ----------
#      y : np.array, shape (n,)
#         data
#     shape : np.array, shape (m),
#     Returns
#     -------
#     Y : np.array, shape (n, *shape)
#     """
#     import warnings
#     warnings.warn('Will be deprecated. Use np.newaxis instead')
#     for dim in range(len(shape)):
#         y = y[..., np.newaxis]
#     return y
# 
# def nandigitize(x, bins, right=None):
#     x = np.array(x)
#     dims = x.shape
#     x = np.reshape(x, [1, -1])
#     sel = ~ np.isnan(x)
#     x_ = x[sel]
#     x[sel] = np.digitize(x_, bins, right=right)
#     x[~sel] = np.nan
#     return x.reshape(dims)


# Path: jr/stats/circ.py
import numpy as np
from ..utils import tile_memory_free, nandigitize
from nose.tools import assert_almost_equal

def circ_mean(alpha, axis=None):
    alpha = np.arctan2(np.nanmean(np.sin(alpha), axis=axis),
                       np.nanmean(np.cos(alpha), axis=axis))
    return alpha % (2 * np.pi)


def circ_cummean(alpha, axis=None):
    alpha = np.arctan2(np.cummean(np.sin(alpha), axis=axis),
                       np.cummean(np.cos(alpha), axis=axis))
    return alpha % (2 * np.pi)


def circ_std(alpha, axis=None):
    return np.sqrt(np.nanmean(np.sin(alpha), axis=axis) ** 2 +
                   np.nanmean(np.cos(alpha), axis=axis) ** 2)


def circ_digitize(x, bins=None, n_bins=None):
    if n_bins is None:
        n_bins = len(np.unique(x)) / 10
    if bins is None:
        bins = np.hstack((
            -np.pi, np.linspace(-np.pi + 2 * np.pi / n_bins / 2.,
                                np.pi - 2 * np.pi / n_bins / 2., n_bins),
            np.pi))
    # TODO: put in test
    # check that first and last bin wrap up
    assert_almost_equal(np.diff(bins)[0], np.diff(bins)[-1])
    # check that first and last bin are half size as the other ones
    assert_almost_equal(np.diff(bins)[0] * 2, np.diff(bins)[1])

    x_bin = nandigitize(x, bins, right=True) - 1  # XXX -1!