[Numpy-discussion] numpy1.2 : make sorts unary ufuncs

Charles R Harris charlesr.harris at gmail.com
Sat Apr 19 03:29:13 EDT 2008


On Sat, Apr 19, 2008 at 1:12 AM, Robert Kern <robert.kern at gmail.com> wrote:

> On Sat, Apr 19, 2008 at 1:55 AM, Charles R Harris
> <charlesr.harris at gmail.com> wrote:
>
> > Yes, but the inner loop is just something that uses the array values
> along
> > that axis to produce another set of values, i.e., it is a vector valued
> > function of vectors. So is a sort, so is argsort, so is the inner
> product,
> > so on and so forth. That's what we have here:
> >
> > typedef void (*PyUFuncGenericFunction) (char **, npy_intp *, npy_intp *,
> > void *);
> >
> >  No difference that I can see. It is the call function in PyUFuncObject
> that
> > matters.
>
> I believe this is the disconnect. From my perspective, the fact that
> the inner kernel function of a ufunc has a sufficient argument list to
> do a sort isn't important. The signature of that kernel function isn't
> what makes a ufunc; it's all of the code around it that does
> broadcasting, type matching and manipulation, etc. If we're changing
> that code to accommodate sorting, we haven't gained anything. We've
> just moved some code around; possibly we've reduced the line count,
> but I fear that we will muddy ufunc implementation with non-ufunc
> functionality and special cases.
>
> If you want to go down this road, I think you need to do what Travis
> suggests: factor out some of the common code between ufuncs and sorts
> into a "superclass" (not really, but you get the idea), and then
> implement ufuncs and sorts based on that. I think trying to shove
> sorts into ufuncs-qua-ufuncs is a bad idea. There is more than one
> path to code reuse.
>

Right now we have:

typedef struct {
    PyObject_HEAD
    int nin, nout, nargs;
    int identity;
    PyUFuncGenericFunction *functions;
    void **data;
    int ntypes;
    int check_return;
    char *name, *types;
    char *doc;
    void *ptr;
    PyObject *obj;
    PyObject *userloops;
} PyUFuncObject;

Which could be derived from something slightly more general. We could also
leave out reduce, accumulate, etc., which are special cases. We then have
common code for registration, etc. The call function still has to check
types, dispatch the calls for the axis, maybe create output arrays, as for
maximum.reduce, and so on. Broadcasting isn't applicable to unary type
things and many functions, say in argsort, look unary from the top, so that
doesn't enter in.

Chuck

> --
> Robert Kern
>
> "I have come to believe that the whole world is an enigma, a harmless
> enigma that is made terrible by our own mad attempt to interpret it as
> though it had an underlying truth."
>  -- Umberto Eco
> _______________________________________________
> Numpy-discussion mailing list
> Numpy-discussion at scipy.org
> http://projects.scipy.org/mailman/listinfo/numpy-discussion
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/numpy-discussion/attachments/20080419/80cd308f/attachment.html>


More information about the NumPy-Discussion mailing list