<commit_before># Author: <NAME>
# 1999 -- 2002

import types
import warnings

import sigtools
from scipy import special, linalg
from scipy.fftpack import fft, ifft, ifftshift, fft2, ifft2, fftn, ifftn
from numpy import polyadd, polymul, polydiv, polysub, \
     roots, poly, polyval, polyder, cast, asarray, isscalar, atleast_1d, \
     ones, sin, linspace, real, extract, real_if_close, zeros, array, arange, \
     where, sqrt, rank, newaxis, argmax, product, cos, pi, exp, \
     ravel, size, less_equal, sum, r_, iscomplexobj, take, \
     argsort, allclose, expand_dims, unique, prod, sort, reshape, \
     transpose, dot, any, mean, cosh, arccosh, \
     arccos, concatenate, flipud
import numpy as np
from scipy.misc import factorial

_modedict = {'valid':0, 'same':1, 'full':2}

_boundarydict = {'fill':0, 'pad':0, 'wrap':2, 'circular':2, 'symm':1,
                 'symmetric':1, 'reflect':4}

def _valfrommode(mode):
    try:
        val = _modedict[mode]
    except KeyError:
        if mode not in [0,1,2]:
            raise ValueError, "Acceptable mode flags are 'valid' (0)," \
                  "'same' (1), or 'full' (2)."
        val = mode
    return val

def _bvalfromboundary(boundary):
    try:
        val = _boundarydict[boundary] << 2
    except KeyError:
        if val not in [0,1,2] :
            raise ValueError, "Acceptable boundary flags are 'fill', 'wrap'" \
                  " (or 'circular'), \n  and 'symm' (or 'symmetric')."
        val = boundary << 2
    return val


def correlate(in1, in2, mode='full', old_behavior=True):
    """Cross-correlate two N-dimensional arrays.

    Cross-correlate in1 and in2 with the output size determined by the mode
    argument.

    Arguments
    ---------
    in1: array
        first input.
    in2: array
        second input. Should have the same number of dimensions as in1.
    mode: str {'valid', 'same', 'full'}
        a string indicating the size of the output:
            - 'valid': the output consists only of those elements that do not
            rely on the zero-padding.
            - 'same': the output is the same size as the largest input centered
              with respect to the 'full' output.
            - 'full': the output is the full discrete linear cross-correlation
              of the inputs. (Default)
    old_behavior: bool
        If True (default), the old behavior of correlate is implemented:
            - if in1.size < in2.size, in1 and in2 are swapped (correlate(in1,
              in2) == correlate(in2, in1))
            - For complex inputs, the conjugate is not taken for in2
        If False, the new, conventional definition of correlate is implemented.

    Returns
    -------
    out: array
        an N-dimensional array containing a subset of the discrete linear
        cross-correlation of in1 with in2.

    Note
    ----
    The correlation z of two arrays x and y of rank d is defined as

      z[...,k,...] = sum[..., i_l, ...] 
            x[..., i_l,...] * conj(y[..., i_l + k,...])
    """
    val = _valfrommode(mode)

    if old_behavior:
        warnings.warn(DeprecationWarning("""\
old_behavior for correlation is deprecated: it is still the default for 0.8, but it will default to False for 0.9, and will disappear for 0.10"""))
        if np.iscomplexobj(in2):
            in2 = in2.conjugate()
        if in1.size < in2.size:
            swp = in2
            in2 = in1
            in1 = swp

    if mode == 'valid':
        ps = [i - j + 1 for i, j in zip(in1.shape, in2.shape)]
        out = np.empty(ps, in1.dtype)
        for i in range(len(ps)):
            if ps[i] <= 0:
                raise ValueError("Dimension of x(%d) < y(%d) " \
                                 "not compatible with valid mode" % \
                                 (x.shape[i], y.shape[i]))

        z = sigtools._correlateND(in1, in2, out, val)
    else:
        ps = [i + j - 1 for i, j in zip(in1.shape, in2.shape)]
        # zero pad input
        in1zpadded = np.zeros(ps, in1.dtype)
        sc = [slice(0, i) for i in in1.shape]
        in1zpadded[sc] = in1.copy()

        if mode == 'full':
            out = np.empty(ps, in1.dtype)
            z = sigtools._correlateND(in1zpadded, in2, out, val)
        elif mode == 'same':
            out = np.empty(in1.shape, in1.dtype)

            z = sigtools._correlateND(in1zpadded, in2, out, val)
        else:
            raise ValueError("Uknown mode %s" % mode)

    return z

