Coverage for /var/srv/projects/api.amasfac.comuna18.com/tmp/venv/lib/python3.9/site-packages/numpy/core/_methods.py: 16%
158 statements
« prev ^ index » next coverage.py v6.4.4, created at 2023-07-17 14:22 -0600
« prev ^ index » next coverage.py v6.4.4, created at 2023-07-17 14:22 -0600
1"""
2Array methods which are called by both the C-code for the method
3and the Python code for the NumPy-namespace function
5"""
6import warnings
7from contextlib import nullcontext
9from numpy.core import multiarray as mu
10from numpy.core import umath as um
11from numpy.core.multiarray import asanyarray
12from numpy.core import numerictypes as nt
13from numpy.core import _exceptions
14from numpy._globals import _NoValue
15from numpy.compat import pickle, os_fspath
17# save those O(100) nanoseconds!
18umr_maximum = um.maximum.reduce
19umr_minimum = um.minimum.reduce
20umr_sum = um.add.reduce
21umr_prod = um.multiply.reduce
22umr_any = um.logical_or.reduce
23umr_all = um.logical_and.reduce
25# Complex types to -> (2,)float view for fast-path computation in _var()
26_complex_to_float = {
27 nt.dtype(nt.csingle) : nt.dtype(nt.single),
28 nt.dtype(nt.cdouble) : nt.dtype(nt.double),
29}
30# Special case for windows: ensure double takes precedence
31if nt.dtype(nt.longdouble) != nt.dtype(nt.double): 31 ↛ 38line 31 didn't jump to line 38, because the condition on line 31 was never false
32 _complex_to_float.update({
33 nt.dtype(nt.clongdouble) : nt.dtype(nt.longdouble),
34 })
36# avoid keyword arguments to speed up parsing, saves about 15%-20% for very
37# small reductions
38def _amax(a, axis=None, out=None, keepdims=False,
39 initial=_NoValue, where=True):
40 return umr_maximum(a, axis, None, out, keepdims, initial, where)
42def _amin(a, axis=None, out=None, keepdims=False,
43 initial=_NoValue, where=True):
44 return umr_minimum(a, axis, None, out, keepdims, initial, where)
46def _sum(a, axis=None, dtype=None, out=None, keepdims=False,
47 initial=_NoValue, where=True):
48 return umr_sum(a, axis, dtype, out, keepdims, initial, where)
50def _prod(a, axis=None, dtype=None, out=None, keepdims=False,
51 initial=_NoValue, where=True):
52 return umr_prod(a, axis, dtype, out, keepdims, initial, where)
54def _any(a, axis=None, dtype=None, out=None, keepdims=False, *, where=True):
55 # Parsing keyword arguments is currently fairly slow, so avoid it for now
56 if where is True:
57 return umr_any(a, axis, dtype, out, keepdims)
58 return umr_any(a, axis, dtype, out, keepdims, where=where)
60def _all(a, axis=None, dtype=None, out=None, keepdims=False, *, where=True):
61 # Parsing keyword arguments is currently fairly slow, so avoid it for now
62 if where is True:
63 return umr_all(a, axis, dtype, out, keepdims)
64 return umr_all(a, axis, dtype, out, keepdims, where=where)
66def _count_reduce_items(arr, axis, keepdims=False, where=True):
67 # fast-path for the default case
68 if where is True:
69 # no boolean mask given, calculate items according to axis
70 if axis is None:
71 axis = tuple(range(arr.ndim))
72 elif not isinstance(axis, tuple):
73 axis = (axis,)
74 items = 1
75 for ax in axis:
76 items *= arr.shape[mu.normalize_axis_index(ax, arr.ndim)]
77 items = nt.intp(items)
78 else:
79 # TODO: Optimize case when `where` is broadcast along a non-reduction
80 # axis and full sum is more excessive than needed.
82 # guarded to protect circular imports
83 from numpy.lib.stride_tricks import broadcast_to
84 # count True values in (potentially broadcasted) boolean mask
85 items = umr_sum(broadcast_to(where, arr.shape), axis, nt.intp, None,
86 keepdims)
87 return items
89# Numpy 1.17.0, 2019-02-24
90# Various clip behavior deprecations, marked with _clip_dep as a prefix.
92def _clip_dep_is_scalar_nan(a):
93 # guarded to protect circular imports
94 from numpy.core.fromnumeric import ndim
95 if ndim(a) != 0:
96 return False
97 try:
98 return um.isnan(a)
99 except TypeError:
100 return False
102def _clip_dep_is_byte_swapped(a):
103 if isinstance(a, mu.ndarray):
104 return not a.dtype.isnative
105 return False
107def _clip_dep_invoke_with_casting(ufunc, *args, out=None, casting=None, **kwargs):
108 # normal path
109 if casting is not None:
110 return ufunc(*args, out=out, casting=casting, **kwargs)
112 # try to deal with broken casting rules
113 try:
114 return ufunc(*args, out=out, **kwargs)
115 except _exceptions._UFuncOutputCastingError as e:
116 # Numpy 1.17.0, 2019-02-24
117 warnings.warn(
118 "Converting the output of clip from {!r} to {!r} is deprecated. "
119 "Pass `casting=\"unsafe\"` explicitly to silence this warning, or "
120 "correct the type of the variables.".format(e.from_, e.to),
121 DeprecationWarning,
122 stacklevel=2
123 )
124 return ufunc(*args, out=out, casting="unsafe", **kwargs)
126def _clip(a, min=None, max=None, out=None, *, casting=None, **kwargs):
127 if min is None and max is None:
128 raise ValueError("One of max or min must be given")
130 # Numpy 1.17.0, 2019-02-24
131 # This deprecation probably incurs a substantial slowdown for small arrays,
132 # it will be good to get rid of it.
133 if not _clip_dep_is_byte_swapped(a) and not _clip_dep_is_byte_swapped(out):
134 using_deprecated_nan = False
135 if _clip_dep_is_scalar_nan(min):
136 min = -float('inf')
137 using_deprecated_nan = True
138 if _clip_dep_is_scalar_nan(max):
139 max = float('inf')
140 using_deprecated_nan = True
141 if using_deprecated_nan:
142 warnings.warn(
143 "Passing `np.nan` to mean no clipping in np.clip has always "
144 "been unreliable, and is now deprecated. "
145 "In future, this will always return nan, like it already does "
146 "when min or max are arrays that contain nan. "
147 "To skip a bound, pass either None or an np.inf of an "
148 "appropriate sign.",
149 DeprecationWarning,
150 stacklevel=2
151 )
153 if min is None:
154 return _clip_dep_invoke_with_casting(
155 um.minimum, a, max, out=out, casting=casting, **kwargs)
156 elif max is None:
157 return _clip_dep_invoke_with_casting(
158 um.maximum, a, min, out=out, casting=casting, **kwargs)
159 else:
160 return _clip_dep_invoke_with_casting(
161 um.clip, a, min, max, out=out, casting=casting, **kwargs)
163def _mean(a, axis=None, dtype=None, out=None, keepdims=False, *, where=True):
164 arr = asanyarray(a)
166 is_float16_result = False
168 rcount = _count_reduce_items(arr, axis, keepdims=keepdims, where=where)
169 if rcount == 0 if where is True else umr_any(rcount == 0, axis=None):
170 warnings.warn("Mean of empty slice.", RuntimeWarning, stacklevel=2)
172 # Cast bool, unsigned int, and int to float64 by default
173 if dtype is None:
174 if issubclass(arr.dtype.type, (nt.integer, nt.bool_)):
175 dtype = mu.dtype('f8')
176 elif issubclass(arr.dtype.type, nt.float16):
177 dtype = mu.dtype('f4')
178 is_float16_result = True
180 ret = umr_sum(arr, axis, dtype, out, keepdims, where=where)
181 if isinstance(ret, mu.ndarray):
182 ret = um.true_divide(
183 ret, rcount, out=ret, casting='unsafe', subok=False)
184 if is_float16_result and out is None:
185 ret = arr.dtype.type(ret)
186 elif hasattr(ret, 'dtype'):
187 if is_float16_result:
188 ret = arr.dtype.type(ret / rcount)
189 else:
190 ret = ret.dtype.type(ret / rcount)
191 else:
192 ret = ret / rcount
194 return ret
196def _var(a, axis=None, dtype=None, out=None, ddof=0, keepdims=False, *,
197 where=True):
198 arr = asanyarray(a)
200 rcount = _count_reduce_items(arr, axis, keepdims=keepdims, where=where)
201 # Make this warning show up on top.
202 if ddof >= rcount if where is True else umr_any(ddof >= rcount, axis=None):
203 warnings.warn("Degrees of freedom <= 0 for slice", RuntimeWarning,
204 stacklevel=2)
206 # Cast bool, unsigned int, and int to float64 by default
207 if dtype is None and issubclass(arr.dtype.type, (nt.integer, nt.bool_)):
208 dtype = mu.dtype('f8')
210 # Compute the mean.
211 # Note that if dtype is not of inexact type then arraymean will
212 # not be either.
213 arrmean = umr_sum(arr, axis, dtype, keepdims=True, where=where)
214 # The shape of rcount has to match arrmean to not change the shape of out
215 # in broadcasting. Otherwise, it cannot be stored back to arrmean.
216 if rcount.ndim == 0:
217 # fast-path for default case when where is True
218 div = rcount
219 else:
220 # matching rcount to arrmean when where is specified as array
221 div = rcount.reshape(arrmean.shape)
222 if isinstance(arrmean, mu.ndarray):
223 arrmean = um.true_divide(arrmean, div, out=arrmean, casting='unsafe',
224 subok=False)
225 elif hasattr(arrmean, "dtype"):
226 arrmean = arrmean.dtype.type(arrmean / rcount)
227 else:
228 arrmean = arrmean / rcount
230 # Compute sum of squared deviations from mean
231 # Note that x may not be inexact and that we need it to be an array,
232 # not a scalar.
233 x = asanyarray(arr - arrmean)
235 if issubclass(arr.dtype.type, (nt.floating, nt.integer)):
236 x = um.multiply(x, x, out=x)
237 # Fast-paths for built-in complex types
238 elif x.dtype in _complex_to_float:
239 xv = x.view(dtype=(_complex_to_float[x.dtype], (2,)))
240 um.multiply(xv, xv, out=xv)
241 x = um.add(xv[..., 0], xv[..., 1], out=x.real).real
242 # Most general case; includes handling object arrays containing imaginary
243 # numbers and complex types with non-native byteorder
244 else:
245 x = um.multiply(x, um.conjugate(x), out=x).real
247 ret = umr_sum(x, axis, dtype, out, keepdims=keepdims, where=where)
249 # Compute degrees of freedom and make sure it is not negative.
250 rcount = um.maximum(rcount - ddof, 0)
252 # divide by degrees of freedom
253 if isinstance(ret, mu.ndarray):
254 ret = um.true_divide(
255 ret, rcount, out=ret, casting='unsafe', subok=False)
256 elif hasattr(ret, 'dtype'):
257 ret = ret.dtype.type(ret / rcount)
258 else:
259 ret = ret / rcount
261 return ret
263def _std(a, axis=None, dtype=None, out=None, ddof=0, keepdims=False, *,
264 where=True):
265 ret = _var(a, axis=axis, dtype=dtype, out=out, ddof=ddof,
266 keepdims=keepdims, where=where)
268 if isinstance(ret, mu.ndarray):
269 ret = um.sqrt(ret, out=ret)
270 elif hasattr(ret, 'dtype'):
271 ret = ret.dtype.type(um.sqrt(ret))
272 else:
273 ret = um.sqrt(ret)
275 return ret
277def _ptp(a, axis=None, out=None, keepdims=False):
278 return um.subtract(
279 umr_maximum(a, axis, None, out, keepdims),
280 umr_minimum(a, axis, None, None, keepdims),
281 out
282 )
284def _dump(self, file, protocol=2):
285 if hasattr(file, 'write'):
286 ctx = nullcontext(file)
287 else:
288 ctx = open(os_fspath(file), "wb")
289 with ctx as f:
290 pickle.dump(self, f, protocol=protocol)
292def _dumps(self, protocol=2):
293 return pickle.dumps(self, protocol=protocol)