On Tue, Jun 21, 2011 at 2:28 PM, Charles R Harris <charlesr.har...@gmail.com> wrote: > > > On Tue, Jun 21, 2011 at 11:57 AM, Mark Wiebe <mwwi...@gmail.com> wrote: >> >> On Tue, Jun 21, 2011 at 12:36 PM, Charles R Harris >> <charlesr.har...@gmail.com> wrote: >>> >>> >>> On Mon, Jun 20, 2011 at 12:32 PM, Mark Wiebe <mwwi...@gmail.com> wrote: >>>> >>>> NumPy has a mechanism built in to allow subclasses to adjust or override >>>> aspects of the ufunc behavior. While this goal is important, this mechanism >>>> only allows for very limited customization, making for instance the masked >>>> arrays unable to work with the native ufuncs in a full and proper way. I >>>> would like to deprecate the current mechanism, in particular >>>> __array_prepare__ and __array_wrap__, and introduce a new method I will >>>> describe below. If you've ever used these mechanisms, please review this >>>> design to see if it meets your needs. >>>> >>> >>> The current approach is at a dead end, so something better needs to be >>> done. >>> >>>> >>>> Any class type which would like to override its behavior in ufuncs would >>>> define a method called _numpy_ufunc_, and optionally an attribute >>>> __array_priority__ as can already be done. The class which wins the >>>> priority >>>> battle gets its _numpy_ufunc_ function called as follows: >>>> >>>> return arr._numpy_ufunc_(current_ufunc, *args, **kwargs) >>>> >>>> To support this overloading, the ufunc would get a new support method, >>>> result_type, and there would be a new global function, >>>> broadcast_empty_like. >>>> The function ufunc.empty_like behaves like the global np.result_type, >>>> but produces the output type or a tuple of output types specific to the >>>> ufunc, which may follow a different convention than regular arithmetic type >>>> promotion. This allows for a class to create an output array of the correct >>>> type to pass to the ufunc if it needs to be different than the default. >>>> The function broadcast_empty_like is just like empty_like, but takes a >>>> list or tuple of arrays which are to be broadcast together for producing >>>> the >>>> output, instead of just one. >>> >>> How does the ufunc get called so it doesn't get caught in an endless >>> loop? I like the proposed method if it can also be used for classes that >>> don't subclass ndarray. Masked array, for instance, should probably not >>> subclass ndarray. >> >> The function being called needs to ensure this, either by extracting a raw >> ndarray from instances of its class, or adding a 'subok = False' parameter >> to the kwargs. Supporting objects that aren't ndarray subclasses is one of >> the purposes for this approach, and neither of my two example cases >> subclassed ndarray. > > Sounds good. Many of the current uses of __array_wrap__ that I am aware of > are in the wrappers in the linalg module and don't go through the ufunc > machinery. How would that be handled?
I contributed the __array_prepare__ method a while back so classes could raise errors before the array data is modified in place. Specifically, I was concerned about units support in my quantities package (http://pypi.python.org/pypi/quantities). But I agree that this approach is needs to be reconsidered. It would be nice for subclasses to have an opportunity to intercept and process the values passed to a ufunc on their way in. For example, it would be nice if when I did np.cos(1.5 degrees), my subclass could intercept the value and pass a new one on to the ufunc machinery that is expressed in radians. I thought PJ Eby's generic functions PEP would be a really good way to handle ufuncs, but the PEP has stagnated. Darren _______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion