[Numpy-discussion] generalized ufunc problem

Warren Weckesser warren.weckesser@enthought....
Thu Jan 21 18:30:59 CST 2010


David,

I haven't tried creating a ufunc before, so I can't help you with that, 
but since you are working on logsumexp, you might be interested in the 
version I posted here in October:

    http://mail.scipy.org/pipermail/scipy-user/2009-October/022931.html

and the attached tests.


Warren


David Warde-Farley wrote:
> 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@_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);
>
> ....
>
>
> _______________________________________________
> NumPy-Discussion mailing list
> NumPy-Discussion@scipy.org
> http://mail.scipy.org/mailman/listinfo/numpy-discussion
>   

-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: my_logsumexp_test.py
Url: http://mail.scipy.org/pipermail/numpy-discussion/attachments/20100121/6c64ab74/attachment.pl 


More information about the NumPy-Discussion mailing list