{
"metadata": {
"name": "",
"signature": "sha256:a7875dee526a07ff1c2244d7033afa9442c6d7086381022524bc8cba5ed7fd95"
},
"nbformat": 3,
"nbformat_minor": 0,
"worksheets": [
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This week I'm still working on the pull request for ufunc overrides, however I\n",
"think it is finally nearing completion. The implementation is working as\n",
"described and all tests are passing. I'm looking forward to working on SciPy again. \n",
"\n",
"The main aspects I've been working on are ufunc overrides method\n",
"resolution order, and argument normalization.\n",
"\n",
"## Method Resolution Order (MRO)\n",
"\n",
"Python functions in certain cases have a special MRO which is a bit more\n",
"complicated than the default left to right. Whenever ther right argument is a\n",
"subtype of the left argument its special method corresponding to the calling\n",
"function is called first. So for example, `add(a, b)` would normally call\n",
"`a.__add__(b)` but if `b` is a subtype of `a`, then `b.__radd__(a)` is called.\n",
"However there are no examples in the Python standard library of a ternary or\n",
"greater function from which we can copy. So we have tried to generalize this\n",
"concept to a higher order. \n",
"\n",
"The MRO algorithm is succinctly stated by\n",
"[@njsmith](https://github.com/numpy/numpy/pull/3524#issuecomment-21484153) as:\n",
"\n",
">While there remain untried inputs, pick the leftmost one which does not have a\n",
">proper subtype still remaining to be checked.\n",
"\n",
"Where inputs are the inputs to the ufunc. *Trying* an input refers to calling\n",
"its `__numpy_ufunc__` method (if it has one) and seeing that it does not return\n",
"`NotImplemented`.\n",
"\n",
"So Basically if a ufunc has three inputs (`a, b, as`) in that order, where `as`\n",
"is a subtype of `a`. They will be tried in the order `b > as > a`.\n",
"\n",
"\n",
"## Argument Normalization\n",
"\n",
"Many of NumPy's ufuncs can take a `out` argument, which specifies where the\n",
"output of the ufunc is assigned. The `out` argument can be passed as either a\n",
"positional, or keyword argument. So na\u00efvely checking a ufuncs arguments for\n",
"`__numpy_ufunc__` and then passing said arguments unaltered is not always\n",
"sensible. So given `nargs` - the number of args, and `nin` - the number of\n",
"inputs, we can check for an `out` positional argument and move it to the\n",
"keyword arguments. The normalized arguments are then passed the\n",
"`__numpy_ufunc__` method."
]
}
],
"metadata": {}
}
]
}