<commit_before>#!python
#cython: boundscheck=False
#cython: wraparound=False
#cython: cdivision=True


import numpy as np
cimport cython
cimport numpy as cnp
from fused_types cimport floating, number

cdef extern from "math.h":
    double floor(double x) nogil
    int isinf(double) nogil

cdef inline int ifloor(double x) nogil:
    return int(floor(x))


def quantize_positive_2d(floating[:, :] v, int num_levels):
    r"""Quantizes a 2D image to the requested number or quantization levels

    Quantizes the input image at the given number of intensity levels, 
    considering 0 as a special value: at the end, only those voxels with zero
    intensity have label zero

    Parameters
    ----------
    v : array, shape (R, C)
        the image to be quantized
    num_levels : int
        the number of levels
    """
    ftype = np.asarray(v).dtype
    cdef:
        cnp.npy_intp nrows = v.shape[0]
        cnp.npy_intp ncols = v.shape[1]
        cnp.npy_intp npix = nrows * ncols
        cnp.npy_intp i, j, l
        double epsilon, delta
        double min_val = -1
        double max_val = -1
        int[:] hist = np.zeros(shape=(num_levels,), dtype=np.int32)
        int[:, :] out = np.zeros(shape=(nrows, ncols,), dtype=np.int32)
        floating[:] levels = np.zeros(shape=(num_levels,), dtype=ftype)

    #Quantizing at zero levels is undefined
    #Quantizing at one level is not supported because we want to make sure the
    #maximum level in the quantization is never greater than num_levels-1
    if(num_levels < 2):
        return None, None, None

    num_levels -= 1  # zero is one of the levels

    with nogil:

        for i in range(nrows):
            for j in range(ncols):
                if(v[i, j] > 0):
                    if((min_val < 0) or (v[i, j] < min_val)):
                        min_val = v[i, j]
                    if(v[i, j] > max_val):
                        max_val = v[i, j]
        epsilon = 1e-8
        delta = (max_val - min_val + epsilon) / num_levels
        # notice that we decreased num_levels, so levels[0..num_levels] are well
        # defined
        if((num_levels < 2) or (delta < epsilon)):
            for i in range(nrows):
                for j in range(ncols):
                    if(v[i, j] > 0):
                        out[i, j] = 1
                    else:
                        out[i, j] = 0
                        hist[0] += 1
            levels[0] = 0
            levels[1] = 0.5 * (min_val + max_val)
            hist[1] = npix - hist[0]
            with gil:
                return out, levels, hist

        levels[0] = 0
        levels[1] = min_val + delta * 0.5
        for i in range(2, 1 + num_levels):
            levels[i] = levels[i - 1] + delta
        for i in range(nrows):
            for j in range(ncols):
                if(v[i, j] > 0):
                    l = ifloor((v[i, j] - min_val) / delta)
                    out[i, j] = l + 1
                    hist[l + 1] += 1
                else:
                    out[i, j] = 0
                    hist[0] += 1

    return out, levels, hist


def quantize_positive_3d(floating[:, :, :] v, int num_levels):
    r"""Quantizes a 3D volume to the requested number or quantization levels

    Quantizes the input volume at the given number of intensity levels,
    considering 0 as a special value: at the end, only those voxels with zero
    intensity have label zero

    Parameters
    ----------
    v : array, shape (S, R, C)
        the volume to be quantized
    num_levels : int
        the number of levels
    """
    ftype = np.asarray(v).dtype
    cdef:
        cnp.npy_intp nslices = v.shape[0]
        cnp.npy_intp nrows = v.shape[1]
        cnp.npy_intp ncols = v.shape[2]
        cnp.npy_intp nvox = nrows * ncols * nslices
        cnp.npy_intp i, j, k, l
        double epsilon, delta
        double min_val = -1
        double max_val = -1
        int[:] hist = np.zeros(shape=(num_levels,), dtype=np.int32)
        int[:, :, :] out = np.zeros(shape=(nslices, nrows, ncols),
                                    dtype=np.int32)
        floating[:] levels = np.zeros(shape=(num_levels,), dtype=ftype)

    #Quantizing at zero levels is undefined
    #Quantizing at one level is not supported because we want to make sure the<commit_msg>DOC: extended docstrings and added notes regarding invalid cases in quantization functions.<commit_after>#!python
#cython: boundscheck=False
#cython: wraparound=False
#cython: cdivision=True


import numpy as np
cimport cython
cimport numpy as cnp
from fused_types cimport floating, number

cdef extern from "math.h":
    double floor(double x) nogil
    int isinf(double) nogil

cdef inline int ifloor(double x) nogil:
    return int(floor(x))


