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

1""" 

2Array methods which are called by both the C-code for the method 

3and the Python code for the NumPy-namespace function 

4 

5""" 

6import warnings 

7from contextlib import nullcontext 

8 

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 

16 

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 

24 

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 }) 

35 

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) 

41 

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) 

45 

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) 

49 

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) 

53 

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) 

59 

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) 

65 

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. 

81 

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 

88 

89# Numpy 1.17.0, 2019-02-24 

90# Various clip behavior deprecations, marked with _clip_dep as a prefix. 

91 

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 

101 

102def _clip_dep_is_byte_swapped(a): 

103 if isinstance(a, mu.ndarray): 

104 return not a.dtype.isnative 

105 return False 

106 

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) 

111 

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) 

125 

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") 

129 

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 ) 

152 

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) 

162 

163def _mean(a, axis=None, dtype=None, out=None, keepdims=False, *, where=True): 

164 arr = asanyarray(a) 

165 

166 is_float16_result = False 

167 

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) 

171 

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 

179 

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 

193 

194 return ret 

195 

196def _var(a, axis=None, dtype=None, out=None, ddof=0, keepdims=False, *, 

197 where=True): 

198 arr = asanyarray(a) 

199 

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) 

205 

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') 

209 

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 

229 

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) 

234 

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 

246 

247 ret = umr_sum(x, axis, dtype, out, keepdims=keepdims, where=where) 

248 

249 # Compute degrees of freedom and make sure it is not negative. 

250 rcount = um.maximum(rcount - ddof, 0) 

251 

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 

260 

261 return ret 

262 

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) 

267 

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) 

274 

275 return ret 

276 

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 ) 

283 

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) 

291 

292def _dumps(self, protocol=2): 

293 return pickle.dumps(self, protocol=protocol)