[Numpy-discussion] generalized ufunc problem
David Warde-Farley
dwf at cs.toronto.edu
Thu Jan 21 19:13:17 EST 2010
I decided to take a crack at adding a generalized ufunc for logsumexp,
i.e. collapsed an array along the last dimension by subtracting the
maximum element E along that dimension, taking the exponential,
adding, and then adding back E. Functionally the same
logaddexp.reduce() but presumably faster and less prone to error
accumulation.
I added the following to umath_tests.c.src and got everything to
compile, but for some reason it doesn't give me the behaviour I'm
looking for. I was expecting a (500, 50) array to be collapsed down to
a (500,) array. Is that not what the signature calls for?
Thanks,
David
char *logsumexp_signature = "(i)->()";
/**begin repeat
#TYPE=LONG,DOUBLE#
#typ=npy_long, npy_double#
#EXPFUN=expl, exp#
#LOGFUN=logl, log#
*/
/*
* This implements the function
* out[n] = sum_i { in1[n, i] * in2[n, i] }.
*/
static void
@TYPE at _logsumexp(char **args, intp *dimensions, intp *steps, void
*NPY_UNUSED(func))
{
INIT_OUTER_LOOP_3
intp di = dimensions[0];
intp i;
intp is1=steps[0];
BEGIN_OUTER_LOOP_3
char *ip1=args[0], *op=args[1];
@typ@ max = (*(@typ@ *)ip1);
@typ@ sum = 0;
for (i = 0; i < di; i++) {
max = max < (*(@typ@ *)ip1) ? (*(@typ@ *)ip1) : max;
ip1 += is1;
}
ip1 = args[0];
for (i = 0; i < di; i++) {
sum += @EXPFUN@((*(@typ@ *)ip1) - max);
ip1 += is1;
}
*(@typ@ *)op = @LOGFUN@(sum + max);
END_OUTER_LOOP
}
/**end repeat**/
static PyUFuncGenericFunction logsumexp_functions[] =
{ LONG_logsumexp, DOUBLE_logsumexp };
static void * logsumexp_data[] = { (void *)NULL, (void *)NULL };
static char logsumexp_signatures[] = { PyArray_LONG, PyArray_LONG,
PyArray_DOUBLE, PyArray_DOUBLE };
/* and inside addUfuncs() */
...
f = PyUFunc_FromFuncAndData(logsumexp_functions, logsumexp_data,
logsumexp_signatures, 2, 1, 1,
PyUFunc_None, "logsumexp", "inner1d
with a weight argument \\n""\" \"\n"" \\
\"(i)->()\\\" \\n""", 0); PyDict_SetItemString(dictionary,
"logsumexp", f); Py_DECREF(f);
....
More information about the NumPy-Discussion
mailing list