def _centered(arr, newsize):
    # Return the center newsize portion of the array.
    newsize = asarray(newsize)
    currsize = array(arr.shape)
    startind = (currsize - newsize) / 2
    endind = startind + newsize
    myslice = [slice(startind[k], endind[k]) for k in range(len(endind))]
    return arr[tuple(myslice)]

def fftconvolve(in1, in2, mode="full"):
    """Convolve two N-dimensional arrays using FFT. See convolve.

    """
    s1 = array(in1.shape)
    s2 = array(in2.shape)
    complex_result = (np.issubdtype(in1.dtype, np.complex) or
                      np.issubdtype(in2.dtype, np.complex))
    size = s1+s2-1
    IN1 = fftn(in1,size)
    IN1 *= fftn(in2,size)
    ret = ifftn(IN1)
    del IN1
    if not complex_result:
        ret = ret.real
    if mode == "full":
        return ret
    elif mode == "same":
        if product(s1,axis=0) > product(s2,axis=0):
            osize = s1
        else:
            osize = s2
        return _centered(ret,osize)
    elif mode == "valid":
        return _centered(ret,abs(s2-s1)+1)


def convolve(in1, in2, mode='full'):
    """Convolve two N-dimensional arrays.

    Convolve in1 and in2 with output size determined by mode.

    Arguments
    ---------
    in1: array
        first input.
    in2: array
        second input. Should have the same number of dimensions as in1.
    mode: str {'valid', 'same', 'full'}
        a string indicating the size of the output:
            - 'valid': the output consists only of those elements that do not
            rely on the zero-padding.
            - 'same': the output is the same size as the largest input centered
              with respect to the 'full' output.
            - 'full': the output is the full discrete linear cross-correlation
              of the inputs. (Default)

    Returns
    -------
    out: array
        an N-dimensional array containing a subset of the discrete linear
        cross-correlation of in1 with in2.
    """
    volume = asarray(in1)
    kernel = asarray(in2)

    slice_obj = [slice(None,None,-1)]*len(kernel.shape)

    if np.iscomplexobj(kernel):
        return correlate(volume, kernel[slice_obj].conj(), mode, old_behavior=False)
    else:
        return correlate(volume, kernel[slice_obj], mode)

def order_filter(a, domain, rank):
    """Perform an order filter on an N-dimensional array.

  Description:

    Perform an order filter on the array in.  The domain argument acts as a
    mask centered over each pixel.  The non-zero elements of domain are
    used to select elements surrounding each input pixel which are placed
    in a list.   The list is sorted, and the output for that pixel is the
    element corresponding to rank in the sorted list.

  Inputs:

    in -- an N-dimensional input array.
    domain -- a mask array with the same number of dimensions as in.  Each
              dimension should have an odd number of elements.
    rank -- an non-negative integer which selects the element from the
            sorted list (0 corresponds to the largest element, 1 is the
            next largest element, etc.)

  Output: (out,)

    out -- the results of the order filter in an array with the same
           shape as in.

    """
    domain = asarray(domain)
    size = domain.shape
    for k in range(len(size)):
        if (size[k] % 2) != 1:
            raise ValueError, "Each dimension of domain argument " \
                  "should have an odd number of elements."
    return sigtools._order_filterND(a, domain, rank)


def medfilt(volume,kernel_size=None):
    """Perform a median filter on an N-dimensional array.

  Description:

    Apply a median filter to the input array using a local window-size
    given by kernel_size.

  Inputs:

    in -- An N-dimensional input array.
    kernel_size -- A scalar or an N-length list giving the size of the
                   median filter window in each dimension.  Elements of
                   kernel_size should be odd.  If kernel_size is a scalar,
                   then this scalar is used as the size in each dimension.

  Outputs: (out,)

    out -- An array the same size as input containing the median filtered
           result.

    """
    volume = asarray(volume)
    if kernel_size is None:
        kernel_size = [3] * len(volume.shape)
    kernel_size = asarray(kernel_size)
    if len(kernel_size.shape) == 0:
        kernel_size = [kernel_size.item()] * len(volume.shape)
    kernel_size = asarray(kernel_size)

    for k in range(len(volume.shape)):
        if (kernel_size[k] % 2) != 1:
            raise ValueError, "Each element of kernel_size should be odd."

    domain = ones(kernel_size)

    numels = product(kernel_size,axis=0)
    order = int(numels/2)
    return sigtools._order_filterND(volume,domain,order)


