/** convolve example using element-wise API */ #include "Python.h" #include #include #include #include #include "libnumarray.h" static PyObject *_Error; static int Convolve1d(PyArrayObject *kernel, PyArrayObject *data, PyArrayObject *convolved) { int xc, xk; int ksizex = kernel->dimensions[0]; int halfk = ksizex / 2; int dsizex = data->dimensions[0]; for(xc=0; xcdimensions[0], kcols = kernel->dimensions[1]; int drows = data->dimensions[0], dcols = data->dimensions[1]; int halfkrows = krows/2; int halfkcols = kcols/2; /* Copy the data in the half kernel "frame" straight through. */ for(di=0; dind != 1) || (data->nd != 1)) return PyErr_Format(_Error, "Convolve1d: numarray must have exactly 1 dimension."); if (!NA_ShapeEqual(data, convolved)) return PyErr_Format(_Error, "Convolve1d: data and output numarray need same length."); if (!NA_ShapeLessThan(kernel, data)) return PyErr_Format(_Error, "Convolve1d: kernel must be smaller than data in both dimensions"); if (Convolve1d(kernel, data, convolved) < 0) { return NULL; } else { Py_XDECREF(kernel); Py_XDECREF(data); /* If convolved is Py_None, return cshadow. Else, DECREF cshadow to deallocate it and copy cshadow back onto convolved and return Py_None. */ return NA_ReturnOutput(oconvolved, convolved); } } static PyObject * Py_Convolve2d(PyObject *obj, PyObject *args) { PyObject *okernel, *odata, *oconvolved = Py_None; PyArrayObject *kernel, *data, *convolved; if (!PyArg_ParseTuple(args, "OO|O", &okernel, &odata, &oconvolved)) return PyErr_Format(_Error, "Convolve2d: Invalid parameters."); /* Require the kernel to be a C_array. Make it so if it isn't. */ kernel = NA_InputArray(okernel, tFloat64, NUM_C_ARRAY); /* Accept any variety of type tFloat w/o conversion; translate lists/tuples. No copy except for lists and non-tFloat64. */ data = NA_InputArray(odata, tFloat64, 0); /* Accept any variety of type tFloat w/o conversion/shadowing. If oconvolved is Py_None (unspecified) call data.new(Float64) to create convolved, effectively cloning it from data. */ convolved = NA_OptionalOutputArray(oconvolved, tFloat64, 0, data); if (!kernel || !data || !convolved) return NULL; if ((kernel->nd != 2) || (data->nd != 2)) return PyErr_Format(_Error, "Convolve2d: numarray must have 2 dimensions."); if (!NA_ShapeEqual(data, convolved)) return PyErr_Format(_Error, "Convolve2d: data,output numarray need identical shapes."); if (!NA_ShapeLessThan(kernel, data)) return PyErr_Format(_Error, "Convolve2d: kernel must be smaller than data in both dimensions"); if (Convolve2d(kernel, data, convolved) < 0) return NULL; else { Py_XDECREF(kernel); Py_XDECREF(data); /* If convolved is Py_None, return cshadow. Else, DECREF cshadow to deallocate it and copy cshadow back onto convolved and return Py_None. */ return NA_ReturnOutput(oconvolved, convolved); } } static PyMethodDef _convolveMethods[] = { {"Convolve1d", Py_Convolve1d, METH_VARARGS, "Convolve1d(kernel, data, output=None) convolves 1d array 'kernel'" \ "with 1d array 'data' either returning the result or silently storing" \ "it in 'output'."}, {"Convolve2d", Py_Convolve2d, METH_VARARGS, "Convolve2d(kernel, data, output=None) convolves 2d array 'kernel'" \ "with 2d array 'data' either returning the result or silently storing" \ "it in 'output'."}, {NULL, NULL} /* Sentinel */ }; /* platform independent*/ #ifdef MS_WIN32 __declspec(dllexport) #endif void initelement_wise(void) { PyObject *m, *d; m = Py_InitModule("element_wise", _convolveMethods); d = PyModule_GetDict(m); _Error = PyErr_NewException("_element_wise.error", NULL, NULL); PyDict_SetItemString(d, "error", _Error); import_libnumarray(); } /* * Local Variables: * mode: C * c-file-style: "python" * End: */