8000 ENH: Augment ufunc.reduce with state · Issue #8773 · numpy/numpy · GitHub
[go: up one dir, main page]

Skip to content

ENH: Augment ufunc.reduce with state #8773

New issue

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

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
eric-wieser opened this issue Mar 11, 2017 · 6 comments
Open

ENH: Augment ufunc.reduce with state #8773

eric-wieser opened this issue Mar 11, 2017 · 6 comments

Comments

@eric-wieser
Copy link
Member
eric-wieser commented Mar 11, 2017

Right now, reduce can be roughly described as:

it = iter_along_axis(arr)  #pseudocode
result = func.identity or next(it)
for i in it:
    result = func(result, i)
return result

Or diagramatically:

       x2     x3     x3      xn
       |      |      |       |
       V      V      V       V
x1 -> (f) -> (f) -> (f) ... (f) --> result

What I'm proposing is a more powerful variant that allows extra state to be preserved between each function call:

it = iter_along_axis(arr)  #pseudocode
result =  func.identity or next(it)
state = None
for i in it:
    result, state = func(result, i, reduce_state=state)
return result
         x2     x3     x3      xn
         |      |      |       |
         V      V      V       V
x1   -> ( ) -> ( ) -> ( ) ... ( ) --> result
        (f)    (f)    (f)     (f)
None -> ( ) -> ( ) -> ( ) ... ( )

This makes ufuncs capable of describing:

@eric-wieser
Copy link
Member Author

An alternative way to implement this might be to just allow the ufunc to modify its reduce_state parameter directly, like an out argument

@njsmith
Copy link
Member
njsmith commented Mar 12, 2017 via email

@eric-wieser
Copy link
Member Author

@njsmith : I was wrong about gcd - ufunc.reduce is already able to handle this.

Yes, gufuncs do provide a more general solution, but they don't support an axis= argument for the basic case, nor can they be accumulated.

@mhvk
Copy link
Contributor
mhvk commented Oct 21, 2017

This makes me realize I should get back to #8819, implementing axes for gufuncs...

@hameerabbasi
Copy link
Contributor

This would also make things like all_equal relatively simple without an intermediate array. For example, the state could be True by default and then f would do state = state && (x_i == x_{i-1}.

You would have to output the state in this case though.

@mhvk
Copy link
Contributor
mhvk commented Feb 28, 2018

Looking at this again, the logical path would seem to be a gufunc, with reduce just being a special case of one. #8819 is about to provide the ability to work along a single axis. Combined axes or axes=None is less trivial, though (might would need a transpose or ravel preprocessing step).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants
0