Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

Already on GitHub? Sign in to your account

BUG cannot specify second output to ufunc as keyword argument #4752

Closed
mhvk opened this Issue May 28, 2014 · 12 comments

Comments

Projects
None yet
4 participants
Contributor

mhvk commented May 28, 2014

Currently, it does not seem possible to pass on an array to catch the second output of a ufunc via a keyword parameter:

a1 = np.array([1.])
a2 = np.array([1.])
np.modf(1.333, out=a1, out2=a2)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-4-9ca83f6d80bd> in <module>()
----> 1 np.modf(1.333, out=a1, out2=a2)

ValueError: cannot specify 'out' as both a positional and keyword argument

One can do np.modf(1.333, out=a1), which works as expected. If one gives instead np.modf(1.333, out2=a2), the first part is assigned to a2. (Note that the documentation suggests to use out1, out2, but any characters after out simply seem to be skipped.)

It would seem good to have the option of giving these as keyword arguments. One solution might be to have it be consistent with the usage in __numpy_ufunc__, i.e., one would give np.modf(values, out=(a1, a2)).

Member

jaimefrio commented Oct 17, 2014

Currently the only way to specify multiple output arguments is as positional arguments. Using your example:

>>> np.modf(1.3333, a1, a2)
(array([ 0.3333]), array([ 1.]))
>>> a1
array([ 0.3333])
>>> a2
array([ 1.])

To add a different behavior (such as the tuple of arrays passed as a kwarg with out=) would require discussion on the list.

Owner

njsmith commented Oct 17, 2014

Yeah, we should discuss it on the list, but everyone will be in favor :-)
out=(out1, out2) just makes sense.

On Fri, Oct 17, 2014 at 2:42 AM, Jaime notifications@github.com wrote:

Currently the only way to specify multiple output arguments is as
positional arguments. Using your example:

np.modf(1.3333, a1, a2)
(array([ 0.3333]), array([ 1.]))
a1
array([ 0.3333])
a2
array([ 1.])

To add a different behavior (such as the tuple of arrays passed as a kwarg
with out=) would require discussion on the list.


Reply to this email directly or view it on GitHub
#4752 (comment).

Nathaniel J. Smith
Postdoctoral researcher - Informatics - University of Edinburgh
http://vorpus.org

Member

jaimefrio commented Oct 17, 2014

I'm sure someone will not like the color of the bike shed... Just pinged the list, lets see if anyone cares. We should take advantage of me having the code of ufunc_object.c still fresh in memory.

Contributor

mhvk commented Feb 27, 2015

@jaimefrio - this has been quite a while, but maybe you are still well-versed enough in ufunc_object.c to make the dual-output case work? I ilke how your suggestion of ufunc(<inputs>, out=tuple(outputs)) jives with what one gets passed on with __numpy_ufunc__.

Member

jaimefrio commented Feb 27, 2015

