| | 12 | ---- |
| | 13 | = Ufuncs and Masked Arrays = |
| | 14 | |
| | 15 | In changeset:1835, Travis added {{{__array_wrap__}}} hook to the {{{MaskedArray}}} class. This was done in an attempt |
| | 16 | to fix mixed arithmetics. Unfortunately, there is not enought information within the {{{__array_wrap__}}} hook to correctly |
| | 17 | generate the mask: |
| | 18 | {{{ |
| | 19 | >>> from numpy import * |
| | 20 | >>> print ma.array([1])/ma.array([0]) |
| | 21 | [--] |
| | 22 | >>> print array([1])/ma.array([0]) |
| | 23 | [0] |
| | 24 | }}} |
| | 25 | In order to fix this situation, more information has to be passed to the {{{__array_wrap__}}} hook by the ufunc. Sasha proposes |
| | 26 | to change the {{{__array_wrap__}}} signature form |
| | 27 | {{{ |
| | 28 | def __array_wrap__(self, arr) |
| | 29 | }}} |
| | 30 | to |
| | 31 | {{{ |
| | 32 | def __array_wrap__(self, arr, context) |
| | 33 | }}} |
| | 34 | and make ufuncs pass a tuple context=(func, args, i), where func is the ufunc itself, args is the tuple of ufunc arguments and |
| | 35 | i is the index of self in the args tuple. Strictly speaking, i is not necessary, but it is available in ufunc and may prove to be helpful |
| | 36 | in the future. |
| | 37 | |
| | 38 | Once ufuncs can handle the case of mixed arguments to binary operations, it is tempting to get rid of ma wrapers to ufuncs alltogether |
| | 39 | and implement ma logic entirely in {{{__array_wrap__}}} and {{{__array__}}} hooks. Unfortunately, {{{__array__}}} hook suffers from the |
| | 40 | same problem: before passing data to ufunc ma array heeds to replace masked values with something safe for the given operation. In |
| | 41 | order to do this more information in needed than passed to {{{__array__}}} hook. Sasha proposes to make a similar change to {{{__array__}}} |
| | 42 | hook as for {{{__array_wrap__}}} hook above. |
| | 43 | |
| | 44 | The new signature will be |
| | 45 | {{{ |
| | 46 | def __array__(self, dtype=None, context=None) |
| | 47 | }}} |
| | 48 | The ufuncs will pass to {{{__array__}}} a tuple context=(func, args, i), where func is the ufunc itself, args is the tuple of ufunc arguments and |
| | 49 | i is the index of self in the args tuple. For backward compatibility ufuncs will allow a two-argument {{{__array__}}} and classes that will take |
| | 50 | advantage of context will define {{{__array__}}} with a default value for context so that it can be called with one or two arguments as well. |
| | 51 | |