8
#include "numpy/libnumarray.h"
10
#define MAX_ARRAYS 1024
12
static PyObject *_Error;
14
typedef Float64 (*combiner)(int, int, int, Float64 temp[MAX_ARRAYS]);
18
_mask_and_sort(int ninputs, int index, Float64 **inputs, Bool **masks,
19
Float64 temp[MAX_ARRAYS])
23
for (i=j=0; i<ninputs; i++) {
24
if (masks[i][index] == 0)
25
temp[j++] = inputs[i][index];
28
for (i=j=0; i<ninputs; i++) {
29
temp[j++] = inputs[i][index];
33
for(i=0; i<goodpix; i++) {
34
for (j=i+1; j<goodpix; j++) {
35
if (temp[j] < temp[i]) {
36
Float64 temp2 = temp[j];
46
_inner_median(int goodpix, int nlow, int nhigh, Float64 temp[MAX_ARRAYS])
49
int midpoint, medianpix = goodpix-nhigh-nlow;
53
midpoint = medianpix / 2;
54
if (medianpix % 2) /* odd */ {
55
median = temp[ midpoint + nlow ];
57
median = (temp[ midpoint + nlow ] +
58
temp[ midpoint + nlow - 1 ]) / 2.0;
65
_inner_average(int goodpix, int nlow, int nhigh, Float64 temp[MAX_ARRAYS])
68
int i, averagepix = goodpix-nhigh-nlow;
70
if (averagepix <= 0) {
73
for(i=nlow, average=0; i<averagepix+nlow; i++)
75
average /= averagepix;
81
_inner_minimum(int goodpix, int nlow, int nhigh, Float64 temp[MAX_ARRAYS])
83
int minimumpix = goodpix-nhigh-nlow;
84
if (minimumpix <= 0) {
92
_combine(combiner f, int dim, int maxdim, int ninputs, int nlow, int nhigh,
93
PyArrayObject *inputs[], PyArrayObject *masks[], PyArrayObject *output)
97
if (dim == maxdim-1) {
98
Float64 sorted[MAX_ARRAYS];
99
Float64 *tinputs[MAX_ARRAYS];
100
Bool *tmasks[MAX_ARRAYS];
102
int cols = inputs[0]->dimensions[dim];
104
/* Allocate and convert 1 temporary row at a time */
105
for(i=0; i<ninputs; i++)
106
tinputs[i] = (Float64 *) inputs[i]->data;
108
for(i=0; i<ninputs; i++)
109
tmasks[i] = (Bool *) masks[i]->data;
111
toutput = (Float64 *) output->data;
113
for(j=0; j<cols; j++) {
114
int goodpix = _mask_and_sort(
115
ninputs, j, tinputs, masks ? tmasks : NULL, sorted);
116
toutput[j] = f(goodpix, nlow, nhigh, sorted);
119
for (i=0; i<inputs[0]->dimensions[dim]; i++) {
120
for(j=0; j<ninputs; j++) {
121
inputs[j]->data += inputs[j]->strides[dim]*i;
123
masks[j]->data += masks[j]->strides[dim]*i;
126
output->data += output->strides[dim]*i;
127
_combine(f, dim+1, maxdim, ninputs, nlow, nhigh,
128
inputs, masks, output);
129
for(j=0; j<ninputs; j++) {
130
inputs[j]->data -= inputs[j]->strides[dim]*i;
132
masks[j]->data -= masks[j]->strides[dim]*i;
135
output->data -= output->strides[dim]*i;
147
static fmapping functions[] = {
148
{"median", _inner_median},
149
{"average", _inner_average},
150
{"minimum", _inner_minimum},
155
_Py_combine(PyObject *obj, PyObject *args, PyObject *kw)
157
PyObject *arrays, *output;
158
int nlow=0, nhigh=0, narrays;
159
PyObject *badmasks=Py_None;
160
char *keywds[] = { "arrays", "output", "nlow", "nhigh",
161
"badmasks", "kind", NULL };
164
PyArrayObject *arr[MAX_ARRAYS], *bmk[MAX_ARRAYS], *toutput;
167
if (!PyArg_ParseTupleAndKeywords(args, kw, "OO|iiOs:combine", keywds,
168
&arrays, &output, &nlow, &nhigh, &badmasks, &kind))
171
narrays = PySequence_Length(arrays);
174
PyExc_TypeError, "combine: arrays is not a sequence");
175
if (narrays > MAX_ARRAYS)
177
PyExc_TypeError, "combine: too many arrays.");
179
for(i=0; i<narrays; i++) {
180
PyObject *a = PySequence_GetItem(arrays, i);
182
arr[i] = NA_InputArray(a, tFloat64, C_ARRAY);
183
if (!arr[i]) return NULL;
185
if (badmasks != Py_None) {
186
a = PySequence_GetItem(badmasks, i);
188
bmk[i] = NA_InputArray(a, tBool, C_ARRAY);
189
if (!bmk[i]) return NULL;
194
toutput = NA_OutputArray(output, tFloat64, C_ARRAY);
195
if (!toutput) return NULL;
197
for (i=0,f=0; i<ELEM(functions); i++)
198
if (!strcmp(kind, functions[i].name)) {
199
f = functions[i].fptr;
202
if (!f) return PyErr_Format(
203
PyExc_ValueError, "Invalid comination function.");
205
if (_combine( f, 0, arr[0]->nd, narrays, nlow, nhigh,
206
arr, (badmasks != Py_None ? bmk : NULL),
210
for(i=0; i<narrays; i++) {
212
if (badmasks != Py_None) {
222
static PyMethodDef _combineMethods[] = {
223
{"combine", (PyCFunction) _Py_combine, METH_VARARGS | METH_KEYWORDS},
224
{NULL, NULL} /* Sentinel */
227
/* platform independent*/
229
__declspec(dllexport)
232
void init_combine(void)
235
m = Py_InitModule("_combine", _combineMethods);
236
d = PyModule_GetDict(m);
237
_Error = PyErr_NewException("_combine.error", NULL, NULL);
238
PyDict_SetItemString(d, "error", _Error);
239
import_libnumarray();
245
* c-file-style: "python"