def wiener(im,mysize=None,noise=None):
    """Perform a Wiener filter on an N-dimensional array.

  Description:

    Apply a Wiener filter to the N-dimensional array in.

  Inputs:

    in -- an N-dimensional array.
    kernel_size -- A scalar or an N-length list giving the size of the
                   median filter window in each dimension.  Elements of
                   kernel_size should be odd.  If kernel_size is a scalar,
                   then this scalar is used as the size in each dimension.
    noise -- The noise-power to use.  If None, then noise is estimated as
             the average of the local variance of the input.

  Outputs: (out,)

    out -- Wiener filtered result with the same shape as in.

    """
    im = asarray(im)
    if mysize is None:
        mysize = [3] * len(im.shape)
    mysize = asarray(mysize);

    # Estimate the local mean
    lMean = correlate(im,ones(mysize), 'same') / product(mysize,axis=0)

    # Estimate the local variance
    lVar = correlate(im**2,ones(mysize), 'same') / product(mysize,axis=0) - lMean**2

    # Estimate the noise power if needed.
    if noise==None:
        noise = mean(ravel(lVar),axis=0)

    res = (im - lMean)
    res *= (1-noise / lVar)
    res += lMean
    out = where(lVar < noise, lMean, res)

    return out


def convolve2d(in1, in2, mode='full', boundary='fill', fillvalue=0):
    """Convolve two 2-dimensional arrays.

  Description:

     Convolve in1 and in2 with output size determined by mode and boundary
     conditions determined by boundary and fillvalue.

  Inputs:

    in1 -- a 2-dimensional array.
    in2 -- a 2-dimensional array.
    mode -- a flag indicating the size of the output
            'valid'  (0): The output consists only of those elements that<commit_msg>Force new behavior when using correlate in both convolve and Wiener.<commit_after># Author: <NAME>
# 1999 -- 2002

import types
import warnings

import sigtools
from scipy import special, linalg
from scipy.fftpack import fft, ifft, ifftshift, fft2, ifft2, fftn, ifftn
from numpy import polyadd, polymul, polydiv, polysub, \
     roots, poly, polyval, polyder, cast, asarray, isscalar, atleast_1d, \
     ones, sin, linspace, real, extract, real_if_close, zeros, array, arange, \
     where, sqrt, rank, newaxis, argmax, product, cos, pi, exp, \
     ravel, size, less_equal, sum, r_, iscomplexobj, take, \
     argsort, allclose, expand_dims, unique, prod, sort, reshape, \
     transpose, dot, any, mean, cosh, arccosh, \
     arccos, concatenate, flipud
import numpy as np
from scipy.misc import factorial

_modedict = {'valid':0, 'same':1, 'full':2}

_boundarydict = {'fill':0, 'pad':0, 'wrap':2, 'circular':2, 'symm':1,
                 'symmetric':1, 'reflect':4}

def _valfrommode(mode):
    try:
        val = _modedict[mode]
    except KeyError:
        if mode not in [0,1,2]:
            raise ValueError, "Acceptable mode flags are 'valid' (0)," \
                  "'same' (1), or 'full' (2)."
        val = mode
    return val

def _bvalfromboundary(boundary):
    try:
        val = _boundarydict[boundary] << 2
    except KeyError:
        if val not in [0,1,2] :
            raise ValueError, "Acceptable boundary flags are 'fill', 'wrap'" \
                  " (or 'circular'), \n  and 'symm' (or 'symmetric')."
        val = boundary << 2
    return val


def correlate(in1, in2, mode='full', old_behavior=True):
    """Cross-correlate two N-dimensional arrays.

    Cross-correlate in1 and in2 with the output size determined by the mode
    argument.

    Arguments
    ---------
    in1: array
        first input.
    in2: array
        second input. Should have the same number of dimensions as in1.
    mode: str {'valid', 'same', 'full'}
        a string indicating the size of the output:
            - 'valid': the output consists only of those elements that do not
            rely on the zero-padding.
            - 'same': the output is the same size as the largest input centered
              with respect to the 'full' output.
            - 'full': the output is the full discrete linear cross-correlation
              of the inputs. (Default)
    old_behavior: bool
        If True (default), the old behavior of correlate is implemented:
            - if in1.size < in2.size, in1 and in2 are swapped (correlate(in1,
              in2) == correlate(in2, in1))
            - For complex inputs, the conjugate is not taken for in2
        If False, the new, conventional definition of correlate is implemented.

    Returns
    -------
    out: array
        an N-dimensional array containing a subset of the discrete linear
        cross-correlation of in1 with in2.

    Note
    ----
    The correlation z of two arrays x and y of rank d is defined as

      z[...,k,...] = sum[..., i_l, ...] 
            x[..., i_l,...] * conj(y[..., i_l + k,...])
    """
    val = _valfrommode(mode)

    if old_behavior:
        warnings.warn(DeprecationWarning("""\
