Example #1
0
int NI_FindObjects(PyArrayObject* input, npy_intp max_label,
                                     npy_intp* regions)
{
    int kk;
    npy_intp size, jj;
    NI_Iterator ii;
    char *pi;
    NPY_BEGIN_THREADS_DEF;

    NPY_BEGIN_THREADS;

    /* get input data, size and iterator: */
    pi = (void *)PyArray_DATA(input);
    size = 1;
    for(kk = 0; kk < input->nd; kk++)
        size *= input->dimensions[kk];
    if (!NI_InitPointIterator(input, &ii))
        goto exit;
    if (input->nd > 0) {
        for(jj = 0; jj < 2 * input->nd * max_label; jj++)
            regions[jj] = -1;
    } else {
        for(jj = 0; jj < max_label; jj++)
            regions[jj] = -1;
    }
    /* iterate over all points: */
    for(jj = 0 ; jj < size; jj++) {
        switch (NI_NormalizeType(input->descr->type_num)) {
        CASE_FIND_OBJECT_POINT(pi, regions, input->nd, input->dimensions,
                                                     max_label, ii,  Bool);
        CASE_FIND_OBJECT_POINT(pi, regions, input->nd, input->dimensions,
                                                     max_label, ii, UInt8);
        CASE_FIND_OBJECT_POINT(pi, regions, input->nd, input->dimensions,
                                                     max_label, ii, UInt16);
        CASE_FIND_OBJECT_POINT(pi, regions, input->nd, input->dimensions,
                                                     max_label, ii, UInt32);
#if HAS_UINT64
        CASE_FIND_OBJECT_POINT(pi, regions, input->nd, input->dimensions,
                                                     max_label, ii, UInt64);
#endif
        CASE_FIND_OBJECT_POINT(pi, regions, input->nd, input->dimensions,
                                                     max_label, ii, Int8);
        CASE_FIND_OBJECT_POINT(pi, regions, input->nd, input->dimensions,
                                                     max_label, ii, Int16);
        CASE_FIND_OBJECT_POINT(pi, regions, input->nd, input->dimensions,
                                                     max_label, ii, Int32);
        CASE_FIND_OBJECT_POINT(pi, regions, input->nd, input->dimensions,
                                                     max_label, ii, Int64);
            break;
        default:
            NPY_END_THREADS;
            PyErr_SetString(PyExc_RuntimeError, "data type not supported");
            goto exit;
        }
        NI_ITERATOR_NEXT(ii, pi);
    }
 exit:
    NPY_END_THREADS;
    return PyErr_Occurred() ? 0 : 1;
}
Example #2
0
/* Initialize a line buffer */
int NI_InitLineBuffer(PyArrayObject *array, int axis, maybelong size1,
        maybelong size2, maybelong buffer_lines, double *buffer_data,
        NI_ExtendMode extend_mode, double extend_value, NI_LineBuffer *buffer)
{
    maybelong line_length = 0, array_lines = 0, size;
    int ii;

    size = 1;
    for(ii = 0; ii < array->nd; ii++)
        size *= array->dimensions[ii];
    /* check if the buffer is big enough: */
    if (size > 0 && buffer_lines < 1) {
        PyErr_SetString(PyExc_RuntimeError, "buffer too small");
        return 0;
    }
    /* Initialize a line iterator to move over the array: */
    if (!NI_InitPointIterator(array, &(buffer->iterator)))
        return 0;
    if (!NI_LineIterator(&(buffer->iterator), axis))
        return 0;
    line_length = array->nd > 0 ? array->dimensions[axis] : 1;
    if (line_length > 0)
        array_lines = line_length > 0 ? size / line_length : 1;
    /* initialize the buffer structure: */
    buffer->array_data = (void *)PyArray_DATA(array);
    buffer->buffer_data = buffer_data;
    buffer->buffer_lines = buffer_lines;
    buffer->array_type = array->descr->type_num;
    buffer->array_lines = array_lines;
    buffer->next_line = 0;
    buffer->size1 = size1;
    buffer->size2 = size2;
    buffer->line_length = line_length;
    buffer->line_stride = array->nd > 0 ? array->strides[axis] : 0;
    buffer->extend_mode = extend_mode;
    buffer->extend_value = extend_value;
    return 1;
}
Example #3
0
/* Initialize a line buffer */
int NI_InitLineBuffer(PyArrayObject *array, int axis, npy_intp size1,
        npy_intp size2, npy_intp buffer_lines, double *buffer_data,
        NI_ExtendMode extend_mode, double extend_value, NI_LineBuffer *buffer)
{
    npy_intp line_length = 0, array_lines = 0, size;

    size = PyArray_SIZE(array);
    /* check if the buffer is big enough: */
    if (size > 0 && buffer_lines < 1) {
        PyErr_SetString(PyExc_RuntimeError, "buffer too small");
        return 0;
    }
    /* Initialize a line iterator to move over the array: */
    if (!NI_InitPointIterator(array, &(buffer->iterator)))
        return 0;
    if (!NI_LineIterator(&(buffer->iterator), axis))
        return 0;
    line_length = PyArray_NDIM(array) > 0 ? PyArray_DIM(array, axis) : 1;
    if (line_length > 0) {
        array_lines = line_length > 0 ? size / line_length : 1;
    }
    /* initialize the buffer structure: */
    buffer->array_data = (void *)PyArray_DATA(array);
    buffer->buffer_data = buffer_data;
    buffer->buffer_lines = buffer_lines;
    buffer->array_type = NI_CanonicalType(PyArray_TYPE(array));
    buffer->array_lines = array_lines;
    buffer->next_line = 0;
    buffer->size1 = size1;
    buffer->size2 = size2;
    buffer->line_length = line_length;
    buffer->line_stride =
                    PyArray_NDIM(array) > 0 ? PyArray_STRIDE(array, axis) : 0;
    buffer->extend_mode = extend_mode;
    buffer->extend_value = extend_value;
    return 1;
}
Example #4
0
int NI_GenericFilter(PyArrayObject* input,
                     int (*function)(double*, npy_intp, double*, void*), void *data,
                     PyArrayObject* footprint, PyArrayObject* output,
                     NI_ExtendMode mode, double cvalue, npy_intp *origins)
{
    Bool *pf = NULL;
    npy_intp fsize, jj, filter_size = 0, border_flag_value;
    npy_intp *offsets = NULL, *oo, size;
    NI_FilterIterator fi;
    NI_Iterator ii, io;
    char *pi, *po;
    double *buffer = NULL;
    int ll;

    /* get the the footprint: */
    fsize = 1;
    for(ll = 0; ll < footprint->nd; ll++)
        fsize *= footprint->dimensions[ll];
    pf = (Bool*)PyArray_DATA(footprint);
    for(jj = 0; jj < fsize; jj++) {
        if (pf[jj])
            ++filter_size;
    }
    /* initialize filter offsets: */
    if (!NI_InitFilterOffsets(input, pf, footprint->dimensions, origins,
                              mode, &offsets, &border_flag_value, NULL))
        goto exit;
    /* initialize filter iterator: */
    if (!NI_InitFilterIterator(input->nd, footprint->dimensions,
                               filter_size, input->dimensions, origins, &fi))
        goto exit;
    /* initialize input element iterator: */
    if (!NI_InitPointIterator(input, &ii))
        goto exit;
    /* initialize output element iterator: */
    if (!NI_InitPointIterator(output, &io))
        goto exit;
    /* get data pointers an array size: */
    pi = (void *)PyArray_DATA(input);
    po = (void *)PyArray_DATA(output);
    size = 1;
    for(ll = 0; ll < input->nd; ll++)
        size *= input->dimensions[ll];
    /* buffer for filter calculation: */
    buffer = (double*)malloc(filter_size * sizeof(double));
    if (!buffer) {
        PyErr_NoMemory();
        goto exit;
    }
    /* iterate over the elements: */
    oo = offsets;
    for(jj = 0; jj < size; jj++) {
        double tmp = 0.0;
        switch (NI_NormalizeType(input->descr->type_num)) {
            CASE_FILTER_POINT(pi, oo, filter_size, cvalue, Bool,
                              tmp, border_flag_value, function, data, buffer);
            CASE_FILTER_POINT(pi, oo, filter_size, cvalue, UInt8,
                              tmp, border_flag_value, function, data, buffer);
            CASE_FILTER_POINT(pi, oo, filter_size, cvalue, UInt16,
                              tmp, border_flag_value, function, data, buffer);
            CASE_FILTER_POINT(pi, oo, filter_size, cvalue, UInt32,
                              tmp, border_flag_value, function, data, buffer);
#if HAS_UINT64
            CASE_FILTER_POINT(pi, oo, filter_size, cvalue, UInt64,
                              tmp, border_flag_value, function, data, buffer);
#endif
            CASE_FILTER_POINT(pi, oo, filter_size, cvalue, Int8,
                              tmp, border_flag_value, function, data, buffer);
            CASE_FILTER_POINT(pi, oo, filter_size, cvalue, Int16,
                              tmp, border_flag_value, function, data, buffer);
            CASE_FILTER_POINT(pi, oo, filter_size, cvalue, Int32,
                              tmp, border_flag_value, function, data, buffer);
            CASE_FILTER_POINT(pi, oo, filter_size, cvalue, Int64,
                              tmp, border_flag_value, function, data, buffer);
            CASE_FILTER_POINT(pi, oo, filter_size, cvalue, Float32,
                              tmp, border_flag_value, function, data, buffer);
            CASE_FILTER_POINT(pi, oo, filter_size, cvalue, Float64,
                              tmp, border_flag_value, function, data, buffer);
        default:
            PyErr_SetString(PyExc_RuntimeError, "array type not supported");
            goto exit;
        }
        switch (NI_NormalizeType(output->descr->type_num)) {
            CASE_FILTER_OUT(po, tmp, Bool);
            CASE_FILTER_OUT(po, tmp, UInt8);
            CASE_FILTER_OUT(po, tmp, UInt16);
            CASE_FILTER_OUT(po, tmp, UInt32);
#if HAS_UINT64
            CASE_FILTER_OUT(po, tmp, UInt64);
#endif
            CASE_FILTER_OUT(po, tmp, Int8);
            CASE_FILTER_OUT(po, tmp, Int16);
            CASE_FILTER_OUT(po, tmp, Int32);
            CASE_FILTER_OUT(po, tmp, Int64);
            CASE_FILTER_OUT(po, tmp, Float32);
            CASE_FILTER_OUT(po, tmp, Float64);
        default:
            PyErr_SetString(PyExc_RuntimeError, "array type not supported");
            goto exit;
        }
        NI_FILTER_NEXT2(fi, ii, io, oo, pi, po);
    }
exit:
    if (offsets) free(offsets);
    if (buffer) free(buffer);
    return PyErr_Occurred() ? 0 : 1;
}
Example #5
0
int
NI_GeometricTransform(PyArrayObject *input, int (*map)(npy_intp*, double*,
                int, int, void*), void* map_data, PyArrayObject* matrix_ar,
                PyArrayObject* shift_ar, PyArrayObject *coordinates,
                PyArrayObject *output, int order, int mode, double cval)
{
    char *po, *pi, *pc = NULL;
    npy_intp **edge_offsets = NULL, **data_offsets = NULL, filter_size;
    npy_intp ftmp[NPY_MAXDIMS], *fcoordinates = NULL, *foffsets = NULL;
    npy_intp cstride = 0, kk, hh, ll, jj;
    npy_intp size;
    double **splvals = NULL, icoor[NPY_MAXDIMS];
    npy_intp idimensions[NPY_MAXDIMS], istrides[NPY_MAXDIMS];
    NI_Iterator io, ic;
    npy_double *matrix = matrix_ar ? (npy_double*)PyArray_DATA(matrix_ar) : NULL;
    npy_double *shift = shift_ar ? (npy_double*)PyArray_DATA(shift_ar) : NULL;
    int irank = 0, orank;
    NPY_BEGIN_THREADS_DEF;

    NPY_BEGIN_THREADS;

    for(kk = 0; kk < PyArray_NDIM(input); kk++) {
        idimensions[kk] = PyArray_DIM(input, kk);
        istrides[kk] = PyArray_STRIDE(input, kk);
    }
    irank = PyArray_NDIM(input);
    orank = PyArray_NDIM(output);

    /* if the mapping is from array coordinates: */
    if (coordinates) {
        /* initialize a line iterator along the first axis: */
        if (!NI_InitPointIterator(coordinates, &ic))
            goto exit;
        cstride = ic.strides[0];
        if (!NI_LineIterator(&ic, 0))
            goto exit;
        pc = (void *)(PyArray_DATA(coordinates));
    }

    /* offsets used at the borders: */
    edge_offsets = malloc(irank * sizeof(npy_intp*));
    data_offsets = malloc(irank * sizeof(npy_intp*));
    if (NPY_UNLIKELY(!edge_offsets || !data_offsets)) {
        NPY_END_THREADS;
        PyErr_NoMemory();
        goto exit;
    }
    for(jj = 0; jj < irank; jj++)
        data_offsets[jj] = NULL;
    for(jj = 0; jj < irank; jj++) {
        data_offsets[jj] = malloc((order + 1) * sizeof(npy_intp));
        if (NPY_UNLIKELY(!data_offsets[jj])) {
            NPY_END_THREADS;
            PyErr_NoMemory();
            goto exit;
        }
    }
    /* will hold the spline coefficients: */
    splvals = malloc(irank * sizeof(double*));
    if (NPY_UNLIKELY(!splvals)) {
        NPY_END_THREADS;
        PyErr_NoMemory();
        goto exit;
    }
    for(jj = 0; jj < irank; jj++)
        splvals[jj] = NULL;
    for(jj = 0; jj < irank; jj++) {
        splvals[jj] = malloc((order + 1) * sizeof(double));
        if (NPY_UNLIKELY(!splvals[jj])) {
            NPY_END_THREADS;
            PyErr_NoMemory();
            goto exit;
        }
    }

    filter_size = 1;
    for(jj = 0; jj < irank; jj++)
        filter_size *= order + 1;

    /* initialize output iterator: */
    if (!NI_InitPointIterator(output, &io))
        goto exit;

    /* get data pointers: */
    pi = (void *)PyArray_DATA(input);
    po = (void *)PyArray_DATA(output);

    /* make a table of all possible coordinates within the spline filter: */
    fcoordinates = malloc(irank * filter_size * sizeof(npy_intp));
    /* make a table of all offsets within the spline filter: */
    foffsets = malloc(filter_size * sizeof(npy_intp));
    if (NPY_UNLIKELY(!fcoordinates || !foffsets)) {
        NPY_END_THREADS;
        PyErr_NoMemory();
        goto exit;
    }
    for(jj = 0; jj < irank; jj++)
        ftmp[jj] = 0;
    kk = 0;
    for(hh = 0; hh < filter_size; hh++) {
        for(jj = 0; jj < irank; jj++)
            fcoordinates[jj + hh * irank] = ftmp[jj];
        foffsets[hh] = kk;
        for(jj = irank - 1; jj >= 0; jj--) {
            if (ftmp[jj] < order) {
                ftmp[jj]++;
                kk += istrides[jj];
                break;
            } else {
                ftmp[jj] = 0;
                kk -= istrides[jj] * order;
            }
        }
    }

    size = PyArray_SIZE(output);
    for(kk = 0; kk < size; kk++) {
        double t = 0.0;
        int constant = 0, edge = 0;
        npy_intp offset = 0;
        if (map) {
            NPY_END_THREADS;
            /* call mappint functions: */
            if (!map(io.coordinates, icoor, orank, irank, map_data)) {
                if (!PyErr_Occurred())
                    PyErr_SetString(PyExc_RuntimeError,
                                                    "unknown error in mapping function");
                goto exit;
            }
            NPY_BEGIN_THREADS;
        } else if (matrix) {
            /* do an affine transformation: */
            npy_double *p = matrix;
            for(hh = 0; hh < irank; hh++) {
                icoor[hh] = 0.0;
                for(ll = 0; ll < orank; ll++)
                    icoor[hh] += io.coordinates[ll] * *p++;
                icoor[hh] += shift[hh];
            }
        } else if (coordinates) {
            /* mapping is from an coordinates array: */
            char *p = pc;
            switch (PyArray_TYPE(coordinates)) {
                CASE_MAP_COORDINATES(NPY_BOOL, npy_bool,
                                     p, icoor, irank, cstride);
                CASE_MAP_COORDINATES(NPY_UBYTE, npy_ubyte,
                                     p, icoor, irank, cstride);
                CASE_MAP_COORDINATES(NPY_USHORT, npy_ushort,
                                     p, icoor, irank, cstride);
                CASE_MAP_COORDINATES(NPY_UINT, npy_uint,
                                     p, icoor, irank, cstride);
                CASE_MAP_COORDINATES(NPY_ULONG, npy_ulong,
                                     p, icoor, irank, cstride);
                CASE_MAP_COORDINATES(NPY_ULONGLONG, npy_ulonglong,
                                     p, icoor, irank, cstride);
                CASE_MAP_COORDINATES(NPY_BYTE, npy_byte,
                                     p, icoor, irank, cstride);
                CASE_MAP_COORDINATES(NPY_SHORT, npy_short,
                                     p, icoor, irank, cstride);
                CASE_MAP_COORDINATES(NPY_INT, npy_int,
                                     p, icoor, irank, cstride);
                CASE_MAP_COORDINATES(NPY_LONG, npy_long,
                                     p, icoor, irank, cstride);
                CASE_MAP_COORDINATES(NPY_LONGLONG, npy_longlong,
                                     p, icoor, irank, cstride);
                CASE_MAP_COORDINATES(NPY_FLOAT, npy_float,
                                     p, icoor, irank, cstride);
                CASE_MAP_COORDINATES(NPY_DOUBLE, npy_double,
                                     p, icoor, irank, cstride);
            default:
                NPY_END_THREADS;
                PyErr_SetString(PyExc_RuntimeError,
                                "coordinate array data type not supported");
                goto exit;
            }
        }
        /* iterate over axes: */
        for(hh = 0; hh < irank; hh++) {
            /* if the input coordinate is outside the borders, map it: */
            double cc = map_coordinate(icoor[hh], idimensions[hh], mode);
            if (cc > -1.0) {
                /* find the filter location along this axis: */
                npy_intp start;
                if (order & 1) {
                    start = (npy_intp)floor(cc) - order / 2;
                } else {
                    start = (npy_intp)floor(cc + 0.5) - order / 2;
                }
                /* get the offset to the start of the filter: */
                offset += istrides[hh] * start;
                if (start < 0 || start + order >= idimensions[hh]) {
                    /* implement border mapping, if outside border: */
                    edge = 1;
                    edge_offsets[hh] = data_offsets[hh];
                    for(ll = 0; ll <= order; ll++) {
                        npy_intp idx = start + ll;
                        npy_intp len = idimensions[hh];
                        if (len <= 1) {
                            idx = 0;
                        } else {
                            npy_intp s2 = 2 * len - 2;
                            if (idx < 0) {
                                idx = s2 * (int)(-idx / s2) + idx;
                                idx = idx <= 1 - len ? idx + s2 : -idx;
                            } else if (idx >= len) {
                                idx -= s2 * (int)(idx / s2);
                                if (idx >= len)
                                    idx = s2 - idx;
                            }
                        }
                        /* calculate and store the offests at this edge: */
                        edge_offsets[hh][ll] = istrides[hh] * (idx - start);
                    }
                } else {
                    /* we are not at the border, use precalculated offsets: */
                    edge_offsets[hh] = NULL;
                }
                spline_coefficients(cc, order, splvals[hh]);
            } else {
                /* we use the constant border condition: */
                constant = 1;
                break;
            }
        }

        if (!constant) {
            npy_intp *ff = fcoordinates;
            const int type_num = PyArray_TYPE(input);
            t = 0.0;
            for(hh = 0; hh < filter_size; hh++) {
                double coeff = 0.0;
                npy_intp idx = 0;

                if (NPY_UNLIKELY(edge)) {
                    for(ll = 0; ll < irank; ll++) {
                        if (edge_offsets[ll])
                            idx += edge_offsets[ll][ff[ll]];
                        else
                            idx += ff[ll] * istrides[ll];
                    }
                } else {
                    idx = foffsets[hh];
                }
                idx += offset;
                switch (type_num) {
                    CASE_INTERP_COEFF(NPY_BOOL, npy_bool,
                                      coeff, pi, idx);
                    CASE_INTERP_COEFF(NPY_UBYTE, npy_ubyte,
                                      coeff, pi, idx);
                    CASE_INTERP_COEFF(NPY_USHORT, npy_ushort,
                                      coeff, pi, idx);
                    CASE_INTERP_COEFF(NPY_UINT, npy_uint,
                                      coeff, pi, idx);
                    CASE_INTERP_COEFF(NPY_ULONG, npy_ulong,
                                      coeff, pi, idx);
                    CASE_INTERP_COEFF(NPY_ULONGLONG, npy_ulonglong,
                                      coeff, pi, idx);
                    CASE_INTERP_COEFF(NPY_BYTE, npy_byte,
                                      coeff, pi, idx);
                    CASE_INTERP_COEFF(NPY_SHORT, npy_short,
                                      coeff, pi, idx);
                    CASE_INTERP_COEFF(NPY_INT, npy_int,
                                      coeff, pi, idx);
                    CASE_INTERP_COEFF(NPY_LONG, npy_long,
                                      coeff, pi, idx);
                    CASE_INTERP_COEFF(NPY_LONGLONG, npy_longlong,
                                      coeff, pi, idx);
                    CASE_INTERP_COEFF(NPY_FLOAT, npy_float,
                                      coeff, pi, idx);
                    CASE_INTERP_COEFF(NPY_DOUBLE, npy_double,
                                      coeff, pi, idx);
                default:
                    NPY_END_THREADS;
                    PyErr_SetString(PyExc_RuntimeError,
                                    "data type not supported");
                    goto exit;
                }
                /* calculate the interpolated value: */
                for(ll = 0; ll < irank; ll++)
                    if (order > 0)
                        coeff *= splvals[ll][ff[ll]];
                t += coeff;
                ff += irank;
            }
        } else {
            t = cval;
        }
        /* store output value: */
        switch (PyArray_TYPE(output)) {
            CASE_INTERP_OUT(NPY_BOOL, npy_bool, po, t);
            CASE_INTERP_OUT_UINT(UBYTE, npy_ubyte, po, t);
            CASE_INTERP_OUT_UINT(USHORT, npy_ushort, po, t);
            CASE_INTERP_OUT_UINT(UINT, npy_uint, po, t);
            CASE_INTERP_OUT_UINT(ULONG, npy_ulong, po, t);
            CASE_INTERP_OUT_UINT(ULONGLONG, npy_ulonglong, po, t);
            CASE_INTERP_OUT_INT(BYTE, npy_byte, po, t);
            CASE_INTERP_OUT_INT(SHORT, npy_short, po, t);
            CASE_INTERP_OUT_INT(INT, npy_int, po, t);
            CASE_INTERP_OUT_INT(LONG, npy_long, po, t);
            CASE_INTERP_OUT_INT(LONGLONG, npy_longlong, po, t);
            CASE_INTERP_OUT(NPY_FLOAT, npy_float, po, t);
            CASE_INTERP_OUT(NPY_DOUBLE, npy_double, po, t);
        default:
            NPY_END_THREADS;
            PyErr_SetString(PyExc_RuntimeError, "data type not supported");
            goto exit;
        }
        if (coordinates) {
            NI_ITERATOR_NEXT2(io, ic, po, pc);
        } else {
            NI_ITERATOR_NEXT(io, po);
        }
    }

 exit:
    NPY_END_THREADS;
    free(edge_offsets);
    if (data_offsets) {
        for(jj = 0; jj < irank; jj++)
            free(data_offsets[jj]);
        free(data_offsets);
    }
    if (splvals) {
        for(jj = 0; jj < irank; jj++)
            free(splvals[jj]);
        free(splvals);
    }
    free(foffsets);
    free(fcoordinates);
    return PyErr_Occurred() ? 0 : 1;
}
Example #6
0
int NI_Correlate(PyArrayObject* input, PyArrayObject* weights,
                 PyArrayObject* output, NI_ExtendMode mode,
                 double cvalue, npy_intp *origins)
{
    Bool *pf = NULL;
    npy_intp fsize, jj, kk, filter_size = 0, border_flag_value;
    npy_intp *offsets = NULL, *oo, size;
    NI_FilterIterator fi;
    NI_Iterator ii, io;
    char *pi, *po;
    Float64 *pw;
    Float64 *ww = NULL;
    int ll, err = 0;
    NPY_BEGIN_THREADS_DEF;

    /* get the the footprint: */
    fsize = 1;
    for(ll = 0; ll < weights->nd; ll++)
        fsize *= weights->dimensions[ll];
    pw = (Float64*)PyArray_DATA(weights);
    pf = (Bool*)malloc(fsize * sizeof(Bool));
    if (!pf) {
        PyErr_NoMemory();
        goto exit;
    }
    for(jj = 0; jj < fsize; jj++) {
        if (fabs(pw[jj]) > DBL_EPSILON) {
            pf[jj] = 1;
            ++filter_size;
        } else {
            pf[jj] = 0;
        }
    }
    /* copy the weights to contiguous memory: */
    ww = (Float64*)malloc(filter_size * sizeof(Float64));
    if (!ww) {
        PyErr_NoMemory();
        goto exit;
    }
    jj = 0;
    for(kk = 0; kk < fsize; kk++) {
        if (pf[kk]) {
            ww[jj++] = pw[kk];
        }
    }
    /* initialize filter offsets: */
    if (!NI_InitFilterOffsets(input, pf, weights->dimensions, origins,
                              mode, &offsets, &border_flag_value, NULL))
        goto exit;
    /* initialize filter iterator: */
    if (!NI_InitFilterIterator(input->nd, weights->dimensions, filter_size,
                               input->dimensions, origins, &fi))
        goto exit;
    /* initialize input element iterator: */
    if (!NI_InitPointIterator(input, &ii))
        goto exit;
    /* initialize output element iterator: */
    if (!NI_InitPointIterator(output, &io))
        goto exit;

    NPY_BEGIN_THREADS;
    /* get data pointers an array size: */
    pi = (void *)PyArray_DATA(input);
    po = (void *)PyArray_DATA(output);
    size = 1;
    for(ll = 0; ll < input->nd; ll++)
        size *= input->dimensions[ll];
    /* iterator over the elements: */
    oo = offsets;
    for(jj = 0; jj < size; jj++) {
        double tmp = 0.0;
        switch (NI_NormalizeType(input->descr->type_num)) {
            CASE_CORRELATE_POINT(pi, ww, oo, filter_size, cvalue, Bool,
                                 tmp, border_flag_value);
            CASE_CORRELATE_POINT(pi, ww, oo, filter_size, cvalue, UInt8,
                                 tmp, border_flag_value);
            CASE_CORRELATE_POINT(pi, ww, oo, filter_size, cvalue, UInt16,
                                 tmp, border_flag_value);
            CASE_CORRELATE_POINT(pi, ww, oo, filter_size, cvalue, UInt32,
                                 tmp, border_flag_value);
#if HAS_UINT64
            CASE_CORRELATE_POINT(pi, ww, oo, filter_size, cvalue, UInt64,
                                 tmp, border_flag_value);
#endif
            CASE_CORRELATE_POINT(pi, ww, oo, filter_size, cvalue, Int8,
                                 tmp, border_flag_value);
            CASE_CORRELATE_POINT(pi, ww, oo, filter_size, cvalue, Int16,
                                 tmp, border_flag_value);
            CASE_CORRELATE_POINT(pi, ww, oo, filter_size, cvalue, Int32,
                                 tmp, border_flag_value);
            CASE_CORRELATE_POINT(pi, ww, oo, filter_size, cvalue, Int64,
                                 tmp, border_flag_value);
            CASE_CORRELATE_POINT(pi, ww, oo, filter_size, cvalue, Float32,
                                 tmp, border_flag_value);
            CASE_CORRELATE_POINT(pi, ww, oo, filter_size, cvalue, Float64,
                                 tmp, border_flag_value);
        default:
            err = 1;
            goto exit;
        }
        switch (NI_NormalizeType(output->descr->type_num)) {
            CASE_FILTER_OUT(po, tmp, Bool);
            CASE_FILTER_OUT(po, tmp, UInt8);
            CASE_FILTER_OUT(po, tmp, UInt16);
            CASE_FILTER_OUT(po, tmp, UInt32);
#if HAS_UINT64
            CASE_FILTER_OUT(po, tmp, UInt64);
#endif
            CASE_FILTER_OUT(po, tmp, Int8);
            CASE_FILTER_OUT(po, tmp, Int16);
            CASE_FILTER_OUT(po, tmp, Int32);
            CASE_FILTER_OUT(po, tmp, Int64);
            CASE_FILTER_OUT(po, tmp, Float32);
            CASE_FILTER_OUT(po, tmp, Float64);
        default:
            err = 1;
            goto exit;
        }
        NI_FILTER_NEXT2(fi, ii, io, oo, pi, po);
    }
exit:
    NPY_END_THREADS;
    if (err == 1) {
        PyErr_SetString(PyExc_RuntimeError, "array type not supported");
    }
    if (offsets) free(offsets);
    if (ww) free(ww);
    if (pf) free(pf);
    return PyErr_Occurred() ? 0 : 1;
}
Example #7
0
int NI_MinOrMaxFilter(PyArrayObject* input, PyArrayObject* footprint,
                      PyArrayObject* structure, PyArrayObject* output,
                      NI_ExtendMode mode, double cvalue, npy_intp *origins,
                      int minimum)
{
    Bool *pf = NULL;
    npy_intp fsize, jj, kk, filter_size = 0, border_flag_value;
    npy_intp *offsets = NULL, *oo, size;
    NI_FilterIterator fi;
    NI_Iterator ii, io;
    char *pi, *po;
    int ll, err = 0;
    double *ss = NULL;
    Float64 *ps;
    NPY_BEGIN_THREADS_DEF;

    /* get the the footprint: */
    fsize = 1;
    for(ll = 0; ll < footprint->nd; ll++)
        fsize *= footprint->dimensions[ll];
    pf = (Bool*)PyArray_DATA(footprint);
    for(jj = 0; jj < fsize; jj++) {
        if (pf[jj]) {
            ++filter_size;
        }
    }
    /* get the structure: */
    if (structure) {
        ss = (double*)malloc(filter_size * sizeof(double));
        if (!ss) {
            PyErr_NoMemory();
            goto exit;
        }
        /* copy the weights to contiguous memory: */
        ps = (Float64*)PyArray_DATA(structure);
        jj = 0;
        for(kk = 0; kk < fsize; kk++)
            if (pf[kk])
                ss[jj++] = minimum ? -ps[kk] : ps[kk];
    }
    /* initialize filter offsets: */
    if (!NI_InitFilterOffsets(input, pf, footprint->dimensions, origins,
                              mode, &offsets, &border_flag_value, NULL))
        goto exit;
    /* initialize filter iterator: */
    if (!NI_InitFilterIterator(input->nd, footprint->dimensions,
                               filter_size, input->dimensions, origins, &fi))
        goto exit;
    /* initialize input element iterator: */
    if (!NI_InitPointIterator(input, &ii))
        goto exit;
    /* initialize output element iterator: */
    if (!NI_InitPointIterator(output, &io))
        goto exit;

    NPY_BEGIN_THREADS;

    /* get data pointers an array size: */
    pi = (void *)PyArray_DATA(input);
    po = (void *)PyArray_DATA(output);
    size = 1;
    for(ll = 0; ll < input->nd; ll++)
        size *= input->dimensions[ll];
    /* iterator over the elements: */
    oo = offsets;
    for(jj = 0; jj < size; jj++) {
        double tmp = 0.0;
        switch (NI_NormalizeType(input->descr->type_num)) {
            CASE_MIN_OR_MAX_POINT(pi, oo, filter_size, cvalue, Bool,
                                  minimum, tmp, border_flag_value, ss);
            CASE_MIN_OR_MAX_POINT(pi, oo, filter_size, cvalue, UInt8,
                                  minimum, tmp, border_flag_value, ss);
            CASE_MIN_OR_MAX_POINT(pi, oo, filter_size, cvalue, UInt16,
                                  minimum, tmp, border_flag_value, ss);
            CASE_MIN_OR_MAX_POINT(pi, oo, filter_size, cvalue, UInt32,
                                  minimum, tmp, border_flag_value, ss);
#if HAS_UINT64
            CASE_MIN_OR_MAX_POINT(pi, oo, filter_size, cvalue, UInt64,
                                  minimum, tmp, border_flag_value, ss);
#endif
            CASE_MIN_OR_MAX_POINT(pi, oo, filter_size, cvalue, Int8,
                                  minimum, tmp, border_flag_value, ss);
            CASE_MIN_OR_MAX_POINT(pi, oo, filter_size, cvalue, Int16,
                                  minimum, tmp, border_flag_value, ss);
            CASE_MIN_OR_MAX_POINT(pi, oo, filter_size, cvalue, Int32,
                                  minimum, tmp, border_flag_value, ss);
            CASE_MIN_OR_MAX_POINT(pi, oo, filter_size, cvalue, Int64,
                                  minimum, tmp, border_flag_value, ss);
            CASE_MIN_OR_MAX_POINT(pi, oo, filter_size, cvalue, Float32,
                                  minimum, tmp, border_flag_value, ss);
            CASE_MIN_OR_MAX_POINT(pi, oo, filter_size, cvalue, Float64,
                                  minimum, tmp, border_flag_value, ss);
        default:
            err = 1;
            goto exit;
        }
        switch (NI_NormalizeType(output->descr->type_num)) {
            CASE_FILTER_OUT(po, tmp, Bool);
            CASE_FILTER_OUT(po, tmp, UInt8);
            CASE_FILTER_OUT(po, tmp, UInt16);
            CASE_FILTER_OUT(po, tmp, UInt32);
#if HAS_UINT64
            CASE_FILTER_OUT(po, tmp, UInt64);
#endif
            CASE_FILTER_OUT(po, tmp, Int8);
            CASE_FILTER_OUT(po, tmp, Int16);
            CASE_FILTER_OUT(po, tmp, Int32);
            CASE_FILTER_OUT(po, tmp, Int64);
            CASE_FILTER_OUT(po, tmp, Float32);
            CASE_FILTER_OUT(po, tmp, Float64);
        default:
            err = 1;
            goto exit;
        }
        NI_FILTER_NEXT2(fi, ii, io, oo, pi, po);
    }
exit:
    NPY_END_THREADS;
    if (err == 1) {
        PyErr_SetString(PyExc_RuntimeError, "array type not supported");
    }
    if (offsets) free(offsets);
    if (ss) free(ss);
    return PyErr_Occurred() ? 0 : 1;
}
int
NI_GeometricTransform(PyArrayObject *input, int (*map)(npy_intp*, double*,
                int, int, void*), void* map_data, PyArrayObject* matrix_ar,
                PyArrayObject* shift_ar, PyArrayObject *coordinates,
                PyArrayObject *output, int order, int mode, double cval)
{
    char *po, *pi, *pc = NULL;
    npy_intp **edge_offsets = NULL, **data_offsets = NULL, filter_size;
    npy_intp ftmp[MAXDIM], *fcoordinates = NULL, *foffsets = NULL;
    npy_intp cstride = 0, kk, hh, ll, jj, *idxs = NULL;
    npy_intp size;
    double **splvals = NULL, icoor[MAXDIM];
    npy_intp idimensions[MAXDIM], istrides[MAXDIM];
    NI_Iterator io, ic;
    Float64 *matrix = matrix_ar ? (Float64*)PyArray_DATA(matrix_ar) : NULL;
    Float64 *shift = shift_ar ? (Float64*)PyArray_DATA(shift_ar) : NULL;
    int irank = 0, orank, qq;

    for(kk = 0; kk < input->nd; kk++) {
        idimensions[kk] = input->dimensions[kk];
        istrides[kk] = input->strides[kk];
    }
    irank = input->nd;
    orank = output->nd;

    /* if the mapping is from array coordinates: */
    if (coordinates) {
        /* initialze a line iterator along the first axis: */
        if (!NI_InitPointIterator(coordinates, &ic))
            goto exit;
        cstride = ic.strides[0];
        if (!NI_LineIterator(&ic, 0))
            goto exit;
        pc = (void *)(PyArray_DATA(coordinates));
    }

    /* offsets used at the borders: */
    edge_offsets = (npy_intp**)malloc(irank * sizeof(npy_intp*));
    data_offsets = (npy_intp**)malloc(irank * sizeof(npy_intp*));
    if (!edge_offsets || !data_offsets) {
        PyErr_NoMemory();
        goto exit;
    }
    for(jj = 0; jj < irank; jj++)
        data_offsets[jj] = NULL;
    for(jj = 0; jj < irank; jj++) {
        data_offsets[jj] = (npy_intp*)malloc((order + 1) * sizeof(npy_intp));
        if (!data_offsets[jj]) {
            PyErr_NoMemory();
            goto exit;
        }
    }
    /* will hold the spline coefficients: */
    splvals = (double**)malloc(irank * sizeof(double*));
    if (!splvals) {
        PyErr_NoMemory();
        goto exit;
    }
    for(jj = 0; jj < irank; jj++)
        splvals[jj] = NULL;
    for(jj = 0; jj < irank; jj++) {
        splvals[jj] = (double*)malloc((order + 1) * sizeof(double));
        if (!splvals[jj]) {
            PyErr_NoMemory();
            goto exit;
        }
    }

    filter_size = 1;
    for(jj = 0; jj < irank; jj++)
        filter_size *= order + 1;
    idxs = (npy_intp*)malloc(filter_size * sizeof(idxs));
    if (!idxs) {
        PyErr_NoMemory();
        goto exit;
    }

    /* initialize output iterator: */
    if (!NI_InitPointIterator(output, &io))
        goto exit;

    /* get data pointers: */
    pi = (void *)PyArray_DATA(input);
    po = (void *)PyArray_DATA(output);

    /* make a table of all possible coordinates within the spline filter: */
    fcoordinates = (npy_intp*)malloc(irank * filter_size * sizeof(npy_intp));
    /* make a table of all offsets within the spline filter: */
    foffsets = (npy_intp*)malloc(filter_size * sizeof(npy_intp));
    if (!fcoordinates || !foffsets) {
        PyErr_NoMemory();
        goto exit;
    }
    for(jj = 0; jj < irank; jj++)
        ftmp[jj] = 0;
    kk = 0;
    for(hh = 0; hh < filter_size; hh++) {
        for(jj = 0; jj < irank; jj++)
            fcoordinates[jj + hh * irank] = ftmp[jj];
        foffsets[hh] = kk;
        for(jj = irank - 1; jj >= 0; jj--) {
            if (ftmp[jj] < order) {
                ftmp[jj]++;
                kk += istrides[jj];
                break;
            } else {
                ftmp[jj] = 0;
                kk -= istrides[jj] * order;
            }
        }
    }

    size = 1;
    for(qq = 0; qq < output->nd; qq++)
        size *= output->dimensions[qq];
    for(kk = 0; kk < size; kk++) {
        double t = 0.0;
        int constant = 0, edge = 0, offset = 0;
        if (map) {
            /* call mappint functions: */
            if (!map(io.coordinates, icoor, orank, irank, map_data)) {
                if (!PyErr_Occurred())
                    PyErr_SetString(PyExc_RuntimeError,
                                                    "unknown error in mapping function");
                goto exit;
            }
        } else if (matrix) {
            /* do an affine transformation: */
            Float64 *p = matrix;
            for(hh = 0; hh < irank; hh++) {
                icoor[hh] = 0.0;
                for(ll = 0; ll < orank; ll++)
                    icoor[hh] += io.coordinates[ll] * *p++;
                icoor[hh] += shift[hh];
            }
        } else if (coordinates) {
            /* mapping is from an coordinates array: */
            char *p = pc;
            switch(coordinates->descr->type_num) {
                CASE_MAP_COORDINATES(p, icoor, irank, cstride, Bool);
                CASE_MAP_COORDINATES(p, icoor, irank, cstride, UInt8);
                CASE_MAP_COORDINATES(p, icoor, irank, cstride, UInt16);
                CASE_MAP_COORDINATES(p, icoor, irank, cstride, UInt32);
#if HAS_UINT64
                CASE_MAP_COORDINATES(p, icoor, irank, cstride, UInt64);
#endif
                CASE_MAP_COORDINATES(p, icoor, irank, cstride, Int8);
                CASE_MAP_COORDINATES(p, icoor, irank, cstride, Int16);
                CASE_MAP_COORDINATES(p, icoor, irank, cstride, Int32);
                CASE_MAP_COORDINATES(p, icoor, irank, cstride, Int64);
                CASE_MAP_COORDINATES(p, icoor, irank, cstride, Float32);
                CASE_MAP_COORDINATES(p, icoor, irank, cstride, Float64);
            default:
                PyErr_SetString(PyExc_RuntimeError,
                                                "coordinate array data type not supported");
                goto exit;
            }
        }
        /* iterate over axes: */
        for(hh = 0; hh < irank; hh++) {
            /* if the input coordinate is outside the borders, map it: */
            double cc = map_coordinate(icoor[hh], idimensions[hh], mode);
            if (cc > -1.0) {
                /* find the filter location along this axis: */
                int start;
                if (order & 1) {
                    start = (int)floor(cc) - order / 2;
                } else {
                    start = (int)floor(cc + 0.5) - order / 2;
                }
                /* get the offset to the start of the filter: */
                offset += istrides[hh] * start;
                if (start < 0 || start + order >= idimensions[hh]) {
                    /* implement border mapping, if outside border: */
                    edge = 1;
                    edge_offsets[hh] = data_offsets[hh];
                    for(ll = 0; ll <= order; ll++) {
                        int idx = start + ll;
                        int len = idimensions[hh];
                        if (len <= 1) {
                            idx = 0;
                        } else {
                            int s2 = 2 * len - 2;
                            if (idx < 0) {
                                idx = s2 * (int)(-idx / s2) + idx;
                                idx = idx <= 1 - len ? idx + s2 : -idx;
                            } else if (idx >= len) {
                                idx -= s2 * (int)(idx / s2);
                                if (idx >= len)
                                    idx = s2 - idx;
                            }
                        }
                        /* calculate and store the offests at this edge: */
                        edge_offsets[hh][ll] = istrides[hh] * (idx - start);
                    }
                } else {
                    /* we are not at the border, use precalculated offsets: */
                    edge_offsets[hh] = NULL;
                }
                spline_coefficients(cc, order, splvals[hh]);
            } else {
                /* we use the constant border condition: */
                constant = 1;
                break;
            }
        }

        if (!constant) {
            npy_intp *ff = fcoordinates;
            for(hh = 0; hh < filter_size; hh++) {
                int idx = 0;
                if (edge) {
                    for(ll = 0; ll < irank; ll++) {
                        if (edge_offsets[ll])
                            idx += edge_offsets[ll][ff[ll]];
                        else
                            idx += ff[ll] * istrides[ll];
                    }
                } else {
                    idx = foffsets[hh];
                }
                idx += offset;
                idxs[hh] = idx;
                ff += irank;
            }
        }
        if (!constant) {
            npy_intp *ff = fcoordinates;
            t = 0.0;
            for(hh = 0; hh < filter_size; hh++) {
                double coeff = 0.0;
                switch(input->descr->type_num) {
                    CASE_INTERP_COEFF(coeff, pi, idxs[hh], Bool);
                    CASE_INTERP_COEFF(coeff, pi, idxs[hh], UInt8);
                    CASE_INTERP_COEFF(coeff, pi, idxs[hh], UInt16);
                    CASE_INTERP_COEFF(coeff, pi, idxs[hh], UInt32);
#if HAS_UINT64
                    CASE_INTERP_COEFF(coeff, pi, idxs[hh], UInt64);
#endif
                    CASE_INTERP_COEFF(coeff, pi, idxs[hh], Int8);
                    CASE_INTERP_COEFF(coeff, pi, idxs[hh], Int16);
                    CASE_INTERP_COEFF(coeff, pi, idxs[hh], Int32);
                    CASE_INTERP_COEFF(coeff, pi, idxs[hh], Int64);
                    CASE_INTERP_COEFF(coeff, pi, idxs[hh], Float32);
                    CASE_INTERP_COEFF(coeff, pi, idxs[hh], Float64);
                default:
                    PyErr_SetString(PyExc_RuntimeError,
                                                    "data type not supported");
                    goto exit;
                }
                /* calculate the interpolated value: */
                for(ll = 0; ll < irank; ll++)
                    if (order > 0)
                        coeff *= splvals[ll][ff[ll]];
                t += coeff;
                ff += irank;
            }
        } else {
            t = cval;
        }
        /* store output value: */
        switch (output->descr->type_num) {
            CASE_INTERP_OUT(po, t, Bool);
            CASE_INTERP_OUT_UINT(po, t, UInt8, 0, MAX_UINT8);
            CASE_INTERP_OUT_UINT(po, t, UInt16, 0, MAX_UINT16);
            CASE_INTERP_OUT_UINT(po, t, UInt32, 0, MAX_UINT32);
#if HAS_UINT64
            /* FIXME */
            CASE_INTERP_OUT_UINT(po, t, UInt64, 0, MAX_UINT32);
#endif
            CASE_INTERP_OUT_INT(po, t, Int8, MIN_INT8, MAX_INT8);
            CASE_INTERP_OUT_INT(po, t, Int16, MIN_INT16, MAX_INT16);
            CASE_INTERP_OUT_INT(po, t, Int32, MIN_INT32, MAX_INT32);
            CASE_INTERP_OUT_INT(po, t, Int64, MIN_INT64, MAX_INT64);
            CASE_INTERP_OUT(po, t, Float32);
            CASE_INTERP_OUT(po, t, Float64);
        default:
            PyErr_SetString(PyExc_RuntimeError, "data type not supported");
            goto exit;
        }
        if (coordinates) {
            NI_ITERATOR_NEXT2(io, ic, po, pc);
        } else {
            NI_ITERATOR_NEXT(io, po);
        }
    }

 exit:
    if (edge_offsets)
        free(edge_offsets);
    if (data_offsets) {
        for(jj = 0; jj < irank; jj++)
            free(data_offsets[jj]);
        free(data_offsets);
    }
    if (splvals) {
        for(jj = 0; jj < irank; jj++)
            free(splvals[jj]);
        free(splvals);
    }
    if (foffsets)
        free(foffsets);
    if (fcoordinates)
        free(fcoordinates);
    if (idxs)
        free(idxs);
    return PyErr_Occurred() ? 0 : 1;
}
int NI_ZoomShift(PyArrayObject *input, PyArrayObject* zoom_ar,
                                 PyArrayObject* shift_ar, PyArrayObject *output,
                                 int order, int mode, double cval)
{
    char *po, *pi;
    npy_intp **zeros = NULL, **offsets = NULL, ***edge_offsets = NULL;
    npy_intp ftmp[MAXDIM], *fcoordinates = NULL, *foffsets = NULL;
    npy_intp jj, hh, kk, filter_size, odimensions[MAXDIM];
    npy_intp idimensions[MAXDIM], istrides[MAXDIM], *idxs = NULL;
    npy_intp size;
    double ***splvals = NULL;
    NI_Iterator io;
    Float64 *zooms = zoom_ar ? (Float64*)PyArray_DATA(zoom_ar) : NULL;
    Float64 *shifts = shift_ar ? (Float64*)PyArray_DATA(shift_ar) : NULL;
    int rank = 0, qq;

    for(kk = 0; kk < input->nd; kk++) {
        idimensions[kk] = input->dimensions[kk];
        istrides[kk] = input->strides[kk];
        odimensions[kk] = output->dimensions[kk];
    }
    rank = input->nd;

    /* if the mode is 'constant' we need some temps later: */
    if (mode == NI_EXTEND_CONSTANT) {
        zeros = (npy_intp**)malloc(rank * sizeof(npy_intp*));
        if (!zeros) {
            PyErr_NoMemory();
            goto exit;
        }
        for(jj = 0; jj < rank; jj++)
            zeros[jj] = NULL;
        for(jj = 0; jj < rank; jj++) {
            zeros[jj] = (npy_intp*)malloc(odimensions[jj] * sizeof(npy_intp));
            if(!zeros[jj]) {
                PyErr_NoMemory();
                goto exit;
            }
        }
    }

    /* store offsets, along each axis: */
    offsets = (npy_intp**)malloc(rank * sizeof(npy_intp*));
    /* store spline coefficients, along each axis: */
    splvals = (double***)malloc(rank * sizeof(double**));
    /* store offsets at all edges: */
    edge_offsets = (npy_intp***)malloc(rank * sizeof(npy_intp**));
    if (!offsets || !splvals || !edge_offsets) {
        PyErr_NoMemory();
        goto exit;
    }
    for(jj = 0; jj < rank; jj++) {
        offsets[jj] = NULL;
        splvals[jj] = NULL;
        edge_offsets[jj] = NULL;
    }
    for(jj = 0; jj < rank; jj++) {
        offsets[jj] = (npy_intp*)malloc(odimensions[jj] * sizeof(npy_intp));
        splvals[jj] = (double**)malloc(odimensions[jj] * sizeof(double*));
        edge_offsets[jj] = (npy_intp**)malloc(odimensions[jj] * sizeof(npy_intp*));
        if (!offsets[jj] || !splvals[jj] || !edge_offsets[jj]) {
            PyErr_NoMemory();
            goto exit;
        }
        for(hh = 0; hh < odimensions[jj]; hh++) {
            splvals[jj][hh] = NULL;
            edge_offsets[jj][hh] = NULL;
        }
    }

    /* precalculate offsets, and offsets at the edge: */
    for(jj = 0; jj < rank; jj++) {
        double shift = 0.0, zoom = 0.0;
        if (shifts)
            shift = shifts[jj];
        if (zooms)
            zoom = zooms[jj];
        for(kk = 0; kk < odimensions[jj]; kk++) {
            double cc = (double)kk;
            if (shifts)
                cc += shift;
            if (zooms)
                cc *= zoom;
            cc = map_coordinate(cc, idimensions[jj], mode);
            if (cc > -1.0) {
                int start;
                if (zeros && zeros[jj])
                    zeros[jj][kk] = 0;
                if (order & 1) {
                    start = (int)floor(cc) - order / 2;
                } else {
                    start = (int)floor(cc + 0.5) - order / 2;
                }
                offsets[jj][kk] = istrides[jj] * start;
                if (start < 0 || start + order >= idimensions[jj]) {
                    edge_offsets[jj][kk] = (npy_intp*)malloc((order + 1) * sizeof(npy_intp));
                    if (!edge_offsets[jj][kk]) {
                        PyErr_NoMemory();
                        goto exit;
                    }
                    for(hh = 0; hh <= order; hh++) {
                        int idx = start + hh;
                         int len = idimensions[jj];
                        if (len <= 1) {
                            idx = 0;
                        } else {
                            int s2 = 2 * len - 2;
                            if (idx < 0) {
                                idx = s2 * (int)(-idx / s2) + idx;
                                idx = idx <= 1 - len ? idx + s2 : -idx;
                            } else if (idx >= len) {
                                idx -= s2 * (int)(idx / s2);
                                if (idx >= len)
                                    idx = s2 - idx;
                            }
                        }
                        edge_offsets[jj][kk][hh] = istrides[jj] * (idx - start);
                    }
                }
                if (order > 0) {
                    splvals[jj][kk] = (double*)malloc((order + 1) * sizeof(double));
                    if (!splvals[jj][kk]) {
                        PyErr_NoMemory();
                        goto exit;
                    }
                    spline_coefficients(cc, order, splvals[jj][kk]);
                }
            } else {
                zeros[jj][kk] = 1;
            }
        }
    }

    filter_size = 1;
    for(jj = 0; jj < rank; jj++)
        filter_size *= order + 1;
    idxs = (npy_intp*)malloc(filter_size * sizeof(idxs));
    if (!idxs) {
        PyErr_NoMemory();
        goto exit;
    }

    if (!NI_InitPointIterator(output, &io))
        goto exit;

    pi = (void *)PyArray_DATA(input);
    po = (void *)PyArray_DATA(output);

    /* store all coordinates and offsets with filter: */
    fcoordinates = (npy_intp*)malloc(rank * filter_size * sizeof(npy_intp));
    foffsets = (npy_intp*)malloc(filter_size * sizeof(npy_intp));
    if (!fcoordinates || !foffsets) {
        PyErr_NoMemory();
        goto exit;
    }

    for(jj = 0; jj < rank; jj++)
        ftmp[jj] = 0;
    kk = 0;
    for(hh = 0; hh < filter_size; hh++) {
        for(jj = 0; jj < rank; jj++)
            fcoordinates[jj + hh * rank] = ftmp[jj];
        foffsets[hh] = kk;
        for(jj = rank - 1; jj >= 0; jj--) {
            if (ftmp[jj] < order) {
                ftmp[jj]++;
                kk += istrides[jj];
                break;
            } else {
                ftmp[jj] = 0;
                kk -= istrides[jj] * order;
            }
        }
    }
    size = 1;
    for(qq = 0; qq < output->nd; qq++)
        size *= output->dimensions[qq];
    for(kk = 0; kk < size; kk++) {
        double t = 0.0;
        int edge = 0, oo = 0, zero = 0;

        for(hh = 0; hh < rank; hh++) {
            if (zeros && zeros[hh][io.coordinates[hh]]) {
                /* we use constant border condition */
                zero = 1;
                break;
            }
            oo += offsets[hh][io.coordinates[hh]];
            if (edge_offsets[hh][io.coordinates[hh]])
                edge = 1;
        }

        if (!zero) {
            npy_intp *ff = fcoordinates;
            for(hh = 0; hh < filter_size; hh++) {
                int idx = 0;
                if (edge) {
                        /* use precalculated edge offsets: */
                    for(jj = 0; jj < rank; jj++) {
                        if (edge_offsets[jj][io.coordinates[jj]])
                            idx += edge_offsets[jj][io.coordinates[jj]][ff[jj]];
                        else
                            idx += ff[jj] * istrides[jj];
                    }
                    idx += oo;
                } else {
                    /* use normal offsets: */
                    idx += oo + foffsets[hh];
                }
                idxs[hh] = idx;
                ff += rank;
            }
        }
        if (!zero) {
            npy_intp *ff = fcoordinates;
            t = 0.0;
            for(hh = 0; hh < filter_size; hh++) {
                double coeff = 0.0;
                switch(input->descr->type_num) {
                    CASE_INTERP_COEFF(coeff, pi, idxs[hh], Bool);
                    CASE_INTERP_COEFF(coeff, pi, idxs[hh], UInt8);
                    CASE_INTERP_COEFF(coeff, pi, idxs[hh], UInt16);
                    CASE_INTERP_COEFF(coeff, pi, idxs[hh], UInt32);
#if HAS_UINT64
                    CASE_INTERP_COEFF(coeff, pi, idxs[hh], UInt64);
#endif
                    CASE_INTERP_COEFF(coeff, pi, idxs[hh], Int8);
                    CASE_INTERP_COEFF(coeff, pi, idxs[hh], Int16);
                    CASE_INTERP_COEFF(coeff, pi, idxs[hh], Int32);
                    CASE_INTERP_COEFF(coeff, pi, idxs[hh], Int64);
                    CASE_INTERP_COEFF(coeff, pi, idxs[hh], Float32);
                    CASE_INTERP_COEFF(coeff, pi, idxs[hh], Float64);
                default:
                    PyErr_SetString(PyExc_RuntimeError,
                                                    "data type not supported");
                    goto exit;
                }
                /* calculate interpolated value: */
                for(jj = 0; jj < rank; jj++)
                    if (order > 0)
                        coeff *= splvals[jj][io.coordinates[jj]][ff[jj]];
                t += coeff;
                ff += rank;
            }
        } else {
            t = cval;
        }
        /* store output: */
        switch (output->descr->type_num) {
            CASE_INTERP_OUT(po, t, Bool);
            CASE_INTERP_OUT_UINT(po, t, UInt8, 0, MAX_UINT8);
            CASE_INTERP_OUT_UINT(po, t, UInt16, 0, MAX_UINT16);
            CASE_INTERP_OUT_UINT(po, t, UInt32, 0, MAX_UINT32);
#if HAS_UINT64
            /* FIXME */
            CASE_INTERP_OUT_UINT(po, t, UInt64, 0, MAX_UINT32);
#endif
            CASE_INTERP_OUT_INT(po, t, Int8, MIN_INT8, MAX_INT8);
            CASE_INTERP_OUT_INT(po, t, Int16, MIN_INT16, MAX_INT16);
            CASE_INTERP_OUT_INT(po, t, Int32, MIN_INT32, MAX_INT32);
            CASE_INTERP_OUT_INT(po, t, Int64, MIN_INT64, MAX_INT64);
            CASE_INTERP_OUT(po, t, Float32);
            CASE_INTERP_OUT(po, t, Float64);
        default:
            PyErr_SetString(PyExc_RuntimeError, "data type not supported");
            goto exit;
        }
        NI_ITERATOR_NEXT(io, po);
    }

 exit:
    if (zeros) {
        for(jj = 0; jj < rank; jj++)
            if (zeros[jj])
                free(zeros[jj]);
        free(zeros);
    }
    if (offsets) {
        for(jj = 0; jj < rank; jj++)
            if (offsets[jj])
                free(offsets[jj]);
        free(offsets);
    }
    if (splvals) {
        for(jj = 0; jj < rank; jj++) {
            if (splvals[jj]) {
                for(hh = 0; hh < odimensions[jj]; hh++)
                    if (splvals[jj][hh])
                        free(splvals[jj][hh]);
                free(splvals[jj]);
            }
        }
        free(splvals);
    }
    if (edge_offsets) {
        for(jj = 0; jj < rank; jj++) {
            if (edge_offsets[jj]) {
                for(hh = 0; hh < odimensions[jj]; hh++)
                    if (edge_offsets[jj][hh])
                        free(edge_offsets[jj][hh]);
                free(edge_offsets[jj]);
            }
        }
        free(edge_offsets);
    }
    if (foffsets)
        free(foffsets);
    if (fcoordinates)
        free(fcoordinates);
    if (idxs)
        free(idxs);
    return PyErr_Occurred() ? 0 : 1;
}
Example #10
0
int NI_Statistics(PyArrayObject *input, PyArrayObject *labels,
    npy_intp min_label, npy_intp max_label, npy_intp *indices,
    npy_intp n_results, double *sum, npy_intp *total, double *variance,
    double *minimum, double *maximum, npy_intp* min_pos, npy_intp* max_pos)
{
    char *pi = NULL, *pm = NULL;
    NI_Iterator ii, mi;
    npy_intp jj, size, idx = 0, label = 1, doit = 1;
    int qq;
    NPY_BEGIN_THREADS_DEF;

    /* input iterator: */
    if (!NI_InitPointIterator(input, &ii))
        return 0;
    /* input data: */
    pi = (void *)PyArray_DATA(input);
    if (labels) {
        if (!NI_InitPointIterator(labels, &mi))
            return 0;
        pm = (void *)PyArray_DATA(labels);
    }

    NPY_BEGIN_THREADS;

    /* input size: */
    size = 1;
    for(qq = 0; qq < input->nd; qq++)
        size *= input->dimensions[qq];
    for(jj = 0; jj < n_results; jj++) {
        if (sum)
            sum[jj] = 0.0;
        if (total)
            total[jj] = 0;
        if (variance)
            variance[jj] = 0;
        if (minimum)
            minimum[jj] = DBL_MAX;
        if (maximum)
            maximum[jj] = -DBL_MAX;
        if (min_pos)
            min_pos[jj] = 0;
        if (max_pos)
            max_pos[jj] = 0;
    }
    /* iterate over array: */
    for(jj = 0; jj < size; jj++) {
        NI_GET_LABEL(pm, label, NI_NormalizeType(labels->descr->type_num));
        if (min_label >= 0) {
            if (label >= min_label && label <= max_label) {
                idx = indices[label - min_label];
                doit = idx >= 0;
            } else {
                doit = 0;
            }
        } else {
            doit = label != 0;
        }
        if (doit) {
            double val;
            NI_GET_VALUE(pi, val, NI_NormalizeType(input->descr->type_num));
            if (sum)
                sum[idx] += val;
            if (total)
                total[idx]++;
            if (minimum && val < minimum[idx]) {
                minimum[idx] = val;
                if (min_pos)
                    min_pos[idx] = jj;
            }
            if (maximum && (val > maximum[idx])) {
                maximum[idx] = val;
                if (max_pos)
                    max_pos[idx] = jj;
            }
        }
        if (labels) {
            NI_ITERATOR_NEXT2(ii, mi, pi, pm);
        } else {
            NI_ITERATOR_NEXT(ii, pi);
        }
    }
    if (minimum) {
        for(jj = 0; jj < n_results; jj++) {
            if (!(minimum[jj] < DBL_MAX))
                minimum[jj] = 0.0;
        }
    }
    if (maximum) {
        for(jj = 0; jj < n_results; jj++) {
            if (!(maximum[jj] > -DBL_MAX))
                maximum[jj] = 0.0;
        }
    }
    if (variance) {
        int do_var = 0;
        for(jj = 0; jj < n_results; jj++)
            if (total[jj] > 1) {
                do_var = 1;
                break;
            }
        if (do_var) {
            /* reset input iterator: */
            NI_ITERATOR_RESET(ii);
            pi = (void *)PyArray_DATA(input);
            if (labels) {
                /* reset label iterator: */
                NI_ITERATOR_RESET(mi);
                pm = (void *)PyArray_DATA(labels);
            }
            for(jj = 0; jj < size; jj++) {
                NI_GET_LABEL(pm, label, NI_NormalizeType(labels->descr->type_num));
                if (min_label >= 0) {
                    if (label >= min_label && label <= max_label) {
                        idx = indices[label - min_label];
                        doit = idx >= 0;
                    } else {
                        doit = 0;
                    }
                } else {
                    doit = label != 0;
                }
                if (doit) {
                    double val;
                    NI_GET_VALUE(pi, val, NI_NormalizeType(input->descr->type_num));
                    val = val - sum[idx] / total[idx];
                    variance[idx] += val * val;
                }
                if (labels) {
                    NI_ITERATOR_NEXT2(ii, mi, pi, pm);
                } else {
                    NI_ITERATOR_NEXT(ii, pi);
                }
            }
            for(jj = 0; jj < n_results; jj++)
                variance[jj] = (total[jj] > 1 ?
                                                variance[jj] / (total[jj] - 1) : 0.0);
        }
    }
    NPY_END_THREADS;
    return 1;
}
Example #11
0
int NI_CenterOfMass(PyArrayObject *input, PyArrayObject *labels,
                    npy_intp min_label, npy_intp max_label, npy_intp *indices,
                    npy_intp n_results, double *center_of_mass)
{
    char *pi = NULL, *pm = NULL;
    NI_Iterator ii, mi;
    npy_intp jj, kk, size, idx = 0, label = 1, doit = 1;
    double *sum = NULL;
    int qq;
    NPY_BEGIN_THREADS_DEF;

    /* input iterator: */
    if (!NI_InitPointIterator(input, &ii))
        goto exit;
    /* input data: */
    pi = (void *)PyArray_DATA(input);
    if (labels) {
        if (!NI_InitPointIterator(labels, &mi))
            goto exit;
        pm = (void *)PyArray_DATA(labels);
    }
    /* input size: */
    size = 1;
    for(qq = 0; qq < input->nd; qq++)
        size *= input->dimensions[qq];
    sum = (double*)malloc(n_results * sizeof(double));
    if (!sum) {
        PyErr_NoMemory();
        goto exit;
    }

    NPY_BEGIN_THREADS;

    for(jj = 0; jj < n_results; jj++) {
        sum[jj] = 0.0;
        for(kk = 0; kk < input->nd; kk++)
            center_of_mass[jj * input->nd + kk] = 0.0;
    }
    /* iterate over array: */
    for(jj = 0; jj < size; jj++) {
        NI_GET_LABEL(pm, label, NI_NormalizeType(labels->descr->type_num));
        if (min_label >= 0) {
            if (label >= min_label && label <= max_label) {
                idx = indices[label - min_label];
                doit = idx >= 0;
            } else {
                doit = 0;
            }
        } else {
            doit = label != 0;
        }
        if (doit) {
            double val;
            NI_GET_VALUE(pi, val, NI_NormalizeType(input->descr->type_num));
            sum[idx] += val;
            for(kk = 0; kk < input->nd; kk++)
                center_of_mass[idx * input->nd + kk] += val * ii.coordinates[kk];
        }
        if (labels) {
            NI_ITERATOR_NEXT2(ii, mi, pi, pm);
        } else {
            NI_ITERATOR_NEXT(ii, pi);
        }
    }
    for(jj = 0; jj < n_results; jj++)
        for(kk = 0; kk < input->nd; kk++)
            center_of_mass[jj * input->nd + kk] /= sum[jj];
 exit:
    NPY_END_THREADS;
    free(sum);
    return  PyErr_Occurred() == NULL;
}
Example #12
0
int NI_MinOrMaxFilter(PyArrayObject* input, PyArrayObject* footprint,
                      PyArrayObject* structure, PyArrayObject* output,
                      NI_ExtendMode mode, double cvalue, npy_intp *origins,
                      int minimum)
{
    npy_bool *pf = NULL;
    npy_intp fsize, jj, kk, filter_size = 0, border_flag_value;
    npy_intp *offsets = NULL, *oo, size;
    NI_FilterIterator fi;
    NI_Iterator ii, io;
    char *pi, *po;
    int err = 0;
    double *ss = NULL;
    npy_double *ps;
    NPY_BEGIN_THREADS_DEF;

    /* get the the footprint: */
    fsize = PyArray_SIZE(footprint);
    pf = (npy_bool*)PyArray_DATA(footprint);
    for(jj = 0; jj < fsize; jj++) {
        if (pf[jj]) {
            ++filter_size;
        }
    }
    /* get the structure: */
    if (structure) {
        ss = malloc(filter_size * sizeof(double));
        if (!ss) {
            PyErr_NoMemory();
            goto exit;
        }
        /* copy the weights to contiguous memory: */
        ps = (npy_double*)PyArray_DATA(structure);
        jj = 0;
        for(kk = 0; kk < fsize; kk++)
            if (pf[kk])
                ss[jj++] = minimum ? -ps[kk] : ps[kk];
    }
    /* initialize filter offsets: */
    if (!NI_InitFilterOffsets(input, pf, PyArray_DIMS(footprint), origins,
                              mode, &offsets, &border_flag_value, NULL)) {
        goto exit;
    }
    /* initialize filter iterator: */
    if (!NI_InitFilterIterator(PyArray_NDIM(input), PyArray_DIMS(footprint),
                               filter_size, PyArray_DIMS(input), origins,
                               &fi)) {
        goto exit;
    }
    /* initialize input element iterator: */
    if (!NI_InitPointIterator(input, &ii))
        goto exit;
    /* initialize output element iterator: */
    if (!NI_InitPointIterator(output, &io))
        goto exit;

    NPY_BEGIN_THREADS;

    /* get data pointers an array size: */
    pi = (void *)PyArray_DATA(input);
    po = (void *)PyArray_DATA(output);
    size = PyArray_SIZE(input);
    /* iterator over the elements: */
    oo = offsets;
    for(jj = 0; jj < size; jj++) {
        double tmp = 0.0;
        switch (PyArray_TYPE(input)) {
            CASE_MIN_OR_MAX_POINT(NPY_BOOL, npy_bool,
                                  pi, oo, filter_size, cvalue, minimum, tmp,
                                  border_flag_value, ss);
            CASE_MIN_OR_MAX_POINT(NPY_UBYTE, npy_ubyte,
                                  pi, oo, filter_size, cvalue, minimum, tmp,
                                  border_flag_value, ss);
            CASE_MIN_OR_MAX_POINT(NPY_USHORT, npy_ushort,
                                  pi, oo, filter_size, cvalue, minimum, tmp,
                                  border_flag_value, ss);
            CASE_MIN_OR_MAX_POINT(NPY_UINT, npy_uint,
                                  pi, oo, filter_size, cvalue, minimum, tmp,
                                  border_flag_value, ss);
            CASE_MIN_OR_MAX_POINT(NPY_ULONG, npy_ulong,
                                  pi, oo, filter_size, cvalue, minimum, tmp,
                                  border_flag_value, ss);
            CASE_MIN_OR_MAX_POINT(NPY_ULONGLONG, npy_ulonglong,
                                  pi, oo, filter_size, cvalue, minimum, tmp,
                                  border_flag_value, ss);
            CASE_MIN_OR_MAX_POINT(NPY_BYTE, npy_byte,
                                  pi, oo, filter_size, cvalue, minimum, tmp,
                                  border_flag_value, ss);
            CASE_MIN_OR_MAX_POINT(NPY_SHORT, npy_short,
                                  pi, oo, filter_size, cvalue, minimum, tmp,
                                  border_flag_value, ss);
            CASE_MIN_OR_MAX_POINT(NPY_INT, npy_int,
                                  pi, oo, filter_size, cvalue, minimum, tmp,
                                  border_flag_value, ss);
            CASE_MIN_OR_MAX_POINT(NPY_LONG, npy_long,
                                  pi, oo, filter_size, cvalue, minimum, tmp,
                                  border_flag_value, ss);
            CASE_MIN_OR_MAX_POINT(NPY_LONGLONG, npy_longlong,
                                  pi, oo, filter_size, cvalue, minimum, tmp,
                                  border_flag_value, ss);
            CASE_MIN_OR_MAX_POINT(NPY_FLOAT, npy_float,
                                  pi, oo, filter_size, cvalue, minimum, tmp,
                                  border_flag_value, ss);
            CASE_MIN_OR_MAX_POINT(NPY_DOUBLE, npy_double,
                                  pi, oo, filter_size, cvalue, minimum, tmp,
                                  border_flag_value, ss);
            default:
                err = 1;
                goto exit;
        }
        switch (PyArray_TYPE(output)) {
            CASE_FILTER_OUT(NPY_BOOL, npy_bool, po, tmp);
            CASE_FILTER_OUT(NPY_UBYTE, npy_ubyte, po, tmp);
            CASE_FILTER_OUT(NPY_USHORT, npy_ushort, po, tmp);
            CASE_FILTER_OUT(NPY_UINT, npy_uint, po, tmp);
            CASE_FILTER_OUT(NPY_ULONG, npy_ulong, po, tmp);
            CASE_FILTER_OUT(NPY_ULONGLONG, npy_ulonglong, po, tmp);
            CASE_FILTER_OUT(NPY_BYTE, npy_byte, po, tmp);
            CASE_FILTER_OUT(NPY_SHORT, npy_short, po, tmp);
            CASE_FILTER_OUT(NPY_INT, npy_int, po, tmp);
            CASE_FILTER_OUT(NPY_LONG, npy_long, po, tmp);
            CASE_FILTER_OUT(NPY_LONGLONG, npy_longlong, po, tmp);
            CASE_FILTER_OUT(NPY_FLOAT, npy_float, po, tmp);
            CASE_FILTER_OUT(NPY_DOUBLE, npy_double, po, tmp);
            default:
                err = 1;
                goto exit;
        }
        NI_FILTER_NEXT2(fi, ii, io, oo, pi, po);
    }
exit:
    NPY_END_THREADS;
    if (err == 1) {
        PyErr_SetString(PyExc_RuntimeError, "array type not supported");
    }
    free(offsets);
    free(ss);
    return PyErr_Occurred() ? 0 : 1;
}
Example #13
0
int NI_GenericFilter(PyArrayObject* input,
            int (*function)(double*, npy_intp, double*, void*), void *data,
            PyArrayObject* footprint, PyArrayObject* output,
            NI_ExtendMode mode, double cvalue, npy_intp *origins)
{
    npy_bool *pf = NULL;
    npy_intp fsize, jj, filter_size = 0, border_flag_value;
    npy_intp *offsets = NULL, *oo, size;
    NI_FilterIterator fi;
    NI_Iterator ii, io;
    char *pi, *po;
    double *buffer = NULL;

    /* get the the footprint: */
    fsize = PyArray_SIZE(footprint);
    pf = (npy_bool*)PyArray_DATA(footprint);
    for(jj = 0; jj < fsize; jj++) {
        if (pf[jj])
            ++filter_size;
    }
    /* initialize filter offsets: */
    if (!NI_InitFilterOffsets(input, pf, PyArray_DIMS(footprint), origins,
                              mode, &offsets, &border_flag_value, NULL)) {
        goto exit;
    }
    /* initialize filter iterator: */
    if (!NI_InitFilterIterator(PyArray_NDIM(input), PyArray_DIMS(footprint),
                               filter_size, PyArray_DIMS(input), origins,
                               &fi)) {
        goto exit;
    }
    /* initialize input element iterator: */
    if (!NI_InitPointIterator(input, &ii))
        goto exit;
    /* initialize output element iterator: */
    if (!NI_InitPointIterator(output, &io))
        goto exit;
    /* get data pointers an array size: */
    pi = (void *)PyArray_DATA(input);
    po = (void *)PyArray_DATA(output);
    size = PyArray_SIZE(input);
    /* buffer for filter calculation: */
    buffer = malloc(filter_size * sizeof(double));
    if (!buffer) {
        PyErr_NoMemory();
        goto exit;
    }
    /* iterate over the elements: */
    oo = offsets;
    for(jj = 0; jj < size; jj++) {
        double tmp = 0.0;
        switch (PyArray_TYPE(input)) {
            CASE_FILTER_POINT(NPY_BOOL, npy_bool,
                              pi, oo, filter_size, cvalue, tmp,
                              border_flag_value, function, data, buffer);
            CASE_FILTER_POINT(NPY_UBYTE, npy_ubyte,
                              pi, oo, filter_size, cvalue, tmp,
                              border_flag_value, function, data, buffer);
            CASE_FILTER_POINT(NPY_USHORT, npy_ushort,
                              pi, oo, filter_size, cvalue, tmp,
                              border_flag_value, function, data, buffer);
            CASE_FILTER_POINT(NPY_UINT, npy_uint,
                              pi, oo, filter_size, cvalue, tmp,
                              border_flag_value, function, data, buffer);
            CASE_FILTER_POINT(NPY_ULONG, npy_ulong,
                              pi, oo, filter_size, cvalue, tmp,
                              border_flag_value, function, data, buffer);
            CASE_FILTER_POINT(NPY_ULONGLONG, npy_ulonglong,
                              pi, oo, filter_size, cvalue, tmp,
                              border_flag_value, function, data, buffer);
            CASE_FILTER_POINT(NPY_BYTE, npy_byte,
                              pi, oo, filter_size, cvalue, tmp,
                              border_flag_value, function, data, buffer);
            CASE_FILTER_POINT(NPY_SHORT, npy_short,
                              pi, oo, filter_size, cvalue, tmp,
                              border_flag_value, function, data, buffer);
            CASE_FILTER_POINT(NPY_INT, npy_int,
                              pi, oo, filter_size, cvalue, tmp,
                              border_flag_value, function, data, buffer);
            CASE_FILTER_POINT(NPY_LONG, npy_long,
                              pi, oo, filter_size, cvalue, tmp,
                              border_flag_value, function, data, buffer);
            CASE_FILTER_POINT(NPY_LONGLONG, npy_longlong,
                              pi, oo, filter_size, cvalue, tmp,
                              border_flag_value, function, data, buffer);
            CASE_FILTER_POINT(NPY_FLOAT, npy_float,
                              pi, oo, filter_size, cvalue, tmp,
                              border_flag_value, function, data, buffer);
            CASE_FILTER_POINT(NPY_DOUBLE, npy_double,
                              pi, oo, filter_size, cvalue, tmp,
                              border_flag_value, function, data, buffer);
            default:
                PyErr_SetString(PyExc_RuntimeError,
                                "array type not supported");
                goto exit;
        }
        switch (PyArray_TYPE(output)) {
            CASE_FILTER_OUT(NPY_BOOL, npy_bool, po, tmp);
            CASE_FILTER_OUT(NPY_UBYTE, npy_ubyte, po, tmp);
            CASE_FILTER_OUT(NPY_USHORT, npy_ushort, po, tmp);
            CASE_FILTER_OUT(NPY_UINT, npy_uint, po, tmp);
            CASE_FILTER_OUT(NPY_ULONG, npy_ulong, po, tmp);
            CASE_FILTER_OUT(NPY_ULONGLONG, npy_ulonglong, po, tmp);
            CASE_FILTER_OUT(NPY_BYTE, npy_byte, po, tmp);
            CASE_FILTER_OUT(NPY_SHORT, npy_short, po, tmp);
            CASE_FILTER_OUT(NPY_INT, npy_int, po, tmp);
            CASE_FILTER_OUT(NPY_LONG, npy_long, po, tmp);
            CASE_FILTER_OUT(NPY_LONGLONG, npy_longlong, po, tmp);
            CASE_FILTER_OUT(NPY_FLOAT, npy_float, po, tmp);
            CASE_FILTER_OUT(NPY_DOUBLE, npy_double, po, tmp);
            default:
                PyErr_SetString(PyExc_RuntimeError,
                                "array type not supported");
                goto exit;
        }
        NI_FILTER_NEXT2(fi, ii, io, oo, pi, po);
    }
exit:
    free(offsets);
    free(buffer);
    return PyErr_Occurred() ? 0 : 1;
}
Example #14
0
int NI_Correlate(PyArrayObject* input, PyArrayObject* weights,
                 PyArrayObject* output, NI_ExtendMode mode,
                 double cvalue, npy_intp *origins)
{
    npy_bool *pf = NULL;
    npy_intp fsize, jj, kk, filter_size = 0, border_flag_value;
    npy_intp *offsets = NULL, *oo, size;
    NI_FilterIterator fi;
    NI_Iterator ii, io;
    char *pi, *po;
    npy_double *pw;
    npy_double *ww = NULL;
    int err = 0;
    NPY_BEGIN_THREADS_DEF;

    /* get the the footprint: */
    fsize = PyArray_SIZE(weights);
    pw = (npy_double*)PyArray_DATA(weights);
    pf = malloc(fsize * sizeof(npy_bool));
    if (!pf) {
        PyErr_NoMemory();
        goto exit;
    }
    for(jj = 0; jj < fsize; jj++) {
        if (fabs(pw[jj]) > DBL_EPSILON) {
            pf[jj] = 1;
            ++filter_size;
        } else {
            pf[jj] = 0;
        }
    }
    /* copy the weights to contiguous memory: */
    ww = malloc(filter_size * sizeof(npy_double));
    if (!ww) {
        PyErr_NoMemory();
        goto exit;
    }
    jj = 0;
    for(kk = 0; kk < fsize; kk++) {
        if (pf[kk]) {
            ww[jj++] = pw[kk];
        }
    }
    /* initialize filter offsets: */
    if (!NI_InitFilterOffsets(input, pf, PyArray_DIMS(weights), origins,
                              mode, &offsets, &border_flag_value, NULL)) {
        goto exit;
    }
    /* initialize filter iterator: */
    if (!NI_InitFilterIterator(PyArray_NDIM(input), PyArray_DIMS(weights),
                               filter_size, PyArray_DIMS(input), origins,
                               &fi)) {
        goto exit;
    }
    /* initialize input element iterator: */
    if (!NI_InitPointIterator(input, &ii))
        goto exit;
    /* initialize output element iterator: */
    if (!NI_InitPointIterator(output, &io))
        goto exit;

    NPY_BEGIN_THREADS;
    /* get data pointers an array size: */
    pi = (void *)PyArray_DATA(input);
    po = (void *)PyArray_DATA(output);
    size = PyArray_SIZE(input);
    /* iterator over the elements: */
    oo = offsets;
    for(jj = 0; jj < size; jj++) {
        double tmp = 0.0;
        switch (PyArray_TYPE(input)) {
            CASE_CORRELATE_POINT(NPY_BOOL, npy_bool,
                                 pi, ww, oo, filter_size, cvalue, tmp,
                                 border_flag_value);
            CASE_CORRELATE_POINT(NPY_UBYTE, npy_ubyte,
                                 pi, ww, oo, filter_size, cvalue, tmp,
                                 border_flag_value);
            CASE_CORRELATE_POINT(NPY_USHORT, npy_ushort,
                                 pi, ww, oo, filter_size, cvalue, tmp,
                                 border_flag_value);
            CASE_CORRELATE_POINT(NPY_UINT, npy_uint,
                                 pi, ww, oo, filter_size, cvalue, tmp,
                                 border_flag_value);
            CASE_CORRELATE_POINT(NPY_ULONG, npy_ulong,
                                 pi, ww, oo, filter_size, cvalue, tmp,
                                 border_flag_value);
            CASE_CORRELATE_POINT(NPY_ULONGLONG, npy_ulonglong,
                                 pi, ww, oo, filter_size, cvalue, tmp,
                                 border_flag_value);
            CASE_CORRELATE_POINT(NPY_BYTE, npy_byte,
                                 pi, ww, oo, filter_size, cvalue, tmp,
                                 border_flag_value);
            CASE_CORRELATE_POINT(NPY_SHORT, npy_short,
                                 pi, ww, oo, filter_size, cvalue, tmp,
                                 border_flag_value);
            CASE_CORRELATE_POINT(NPY_INT, npy_int,
                                 pi, ww, oo, filter_size, cvalue, tmp,
                                 border_flag_value);
            CASE_CORRELATE_POINT(NPY_LONG, npy_long,
                                 pi, ww, oo, filter_size, cvalue, tmp,
                                 border_flag_value);
            CASE_CORRELATE_POINT(NPY_LONGLONG, npy_longlong,
                                 pi, ww, oo, filter_size, cvalue, tmp,
                                 border_flag_value);
            CASE_CORRELATE_POINT(NPY_FLOAT, npy_float,
                                 pi, ww, oo, filter_size, cvalue, tmp,
                                 border_flag_value);
            CASE_CORRELATE_POINT(NPY_DOUBLE, npy_double,
                                 pi, ww, oo, filter_size, cvalue, tmp,
                                 border_flag_value);
            default:
                err = 1;
                goto exit;
        }
        switch (PyArray_TYPE(output)) {
            CASE_FILTER_OUT(NPY_BOOL, npy_bool, po, tmp);
            CASE_FILTER_OUT(NPY_UBYTE, npy_ubyte, po, tmp);
            CASE_FILTER_OUT(NPY_USHORT, npy_ushort, po, tmp);
            CASE_FILTER_OUT(NPY_UINT, npy_uint, po, tmp);
            CASE_FILTER_OUT(NPY_ULONG, npy_ulong, po, tmp);
            CASE_FILTER_OUT(NPY_ULONGLONG, npy_ulonglong, po, tmp);
            CASE_FILTER_OUT(NPY_BYTE, npy_byte, po, tmp);
            CASE_FILTER_OUT(NPY_SHORT, npy_short, po, tmp);
            CASE_FILTER_OUT(NPY_INT, npy_int, po, tmp);
            CASE_FILTER_OUT(NPY_LONG, npy_long, po, tmp);
            CASE_FILTER_OUT(NPY_LONGLONG, npy_longlong, po, tmp);
            CASE_FILTER_OUT(NPY_FLOAT, npy_float, po, tmp);
            CASE_FILTER_OUT(NPY_DOUBLE, npy_double, po, tmp);
            default:
                err = 1;
                goto exit;
        }
        NI_FILTER_NEXT2(fi, ii, io, oo, pi, po);
    }
exit:
    NPY_END_THREADS;
    if (err == 1) {
        PyErr_SetString(PyExc_RuntimeError, "array type not supported");
    }
    free(offsets);
    free(ww);
    free(pf);
    return PyErr_Occurred() ? 0 : 1;
}
Example #15
0
int NI_FindObjects(PyArrayObject* input, npy_intp max_label,
                                     npy_intp* regions)
{
    npy_intp size, jj;
    NI_Iterator ii;
    char *pi;
    NPY_BEGIN_THREADS_DEF;

    NPY_BEGIN_THREADS;

    /* get input data, size and iterator: */
    pi = (void *)PyArray_DATA(input);
    size = PyArray_SIZE(input);
    if (!NI_InitPointIterator(input, &ii))
        goto exit;
    if (PyArray_NDIM(input) > 0) {
        for (jj = 0; jj < 2 * PyArray_NDIM(input) * max_label; jj++) {
            regions[jj] = -1;
        }
    } else {
        for(jj = 0; jj < max_label; jj++)
            regions[jj] = -1;
    }
    /* iterate over all points: */
    for(jj = 0 ; jj < size; jj++) {
        switch (PyArray_TYPE(input)) {
            CASE_FIND_OBJECT_POINT(NPY_BOOL, npy_bool,
                                   pi, regions, input, max_label, ii);
            CASE_FIND_OBJECT_POINT(NPY_UBYTE, npy_ubyte,
                                   pi, regions, input, max_label, ii);
            CASE_FIND_OBJECT_POINT(NPY_USHORT, npy_ushort,
                                   pi, regions, input, max_label, ii);
            CASE_FIND_OBJECT_POINT(NPY_UINT, npy_uint,
                                   pi, regions, input, max_label, ii);
            CASE_FIND_OBJECT_POINT(NPY_ULONG, npy_ulong,
                                   pi, regions, input, max_label, ii);
            CASE_FIND_OBJECT_POINT(NPY_ULONGLONG, npy_ulonglong,
                                   pi, regions, input, max_label, ii);
            CASE_FIND_OBJECT_POINT(NPY_BYTE, npy_byte,
                                   pi, regions, input, max_label, ii);
            CASE_FIND_OBJECT_POINT(NPY_SHORT, npy_short,
                                   pi, regions, input, max_label, ii);
            CASE_FIND_OBJECT_POINT(NPY_INT, npy_int,
                                   pi, regions, input, max_label, ii);
            CASE_FIND_OBJECT_POINT(NPY_LONG, npy_long,
                                   pi, regions, input, max_label, ii);
            CASE_FIND_OBJECT_POINT(NPY_LONGLONG, npy_longlong,
                                   pi, regions, input, max_label, ii);
            CASE_FIND_OBJECT_POINT(NPY_FLOAT, npy_float,
                                   pi, regions, input, max_label, ii);
            CASE_FIND_OBJECT_POINT(NPY_DOUBLE, npy_double,
                                   pi, regions, input, max_label, ii);
        default:
            NPY_END_THREADS;
            PyErr_SetString(PyExc_RuntimeError, "data type not supported");
            goto exit;
        }
        NI_ITERATOR_NEXT(ii, pi);
    }
 exit:
    NPY_END_THREADS;
    return PyErr_Occurred() ? 0 : 1;
}
Example #16
0
int NI_WatershedIFT(PyArrayObject* input, PyArrayObject* markers,
                                        PyArrayObject* strct, PyArrayObject* output)
{
    char *pl, *pm, *pi;
    int ll;
    npy_intp size, jj, hh, kk, maxval;
    npy_intp strides[WS_MAXDIM], coordinates[WS_MAXDIM];
    npy_intp *nstrides = NULL, nneigh, ssize;
    int i_contiguous, o_contiguous;
    NI_WatershedElement *temp = NULL, **first = NULL, **last = NULL;
    npy_bool *ps = NULL;
    NI_Iterator mi, ii, li;
    NPY_BEGIN_THREADS_DEF;

    i_contiguous = PyArray_ISCONTIGUOUS(input);
    o_contiguous = PyArray_ISCONTIGUOUS(output);
    ssize = PyArray_SIZE(strct);
    if (PyArray_NDIM(input) > WS_MAXDIM) {
        PyErr_SetString(PyExc_RuntimeError, "too many dimensions");
        goto exit;
    }
    size = PyArray_SIZE(input);
    /* Storage for the temporary queue data. */
    temp = malloc(size * sizeof(NI_WatershedElement));
    if (!temp) {
        PyErr_NoMemory();
        goto exit;
    }

    NPY_BEGIN_THREADS;

    pi = (void *)PyArray_DATA(input);
    if (!NI_InitPointIterator(input, &ii))
        goto exit;
    /* Initialization and find the maximum of the input. */
    maxval = 0;
    for(jj = 0; jj < size; jj++) {
        npy_intp ival = 0;
        switch (PyArray_TYPE(input)) {
            CASE_GET_INPUT(NPY_UINT8, npy_uint8, ival, pi);
            CASE_GET_INPUT(NPY_UINT16, npy_uint16, ival, pi);
        default:
            NPY_END_THREADS;
            PyErr_SetString(PyExc_RuntimeError, "data type not supported");
            goto exit;
        }
        temp[jj].index = jj;
        temp[jj].done = 0;
        if (ival > maxval)
            maxval = ival;
        NI_ITERATOR_NEXT(ii, pi);
    }
    pi = (void *)PyArray_DATA(input);
    /* Allocate and initialize the storage for the queue. */
    first = malloc((maxval + 1) * sizeof(NI_WatershedElement*));
    last = malloc((maxval + 1) * sizeof(NI_WatershedElement*));
    if (NPY_UNLIKELY(!first || !last)) {
        NPY_END_THREADS;
        PyErr_NoMemory();
        goto exit;
    }
    for(hh = 0; hh <= maxval; hh++) {
        first[hh] = NULL;
        last[hh] = NULL;
    }
    if (!NI_InitPointIterator(markers, &mi))
        goto exit;
    if (!NI_InitPointIterator(output, &li))
        goto exit;
    pm = (void *)PyArray_DATA(markers);
    pl = (void *)PyArray_DATA(output);
    /* initialize all nodes */
    for (ll = 0; ll < PyArray_NDIM(input); ll++) {
        coordinates[ll] = 0;
    }
    for(jj = 0; jj < size; jj++) {
        /* get marker */
        int label = 0;
        switch (PyArray_TYPE(markers)) {
            CASE_GET_LABEL(NPY_UBYTE, npy_ubyte, label, pm);
            CASE_GET_LABEL(NPY_USHORT, npy_ushort, label, pm);
            CASE_GET_LABEL(NPY_UINT, npy_uint, label, pm);
            CASE_GET_LABEL(NPY_ULONG, npy_ulong, label, pm);
            CASE_GET_LABEL(NPY_ULONGLONG, npy_ulonglong, label, pm);
            CASE_GET_LABEL(NPY_BYTE, npy_byte, label, pm);
            CASE_GET_LABEL(NPY_SHORT, npy_short, label, pm);
            CASE_GET_LABEL(NPY_INT, npy_int, label, pm);
            CASE_GET_LABEL(NPY_LONG, npy_long, label, pm);
            CASE_GET_LABEL(NPY_LONGLONG, npy_longlong, label, pm);
        default:
            NPY_END_THREADS;
            PyErr_SetString(PyExc_RuntimeError, "data type not supported");
            goto exit;
        }
        switch (PyArray_TYPE(output)) {
            CASE_PUT_LABEL(NPY_UBYTE, npy_ubyte, label, pl);
            CASE_PUT_LABEL(NPY_USHORT, npy_ushort, label, pl);
            CASE_PUT_LABEL(NPY_UINT, npy_uint, label, pl);
            CASE_PUT_LABEL(NPY_ULONG, npy_ulong, label, pl);
            CASE_PUT_LABEL(NPY_ULONGLONG, npy_ulonglong, label, pl);
            CASE_PUT_LABEL(NPY_BYTE, npy_byte, label, pl);
            CASE_PUT_LABEL(NPY_SHORT, npy_short, label, pl);
            CASE_PUT_LABEL(NPY_INT, npy_int, label, pl);
            CASE_PUT_LABEL(NPY_LONG, npy_long, label, pl);
            CASE_PUT_LABEL(NPY_LONGLONG, npy_longlong, label, pl);
        default:
            NPY_END_THREADS;
            PyErr_SetString(PyExc_RuntimeError, "data type not supported");
            goto exit;
        }
        NI_ITERATOR_NEXT2(mi, li, pm, pl);
        if (label != 0) {
            /* This node is a marker */
            temp[jj].cost = 0;
            if (!first[0]) {
                first[0] = &(temp[jj]);
                first[0]->next = NULL;
                first[0]->prev = NULL;
                last[0] = first[0];
            } else {
                if (label > 0) {
                    /* object markers are enqueued at the beginning, so they
                       are processed first. */
                    temp[jj].next = first[0];
                    temp[jj].prev = NULL;
                    first[0]->prev = &(temp[jj]);
                    first[0] = &(temp[jj]);
                } else {
                    /* background markers are enqueued at the end, so they are
                         processed after the object markers. */
                    temp[jj].next = NULL;
                    temp[jj].prev = last[0];
                    last[0]->next = &(temp[jj]);
                    last[0] = &(temp[jj]);
                }
            }
        } else {
            /* This node is not a marker */
            temp[jj].cost = maxval + 1;
            temp[jj].next = NULL;
            temp[jj].prev = NULL;
        }
        for (ll = PyArray_NDIM(input) - 1; ll >= 0; ll--) {
            if (coordinates[ll] < PyArray_DIMS(input)[ll] - 1) {
                coordinates[ll]++;
                break;
            } else {
                coordinates[ll] = 0;
            }
        }
    }

    pl = (void *)PyArray_DATA(output);
    ps = (npy_bool*)PyArray_DATA(strct);
    nneigh = 0;
    for (kk = 0; kk < ssize; kk++)
        if (ps[kk] && kk != (ssize / 2))
            ++nneigh;
    nstrides = malloc(nneigh * sizeof(npy_intp));
    if (NPY_UNLIKELY(!nstrides)) {
        NPY_END_THREADS;
        PyErr_NoMemory();
        goto exit;
    }
    strides[PyArray_NDIM(input) - 1] = 1;
    for (ll = PyArray_NDIM(input) - 2; ll >= 0; ll--) {
        strides[ll] = PyArray_DIM(input, ll + 1) * strides[ll + 1];
    }
    for (ll = 0; ll < PyArray_NDIM(input); ll++) {
        coordinates[ll] = -1;
    }
    for(kk = 0; kk < nneigh; kk++)
        nstrides[kk] = 0;
    jj = 0;
    for(kk = 0; kk < ssize; kk++) {
        if (ps[kk]) {
            int offset = 0;
            for (ll = 0; ll < PyArray_NDIM(input); ll++) {
                offset += coordinates[ll] * strides[ll];
            }
            if (offset != 0)
                nstrides[jj++] += offset;
        }
        for (ll = PyArray_NDIM(input) - 1; ll >= 0; ll--) {
            if (coordinates[ll] < 1) {
                coordinates[ll]++;
                break;
            } else {
                coordinates[ll] = -1;
            }
        }
    }
    /* Propagation phase: */
    for(jj = 0; jj <= maxval; jj++) {
        while (first[jj]) {
            /* dequeue first element: */
            NI_WatershedElement *v = first[jj];
            first[jj] = first[jj]->next;
            if (first[jj])
                first[jj]->prev = NULL;
            v->prev = NULL;
            v->next = NULL;
            /* Mark element as done: */
            v->done = 1;
            /* Iterate over the neighbors of the element: */
            for(hh = 0; hh < nneigh; hh++) {
                npy_intp v_index = v->index, p_index = v->index, idx, cc;
                int qq, outside = 0;
                p_index += nstrides[hh];
                /* check if the neighbor is within the extent of the array: */
                idx = p_index;
                for (qq = 0; qq < PyArray_NDIM(input); qq++) {
                    cc = idx / strides[qq];
                    if (cc < 0 || cc >= PyArray_DIM(input, qq)) {
                        outside = 1;
                        break;
                    }
                    idx -= cc * strides[qq];
                }
                if (!outside) {
                    NI_WatershedElement *p = &(temp[p_index]);
                    if (!(p->done)) {
                        /* If the neighbor was not processed yet: */
                        int max, pval, vval, wvp, pcost, label, p_idx, v_idx;
                        switch (PyArray_TYPE(input)) {
                            CASE_WINDEX1(NPY_UBYTE, npy_ubyte,
                                v_index, p_index, strides,
                                PyArray_STRIDES(input), PyArray_NDIM(input),
                                i_contiguous, p_idx, v_idx, pi, vval, pval);
                            CASE_WINDEX1(NPY_USHORT, npy_ushort,
                                v_index, p_index, strides,
                                PyArray_STRIDES(input), PyArray_NDIM(input),
                                i_contiguous, p_idx, v_idx, pi, vval, pval);
                        default:
                            NPY_END_THREADS;
                            PyErr_SetString(PyExc_RuntimeError,
                                            "data type not supported");
                            goto exit;
                        }
                        /* Calculate cost: */
                        wvp = pval - vval;
                        if (wvp < 0)
                            wvp = -wvp;
                        /* Find the maximum of this cost and the current
                             element cost: */
                        pcost = p->cost;
                        max = v->cost > wvp ? v->cost : wvp;
                        if (max < pcost) {
                            /* If this maximum is less than the neighbors cost,
                                 adapt the cost and the label of the neighbor: */
                            int idx;
                            p->cost = max;
                            switch (PyArray_TYPE(output)) {
                                CASE_WINDEX2(NPY_UBYTE, npy_ubyte,
                                             v_index, strides,
                                             PyArray_STRIDES(output),
                                             PyArray_NDIM(input),
                                             idx, o_contiguous, label, pl);
                                CASE_WINDEX2(NPY_USHORT, npy_ushort,
                                             v_index, strides,
                                             PyArray_STRIDES(output),
                                             PyArray_NDIM(input),
                                             idx, o_contiguous, label, pl);
                                CASE_WINDEX2(NPY_UINT, npy_uint,
                                             v_index, strides,
                                             PyArray_STRIDES(output),
                                             PyArray_NDIM(input),
                                             idx, o_contiguous, label, pl);
                                CASE_WINDEX2(NPY_ULONG, npy_ulong,
                                             v_index, strides,
                                             PyArray_STRIDES(output),
                                             PyArray_NDIM(input),
                                             idx, o_contiguous, label, pl);
                                CASE_WINDEX2(NPY_ULONGLONG, npy_ulonglong,
                                             v_index, strides,
                                             PyArray_STRIDES(output),
                                             PyArray_NDIM(input),
                                             idx, o_contiguous, label, pl);
                                CASE_WINDEX2(NPY_BYTE, npy_byte,
                                             v_index, strides,
                                             PyArray_STRIDES(output),
                                             PyArray_NDIM(input),
                                             idx, o_contiguous, label, pl);
                                CASE_WINDEX2(NPY_SHORT, npy_short,
                                             v_index, strides,
                                             PyArray_STRIDES(output),
                                             PyArray_NDIM(input),
                                             idx, o_contiguous, label, pl);
                                CASE_WINDEX2(NPY_INT, npy_int,
                                             v_index, strides,
                                             PyArray_STRIDES(output),
                                             PyArray_NDIM(input),
                                             idx, o_contiguous, label, pl);
                                CASE_WINDEX2(NPY_LONG, npy_long,
                                             v_index, strides,
                                             PyArray_STRIDES(output),
                                             PyArray_NDIM(input),
                                             idx, o_contiguous, label, pl);
                                CASE_WINDEX2(NPY_LONGLONG, npy_longlong,
                                             v_index, strides,
                                             PyArray_STRIDES(output),
                                             PyArray_NDIM(input),
                                             idx, o_contiguous, label, pl);
                            default:
                                NPY_END_THREADS;
                                PyErr_SetString(PyExc_RuntimeError,
                                                "data type not supported");
                                goto exit;
                            }
                            switch (PyArray_TYPE(output)) {
                                CASE_WINDEX3(NPY_UBYTE, npy_ubyte,
                                             p_index, strides,
                                             PyArray_STRIDES(output),
                                             PyArray_NDIM(input),
                                             idx, o_contiguous, label, pl);
                                CASE_WINDEX3(NPY_USHORT, npy_ushort,
                                             p_index, strides,
                                             PyArray_STRIDES(output),
                                             PyArray_NDIM(input),
                                             idx, o_contiguous, label, pl);
                                CASE_WINDEX3(NPY_UINT, npy_uint,
                                             p_index, strides,
                                             PyArray_STRIDES(output),
                                             PyArray_NDIM(input),
                                             idx, o_contiguous, label, pl);
                                CASE_WINDEX3(NPY_ULONG, npy_ulong,
                                             p_index, strides,
                                             PyArray_STRIDES(output),
                                             PyArray_NDIM(input),
                                             idx, o_contiguous, label, pl);
                                CASE_WINDEX3(NPY_ULONGLONG, npy_ulonglong,
                                             p_index, strides,
                                             PyArray_STRIDES(output),
                                             PyArray_NDIM(input),
                                             idx, o_contiguous, label, pl);
                                CASE_WINDEX3(NPY_BYTE, npy_byte,
                                             p_index, strides,
                                             PyArray_STRIDES(output),
                                             PyArray_NDIM(input),
                                             idx, o_contiguous, label, pl);
                                CASE_WINDEX3(NPY_SHORT, npy_short,
                                             p_index, strides,
                                             PyArray_STRIDES(output),
                                             PyArray_NDIM(input),
                                             idx, o_contiguous, label, pl);
                                CASE_WINDEX3(NPY_INT, npy_int,
                                             p_index, strides,
                                             PyArray_STRIDES(output),
                                             PyArray_NDIM(input),
                                             idx, o_contiguous, label, pl);
                                CASE_WINDEX3(NPY_LONG, npy_long,
                                             p_index, strides,
                                             PyArray_STRIDES(output),
                                             PyArray_NDIM(input),
                                             idx, o_contiguous, label, pl);
                                CASE_WINDEX3(NPY_LONGLONG, npy_longlong,
                                             p_index, strides,
                                             PyArray_STRIDES(output),
                                             PyArray_NDIM(input),
                                             idx, o_contiguous, label, pl);
                            default:
                                NPY_END_THREADS;
                                PyErr_SetString(PyExc_RuntimeError,
                                                "data type not supported");
                                goto exit;
                            }
                            /* If the neighbor is in a queue, remove it: */
                            if (p->next || p->prev) {
                                NI_WatershedElement *prev = p->prev, *next = p->next;
                                if (first[pcost] == p)
                                    first[pcost] = next;
                                if (last[pcost] == p)
                                    last[pcost] = prev;
                                if (prev)
                                    prev->next = next;
                                if (next)
                                    next->prev = prev;
                            }
                            /* Insert the neighbor in the appropriate queue: */
                            if (label < 0) {
                                p->prev = last[max];
                                p->next = NULL;
                                if (last[max])
                                    last[max]->next = p;
                                last[max] = p;
                                if (!first[max])
                                    first[max] = p;
                            } else {
                                p->next = first[max];
                                p->prev = NULL;
                                if (first[max])
                                    first[max]->prev = p;
                                first[max] = p;
                                if (!last[max])
                                    last[max] = p;
                            }
                        }
                    }
                }
            }
        }
    }
 exit:
    NPY_END_THREADS;
    free(temp);
    free(first);
    free(last);
    free(nstrides);
    return PyErr_Occurred() ? 0 : 1;
}
Example #17
0
int NI_ZoomShift(PyArrayObject *input, PyArrayObject* zoom_ar,
                                 PyArrayObject* shift_ar, PyArrayObject *output,
                                 int order, int mode, double cval)
{
    char *po, *pi;
    npy_intp **zeros = NULL, **offsets = NULL, ***edge_offsets = NULL;
    npy_intp ftmp[NPY_MAXDIMS], *fcoordinates = NULL, *foffsets = NULL;
    npy_intp jj, hh, kk, filter_size, odimensions[NPY_MAXDIMS];
    npy_intp idimensions[NPY_MAXDIMS], istrides[NPY_MAXDIMS];
    npy_intp size;
    double ***splvals = NULL;
    NI_Iterator io;
    npy_double *zooms = zoom_ar ? (npy_double*)PyArray_DATA(zoom_ar) : NULL;
    npy_double *shifts = shift_ar ? (npy_double*)PyArray_DATA(shift_ar) : NULL;
    int rank = 0;
    NPY_BEGIN_THREADS_DEF;

    NPY_BEGIN_THREADS;

    for (kk = 0; kk < PyArray_NDIM(input); kk++) {
        idimensions[kk] = PyArray_DIM(input, kk);
        istrides[kk] = PyArray_STRIDE(input, kk);
        odimensions[kk] = PyArray_DIM(output, kk);
    }
    rank = PyArray_NDIM(input);

    /* if the mode is 'constant' we need some temps later: */
    if (mode == NI_EXTEND_CONSTANT) {
        zeros = malloc(rank * sizeof(npy_intp*));
        if (NPY_UNLIKELY(!zeros)) {
            NPY_END_THREADS;
            PyErr_NoMemory();
            goto exit;
        }
        for(jj = 0; jj < rank; jj++)
            zeros[jj] = NULL;
        for(jj = 0; jj < rank; jj++) {
            zeros[jj] = malloc(odimensions[jj] * sizeof(npy_intp));
            if (NPY_UNLIKELY(!zeros[jj])) {
                NPY_END_THREADS;
                PyErr_NoMemory();
                goto exit;
            }
        }
    }

    /* store offsets, along each axis: */
    offsets = malloc(rank * sizeof(npy_intp*));
    /* store spline coefficients, along each axis: */
    splvals = malloc(rank * sizeof(double**));
    /* store offsets at all edges: */
    edge_offsets = malloc(rank * sizeof(npy_intp**));
    if (NPY_UNLIKELY(!offsets || !splvals || !edge_offsets)) {
        NPY_END_THREADS;
        PyErr_NoMemory();
        goto exit;
    }
    for(jj = 0; jj < rank; jj++) {
        offsets[jj] = NULL;
        splvals[jj] = NULL;
        edge_offsets[jj] = NULL;
    }
    for(jj = 0; jj < rank; jj++) {
        offsets[jj] = malloc(odimensions[jj] * sizeof(npy_intp));
        splvals[jj] = malloc(odimensions[jj] * sizeof(double*));
        edge_offsets[jj] = malloc(odimensions[jj] * sizeof(npy_intp*));
        if (NPY_UNLIKELY(!offsets[jj] || !splvals[jj] || !edge_offsets[jj])) {
            NPY_END_THREADS;
            PyErr_NoMemory();
            goto exit;
        }
        for(hh = 0; hh < odimensions[jj]; hh++) {
            splvals[jj][hh] = NULL;
            edge_offsets[jj][hh] = NULL;
        }
    }

    /* precalculate offsets, and offsets at the edge: */
    for(jj = 0; jj < rank; jj++) {
        double shift = 0.0, zoom = 0.0;
        if (shifts)
            shift = shifts[jj];
        if (zooms)
            zoom = zooms[jj];
        for(kk = 0; kk < odimensions[jj]; kk++) {
            double cc = (double)kk;
            if (shifts)
                cc += shift;
            if (zooms)
                cc *= zoom;
            cc = map_coordinate(cc, idimensions[jj], mode);
            if (cc > -1.0) {
                npy_intp start;
                if (zeros && zeros[jj])
                    zeros[jj][kk] = 0;
                if (order & 1) {
                    start = (npy_intp)floor(cc) - order / 2;
                } else {
                    start = (npy_intp)floor(cc + 0.5) - order / 2;
                }
                offsets[jj][kk] = istrides[jj] * start;
                if (start < 0 || start + order >= idimensions[jj]) {
                    edge_offsets[jj][kk] = malloc((order + 1) * sizeof(npy_intp));
                    if (NPY_UNLIKELY(!edge_offsets[jj][kk])) {
                        NPY_END_THREADS;
                        PyErr_NoMemory();
                        goto exit;
                    }
                    for(hh = 0; hh <= order; hh++) {
                        npy_intp idx = start + hh;
                        npy_intp len = idimensions[jj];
                        if (len <= 1) {
                            idx = 0;
                        } else {
                            npy_intp s2 = 2 * len - 2;
                            if (idx < 0) {
                                idx = s2 * (npy_intp)(-idx / s2) + idx;
                                idx = idx <= 1 - len ? idx + s2 : -idx;
                            } else if (idx >= len) {
                                idx -= s2 * (npy_intp)(idx / s2);
                                if (idx >= len)
                                    idx = s2 - idx;
                            }
                        }
                        edge_offsets[jj][kk][hh] = istrides[jj] * (idx - start);
                    }
                }
                if (order > 0) {
                    splvals[jj][kk] = malloc((order + 1) * sizeof(double));
                    if (NPY_UNLIKELY(!splvals[jj][kk])) {
                        NPY_END_THREADS;
                        PyErr_NoMemory();
                        goto exit;
                    }
                    spline_coefficients(cc, order, splvals[jj][kk]);
                }
            } else {
                zeros[jj][kk] = 1;
            }
        }
    }

    filter_size = 1;
    for(jj = 0; jj < rank; jj++)
        filter_size *= order + 1;

    if (!NI_InitPointIterator(output, &io))
        goto exit;

    pi = (void *)PyArray_DATA(input);
    po = (void *)PyArray_DATA(output);

    /* store all coordinates and offsets with filter: */
    fcoordinates = malloc(rank * filter_size * sizeof(npy_intp));
    foffsets = malloc(filter_size * sizeof(npy_intp));
    if (NPY_UNLIKELY(!fcoordinates || !foffsets)) {
        NPY_END_THREADS;
        PyErr_NoMemory();
        goto exit;
    }

    for(jj = 0; jj < rank; jj++)
        ftmp[jj] = 0;
    kk = 0;
    for(hh = 0; hh < filter_size; hh++) {
        for(jj = 0; jj < rank; jj++)
            fcoordinates[jj + hh * rank] = ftmp[jj];
        foffsets[hh] = kk;
        for(jj = rank - 1; jj >= 0; jj--) {
            if (ftmp[jj] < order) {
                ftmp[jj]++;
                kk += istrides[jj];
                break;
            } else {
                ftmp[jj] = 0;
                kk -= istrides[jj] * order;
            }
        }
    }
    size = PyArray_SIZE(output);
    for(kk = 0; kk < size; kk++) {
        double t = 0.0;
        npy_intp edge = 0, oo = 0, zero = 0;

        for(hh = 0; hh < rank; hh++) {
            if (zeros && zeros[hh][io.coordinates[hh]]) {
                /* we use constant border condition */
                zero = 1;
                break;
            }
            oo += offsets[hh][io.coordinates[hh]];
            if (edge_offsets[hh][io.coordinates[hh]])
                edge = 1;
        }

        if (!zero) {
            npy_intp *ff = fcoordinates;
            const int type_num = PyArray_TYPE(input);
            t = 0.0;
            for(hh = 0; hh < filter_size; hh++) {
                npy_intp idx = 0;
                double coeff = 0.0;

                if (NPY_UNLIKELY(edge)) {
                    /* use precalculated edge offsets: */
                    for(jj = 0; jj < rank; jj++) {
                        if (edge_offsets[jj][io.coordinates[jj]])
                            idx += edge_offsets[jj][io.coordinates[jj]][ff[jj]];
                        else
                            idx += ff[jj] * istrides[jj];
                    }
                    idx += oo;
                } else {
                    /* use normal offsets: */
                    idx += oo + foffsets[hh];
                }
                switch (type_num) {
                    CASE_INTERP_COEFF(NPY_BOOL, npy_bool,
                                      coeff, pi, idx);
                    CASE_INTERP_COEFF(NPY_UBYTE, npy_ubyte,
                                      coeff, pi, idx);
                    CASE_INTERP_COEFF(NPY_USHORT, npy_ushort,
                                      coeff, pi, idx);
                    CASE_INTERP_COEFF(NPY_UINT, npy_uint,
                                      coeff, pi, idx);
                    CASE_INTERP_COEFF(NPY_ULONG, npy_ulong,
                                      coeff, pi, idx);
                    CASE_INTERP_COEFF(NPY_ULONGLONG, npy_ulonglong,
                                      coeff, pi, idx);
                    CASE_INTERP_COEFF(NPY_BYTE, npy_byte,
                                      coeff, pi, idx);
                    CASE_INTERP_COEFF(NPY_SHORT, npy_short,
                                      coeff, pi, idx);
                    CASE_INTERP_COEFF(NPY_INT, npy_int,
                                      coeff, pi, idx);
                    CASE_INTERP_COEFF(NPY_LONG, npy_long,
                                      coeff, pi, idx);
                    CASE_INTERP_COEFF(NPY_LONGLONG, npy_longlong,
                                      coeff, pi, idx);
                    CASE_INTERP_COEFF(NPY_FLOAT, npy_float,
                                      coeff, pi, idx);
                    CASE_INTERP_COEFF(NPY_DOUBLE, npy_double,
                                      coeff, pi, idx);
                default:
                    NPY_END_THREADS;
                    PyErr_SetString(PyExc_RuntimeError,
                                    "data type not supported");
                    goto exit;
                }
                /* calculate interpolated value: */
                for(jj = 0; jj < rank; jj++)
                    if (order > 0)
                        coeff *= splvals[jj][io.coordinates[jj]][ff[jj]];
                t += coeff;
                ff += rank;
            }
        } else {
            t = cval;
        }
        /* store output: */
        switch (PyArray_TYPE(output)) {
            CASE_INTERP_OUT(NPY_BOOL, npy_bool, po, t);
            CASE_INTERP_OUT_UINT(UBYTE, npy_ubyte, po, t);
            CASE_INTERP_OUT_UINT(USHORT, npy_ushort, po, t);
            CASE_INTERP_OUT_UINT(UINT, npy_uint, po, t);
            CASE_INTERP_OUT_UINT(ULONG, npy_ulong, po, t);
            CASE_INTERP_OUT_UINT(ULONGLONG, npy_ulonglong, po, t);
            CASE_INTERP_OUT_INT(BYTE, npy_byte, po, t);
            CASE_INTERP_OUT_INT(SHORT, npy_short, po, t);
            CASE_INTERP_OUT_INT(INT, npy_int, po, t);
            CASE_INTERP_OUT_INT(LONG, npy_long, po, t);
            CASE_INTERP_OUT_INT(LONGLONG, npy_longlong, po, t);
            CASE_INTERP_OUT(NPY_FLOAT, npy_float, po, t);
            CASE_INTERP_OUT(NPY_DOUBLE, npy_double, po, t);
        default:
            NPY_END_THREADS;
            PyErr_SetString(PyExc_RuntimeError, "data type not supported");
            goto exit;
        }
        NI_ITERATOR_NEXT(io, po);
    }

 exit:
    NPY_END_THREADS;
    if (zeros) {
        for(jj = 0; jj < rank; jj++)
            free(zeros[jj]);
        free(zeros);
    }
    if (offsets) {
        for(jj = 0; jj < rank; jj++)
            free(offsets[jj]);
        free(offsets);
    }
    if (splvals) {
        for(jj = 0; jj < rank; jj++) {
            if (splvals[jj]) {
                for(hh = 0; hh < odimensions[jj]; hh++)
                    free(splvals[jj][hh]);
                free(splvals[jj]);
            }
        }
        free(splvals);
    }
    if (edge_offsets) {
        for(jj = 0; jj < rank; jj++) {
            if (edge_offsets[jj]) {
                for(hh = 0; hh < odimensions[jj]; hh++)
                    free(edge_offsets[jj][hh]);
                free(edge_offsets[jj]);
            }
        }
        free(edge_offsets);
    }
    free(foffsets);
    free(fcoordinates);
    return PyErr_Occurred() ? 0 : 1;
}
Example #18
0
int NI_FourierShift(PyArrayObject *input, PyArrayObject* shift_array,
            npy_intp n, int axis, PyArrayObject* output)
{
    NI_Iterator ii, io;
    char *pi, *po;
    double *shifts = NULL, **params = NULL;
    npy_intp kk, hh, size;
    npy_double *ishifts = (void *)PyArray_DATA(shift_array);
    NPY_BEGIN_THREADS_DEF;

    /* precalculate the shifts: */
    shifts = malloc(PyArray_NDIM(input) * sizeof(double));
    if (!shifts) {
        PyErr_NoMemory();
        goto exit;
    }
    for (kk = 0; kk < PyArray_NDIM(input); kk++) {
        /* along the direction of the real transform we must use the given
             length of that dimensons, unless a complex transform is assumed
             (n < 0): */
        int shape = kk == axis ?
                (n < 0 ? PyArray_DIM(input, kk) : n) : PyArray_DIM(input, kk);
        shifts[kk] = -2.0 * M_PI * *ishifts++ / (double)shape;
    }
    /* allocate memory for tables: */
    params = malloc(PyArray_NDIM(input) * sizeof(double*));
    if (!params) {
        PyErr_NoMemory();
        goto exit;
    }
    for (kk = 0; kk < PyArray_NDIM(input); kk++) {
        params[kk] = NULL;
    }
    for (kk = 0; kk < PyArray_NDIM(input); kk++) {
        if (PyArray_DIM(input, kk) > 1) {
            params[kk] = malloc(PyArray_DIM(input, kk) * sizeof(double));
            if (!params[kk]) {
                PyErr_NoMemory();
                goto exit;
            }
        }
    }

    NPY_BEGIN_THREADS;

    for (hh = 0; hh < PyArray_NDIM(input); hh++) {
        if (params[hh]) {
            if (hh == axis && n >= 0) {
                for (kk = 0; kk < PyArray_DIM(input, hh); kk++) {
                    params[hh][kk] = shifts[hh] * kk;
                }
            }
            else {
                int jj = 0;
                for (kk = 0; kk < (PyArray_DIM(input, hh) + 1) / 2; kk++) {
                    params[hh][jj++] = shifts[hh] * kk;
                }
                for (kk = -(PyArray_DIM(input, hh) / 2); kk < 0; kk++) {
                    params[hh][jj++] = shifts[hh] * kk;
                }
            }
        }
    }
    /* initialize input element iterator: */
    if (!NI_InitPointIterator(input, &ii))
        goto exit;
    /* initialize output element iterator: */
    if (!NI_InitPointIterator(output, &io))
        goto exit;
    pi = (void *)PyArray_DATA(input);
    po = (void *)PyArray_DATA(output);
    size = PyArray_SIZE(input);
    /* iterator over the elements: */
    for(hh = 0; hh < size; hh++) {
        double tmp = 0.0, sint, cost, r = 0.0, i = 0.0;
        for (kk = 0; kk < PyArray_NDIM(input); kk++) {
            if (params[kk])
                tmp += params[kk][ii.coordinates[kk]];
        }
        sint = sin(tmp);
        cost = cos(tmp);
        switch (PyArray_TYPE(input)) {
            CASE_FOURIER_SHIFT_R(NPY_BOOL, npy_bool,
                                 pi, tmp, r, i, cost, sint);
            CASE_FOURIER_SHIFT_R(NPY_UBYTE, npy_ubyte,
                                 pi, tmp, r, i, cost, sint);
            CASE_FOURIER_SHIFT_R(NPY_USHORT, npy_ushort,
                                 pi, tmp, r, i, cost, sint);
            CASE_FOURIER_SHIFT_R(NPY_UINT, npy_uint,
                                 pi, tmp, r, i, cost, sint);
            CASE_FOURIER_SHIFT_R(NPY_ULONG, npy_ulong,
                                 pi, tmp, r, i, cost, sint);
            CASE_FOURIER_SHIFT_R(NPY_ULONGLONG, npy_ulonglong,
                                 pi, tmp, r, i, cost, sint);
            CASE_FOURIER_SHIFT_R(NPY_BYTE, npy_byte,
                                 pi, tmp, r, i, cost, sint);
            CASE_FOURIER_SHIFT_R(NPY_SHORT, npy_short,
                                 pi, tmp, r, i, cost, sint);
            CASE_FOURIER_SHIFT_R(NPY_INT, npy_int,
                                 pi, tmp, r, i, cost, sint);
            CASE_FOURIER_SHIFT_R(NPY_LONG, npy_long,
                                 pi, tmp, r, i, cost, sint);
            CASE_FOURIER_SHIFT_R(NPY_LONGLONG, npy_longlong,
                                 pi, tmp, r, i, cost, sint);
            CASE_FOURIER_SHIFT_R(NPY_FLOAT, npy_float,
                                 pi, tmp, r, i, cost, sint);
            CASE_FOURIER_SHIFT_R(NPY_DOUBLE, npy_double,
                                 pi, tmp, r, i, cost, sint);
            CASE_FOURIER_SHIFT_C(NPY_CFLOAT, npy_cfloat,
                                 pi, r, i, cost, sint);
            CASE_FOURIER_SHIFT_C(NPY_CDOUBLE, npy_cdouble,
                                 pi, r, i, cost, sint);
        default:
            NPY_END_THREADS;
            PyErr_SetString(PyExc_RuntimeError, "data type not supported");
            goto exit;
        }
        switch (PyArray_TYPE(output)) {
            CASE_FOURIER_OUT_CC(NPY_CFLOAT, npy_cfloat, po, r, i);
            CASE_FOURIER_OUT_CC(NPY_CDOUBLE, npy_cdouble, po, r, i);
        default:
            NPY_END_THREADS;
            PyErr_SetString(PyExc_RuntimeError, "data type not supported");
            goto exit;
        }
        NI_ITERATOR_NEXT2(ii, io, pi, po);
    }

 exit:
    NPY_END_THREADS;
    free(shifts);
    if (params) {
        for (kk = 0; kk < PyArray_NDIM(input); kk++) {
            free(params[kk]);
        }
        free(params);
    }
    return PyErr_Occurred() ? 0 : 1;
}
Example #19
0
int NI_FourierFilter(PyArrayObject *input, PyArrayObject* parameter_array,
                     npy_intp n, int axis, PyArrayObject* output,
                     int filter_type)
{
    NI_Iterator ii, io;
    char *pi, *po;
    double *parameters = NULL, **params = NULL;
    npy_intp kk, hh, size;
    npy_double *iparameters = (void *)PyArray_DATA(parameter_array);
    NPY_BEGIN_THREADS_DEF;

    /* precalculate the parameters: */
    parameters = malloc(PyArray_NDIM(input) * sizeof(double));
    if (!parameters) {
        PyErr_NoMemory();
        goto exit;
    }
    for (kk = 0; kk < PyArray_NDIM(input); kk++) {
        /* along the direction of the real transform we must use the given
             length of that dimensons, unless a complex transform is assumed
             (n < 0): */
        int shape = kk == axis ?
                (n < 0 ? PyArray_DIM(input, kk) : n) : PyArray_DIM(input, kk);
        switch (filter_type) {
            case _NI_GAUSSIAN:
                parameters[kk] = *iparameters++ * M_PI / (double)shape;
                parameters[kk] = -2.0 * parameters[kk] * parameters[kk];
                break;
            case _NI_ELLIPSOID:
            case _NI_UNIFORM:
                parameters[kk] = *iparameters++;
                break;
        }
    }
    /* allocate memory for tables: */
    params = malloc(PyArray_NDIM(input) * sizeof(double*));
    if (!params) {
        PyErr_NoMemory();
        goto exit;
    }
    for (kk = 0; kk < PyArray_NDIM(input); kk++) {
        params[kk] = NULL;
    }
    for (kk = 0; kk < PyArray_NDIM(input); kk++) {
        if (PyArray_DIM(input, kk) > 1) {
            params[kk] = malloc(PyArray_DIM(input, kk) * sizeof(double));
            if (!params[kk]) {
                PyErr_NoMemory();
                goto exit;
            }
        }
    }

    NPY_BEGIN_THREADS;

    switch (filter_type) {
        case _NI_GAUSSIAN:
            /* calculate the tables of exponentials: */
            for (hh = 0; hh < PyArray_NDIM(input); hh++) {
                if (params[hh]) {
                    if (hh == axis && n >= 0) {
                        for (kk = 0; kk < PyArray_DIM(input, hh); kk++) {
                            double tmp = parameters[hh] * kk * kk;
                            params[hh][kk] = fabs(tmp) > 50.0 ? 0.0 : exp(tmp);
                        }
                    }
                    else {
                        const npy_intp dim = PyArray_DIM(input, hh);
                        int jj = 0;
                        for (kk = 0; kk < (dim + 1) / 2; kk++) {
                            double tmp = parameters[hh] * kk * kk;
                            params[hh][jj++] =
                                            fabs(tmp) > 50.0 ? 0.0 : exp(tmp);
                        }
                        for (kk = -(dim / 2); kk < 0; kk++) {
                            double tmp = parameters[hh] * kk * kk;
                            params[hh][jj++] =
                                            fabs(tmp) > 50.0 ? 0.0 : exp(tmp);
                        }
                    }
                }
            }
            break;
        case _NI_UNIFORM:
            /* calculate the tables of parameters: */
            for (hh = 0; hh < PyArray_NDIM(input); hh++) {
                if (params[hh]) {
                    params[hh][0] = 1.0;
                    if (hh == axis && n >= 0) {
                        double tmp = M_PI * parameters[hh] / n;
                        for (kk = 1; kk < PyArray_DIM(input, hh); kk++) {
                            params[hh][kk] = tmp > 0.0 ?
                                             sin(tmp * kk) / (tmp * kk) : 0.0;
                        }
                    }
                    else {
                        const npy_intp dim = PyArray_DIM(input, hh);
                        double tmp = M_PI * parameters[hh] / dim;
                        int jj = 1;
                        for (kk = 1; kk < (dim + 1) / 2; kk++) {
                            params[hh][jj++] = tmp > 0.0 ?
                                            sin(tmp * kk) / (tmp * kk) : 0.0;
                        }
                        for (kk = -(dim / 2); kk < 0; kk++) {
                            params[hh][jj++] = tmp > 0.0 ?
                                            sin(tmp * kk) / (tmp * kk) : 0.0;
                        }
                    }
                }
            }
            break;
        case _NI_ELLIPSOID:
            /* calculate the tables of parameters: */
            for (hh = 0; hh < PyArray_NDIM(input); hh++) {
                if (params[hh]) {
                    params[hh][0] = 1.0;
                    if (hh == axis && n >= 0) {
                        double tmp = M_PI * parameters[hh] / n;
                        for (kk = 0; kk < PyArray_DIM(input, hh); kk++) {
                            params[hh][kk] = (double)kk * tmp;
                        }
                    }
                    else {
                        const npy_intp dim = PyArray_DIM(input, hh);
                        double tmp = M_PI * parameters[hh] / dim;
                        int jj = 0;
                        for(kk = 0; kk < (dim + 1) / 2; kk++) {
                            params[hh][jj++] = (double)kk * tmp;
                        }
                        for(kk = -(dim / 2); kk < 0; kk++) {
                            params[hh][jj++] = (double)kk * tmp;
                        }
                    }
                }
                else if (PyArray_DIM(input, hh) > 0) {
                    params[hh][0] = 1.0;
                }
            }
            if (PyArray_NDIM(input) > 1)
                for(hh = 0; hh < PyArray_NDIM(input); hh++)
                    for(kk = 0; kk < PyArray_DIM(input, hh); kk++) {
                        params[hh][kk] *= params[hh][kk];
                    }
            break;
        default:
            break;
    }
    /* initialize input element iterator: */
    if (!NI_InitPointIterator(input, &ii))
        goto exit;
    /* initialize output element iterator: */
    if (!NI_InitPointIterator(output, &io))
        goto exit;
    pi = (void *)PyArray_DATA(input);
    po = (void *)PyArray_DATA(output);
    size = PyArray_SIZE(input);
    /* iterator over the elements: */
    for(hh = 0; hh < size; hh++) {
        double tmp = 1.0;
        switch (filter_type) {
        case _NI_GAUSSIAN:
        case _NI_UNIFORM:
            for (kk = 0; kk < PyArray_NDIM(input); kk++) {
                if (params[kk])
                    tmp *= params[kk][ii.coordinates[kk]];
            }
            break;
        case _NI_ELLIPSOID:
            switch (PyArray_NDIM(input)) {
            case 1:
                tmp = params[0][ii.coordinates[0]];
                tmp = tmp > 0.0 ? sin(tmp) / (tmp) : 1.0;
                break;
            case 2:
                tmp = 0.0;
                for(kk = 0; kk < 2; kk++)
                    tmp += params[kk][ii.coordinates[kk]];
                tmp = sqrt(tmp);
                tmp = tmp > 0.0 ? 2.0 * _bessel_j1(tmp) / tmp : 1.0;
                break;
            case 3:
                {
                    double r = 0.0;
                    for(kk = 0; kk < 3; kk++)
                        r += params[kk][ii.coordinates[kk]];
                    r = sqrt(r);
                    if (r > 0.0) {
                        tmp = 3.0 * (sin(r) - r * cos(r));
                        tmp /= r * r * r;
                    } else {
                        tmp = 1.0;
                    }
                }
                break;
            }
            break;
        default:
            break;
        }
        if (PyArray_TYPE(input) == NPY_CFLOAT ||
                PyArray_TYPE(input) == NPY_CDOUBLE) {
            double tmp_r = 0.0, tmp_i = 0.0;
            switch (PyArray_TYPE(input)) {
                CASE_FOURIER_FILTER_RC(NPY_CFLOAT, npy_cfloat,
                                       pi, tmp, tmp_r, tmp_i);
                CASE_FOURIER_FILTER_RC(NPY_CDOUBLE, npy_cdouble,
                                       pi, tmp, tmp_r, tmp_i);
            default:
                NPY_END_THREADS;
                PyErr_SetString(PyExc_RuntimeError, "data type not supported");
                goto exit;
            }
            switch (PyArray_TYPE(output)) {
                CASE_FOURIER_OUT_CC(NPY_CFLOAT, npy_cfloat, po, tmp_r, tmp_i);
                CASE_FOURIER_OUT_CC(NPY_CDOUBLE, npy_cdouble, po, tmp_r, tmp_i);
            default:
                NPY_END_THREADS;
                PyErr_SetString(PyExc_RuntimeError, "data type not supported");
                goto exit;
            }
        }
        else {
            switch (PyArray_TYPE(input)) {
                CASE_FOURIER_FILTER_RR(NPY_BOOL, npy_bool, pi, tmp);
                CASE_FOURIER_FILTER_RR(NPY_UBYTE, npy_ubyte, pi, tmp);
                CASE_FOURIER_FILTER_RR(NPY_USHORT, npy_ushort, pi, tmp);
                CASE_FOURIER_FILTER_RR(NPY_UINT, npy_uint, pi, tmp);
                CASE_FOURIER_FILTER_RR(NPY_ULONG, npy_ulong, pi, tmp);
                CASE_FOURIER_FILTER_RR(NPY_ULONGLONG, npy_ulonglong, pi, tmp);
                CASE_FOURIER_FILTER_RR(NPY_BYTE, npy_byte, pi, tmp);
                CASE_FOURIER_FILTER_RR(NPY_SHORT, npy_short, pi, tmp);
                CASE_FOURIER_FILTER_RR(NPY_INT, npy_int, pi, tmp);
                CASE_FOURIER_FILTER_RR(NPY_LONG, npy_long, pi, tmp);
                CASE_FOURIER_FILTER_RR(NPY_LONGLONG, npy_longlong, pi, tmp);
                CASE_FOURIER_FILTER_RR(NPY_FLOAT, npy_float, pi, tmp);
                CASE_FOURIER_FILTER_RR(NPY_DOUBLE, npy_double, pi, tmp);
            default:
                NPY_END_THREADS;
                PyErr_SetString(PyExc_RuntimeError, "data type not supported");
                goto exit;
            }
            switch (PyArray_TYPE(output)) {
                CASE_FOURIER_OUT_RR(NPY_FLOAT, npy_float, po, tmp);
                CASE_FOURIER_OUT_RR(NPY_DOUBLE, npy_double, po, tmp);
                CASE_FOURIER_OUT_RC(NPY_CFLOAT, npy_cfloat, po, tmp);
                CASE_FOURIER_OUT_RC(NPY_CDOUBLE, npy_cdouble, po, tmp);
            default:
                NPY_END_THREADS;
                PyErr_SetString(PyExc_RuntimeError, "data type not supported");
                goto exit;
            }
        }
        NI_ITERATOR_NEXT2(ii, io, pi, po);
    }

 exit:
    NPY_END_THREADS;
    free(parameters);
    if (params) {
        for (kk = 0; kk < PyArray_NDIM(input); kk++) {
            free(params[kk]);
        }
        free(params);
    }
    return PyErr_Occurred() ? 0 : 1;
}
Example #20
0
int NI_Histogram(PyArrayObject *input, PyArrayObject *labels,
                 npy_intp min_label, npy_intp max_label, npy_intp *indices,
                 npy_intp n_results, PyArrayObject **histograms,
                 double min, double max, npy_intp nbins)
{
    char *pi = NULL, *pm = NULL;
    NI_Iterator ii, mi;
    npy_intp jj, kk, size, idx = 0, label = 1, doit = 1;
    Int32 **ph = NULL;
    double bsize;
    int qq;
    NPY_BEGIN_THREADS_DEF;

    /* input iterator: */
    if (!NI_InitPointIterator(input, &ii))
        goto exit;
    /* input data: */
    pi = (void *)PyArray_DATA(input);
    if (labels) {
        if (!NI_InitPointIterator(labels, &mi))
            goto exit;
        pm = (void *)PyArray_DATA(labels);
    }
    ph = (Int32**)malloc(n_results * sizeof(Int32*));
    if (!ph) {
        PyErr_NoMemory();
        goto exit;
    }

    NPY_BEGIN_THREADS;

    for(jj = 0; jj < n_results; jj++) {
            ph[jj] = (Int32*)PyArray_DATA(histograms[jj]);
            for(kk = 0; kk < nbins; kk++)
                    ph[jj][kk] = 0;
    }
    bsize = (max - min) / (double)nbins;
    /* input size: */
    size = 1;
    for(qq = 0; qq < input->nd; qq++)
        size *= input->dimensions[qq];
    /* iterate over array: */
    for(jj = 0; jj < size; jj++) {
        NI_GET_LABEL(pm, label, NI_NormalizeType(labels->descr->type_num));
        if (min_label >= 0) {
            if (label >= min_label && label <= max_label) {
                idx = indices[label - min_label];
                doit = idx >= 0;
            } else {
                doit = 0;
            }
        } else {
            doit = label != 0;
        }
        if (doit) {
            npy_intp bin;
            double val;
            NI_GET_VALUE(pi, val, NI_NormalizeType(input->descr->type_num));
            if (val >= min && val < max) {
                bin = (npy_intp)((val - min) / bsize);
                ++(ph[idx][bin]);
            }
        }
        if (labels) {
            NI_ITERATOR_NEXT2(ii, mi, pi, pm);
        } else {
            NI_ITERATOR_NEXT(ii, pi);
        }
    }
 exit:
    NPY_END_THREADS;
    free(ph);
    return  PyErr_Occurred() == NULL;
}