def quantize_positive_2d(floating[:, :] v, int num_levels):
    r"""Quantizes a 2D image to num_levels quantization levels

    Quantizes the input image at num_levels intensity levels considering <=0 
    as a special value. Those input pixels <=0, and only those, will be
    assigned a quantization level of 0. The positive values are divided into 
    the remaining num_levels-1 uniform quanization levels.

    The following are undefined, and return (None, None, None):
    * Quantizing at zero levels because at least one level must be assigned
    * Quantizing at one level because positive values should be assigned a 
      level different from the secial level 0 (at least 2 levels are needed)
   
    Parameters
    ----------
    v : array, shape (R, C)
        the image to be quantized
    num_levels : int
        the number of levels

    Returns
    -------
    out : array, shape (R, C), same shape as v
        the quantized image
    levels: array, shape (num_levels,)
        the quantization values: levels[0]=0, and levels[i] is the mid-point
        of the interval of intensities that are assigned to quantization 
        level i, i=1, ..., num_levels-1. 
    hist: array, shape (num_levels,)
        histogram: the number of pixels that were assigned to each quantization
        level
    """
    ftype = np.asarray(v).dtype
    cdef:
        cnp.npy_intp nrows = v.shape[0]
        cnp.npy_intp ncols = v.shape[1]
        cnp.npy_intp npix = nrows * ncols
        cnp.npy_intp i, j, l
        double epsilon, delta
        double min_val = -1
        double max_val = -1
        int[:] hist = np.zeros(shape=(num_levels,), dtype=np.int32)
        int[:, :] out = np.zeros(shape=(nrows, ncols,), dtype=np.int32)
        floating[:] levels = np.zeros(shape=(num_levels,), dtype=ftype)

    #Quantizing at zero levels is undefined
    #Quantizing at one level is not supported because we want to make sure the
    #maximum level in the quantization is never greater than num_levels-1
    if(num_levels < 2):
        return None, None, None

    num_levels -= 1  # zero is one of the levels

    with nogil:

        for i in range(nrows):
            for j in range(ncols):
                if(v[i, j] > 0):
                    if((min_val < 0) or (v[i, j] < min_val)):
                        min_val = v[i, j]
                    if(v[i, j] > max_val):
                        max_val = v[i, j]
        epsilon = 1e-8
        delta = (max_val - min_val + epsilon) / num_levels
        # notice that we decreased num_levels, so levels[0..num_levels] are well
        # defined
        if((num_levels < 2) or (delta < epsilon)):
            for i in range(nrows):
                for j in range(ncols):
                    if(v[i, j] > 0):
                        out[i, j] = 1
                    else:
                        out[i, j] = 0
                        hist[0] += 1
            levels[0] = 0
            levels[1] = 0.5 * (min_val + max_val)
            hist[1] = npix - hist[0]
            with gil:
                return out, levels, hist

        levels[0] = 0
        levels[1] = min_val + delta * 0.5
        for i in range(2, 1 + num_levels):
            levels[i] = levels[i - 1] + delta
        for i in range(nrows):
            for j in range(ncols):
                if(v[i, j] > 0):
                    l = ifloor((v[i, j] - min_val) / delta)
                    out[i, j] = l + 1
                    hist[l + 1] += 1
                else:
                    out[i, j] = 0
                    hist[0] += 1

    return out, levels, hist


def quantize_positive_3d(floating[:, :, :] v, int num_levels):
    r"""Quantizes a 3D volume to num_levels quantization levels

    Quantizes the input volume at num_levels intensity levels considering <=0 
    as a special value. Those input voxels <=0, and only those, will be
    assigned a quantization level of 0. The positive values are divided into 
    the remaining num_levels-1 uniform quanization levels.

    The following are undefined, and return (None, None, None):
    * Quantizing at zero levels because at least one level must be assigned
    * Quantizing at one level because positive values should be assigned a 
      level different from the secial level 0 (at least 2 levels are needed)
   
    Parameters
    ----------
    v : array, shape (S, R, C)
        the volume to be quantized
    num_levels : int
        the number of levels

    Returns
    -------
    out : array, shape (S, R, C), same shape as v
        the quantized volume
    levels: array, shape (num_levels,)
        the quantization values: levels[0]=0, and levels[i] is the mid-point
        of the interval of intensities that are assigned to quantization 
        level i, i=1, ..., num_levels-1. 
    hist: array, shape (num_levels,)
        histogram: the number of voxels that were assigned to each quantization
        level
    """
    ftype = np.asarray(v).dtype
    cdef:
        cnp.npy_intp nslices = v.shape[0]
        cnp.npy_intp nrows = v.shape[1]
        cnp.npy_intp ncols = v.shape[2]
        cnp.npy_intp nvox = nrows * ncols * nslices
        cnp.npy_intp i, j, k, l
        double epsilon, delta
        double min_val = -1
        double max_val = -1
        int[:] hist = np.zeros(shape=(num_levels,), dtype=np.int32)
        int[:, :, :] out = np.zeros(shape=(nslices, nrows, ncols),
                                    dtype=np.int32)
        floating[:] levels = np.zeros(shape=(num_levels,), dtype=ftype)

    #Quantizing at zero levels is undefined
    #Quantizing at one level is not supported because we want to make sure the
{'fraction_non_alphanumeric': 0.0967741935483871, 'fraction_numerical': 0.013095811266249398, 'mean_word_length': 1.9003071767662665, 'pattern_counts': {'":': 2, '<': 17, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2325454', 'n_tokens_mistral': 3371, 'n_tokens_neox': 3165, 'n_words': 1127}