It is certainly no longer in the L1 cache, but I will try to find time to take a look again this weekend. If I can make sense of it I'll try pinging the list again: if I remember correctly, there wasn't a single response from the list last time. :-(

Owner

njsmith commented Feb 27, 2015

I think this is one of those cases where silence can be read as consent.
It's not exactly a hot-button controversial change.
On Feb 27, 2015 1:46 PM, "Jaime" notifications@github.com wrote:

It is certainly no longer in the L1 cache, but I will try to find time to
take a look again this weekend. If I can make sense of it I'll try pinging
the list again: if I remember correctly, there wasn't a single response
from the list last time. :-(


Reply to this email directly or view it on GitHub
#4752 (comment).

Owner

charris commented Feb 27, 2015

Seems reasonable to me also.

Member

jaimefrio commented Mar 1, 2015

I have it working, but am getting this error when I run the tests:

ERROR: test_out_subok (test_umath.TestOut)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/jaimefrio/open_source/numpy/build/testenv/lib/python2.7/site-packages/numpy/core/tests/test_umath.py", line 65, in test_out_subok
    r1, r2 = np.frexp(d, out=o1, subok=b)
TypeError: 'out' must be an array or tuple of arrays

The way I have it set up, it only accepts a single array to out (as opposed to a tuple) if it only has one return. I guess I'll have to modify it so that you can set the first output array regardless of how many returns the ufunc has. Question is, do we want to keep this behavior forever? Or should we deprecate it?

Owner

njsmith commented Mar 1, 2015

Should probably check with the list, but I doubt there are many people who
will be affected either way.

There is a functionality benefit to allowing some out= arguments to be
unspecified; someone might want to supply some and let the ufunc allocate
the others.

The current mechanism for this is ugly though, because you can provide the
first out= arg while allocating the second, but not vice-versa.

For the new api, maybe we should require that if a tuple is given, the
tuple must have nout entries, but any subset of them can be None, meaning
that entry should be allocated?

In the mean time, I guess we should still allow out=arr to be equivalent to
out=(arr, None, None, ...) for backwards compatibility. In my mind this is
closely linked to how we allow stuff like frexp(a, b, c) using positional
arguments, and there's a ton of code out there relying on positional output
arguments.

Possibly we should deprecate both positional output arguments and the use
of out=arr for multi-output ufuncs, with no plan to actually remove it, but
just to officially nudge people to the cleaner and more readable kwarg api.
That could be a separate discussion though...
On Mar 1, 2015 2:01 PM, "Jaime" notifications@github.com wrote:

I have it working, but am getting this error when I run the tests:

ERROR: test_out_subok (test_umath.TestOut)

Traceback (most recent call last):
File "/Users/jaimefrio/open_source/numpy/build/testenv/lib/python2.7/site-packages/numpy/core/tests/test_umath.py", line 65, in test_out_subok
r1, r2 = np.frexp(d, out=o1, subok=b)
TypeError: 'out' must be an array or tuple of arrays

The way I have it set up, it only accepts a single array to out (as
opposed to a tuple) if it only has one return. I guess I'll have to modify
it so that you can set the first output array regardless of how many
returns the ufunc has. Question is, do we want to keep this behavior
forever? Or should we deprecate it?


Reply to this email directly or view it on GitHub
#4752 (comment).

Contributor

mhvk commented Mar 2, 2015

Agreed with @njsmith - converting to out=(array, None) would seem most logical. I'm not even sure it is worth deprecating -- most important might be to ensure the documentation is clear.

Member

jaimefrio commented Mar 2, 2015

I'll make a PR even if it's half cooked only, and we can have the discussion over the code, which will probably explain itself better than me. My current implementation already does what @njsmith proposes: tuple of nout elements, but None is a perfectly valid entry of that tuple.

@jaimefrio jaimefrio added a commit to jaimefrio/numpy that referenced this issue Mar 2, 2015

@jaimefrio jaimefrio ENH: ufuncs can take a tuple of arrays as 'out' kwarg
Closes #4752
8eac157

@jaimefrio jaimefrio added a commit to jaimefrio/numpy that referenced this issue Mar 3, 2015

@jaimefrio jaimefrio ENH: ufuncs can take a tuple of arrays as 'out' kwarg
Closes #4752
4a09df1

@jaimefrio jaimefrio added a commit to jaimefrio/numpy that referenced this issue Mar 3, 2015

@jaimefrio jaimefrio ENH: ufuncs can take a tuple of arrays as 'out' kwarg
Closes #4752
2929b5e

@jaimefrio jaimefrio added a commit to jaimefrio/numpy that referenced this issue Mar 3, 2015

@jaimefrio jaimefrio ENH: ufuncs can take a tuple of arrays as 'out' kwarg
Closes #4752
284c65a

@jaimefrio jaimefrio added a commit to jaimefrio/numpy that referenced this issue Mar 3, 2015

@jaimefrio jaimefrio ENH: ufuncs can take a tuple of arrays as 'out' kwarg
Closes #4752
b876c2d

@jaimefrio jaimefrio added a commit to jaimefrio/numpy that referenced this issue Mar 3, 2015

@jaimefrio jaimefrio ENH: ufuncs can take a tuple of arrays as 'out' kwarg
Closes #4752
019360e

@jaimefrio jaimefrio added a commit to jaimefrio/numpy that referenced this issue Mar 4, 2015

@jaimefrio jaimefrio ENH: ufuncs can take a tuple of arrays as 'out' kwarg
Closes #4752
590900a

@jaimefrio jaimefrio added a commit to jaimefrio/numpy that referenced this issue Mar 6, 2015

@jaimefrio jaimefrio ENH: ufuncs can take a tuple of arrays as 'out' kwarg
Closes #4752
cb61691

@jaimefrio jaimefrio added a commit to jaimefrio/numpy that referenced this issue Mar 6, 2015

@jaimefrio jaimefrio ENH: ufuncs can take a tuple of arrays as 'out' kwarg
Closes #4752
f931459

@jaimefrio jaimefrio added a commit to jaimefrio/numpy that referenced this issue Mar 6, 2015

@jaimefrio jaimefrio ENH: ufuncs can take a tuple of arrays as 'out' kwarg
Closes #4752
c82cf07

@jaimefrio jaimefrio added a commit to jaimefrio/numpy that referenced this issue Mar 6, 2015

@jaimefrio jaimefrio ENH: ufuncs can take a tuple of arrays as 'out' kwarg
Closes #4752
854a974

@jaimefrio jaimefrio added a commit to jaimefrio/numpy that referenced this issue Mar 8, 2015

@jaimefrio jaimefrio ENH: ufuncs can take a tuple of arrays as 'out' kwarg
Closes #4752
1a7699f

@jaimefrio jaimefrio added a commit to jaimefrio/numpy that referenced this issue Mar 8, 2015

@jaimefrio jaimefrio ENH: ufuncs can take a tuple of arrays as 'out' kwarg
Closes #4752
bb3ae05

@charris charris closed this in #5621 Mar 8, 2015

Contributor

mhvk commented Mar 8, 2015

Thanks, @jaimefrio!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment