array-api icon indicating copy to clipboard operation
array-api copied to clipboard

Add `gradient`

Open jakirkham opened this issue 1 year ago • 6 comments

It would be useful to have some gradient implementation in the spec. Possibly starting with np.gradient.

Though it is worth noting that np.gradient returns separate arrays in a list, but this can be an issue if users want them combined (since this entails a copy of potentially large arrays). To alleviate this, it would be helpful to have some option to return them pre-stacked. Usually it is pretty trivial to split them up later if needed list(a_g).

Edit: Another possible option would be an out parameter. Though this may need some clarification given the current list behavior.

jakirkham avatar Aug 01 '22 19:08 jakirkham

Here is the data on who implements it: https://github.com/data-apis/array-api-comparison/blob/main/data/join.csv. Looks like:

  • yes: NumPy, CuPy, Dask, JAX
  • no: PyTorch, TensorFlow, PyData Sparse

Of course PyTorch and TensorFlow also have functions to calculate gradients, and probably a lot more accurate than np.gradient - just under different names. Not sure if other libraries use the same algorithm as numpy or not, or what should be required there in case we indeed do want to add a gradient function.

np.gradient doesn't seem to be used at all in SciPy or scikit-learn, nor in NumPy itself outside of tests. So I'm curious, what do you need it for @jakirkham?

rgommers avatar Aug 02 '22 10:08 rgommers

It comes up a lot in image processing. Often as an input to other operations (finding local minima/maxima, feature extraction, segmentation, surface construction, optical flow, etc.).

There are a few direct usages of np.gradient in scikit-image. In some cases it appears they have custom kernels.

jakirkham avatar Aug 04 '22 18:08 jakirkham

I'm weakly opposed here.

We do use this inside Xarray (inside the differentiate method) but there are many ways to approximate gradients, and np.gradient only implements one of them (2nd order finite differences).

Instead, I think this would be a good example of a "recipe" that could be implemented on top of the array API. Maybe it would be worth collecting many of these recipes and putting them into a library?

shoyer avatar Aug 18 '22 19:08 shoyer

Wonder if there is some simpler functionality we could capture that would be a useful building block. For example diff or similar

jakirkham avatar Aug 18 '22 19:08 jakirkham

I mean, the simplest version of finite differences for an array representing the values of a function y(x) is literally (y[1:] - y[:-1]) / (x[:1] - x[:-1]).

shoyer avatar Aug 18 '22 19:08 shoyer

The outcome of a conversation in the 4 Aug consortium call was in line with the above discussion. gradient doesn't seem suitable for standardization, however it would be nice to have a good high-quality implementation of a finite differences function on top of the array API.

SciPy just deprecated its two derivate functions in scipy.misc. For np.gradient, it could be improved. There's other packages like numdifftools and findiff for this.

Image processing is probably where this is most often needed. It'd be great if someone could synthesize the best of what is already floating around and putting it up somewhere as a separate function.

@jakirkham can we close this issue? I don't think it's actionable here.

rgommers avatar Sep 05 '22 17:09 rgommers

As this discussion hasn't been active in a while and the general consensus is against adding a gradient function to the array API specification, I'll close this out.

kgryte avatar Feb 09 '23 03:02 kgryte