[Numpy-discussion] ENH: Add "where" argument to reduction functions that are missing it

2024-03-14 Thread Carlos Martin
The following reduction functions receive a "where" argument:
- https://numpy.org/doc/stable/reference/generated/numpy.max.html
- https://numpy.org/doc/stable/reference/generated/numpy.min.html
- https://numpy.org/doc/stable/reference/generated/numpy.sum.html
- https://numpy.org/doc/stable/reference/generated/numpy.prod.html
- https://numpy.org/doc/stable/reference/generated/numpy.mean.html
- https://numpy.org/doc/stable/reference/generated/numpy.var.html
- https://numpy.org/doc/stable/reference/generated/numpy.std.html
and their nan* counterparts, where applicable.

Feature request: Add "where" argument to
- https://numpy.org/doc/stable/reference/generated/numpy.ptp.html
- https://numpy.org/doc/stable/reference/generated/numpy.average.html
- https://numpy.org/doc/stable/reference/generated/numpy.median.html
- https://numpy.org/doc/stable/reference/generated/numpy.quantile.html
- https://numpy.org/doc/stable/reference/generated/numpy.percentile.html
- https://numpy.org/doc/stable/reference/generated/numpy.nanmedian.html
and their nan* counterparts, where applicable.

ptp should be especially straightforward, since it's just max - min.
___
NumPy-Discussion mailing list -- numpy-discussion@python.org
To unsubscribe send an email to numpy-discussion-le...@python.org
https://mail.python.org/mailman3/lists/numpy-discussion.python.org/
Member address: arch...@mail-archive.com


[Numpy-discussion] Re: ENH: Add "where" argument to reduction functions that are missing it

2024-04-08 Thread Carlos Martin
This also applies to
- https://numpy.org/doc/stable/reference/generated/numpy.argmax.html
- https://numpy.org/doc/stable/reference/generated/numpy.argmin.html
and their nan* counterparts.

An `initial` argument could be added to handle the empty case, as with np.max 
and np.min.
___
NumPy-Discussion mailing list -- numpy-discussion@python.org
To unsubscribe send an email to numpy-discussion-le...@python.org
https://mail.python.org/mailman3/lists/numpy-discussion.python.org/
Member address: arch...@mail-archive.com


[Numpy-discussion] ENH: Add more default arguments to various functions

2024-06-04 Thread Carlos Martin
Suggestion: Add the following default arguments to the following functions:

- https://numpy.org/doc/stable/reference/generated/numpy.zeros.html: shape=()
- https://numpy.org/doc/stable/reference/generated/numpy.ones.html: shape=()
- https://numpy.org/doc/stable/reference/generated/numpy.empty.html: shape=()
- https://numpy.org/doc/stable/reference/generated/numpy.heaviside.html: x2=0.5

Feel free to add more examples.
___
NumPy-Discussion mailing list -- numpy-discussion@python.org
To unsubscribe send an email to numpy-discussion-le...@python.org
https://mail.python.org/mailman3/lists/numpy-discussion.python.org/
Member address: arch...@mail-archive.com


[Numpy-discussion] ENH: Uniform interface for accessing minimum or maximum value of a dtype

