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; }
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; }