def quantile(a, q, axis=None):
    '''Quantile (or inverse cumulative distribution) function based on input

    a -- data
    q -- probability value(s)
    axis -- can be None'''
    from pycore import toList
    from math import floor
    q = toList(q)
    sa = _np.sort(a, axis=axis)
    if axis is None:
        size = sa.size
    else:
        size = sa.shape[axis]

    x = [ (size - 1)*p for p in q ]
    n = [ int(floor(f)) for f in x ]
    x = [ f - i for f, i in zip(x,n) ]
    if axis is None:
        return [ sa[i]*(1-f) + sa[i+1]*f for f, i in zip(x,n) ]
    else:
        slices = [ slice(d) for d in sa.shape ]
        result = []
        for f, i in zip(x, n):
            slices[axis] = i
            r = sa[slices]*(1-f)
            slices[axis] = i+1
            r += sa[slices]*f
            result.append(r)
        return result
def quantile(a, q, axis=None):
    '''Quantile (or inverse cumulative distribution) function based on input

    a -- data
    q -- probability value(s)
    axis -- can be None'''
    from pycore import toList
    from math import floor
    q = toList(q)
    sa = _np.sort(a, axis=axis)
    if axis is None:
        size = sa.size
    else:
        size = sa.shape[axis]

    x = [(size - 1) * p for p in q]
    n = [int(floor(f)) for f in x]
    x = [f - i for f, i in zip(x, n)]
    if axis is None:
        return [sa[i] * (1 - f) + sa[i + 1] * f for f, i in zip(x, n)]
    else:
        slices = [slice(d) for d in sa.shape]
        result = []
        for f, i in zip(x, n):
            slices[axis] = i
            r = sa[slices] * (1 - f)
            slices[axis] = i + 1
            r += sa[slices] * f
            result.append(r)
        return result
def centroid(weights, coords=None):
    '''Calculate the centroid of an array with its (half) indexes or
    coordinates (list of 1D arrays), if given, and returns it as a list
    '''
    if coords is None:
        coords = [ _np.arange(d, dtype=_np.float) + 0.5 for d in weights.shape ]
    else:
        from pycore import toList
        coords = toList(coords)

    rank = weights.ndim
    if rank > len(coords):
        raise ValueError, "Number of coordinate arrays must match rank"

    total = weights.sum()
    cshape = [1,]*rank
    result = []
    for i in range(rank):
        cdata = coords[i]
        if cdata.ndim != 1:
            raise ValueError, "All coordinate arrays must be 1D"

        cshape[i] = cdata.shape[0]
        result.append(_np.multiply(weights, cdata.reshape(cshape)).sum()/total)
        cshape[i] = 1

    return result
def centroid(weights, coords=None):
    '''Calculate the centroid of an array with its (half) indexes or
    coordinates (list of 1D arrays), if given, and returns it as a list
    '''
    if coords is None:
        coords = [_np.arange(d, dtype=_np.float) + 0.5 for d in weights.shape]
    else:
        from pycore import toList
        coords = toList(coords)

    rank = weights.ndim
    if rank > len(coords):
        raise ValueError, "Number of coordinate arrays must match rank"

    total = weights.sum()
    cshape = [
        1,
    ] * rank
    result = []
    for i in range(rank):
        cdata = coords[i]
        if cdata.ndim != 1:
            raise ValueError, "All coordinate arrays must be 1D"

        cshape[i] = cdata.shape[0]
        result.append(
            _np.multiply(weights, cdata.reshape(cshape)).sum() / total)
        cshape[i] = 1

    return result