2024-08-25 Thread Carlos Martin
As discussed 
[here](https://github.com/numpy/numpy/issues/5032#issuecomment-1830838701), 
[here](https://github.com/numpy/numpy/issues/5032#issuecomment-2307927804), and 
[here](https://github.com/google/jax/issues/18661#issuecomment-1829031914), I'm 
interested in a uniform interface for accessing the minimum or maximum value of 
a given dtype.

Currently, this requires branching on the type of dtype (boolean, integer, or 
floating point) and then (for the latter two) calling either 
[iinfo](https://numpy.org/doc/stable/reference/generated/numpy.iinfo.html) or 
[finfo](https://numpy.org/doc/stable/reference/generated/numpy.finfo.html), 
respectively. It would be more ergonomic to have a single, uniform interface 
for accessing this information that is dtype-independent.

Possible interfaces include:

```python3
import numpy as np
dt = np.dtype('int32')

dt.min
np.dtypes.info(dt).min
np.dtypes.min(dt)
np.dtypes.min_value(dt)
```
___
NumPy-Discussion mailing list -- numpy-discussion@python.org
To unsubscribe send an email to numpy-discussion-le...@python.org
https://mail.python.org/mailman3/lists/numpy-discussion.python.org/
Member address: arch...@mail-archive.com


[Numpy-discussion] Extend ldexp to handle complex inputs

2024-09-25 Thread Carlos Martin
Currently, 
[ldexp](https://numpy.org/doc/stable/reference/generated/numpy.ldexp.html) 
throws a TypeError on a complex input:

```python3
import numpy as np

def naive_ldexp(x, n):
return x * 2**n

def new_ldexp(x, n):
if np.iscomplex(x):
y = np.empty_like(x)
y.real = np.ldexp(x.real, n)
y.imag = np.ldexp(x.imag, n)
return y
else:
return np.ldexp(x, n)

def main():
x = 2.2 + 3.3j
n = 3

print(naive_ldexp(x, n))
print(new_ldexp(x, n))
print(np.ldexp(x, n))

if __name__ == "__main__":
main()
```

```
(17.6+26.4j)
(17.6+26.4j)
Traceback (most recent call last):
  File "test.py", line 34, in 
main()
  File "test.py", line 30, in main
print(np.ldexp(x, n))
  ^^
TypeError: ufunc 'ldexp' not supported for the input types, and the inputs 
could not be safely coerced to any supported types according to the casting 
rule ''safe''
```

This can easily be solved by applying ldexp to the real and imaginary parts of 
the input, as shown in the function new_ldexp above.
___
NumPy-Discussion mailing list -- numpy-discussion@python.org
To unsubscribe send an email to numpy-discussion-le...@python.org
https://mail.python.org/mailman3/lists/numpy-discussion.python.org/
Member address: arch...@mail-archive.com


[Numpy-discussion] Feature request: Add out-of-place (i.e. pure) versions of all existing in-place operations

2024-11-14 Thread Carlos Martin
Feature request: Add out-of-place (i.e. pure) versions of all existing in-place 
operations, such as the following:
- https://numpy.org/doc/stable/reference/generated/numpy.fill_diagonal.html
- https://numpy.org/doc/stable/reference/generated/numpy.put.html
- https://numpy.org/doc/stable/reference/generated/numpy.place.html
- https://numpy.org/doc/stable/reference/generated/numpy.put_along_axis.html
- https://numpy.org/doc/stable/reference/generated/numpy.putmask.html

This can be done by adding a boolean argument to each function called 
"inplace", which is True by default, but when set to False, makes the function 
return a modified copy of the array. This is the approach taken by JAX for its 
counterparts of these functions:
- https://jax.readthedocs.io/en/latest/_autosummary/jax.numpy.fill_diagonal.html
- https://jax.readthedocs.io/en/latest/_autosummary/jax.numpy.put.html
- https://jax.readthedocs.io/en/latest/_autosummary/jax.numpy.place.html

This would have the following advantages:
- Making it easier to perform these operations in a functional way (potentially 
less error-prone).
- Harmonizing the interfaces of NumPy and JAX.
___
NumPy-Discussion mailing list -- numpy-discussion@python.org
To unsubscribe send an email to numpy-discussion-le...@python.org
https://mail.python.org/mailman3/lists/numpy-discussion.python.org/
Member address: arch...@mail-archive.com


[Numpy-discussion] Add diagonal offset argument to all functions that are missing it

2025-02-09 Thread Carlos Martin
The following functions accept a diagonal offset argument:
- https://numpy.org/doc/stable/reference/generated/numpy.diag.html
- https://numpy.org/doc/stable/reference/generated/numpy.diagflat.html
- https://numpy.org/doc/stable/reference/generated/numpy.diagonal.html
- https://numpy.org/doc/stable/reference/generated/numpy.eye.html
- https://numpy.org/doc/stable/reference/generated/numpy.trace.html
- https://numpy.org/doc/stable/reference/generated/numpy.tri.html
- https://numpy.org/doc/stable/reference/generated/numpy.tril.html
- https://numpy.org/doc/stable/reference/generated/numpy.tril_indices.html
- https://numpy.org/doc/stable/reference/generated/numpy.tril_indices_from.html
- https://numpy.org/doc/stable/reference/generated/numpy.triu.html
- https://numpy.org/doc/stable/reference/generated/numpy.triu_indices.html
- https://numpy.org/doc/stable/reference/generated/numpy.triu_indices_from.html

The following functions lack such an argument:
- https://numpy.org/doc/stable/reference/generated/numpy.diag_indices.html
- https://numpy.org/doc/stable/reference/generated/numpy.diag_indices_from.html
- https://numpy.org/doc/stable/reference/generated/numpy.fill_diagonal.html
- https://github.com/numpy/numpy/issues/14402
- https://github.com/numpy/numpy/issues/18000
- https://github.com/numpy/numpy/pull/15079
- https://numpy.org/doc/stable/reference/generated/numpy.identity.html

Feature request: Add a diagonal offset argument to all of the functions that 
are missing it. (fill_diagonal is already tracked by the aforementioned issues, 
but the rest aren't, to my knowledge.)
___
NumPy-Discussion mailing list -- numpy-discussion@python.org
To unsubscribe send an email to numpy-discussion-le...@python.org
https://mail.python.org/mailman3/lists/numpy-discussion.python.org/
Member address: arch...@mail-archive.com


[Numpy-discussion] Add a "broadcast" option to numpy.concatenate

2025-03-18 Thread Carlos Martin
Often, I've wanted to concatenate arrays with different ndims along a 
particular axis, broadcasting the other axes as needed. Others have sought this 
functionality as well:

- https://stackoverflow.com/questions/56357047
- https://github.com/numpy/numpy/issues/2115
- 
https://stackoverflow.com/questions/52733240/concatenate-1d-array-to-a-3d-array
- 
https://stackoverflow.com/questions/46700081/concat-two-arrays-of-different-dimensions-numpy
- 
https://stackoverflow.com/questions/55879664/how-to-concatenate-a-2d-array-into-every-3d-array
- https://stackoverflow.com/questions/63453495/combining-two-numpy-arrays

However, 
[`numpy.concatenate`](https://numpy.org/doc/stable/reference/generated/numpy.concatenate.html)
 raises an error if the ndims don't match. For example:

```python3
import numpy as np

a = np.full([2], 0.1)
b = np.full([3, 2], 0.2)
c = np.full([5, 3, 2], 0.3)

arrays = [a, b, c]
axis = -1

try:
np.concatenate(arrays, axis)
except ValueError as e:
print(repr(e))
```
```
ValueError('all the input arrays must have same number of dimensions, but the 
array at index 0 has 1 dimension(s) and the array at index 1 has 2 
dimension(s)')
```

It would be convenient to add to `numpy.concatenate` an optional boolean 
argument called `broadcast` that broadcasts the input arrays along the axes 
that are *not* the concatenation axis, before concatenating them. Its default 
value can be `False`, which is the current behavior.

Below is an example implementation:

```python3
def tuple_replace(tupl, index, item):
return tupl[:index] + (item,) + tupl[index:][1:]

def broadcast_concat(arrays, axis):
shape = np.broadcast_shapes(*(tuple_replace(a.shape, axis, 0) for a in 
arrays))
bcast_arrays = [
np.broadcast_to(a, tuple_replace(shape, axis, a.shape[axis])) for a in 
arrays
]
return np.concatenate(bcast_arrays, axis)

output = broadcast_concat(arrays, axis)
assert output.shape[axis] == sum(a.shape[axis] for a in arrays)
```

If desired, I can submit a PR for this.
___
NumPy-Discussion mailing list -- numpy-discussion@python.org
To unsubscribe send an email to numpy-discussion-le...@python.org
https://mail.python.org/mailman3/lists/numpy-discussion.python.org/
Member address: arch...@mail-archive.com


[Numpy-discussion] ENH: Add saturating arithmetic functions

2025-04-26 Thread Carlos Martin
Saturating arithmetic (https://en.wikipedia.org/wiki/Saturation_arithmetic) is 
important in digital signal processing and other areas.

Feature request: Add saturating arithmetic functions for the following basic 
operations:

- addition (C++ counterpart: https://en.cppreference.com/w/cpp/numeric/add_sat)
- subtraction (C++ counterpart: 
https://en.cppreference.com/w/cpp/numeric/sub_sat)
- multiplication (C++ counterpart: 
https://en.cppreference.com/w/cpp/numeric/mul_sat)
- division (C++ counterpart: https://en.cppreference.com/w/cpp/numeric/div_sat)
- casting (C++ counterpart: 
https://en.cppreference.com/w/cpp/numeric/saturate_cast)
- negation

I've implemented these for JAX at 
https://gist.github.com/carlosgmartin/b32fa6fed3aa82f83dfbaac4b6345672.

Corresponding issue: https://github.com/jax-ml/jax/issues/26566.
___
NumPy-Discussion mailing list -- numpy-discussion@python.org
To unsubscribe send an email to numpy-discussion-le...@python.org
https://mail.python.org/mailman3/lists/numpy-discussion.python.org/
Member address: arch...@mail-archive.com


[Numpy-discussion] Add a spectral_radius function

2025-03-01 Thread Carlos Martin
Add a function called `spectral_radius` that computes the 
[spectral_radius](https://en.wikipedia.org/wiki/Spectral_radius) of a given 
matrix.

A naive way to do this is `np.max(np.abs(np.linalg.eigvals(a)))`, but there are 
more efficient methods.
___
NumPy-Discussion mailing list -- numpy-discussion@python.org
To unsubscribe send an email to numpy-discussion-le...@python.org
https://mail.python.org/mailman3/lists/numpy-discussion.python.org/
Member address: arch...@mail-archive.com


[Numpy-discussion] Re: Add a bit_width function

2025-03-06 Thread Carlos Martin
Hi Stefan,

It should work on unsigned integer types and use exact computation (not 
floating-point computations like np.log2).

For an example, see 
https://graphics.stanford.edu/~seander/bithacks.html#IntegerLogDeBruijn.
___
NumPy-Discussion mailing list -- numpy-discussion@python.org
To unsubscribe send an email to numpy-discussion-le...@python.org
https://mail.python.org/mailman3/lists/numpy-discussion.python.org/
Member address: arch...@mail-archive.com


[Numpy-discussion] Add a bit_width function

2025-03-06 Thread Carlos Martin
Feature request: Add a `bit_width` function to NumPy's [bit-wise 
operations](https://numpy.org/doc/stable/reference/routines.bitwise.html) that 
computes the [bit-width](https://en.wikipedia.org/wiki/Bit-width) (also called 
bit-length) of an input.

For an example, see C++'s 
[`bit_width`](https://en.cppreference.com/w/cpp/numeric/bit_width) function.
___
NumPy-Discussion mailing list -- numpy-discussion@python.org
To unsubscribe send an email to numpy-discussion-le...@python.org
https://mail.python.org/mailman3/lists/numpy-discussion.python.org/
Member address: arch...@mail-archive.com


[Numpy-discussion] Re: ENH: Let numpy.size accept multiple axes

2025-06-19 Thread Carlos Martin
Correction: 
[`math.prod`](https://docs.python.org/3/library/math.html#math.prod).
___
NumPy-Discussion mailing list -- numpy-discussion@python.org
To unsubscribe send an email to numpy-discussion-le...@python.org
https://mail.python.org/mailman3//lists/numpy-discussion.python.org
Member address: arch...@mail-archive.com


[Numpy-discussion] ENH: Let numpy.size accept multiple axes

2025-06-19 Thread Carlos Martin
Let the `axis` argument of 
[`numpy.size`](https://numpy.org/doc/stable/reference/generated/numpy.size.html)
 accept a tuple of ints (like other functions that take an `axis` argument) to 
measure the size for multiple axes.

This should be straightforward to implement with 
[`itertools.product`](https://docs.python.org/3/library/itertools.html#itertools.product).
___
NumPy-Discussion mailing list -- numpy-discussion@python.org
To unsubscribe send an email to numpy-discussion-le...@python.org
https://mail.python.org/mailman3//lists/numpy-discussion.python.org
Member address: arch...@mail-archive.com


[Numpy-discussion] ENH: More user-friendly way to pad a specific axis

2025-06-24 Thread Carlos Martin
It is common to want to pad an array along a *specific* axis. Examples:

- 
https://stackoverflow.com/questions/72106542/how-to-pad-the-i-j-axes-of-a-3d-np-array-without-padding-its-k-axis
- https://stackoverflow.com/questions/56076094/zero-pad-ndarray-along-axis
- 
https://stackoverflow.com/questions/66225047/padding-a-3-dimensional-numpy-array-with-the-medians-alongside-specific-axis
- 
https://stackoverflow.com/questions/19349410/how-to-pad-with-zeros-a-tensor-along-some-axis-python
- 
https://stackoverflow.com/questions/74966041/how-to-pad-a-specific-dimension-of-a-numpy-array

Doing so with 
[`numpy.pad`](https://numpy.org/doc/stable/reference/generated/numpy.pad.html) 
requires constructing a list of pairs of length equal to the ndim of the array, 
with exactly one of those pairs at the right position containing the desired 
pad widths. This can be verbose and clumsy when there are several axes.

I propose a new, more user-friendly way to pad along a specific axis (or axes): 
Let the `pad_width` argument accept a *dictionary* whose keys are axes and 
whose values are the `(before, after)` pair (or perhaps single number) for the 
corresponding axis. Example:

```python3
# before
np.pad(array, [(0, 0), (0, 0), (1, 2), (0, 0), (0, 0)])
# after
np.pad(array, {-3: (1, 2)})
```

This should require only minor modification to the implementation of 
`numpy.pad`. If others like this idea, I can create a PR for it.
___
NumPy-Discussion mailing list -- numpy-discussion@python.org
To unsubscribe send an email to numpy-discussion-le...@python.org
https://mail.python.org/mailman3//lists/numpy-discussion.python.org
Member address: arch...@mail-archive.com


[Numpy-discussion] Re: ENH: Add reverse argument to ufunc.accumulate, cumsum, nancumsum, cumprod, nancumprod

2025-06-09 Thread Carlos Martin
My particular use case was computing cumulative returns in the context of 
reinforcement learning.

A GitHub code search suggests that reverse cumsum is a fairly common operation, 
with 3.8k hits: 
https://github.com/search?q=%2Fcumsum%5C%28.*%5C%5B%3A%3A-1%5C%5D%5C%29%5C%5B%3A%3A-1%5C%5D%2F&type=code.
___
NumPy-Discussion mailing list -- numpy-discussion@python.org
To unsubscribe send an email to numpy-discussion-le...@python.org
https://mail.python.org/mailman3//lists/numpy-discussion.python.org
Member address: arch...@mail-archive.com


[Numpy-discussion] ENH: Add reverse argument to ufunc.accumulate, cumsum, nancumsum, cumprod, nancumprod

2025-06-07 Thread Carlos Martin
Add a reverse argument to accumulating functions that, when true, causes the 
accumulation to be performed in reverse. Examples:

- ufunc.accumulate: 
https://numpy.org/doc/stable/reference/generated/numpy.ufunc.accumulate.html
- cumsum: https://numpy.org/doc/stable/reference/generated/numpy.cumsum.html
- nancumsum: 
https://numpy.org/doc/stable/reference/generated/numpy.nancumsum.html
- cumprod: https://numpy.org/doc/stable/reference/generated/numpy.cumprod.html
- nancumprod: 
https://numpy.org/doc/stable/reference/generated/numpy.nancumprod.html

Currently, this can be done via two flips 
(https://numpy.org/doc/stable/reference/generated/numpy.flip.html) before and 
after the operation. But it might be more efficient to do it directly at the 
low level.
___
NumPy-Discussion mailing list -- numpy-discussion@python.org
To unsubscribe send an email to numpy-discussion-le...@python.org
https://mail.python.org/mailman3//lists/numpy-discussion.python.org
Member address: arch...@mail-archive.com


[Numpy-discussion] ENH: Add a non-circular shift function

2025-07-16 Thread Carlos Martin
Feature request: Add a non-circular shift function that is similar to 
[`numpy.roll`](https://numpy.org/doc/stable/reference/generated/numpy.roll.html)
 but, instead of wrapping elements around, replaces unoccupied entries with a 
specified fill value. Examples:

```
>>> import numpy as np
>>> a = np.arange(1, 6)
>>> a
array([1, 2, 3, 4, 5])
>>> np.shifted(a, 2)
array([0, 0, 1, 2, 3])
>>> np.shifted(a, -2)
array([3, 4, 5, 0, 0])
>>> a = np.arange(1, 10).reshape((3, 3))
>>> a
array([[1, 2, 3],
   [4, 5, 6],
   [7, 8, 9]])
>>> np.shifted(a, (1, -2), (0, 1))
array([[0, 0, 0],
   [3, 0, 0],
   [6, 0, 0]])
```

Prior discussion: https://github.com/numpy/numpy/issues/26220

Pull request: https://github.com/numpy/numpy/pull/29389
___
NumPy-Discussion mailing list -- numpy-discussion@python.org
To unsubscribe send an email to numpy-discussion-le...@python.org
https://mail.python.org/mailman3//lists/numpy-discussion.python.org
Member address: arch...@mail-archive.com