old_behavior for correlation is deprecated: it is still the default for 0.8, but it will default to False for 0.9, and will disappear for 0.10"""))
        if np.iscomplexobj(in2):
            in2 = in2.conjugate()
        if in1.size < in2.size:
            swp = in2
            in2 = in1
            in1 = swp

    if mode == 'valid':
        ps = [i - j + 1 for i, j in zip(in1.shape, in2.shape)]
        out = np.empty(ps, in1.dtype)
        for i in range(len(ps)):
            if ps[i] <= 0:
                raise ValueError("Dimension of x(%d) < y(%d) " \
                                 "not compatible with valid mode" % \
                                 (x.shape[i], y.shape[i]))

        z = sigtools._correlateND(in1, in2, out, val)
    else:
        ps = [i + j - 1 for i, j in zip(in1.shape, in2.shape)]
        # zero pad input
        in1zpadded = np.zeros(ps, in1.dtype)
        sc = [slice(0, i) for i in in1.shape]
        in1zpadded[sc] = in1.copy()

        if mode == 'full':
            out = np.empty(ps, in1.dtype)
            z = sigtools._correlateND(in1zpadded, in2, out, val)
        elif mode == 'same':
            out = np.empty(in1.shape, in1.dtype)

            z = sigtools._correlateND(in1zpadded, in2, out, val)
        else:
            raise ValueError("Uknown mode %s" % mode)

    return z

def _centered(arr, newsize):
    # Return the center newsize portion of the array.
    newsize = asarray(newsize)
    currsize = array(arr.shape)
    startind = (currsize - newsize) / 2
    endind = startind + newsize
    myslice = [slice(startind[k], endind[k]) for k in range(len(endind))]
    return arr[tuple(myslice)]

def fftconvolve(in1, in2, mode="full"):
    """Convolve two N-dimensional arrays using FFT. See convolve.

    """
    s1 = array(in1.shape)
    s2 = array(in2.shape)
    complex_result = (np.issubdtype(in1.dtype, np.complex) or
                      np.issubdtype(in2.dtype, np.complex))
    size = s1+s2-1
    IN1 = fftn(in1,size)
    IN1 *= fftn(in2,size)
    ret = ifftn(IN1)
    del IN1
    if not complex_result:
        ret = ret.real
    if mode == "full":
        return ret
    elif mode == "same":
        if product(s1,axis=0) > product(s2,axis=0):
            osize = s1
        else:
            osize = s2
        return _centered(ret,osize)
    elif mode == "valid":
        return _centered(ret,abs(s2-s1)+1)


def convolve(in1, in2, mode='full'):
    """Convolve two N-dimensional arrays.

    Convolve in1 and in2 with output size determined by mode.

    Arguments
    ---------
    in1: array
        first input.
    in2: array
        second input. Should have the same number of dimensions as in1.
    mode: str {'valid', 'same', 'full'}
        a string indicating the size of the output:
            - 'valid': the output consists only of those elements that do not
            rely on the zero-padding.
            - 'same': the output is the same size as the largest input centered
              with respect to the 'full' output.
            - 'full': the output is the full discrete linear cross-correlation
              of the inputs. (Default)

    Returns
    -------
    out: array
        an N-dimensional array containing a subset of the discrete linear
        cross-correlation of in1 with in2.
    """
    volume = asarray(in1)
    kernel = asarray(in2)

    slice_obj = [slice(None,None,-1)]*len(kernel.shape)

    if np.iscomplexobj(kernel):
        return correlate(volume, kernel[slice_obj].conj(), mode, old_behavior=False)
    else:
        return correlate(volume, kernel[slice_obj], mode, old_behavior=False)

def order_filter(a, domain, rank):
    """Perform an order filter on an N-dimensional array.

  Description:

    Perform an order filter on the array in.  The domain argument acts as a
    mask centered over each pixel.  The non-zero elements of domain are
    used to select elements surrounding each input pixel which are placed
    in a list.   The list is sorted, and the output for that pixel is the
    element corresponding to rank in the sorted list.

  Inputs:

    in -- an N-dimensional input array.
    domain -- a mask array with the same number of dimensions as in.  Each
              dimension should have an odd number of elements.
    rank -- an non-negative integer which selects the element from the
            sorted list (0 corresponds to the largest element, 1 is the
            next largest element, etc.)

  Output: (out,)

    out -- the results of the order filter in an array with the same
           shape as in.

    """
    domain = asarray(domain)
    size = domain.shape
    for k in range(len(size)):
        if (size[k] % 2) != 1:
            raise ValueError, "Each dimension of domain argument " \
                  "should have an odd number of elements."
    return sigtools._order_filterND(a, domain, rank)


def medfilt(volume,kernel_size=None):
    """Perform a median filter on an N-dimensional array.

  Description:

    Apply a median filter to the input array using a local window-size
    given by kernel_size.

  Inputs:

    in -- An N-dimensional input array.
    kernel_size -- A scalar or an N-length list giving the size of the
                   median filter window in each dimension.  Elements of
                   kernel_size should be odd.  If kernel_size is a scalar,
                   then this scalar is used as the size in each dimension.

  Outputs: (out,)

    out -- An array the same size as input containing the median filtered
           result.

    """
    volume = asarray(volume)
    if kernel_size is None:
        kernel_size = [3] * len(volume.shape)
    kernel_size = asarray(kernel_size)
    if len(kernel_size.shape) == 0:
        kernel_size = [kernel_size.item()] * len(volume.shape)
    kernel_size = asarray(kernel_size)

    for k in range(len(volume.shape)):
        if (kernel_size[k] % 2) != 1:
            raise ValueError, "Each element of kernel_size should be odd."

    domain = ones(kernel_size)

    numels = product(kernel_size,axis=0)
    order = int(numels/2)
    return sigtools._order_filterND(volume,domain,order)


def wiener(im,mysize=None,noise=None):
    """Perform a Wiener filter on an N-dimensional array.

  Description:

    Apply a Wiener filter to the N-dimensional array in.

  Inputs:

    in -- an N-dimensional array.
    kernel_size -- A scalar or an N-length list giving the size of the
                   median filter window in each dimension.  Elements of
                   kernel_size should be odd.  If kernel_size is a scalar,
                   then this scalar is used as the size in each dimension.
    noise -- The noise-power to use.  If None, then noise is estimated as
             the average of the local variance of the input.

  Outputs: (out,)

    out -- Wiener filtered result with the same shape as in.

    """
    im = asarray(im)
    if mysize is None:
        mysize = [3] * len(im.shape)
    mysize = asarray(mysize);

    # Estimate the local mean
    lMean = correlate(im,ones(mysize), 'same', old_behavior=False) / product(mysize,axis=0)

    # Estimate the local variance
    lVar = correlate(im**2,ones(mysize), 'same', old_behavior=False) / product(mysize,axis=0) - lMean**2

    # Estimate the noise power if needed.
    if noise==None:
        noise = mean(ravel(lVar),axis=0)

    res = (im - lMean)
    res *= (1-noise / lVar)
    res += lMean
    out = where(lVar < noise, lMean, res)

    return out


def convolve2d(in1, in2, mode='full', boundary='fill', fillvalue=0):
    """Convolve two 2-dimensional arrays.

  Description:

     Convolve in1 and in2 with output size determined by mode and boundary
     conditions determined by boundary and fillvalue.

  Inputs:

    in1 -- a 2-dimensional array.
    in2 -- a 2-dimensional array.
    mode -- a flag indicating the size of the output
            'valid'  (0): The output consists only of those elements that
{'fraction_non_alphanumeric': 0.10097955130230668, 'fraction_numerical': 0.014174152484990746, 'mean_word_length': 2.2261540701907676, 'pattern_counts': {'":': 6, '<': 23, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2105163', 'n_tokens_mistral': 6916, 'n_tokens_neox': 6630, 'n_words': 2454}