From 6e57d829cb6628610e163524f203245b247a2839 Mon Sep 17 00:00:00 2001 From: Aaron Meurer Date: Wed, 4 Aug 2021 16:47:05 -0600 Subject: Rename numpy._array_api to numpy.array_api Instead of the leading underscore, the experimentalness of the module will be indicated by omitting a warning on import. That we, we do not have to change the API from underscore to no underscore when the module is no longer experimental. --- numpy/array_api/_statistical_functions.py | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 numpy/array_api/_statistical_functions.py (limited to 'numpy/array_api/_statistical_functions.py') diff --git a/numpy/array_api/_statistical_functions.py b/numpy/array_api/_statistical_functions.py new file mode 100644 index 000000000..61fc60c46 --- /dev/null +++ b/numpy/array_api/_statistical_functions.py @@ -0,0 +1,30 @@ +from __future__ import annotations + +from ._array_object import Array + +from typing import Optional, Tuple, Union + +import numpy as np + +def max(x: Array, /, *, axis: Optional[Union[int, Tuple[int, ...]]] = None, keepdims: bool = False) -> Array: + return Array._new(np.max(x._array, axis=axis, keepdims=keepdims)) + +def mean(x: Array, /, *, axis: Optional[Union[int, Tuple[int, ...]]] = None, keepdims: bool = False) -> Array: + return Array._new(np.asarray(np.mean(x._array, axis=axis, keepdims=keepdims))) + +def min(x: Array, /, *, axis: Optional[Union[int, Tuple[int, ...]]] = None, keepdims: bool = False) -> Array: + return Array._new(np.min(x._array, axis=axis, keepdims=keepdims)) + +def prod(x: Array, /, *, axis: Optional[Union[int, Tuple[int, ...]]] = None, keepdims: bool = False) -> Array: + return Array._new(np.asarray(np.prod(x._array, axis=axis, keepdims=keepdims))) + +def std(x: Array, /, *, axis: Optional[Union[int, Tuple[int, ...]]] = None, correction: Union[int, float] = 0.0, keepdims: bool = False) -> Array: + # Note: the keyword argument correction is different here + return Array._new(np.asarray(np.std(x._array, axis=axis, ddof=correction, keepdims=keepdims))) + +def sum(x: Array, /, *, axis: Optional[Union[int, Tuple[int, ...]]] = None, keepdims: bool = False) -> Array: + return Array._new(np.asarray(np.sum(x._array, axis=axis, keepdims=keepdims))) + +def var(x: Array, /, *, axis: Optional[Union[int, Tuple[int, ...]]] = None, correction: Union[int, float] = 0.0, keepdims: bool = False) -> Array: + # Note: the keyword argument correction is different here + return Array._new(np.asarray(np.var(x._array, axis=axis, ddof=correction, keepdims=keepdims))) -- cgit v1.2.1 From c23abdc57b2e6c0fa4f939085374c01c1c4452a9 Mon Sep 17 00:00:00 2001 From: Aaron Meurer Date: Wed, 4 Aug 2021 19:57:46 -0600 Subject: Remove asarray() calls from the array API statistical functions asarray() is already called in Array._new. --- numpy/array_api/_statistical_functions.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'numpy/array_api/_statistical_functions.py') diff --git a/numpy/array_api/_statistical_functions.py b/numpy/array_api/_statistical_functions.py index 61fc60c46..a606203bc 100644 --- a/numpy/array_api/_statistical_functions.py +++ b/numpy/array_api/_statistical_functions.py @@ -10,21 +10,21 @@ def max(x: Array, /, *, axis: Optional[Union[int, Tuple[int, ...]]] = None, keep return Array._new(np.max(x._array, axis=axis, keepdims=keepdims)) def mean(x: Array, /, *, axis: Optional[Union[int, Tuple[int, ...]]] = None, keepdims: bool = False) -> Array: - return Array._new(np.asarray(np.mean(x._array, axis=axis, keepdims=keepdims))) + return Array._new(np.mean(x._array, axis=axis, keepdims=keepdims)) def min(x: Array, /, *, axis: Optional[Union[int, Tuple[int, ...]]] = None, keepdims: bool = False) -> Array: return Array._new(np.min(x._array, axis=axis, keepdims=keepdims)) def prod(x: Array, /, *, axis: Optional[Union[int, Tuple[int, ...]]] = None, keepdims: bool = False) -> Array: - return Array._new(np.asarray(np.prod(x._array, axis=axis, keepdims=keepdims))) + return Array._new(np.prod(x._array, axis=axis, keepdims=keepdims)) def std(x: Array, /, *, axis: Optional[Union[int, Tuple[int, ...]]] = None, correction: Union[int, float] = 0.0, keepdims: bool = False) -> Array: # Note: the keyword argument correction is different here - return Array._new(np.asarray(np.std(x._array, axis=axis, ddof=correction, keepdims=keepdims))) + return Array._new(np.std(x._array, axis=axis, ddof=correction, keepdims=keepdims)) def sum(x: Array, /, *, axis: Optional[Union[int, Tuple[int, ...]]] = None, keepdims: bool = False) -> Array: - return Array._new(np.asarray(np.sum(x._array, axis=axis, keepdims=keepdims))) + return Array._new(np.sum(x._array, axis=axis, keepdims=keepdims)) def var(x: Array, /, *, axis: Optional[Union[int, Tuple[int, ...]]] = None, correction: Union[int, float] = 0.0, keepdims: bool = False) -> Array: # Note: the keyword argument correction is different here - return Array._new(np.asarray(np.var(x._array, axis=axis, ddof=correction, keepdims=keepdims))) + return Array._new(np.var(x._array, axis=axis, ddof=correction, keepdims=keepdims)) -- cgit v1.2.1 From 8f7d00ed447174d9398af3365709222b529c1cad Mon Sep 17 00:00:00 2001 From: Aaron Meurer Date: Fri, 6 Aug 2021 18:22:00 -0600 Subject: Run (selective) black on the array_api submodule I've omitted a few changes from black that messed up the readability of some complicated if statements that were organized logically line-by-line, and some changes that use unnecessary operator spacing. --- numpy/array_api/_statistical_functions.py | 65 +++++++++++++++++++++++++++---- 1 file changed, 58 insertions(+), 7 deletions(-) (limited to 'numpy/array_api/_statistical_functions.py') diff --git a/numpy/array_api/_statistical_functions.py b/numpy/array_api/_statistical_functions.py index a606203bc..63790b447 100644 --- a/numpy/array_api/_statistical_functions.py +++ b/numpy/array_api/_statistical_functions.py @@ -6,25 +6,76 @@ from typing import Optional, Tuple, Union import numpy as np -def max(x: Array, /, *, axis: Optional[Union[int, Tuple[int, ...]]] = None, keepdims: bool = False) -> Array: + +def max( + x: Array, + /, + *, + axis: Optional[Union[int, Tuple[int, ...]]] = None, + keepdims: bool = False, +) -> Array: return Array._new(np.max(x._array, axis=axis, keepdims=keepdims)) -def mean(x: Array, /, *, axis: Optional[Union[int, Tuple[int, ...]]] = None, keepdims: bool = False) -> Array: + +def mean( + x: Array, + /, + *, + axis: Optional[Union[int, Tuple[int, ...]]] = None, + keepdims: bool = False, +) -> Array: return Array._new(np.mean(x._array, axis=axis, keepdims=keepdims)) -def min(x: Array, /, *, axis: Optional[Union[int, Tuple[int, ...]]] = None, keepdims: bool = False) -> Array: + +def min( + x: Array, + /, + *, + axis: Optional[Union[int, Tuple[int, ...]]] = None, + keepdims: bool = False, +) -> Array: return Array._new(np.min(x._array, axis=axis, keepdims=keepdims)) -def prod(x: Array, /, *, axis: Optional[Union[int, Tuple[int, ...]]] = None, keepdims: bool = False) -> Array: + +def prod( + x: Array, + /, + *, + axis: Optional[Union[int, Tuple[int, ...]]] = None, + keepdims: bool = False, +) -> Array: return Array._new(np.prod(x._array, axis=axis, keepdims=keepdims)) -def std(x: Array, /, *, axis: Optional[Union[int, Tuple[int, ...]]] = None, correction: Union[int, float] = 0.0, keepdims: bool = False) -> Array: + +def std( + x: Array, + /, + *, + axis: Optional[Union[int, Tuple[int, ...]]] = None, + correction: Union[int, float] = 0.0, + keepdims: bool = False, +) -> Array: # Note: the keyword argument correction is different here return Array._new(np.std(x._array, axis=axis, ddof=correction, keepdims=keepdims)) -def sum(x: Array, /, *, axis: Optional[Union[int, Tuple[int, ...]]] = None, keepdims: bool = False) -> Array: + +def sum( + x: Array, + /, + *, + axis: Optional[Union[int, Tuple[int, ...]]] = None, + keepdims: bool = False, +) -> Array: return Array._new(np.sum(x._array, axis=axis, keepdims=keepdims)) -def var(x: Array, /, *, axis: Optional[Union[int, Tuple[int, ...]]] = None, correction: Union[int, float] = 0.0, keepdims: bool = False) -> Array: + +def var( + x: Array, + /, + *, + axis: Optional[Union[int, Tuple[int, ...]]] = None, + correction: Union[int, float] = 0.0, + keepdims: bool = False, +) -> Array: # Note: the keyword argument correction is different here return Array._new(np.var(x._array, axis=axis, ddof=correction, keepdims=keepdims)) -- cgit v1.2.1 From 2d112a98ed7597c4120b31908384ae09b0304659 Mon Sep 17 00:00:00 2001 From: Aaron Meurer Date: Sat, 25 Sep 2021 17:34:22 -0500 Subject: ENH: Updates to numpy.array_api (#19937) * Add __index__ to array_api and update __int__, __bool__, and __float__ The spec specifies that they should only work on arrays with corresponding dtypes. __index__ is new in the spec since the initial PR, and works identically to np.array.__index__. * Add the to_device method to the array_api This method is new since #18585. It does nothing in NumPy since NumPy does not support non-CPU devices. * Update transpose methods in the array_api transpose() was renamed to matrix_transpose() and now operates on stacks of matrices. A function to permute dimensions will be added once it is finalized in the spec. The attribute mT was added and the T attribute was updated to only operate on 2-dimensional arrays as per the spec. * Restrict input dtypes in the array API statistical functions * Add the dtype parameter to the array API sum() and prod() * Add the function permute_dims() to the array_api namespace permute_dims() is the replacement for transpose(), which was split into permute_dims() and matrix_transpose(). * Add tril and triu to the array API namespace * Fix the array_api Array.__repr__ to indent the array properly * Make the Device type in the array_api just accept the string "cpu" --- numpy/array_api/_statistical_functions.py | 35 ++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) (limited to 'numpy/array_api/_statistical_functions.py') diff --git a/numpy/array_api/_statistical_functions.py b/numpy/array_api/_statistical_functions.py index 63790b447..c5abf9468 100644 --- a/numpy/array_api/_statistical_functions.py +++ b/numpy/array_api/_statistical_functions.py @@ -1,8 +1,17 @@ from __future__ import annotations +from ._dtypes import ( + _floating_dtypes, + _numeric_dtypes, +) from ._array_object import Array +from ._creation_functions import asarray +from ._dtypes import float32, float64 -from typing import Optional, Tuple, Union +from typing import TYPE_CHECKING, Optional, Tuple, Union + +if TYPE_CHECKING: + from ._typing import Dtype import numpy as np @@ -14,6 +23,8 @@ def max( axis: Optional[Union[int, Tuple[int, ...]]] = None, keepdims: bool = False, ) -> Array: + if x.dtype not in _numeric_dtypes: + raise TypeError("Only numeric dtypes are allowed in max") return Array._new(np.max(x._array, axis=axis, keepdims=keepdims)) @@ -24,6 +35,8 @@ def mean( axis: Optional[Union[int, Tuple[int, ...]]] = None, keepdims: bool = False, ) -> Array: + if x.dtype not in _floating_dtypes: + raise TypeError("Only floating-point dtypes are allowed in mean") return Array._new(np.mean(x._array, axis=axis, keepdims=keepdims)) @@ -34,6 +47,8 @@ def min( axis: Optional[Union[int, Tuple[int, ...]]] = None, keepdims: bool = False, ) -> Array: + if x.dtype not in _numeric_dtypes: + raise TypeError("Only numeric dtypes are allowed in min") return Array._new(np.min(x._array, axis=axis, keepdims=keepdims)) @@ -42,8 +57,15 @@ def prod( /, *, axis: Optional[Union[int, Tuple[int, ...]]] = None, + dtype: Optional[Dtype] = None, keepdims: bool = False, ) -> Array: + if x.dtype not in _numeric_dtypes: + raise TypeError("Only numeric dtypes are allowed in prod") + # Note: sum() and prod() always upcast float32 to float64 for dtype=None + # We need to do so here before computing the product to avoid overflow + if dtype is None and x.dtype == float32: + x = asarray(x, dtype=float64) return Array._new(np.prod(x._array, axis=axis, keepdims=keepdims)) @@ -56,6 +78,8 @@ def std( keepdims: bool = False, ) -> Array: # Note: the keyword argument correction is different here + if x.dtype not in _floating_dtypes: + raise TypeError("Only floating-point dtypes are allowed in std") return Array._new(np.std(x._array, axis=axis, ddof=correction, keepdims=keepdims)) @@ -64,8 +88,15 @@ def sum( /, *, axis: Optional[Union[int, Tuple[int, ...]]] = None, + dtype: Optional[Dtype] = None, keepdims: bool = False, ) -> Array: + if x.dtype not in _numeric_dtypes: + raise TypeError("Only numeric dtypes are allowed in sum") + # Note: sum() and prod() always upcast float32 to float64 for dtype=None + # We need to do so here before summing to avoid overflow + if dtype is None and x.dtype == float32: + x = asarray(x, dtype=float64) return Array._new(np.sum(x._array, axis=axis, keepdims=keepdims)) @@ -78,4 +109,6 @@ def var( keepdims: bool = False, ) -> Array: # Note: the keyword argument correction is different here + if x.dtype not in _floating_dtypes: + raise TypeError("Only floating-point dtypes are allowed in var") return Array._new(np.var(x._array, axis=axis, ddof=correction, keepdims=keepdims)) -- cgit v1.2.1 From a1813504ad44b70fb139181a9df8465bcb22e24d Mon Sep 17 00:00:00 2001 From: Aaron Meurer Date: Sun, 14 Nov 2021 14:35:06 -0700 Subject: ENH: Add the linalg extension to the array_api submodule (#19980) --- numpy/array_api/_statistical_functions.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'numpy/array_api/_statistical_functions.py') diff --git a/numpy/array_api/_statistical_functions.py b/numpy/array_api/_statistical_functions.py index c5abf9468..7bee3f4db 100644 --- a/numpy/array_api/_statistical_functions.py +++ b/numpy/array_api/_statistical_functions.py @@ -93,11 +93,12 @@ def sum( ) -> Array: if x.dtype not in _numeric_dtypes: raise TypeError("Only numeric dtypes are allowed in sum") - # Note: sum() and prod() always upcast float32 to float64 for dtype=None - # We need to do so here before summing to avoid overflow + # Note: sum() and prod() always upcast integers to (u)int64 and float32 to + # float64 for dtype=None. `np.sum` does that too for integers, but not for + # float32, so we need to special-case it here if dtype is None and x.dtype == float32: - x = asarray(x, dtype=float64) - return Array._new(np.sum(x._array, axis=axis, keepdims=keepdims)) + dtype = float64 + return Array._new(np.sum(x._array, axis=axis, dtype=dtype, keepdims=keepdims)) def var( -- cgit v1.2.1 From 19a398ae78c3f35ce3d29d87b35da059558d72b4 Mon Sep 17 00:00:00 2001 From: Aaron Meurer Date: Tue, 7 Dec 2021 15:35:20 -0700 Subject: BUG: Fix handling of the dtype parameter to numpy.array_api.prod() --- numpy/array_api/_statistical_functions.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'numpy/array_api/_statistical_functions.py') diff --git a/numpy/array_api/_statistical_functions.py b/numpy/array_api/_statistical_functions.py index 7bee3f4db..5bc831ac2 100644 --- a/numpy/array_api/_statistical_functions.py +++ b/numpy/array_api/_statistical_functions.py @@ -65,8 +65,8 @@ def prod( # Note: sum() and prod() always upcast float32 to float64 for dtype=None # We need to do so here before computing the product to avoid overflow if dtype is None and x.dtype == float32: - x = asarray(x, dtype=float64) - return Array._new(np.prod(x._array, axis=axis, keepdims=keepdims)) + dtype = float64 + return Array._new(np.prod(x._array, dtype=dtype, axis=axis, keepdims=keepdims)) def std( -- cgit v1.2.1