Coverage for /var/srv/projects/api.amasfac.comuna18.com/tmp/venv/lib/python3.9/site-packages/numpy/core/function_base.py: 25%

117 statements  

« prev     ^ index     » next       coverage.py v6.4.4, created at 2023-07-17 14:22 -0600

1import functools 

2import warnings 

3import operator 

4import types 

5 

6from . import numeric as _nx 

7from .numeric import result_type, NaN, asanyarray, ndim 

8from numpy.core.multiarray import add_docstring 

9from numpy.core import overrides 

10 

11__all__ = ['logspace', 'linspace', 'geomspace'] 

12 

13 

14array_function_dispatch = functools.partial( 

15 overrides.array_function_dispatch, module='numpy') 

16 

17 

18def _linspace_dispatcher(start, stop, num=None, endpoint=None, retstep=None, 

19 dtype=None, axis=None): 

20 return (start, stop) 

21 

22 

23@array_function_dispatch(_linspace_dispatcher) 

24def linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None, 

25 axis=0): 

26 """ 

27 Return evenly spaced numbers over a specified interval. 

28 

29 Returns `num` evenly spaced samples, calculated over the 

30 interval [`start`, `stop`]. 

31 

32 The endpoint of the interval can optionally be excluded. 

33 

34 .. versionchanged:: 1.16.0 

35 Non-scalar `start` and `stop` are now supported. 

36 

37 .. versionchanged:: 1.20.0 

38 Values are rounded towards ``-inf`` instead of ``0`` when an 

39 integer ``dtype`` is specified. The old behavior can 

40 still be obtained with ``np.linspace(start, stop, num).astype(int)`` 

41 

42 Parameters 

43 ---------- 

44 start : array_like 

45 The starting value of the sequence. 

46 stop : array_like 

47 The end value of the sequence, unless `endpoint` is set to False. 

48 In that case, the sequence consists of all but the last of ``num + 1`` 

49 evenly spaced samples, so that `stop` is excluded. Note that the step 

50 size changes when `endpoint` is False. 

51 num : int, optional 

52 Number of samples to generate. Default is 50. Must be non-negative. 

53 endpoint : bool, optional 

54 If True, `stop` is the last sample. Otherwise, it is not included. 

55 Default is True. 

56 retstep : bool, optional 

57 If True, return (`samples`, `step`), where `step` is the spacing 

58 between samples. 

59 dtype : dtype, optional 

60 The type of the output array. If `dtype` is not given, the data type 

61 is inferred from `start` and `stop`. The inferred dtype will never be 

62 an integer; `float` is chosen even if the arguments would produce an 

63 array of integers. 

64 

65 .. versionadded:: 1.9.0 

66 

67 axis : int, optional 

68 The axis in the result to store the samples. Relevant only if start 

69 or stop are array-like. By default (0), the samples will be along a 

70 new axis inserted at the beginning. Use -1 to get an axis at the end. 

71 

72 .. versionadded:: 1.16.0 

73 

74 Returns 

75 ------- 

76 samples : ndarray 

77 There are `num` equally spaced samples in the closed interval 

78 ``[start, stop]`` or the half-open interval ``[start, stop)`` 

79 (depending on whether `endpoint` is True or False). 

80 step : float, optional 

81 Only returned if `retstep` is True 

82 

83 Size of spacing between samples. 

84 

85 

86 See Also 

87 -------- 

88 arange : Similar to `linspace`, but uses a step size (instead of the 

89 number of samples). 

90 geomspace : Similar to `linspace`, but with numbers spaced evenly on a log 

91 scale (a geometric progression). 

92 logspace : Similar to `geomspace`, but with the end points specified as 

93 logarithms. 

94 

95 Examples 

96 -------- 

97 >>> np.linspace(2.0, 3.0, num=5) 

98 array([2. , 2.25, 2.5 , 2.75, 3. ]) 

99 >>> np.linspace(2.0, 3.0, num=5, endpoint=False) 

100 array([2. , 2.2, 2.4, 2.6, 2.8]) 

101 >>> np.linspace(2.0, 3.0, num=5, retstep=True) 

102 (array([2. , 2.25, 2.5 , 2.75, 3. ]), 0.25) 

103 

104 Graphical illustration: 

105 

106 >>> import matplotlib.pyplot as plt 

107 >>> N = 8 

108 >>> y = np.zeros(N) 

109 >>> x1 = np.linspace(0, 10, N, endpoint=True) 

110 >>> x2 = np.linspace(0, 10, N, endpoint=False) 

111 >>> plt.plot(x1, y, 'o') 

112 [<matplotlib.lines.Line2D object at 0x...>] 

113 >>> plt.plot(x2, y + 0.5, 'o') 

114 [<matplotlib.lines.Line2D object at 0x...>] 

115 >>> plt.ylim([-0.5, 1]) 

116 (-0.5, 1) 

117 >>> plt.show() 

118 

119 """ 

120 num = operator.index(num) 

121 if num < 0: 

122 raise ValueError("Number of samples, %s, must be non-negative." % num) 

123 div = (num - 1) if endpoint else num 

124 

125 # Convert float/complex array scalars to float, gh-3504 

126 # and make sure one can use variables that have an __array_interface__, gh-6634 

127 start = asanyarray(start) * 1.0 

128 stop = asanyarray(stop) * 1.0 

129 

130 dt = result_type(start, stop, float(num)) 

131 if dtype is None: 

132 dtype = dt 

133 

134 delta = stop - start 

135 y = _nx.arange(0, num, dtype=dt).reshape((-1,) + (1,) * ndim(delta)) 

136 # In-place multiplication y *= delta/div is faster, but prevents the multiplicant 

137 # from overriding what class is produced, and thus prevents, e.g. use of Quantities, 

138 # see gh-7142. Hence, we multiply in place only for standard scalar types. 

139 _mult_inplace = _nx.isscalar(delta) 

140 if div > 0: 

141 step = delta / div 

142 if _nx.any(step == 0): 

143 # Special handling for denormal numbers, gh-5437 

144 y /= div 

145 if _mult_inplace: 

146 y *= delta 

147 else: 

148 y = y * delta 

149 else: 

150 if _mult_inplace: 

151 y *= step 

152 else: 

153 y = y * step 

154 else: 

155 # sequences with 0 items or 1 item with endpoint=True (i.e. div <= 0) 

156 # have an undefined step 

157 step = NaN 

158 # Multiply with delta to allow possible override of output class. 

159 y = y * delta 

160 

161 y += start 

162 

163 if endpoint and num > 1: 

164 y[-1] = stop 

165 

166 if axis != 0: 

167 y = _nx.moveaxis(y, 0, axis) 

168 

169 if _nx.issubdtype(dtype, _nx.integer): 

170 _nx.floor(y, out=y) 

171 

172 if retstep: 

173 return y.astype(dtype, copy=False), step 

174 else: 

175 return y.astype(dtype, copy=False) 

176 

177 

178def _logspace_dispatcher(start, stop, num=None, endpoint=None, base=None, 

179 dtype=None, axis=None): 

180 return (start, stop) 

181 

182 

183@array_function_dispatch(_logspace_dispatcher) 

184def logspace(start, stop, num=50, endpoint=True, base=10.0, dtype=None, 

185 axis=0): 

186 """ 

187 Return numbers spaced evenly on a log scale. 

188 

189 In linear space, the sequence starts at ``base ** start`` 

190 (`base` to the power of `start`) and ends with ``base ** stop`` 

191 (see `endpoint` below). 

192 

193 .. versionchanged:: 1.16.0 

194 Non-scalar `start` and `stop` are now supported. 

195 

196 Parameters 

197 ---------- 

198 start : array_like 

199 ``base ** start`` is the starting value of the sequence. 

200 stop : array_like 

201 ``base ** stop`` is the final value of the sequence, unless `endpoint` 

202 is False. In that case, ``num + 1`` values are spaced over the 

203 interval in log-space, of which all but the last (a sequence of 

204 length `num`) are returned. 

205 num : integer, optional 

206 Number of samples to generate. Default is 50. 

207 endpoint : boolean, optional 

208 If true, `stop` is the last sample. Otherwise, it is not included. 

209 Default is True. 

210 base : array_like, optional 

211 The base of the log space. The step size between the elements in 

212 ``ln(samples) / ln(base)`` (or ``log_base(samples)``) is uniform. 

213 Default is 10.0. 

214 dtype : dtype 

215 The type of the output array. If `dtype` is not given, the data type 

216 is inferred from `start` and `stop`. The inferred type will never be 

217 an integer; `float` is chosen even if the arguments would produce an 

218 array of integers. 

219 axis : int, optional 

220 The axis in the result to store the samples. Relevant only if start 

221 or stop are array-like. By default (0), the samples will be along a 

222 new axis inserted at the beginning. Use -1 to get an axis at the end. 

223 

224 .. versionadded:: 1.16.0 

225 

226 

227 Returns 

228 ------- 

229 samples : ndarray 

230 `num` samples, equally spaced on a log scale. 

231 

232 See Also 

233 -------- 

234 arange : Similar to linspace, with the step size specified instead of the 

235 number of samples. Note that, when used with a float endpoint, the 

236 endpoint may or may not be included. 

237 linspace : Similar to logspace, but with the samples uniformly distributed 

238 in linear space, instead of log space. 

239 geomspace : Similar to logspace, but with endpoints specified directly. 

240 

241 Notes 

242 ----- 

243 Logspace is equivalent to the code 

244 

245 >>> y = np.linspace(start, stop, num=num, endpoint=endpoint) 

246 ... # doctest: +SKIP 

247 >>> power(base, y).astype(dtype) 

248 ... # doctest: +SKIP 

249 

250 Examples 

251 -------- 

252 >>> np.logspace(2.0, 3.0, num=4) 

253 array([ 100. , 215.443469 , 464.15888336, 1000. ]) 

254 >>> np.logspace(2.0, 3.0, num=4, endpoint=False) 

255 array([100. , 177.827941 , 316.22776602, 562.34132519]) 

256 >>> np.logspace(2.0, 3.0, num=4, base=2.0) 

257 array([4. , 5.0396842 , 6.34960421, 8. ]) 

258 

259 Graphical illustration: 

260 

261 >>> import matplotlib.pyplot as plt 

262 >>> N = 10 

263 >>> x1 = np.logspace(0.1, 1, N, endpoint=True) 

264 >>> x2 = np.logspace(0.1, 1, N, endpoint=False) 

265 >>> y = np.zeros(N) 

266 >>> plt.plot(x1, y, 'o') 

267 [<matplotlib.lines.Line2D object at 0x...>] 

268 >>> plt.plot(x2, y + 0.5, 'o') 

269 [<matplotlib.lines.Line2D object at 0x...>] 

270 >>> plt.ylim([-0.5, 1]) 

271 (-0.5, 1) 

272 >>> plt.show() 

273 

274 """ 

275 y = linspace(start, stop, num=num, endpoint=endpoint, axis=axis) 

276 if dtype is None: 

277 return _nx.power(base, y) 

278 return _nx.power(base, y).astype(dtype, copy=False) 

279 

280 

281def _geomspace_dispatcher(start, stop, num=None, endpoint=None, dtype=None, 

282 axis=None): 

283 return (start, stop) 

284 

285 

286@array_function_dispatch(_geomspace_dispatcher) 

287def geomspace(start, stop, num=50, endpoint=True, dtype=None, axis=0): 

288 """ 

289 Return numbers spaced evenly on a log scale (a geometric progression). 

290 

291 This is similar to `logspace`, but with endpoints specified directly. 

292 Each output sample is a constant multiple of the previous. 

293 

294 .. versionchanged:: 1.16.0 

295 Non-scalar `start` and `stop` are now supported. 

296 

297 Parameters 

298 ---------- 

299 start : array_like 

300 The starting value of the sequence. 

301 stop : array_like 

302 The final value of the sequence, unless `endpoint` is False. 

303 In that case, ``num + 1`` values are spaced over the 

304 interval in log-space, of which all but the last (a sequence of 

305 length `num`) are returned. 

306 num : integer, optional 

307 Number of samples to generate. Default is 50. 

308 endpoint : boolean, optional 

309 If true, `stop` is the last sample. Otherwise, it is not included. 

310 Default is True. 

311 dtype : dtype 

312 The type of the output array. If `dtype` is not given, the data type 

313 is inferred from `start` and `stop`. The inferred dtype will never be 

314 an integer; `float` is chosen even if the arguments would produce an 

315 array of integers. 

316 axis : int, optional 

317 The axis in the result to store the samples. Relevant only if start 

318 or stop are array-like. By default (0), the samples will be along a 

319 new axis inserted at the beginning. Use -1 to get an axis at the end. 

320 

321 .. versionadded:: 1.16.0 

322 

323 Returns 

324 ------- 

325 samples : ndarray 

326 `num` samples, equally spaced on a log scale. 

327 

328 See Also 

329 -------- 

330 logspace : Similar to geomspace, but with endpoints specified using log 

331 and base. 

332 linspace : Similar to geomspace, but with arithmetic instead of geometric 

333 progression. 

334 arange : Similar to linspace, with the step size specified instead of the 

335 number of samples. 

336 

337 Notes 

338 ----- 

339 If the inputs or dtype are complex, the output will follow a logarithmic 

340 spiral in the complex plane. (There are an infinite number of spirals 

341 passing through two points; the output will follow the shortest such path.) 

342 

343 Examples 

344 -------- 

345 >>> np.geomspace(1, 1000, num=4) 

346 array([ 1., 10., 100., 1000.]) 

347 >>> np.geomspace(1, 1000, num=3, endpoint=False) 

348 array([ 1., 10., 100.]) 

349 >>> np.geomspace(1, 1000, num=4, endpoint=False) 

350 array([ 1. , 5.62341325, 31.6227766 , 177.827941 ]) 

351 >>> np.geomspace(1, 256, num=9) 

352 array([ 1., 2., 4., 8., 16., 32., 64., 128., 256.]) 

353 

354 Note that the above may not produce exact integers: 

355 

356 >>> np.geomspace(1, 256, num=9, dtype=int) 

357 array([ 1, 2, 4, 7, 16, 32, 63, 127, 256]) 

358 >>> np.around(np.geomspace(1, 256, num=9)).astype(int) 

359 array([ 1, 2, 4, 8, 16, 32, 64, 128, 256]) 

360 

361 Negative, decreasing, and complex inputs are allowed: 

362 

363 >>> np.geomspace(1000, 1, num=4) 

364 array([1000., 100., 10., 1.]) 

365 >>> np.geomspace(-1000, -1, num=4) 

366 array([-1000., -100., -10., -1.]) 

367 >>> np.geomspace(1j, 1000j, num=4) # Straight line 

368 array([0. +1.j, 0. +10.j, 0. +100.j, 0.+1000.j]) 

369 >>> np.geomspace(-1+0j, 1+0j, num=5) # Circle 

370 array([-1.00000000e+00+1.22464680e-16j, -7.07106781e-01+7.07106781e-01j, 

371 6.12323400e-17+1.00000000e+00j, 7.07106781e-01+7.07106781e-01j, 

372 1.00000000e+00+0.00000000e+00j]) 

373 

374 Graphical illustration of `endpoint` parameter: 

375 

376 >>> import matplotlib.pyplot as plt 

377 >>> N = 10 

378 >>> y = np.zeros(N) 

379 >>> plt.semilogx(np.geomspace(1, 1000, N, endpoint=True), y + 1, 'o') 

380 [<matplotlib.lines.Line2D object at 0x...>] 

381 >>> plt.semilogx(np.geomspace(1, 1000, N, endpoint=False), y + 2, 'o') 

382 [<matplotlib.lines.Line2D object at 0x...>] 

383 >>> plt.axis([0.5, 2000, 0, 3]) 

384 [0.5, 2000, 0, 3] 

385 >>> plt.grid(True, color='0.7', linestyle='-', which='both', axis='both') 

386 >>> plt.show() 

387 

388 """ 

389 start = asanyarray(start) 

390 stop = asanyarray(stop) 

391 if _nx.any(start == 0) or _nx.any(stop == 0): 

392 raise ValueError('Geometric sequence cannot include zero') 

393 

394 dt = result_type(start, stop, float(num), _nx.zeros((), dtype)) 

395 if dtype is None: 

396 dtype = dt 

397 else: 

398 # complex to dtype('complex128'), for instance 

399 dtype = _nx.dtype(dtype) 

400 

401 # Promote both arguments to the same dtype in case, for instance, one is 

402 # complex and another is negative and log would produce NaN otherwise. 

403 # Copy since we may change things in-place further down. 

404 start = start.astype(dt, copy=True) 

405 stop = stop.astype(dt, copy=True) 

406 

407 out_sign = _nx.ones(_nx.broadcast(start, stop).shape, dt) 

408 # Avoid negligible real or imaginary parts in output by rotating to 

409 # positive real, calculating, then undoing rotation 

410 if _nx.issubdtype(dt, _nx.complexfloating): 

411 all_imag = (start.real == 0.) & (stop.real == 0.) 

412 if _nx.any(all_imag): 

413 start[all_imag] = start[all_imag].imag 

414 stop[all_imag] = stop[all_imag].imag 

415 out_sign[all_imag] = 1j 

416 

417 both_negative = (_nx.sign(start) == -1) & (_nx.sign(stop) == -1) 

418 if _nx.any(both_negative): 

419 _nx.negative(start, out=start, where=both_negative) 

420 _nx.negative(stop, out=stop, where=both_negative) 

421 _nx.negative(out_sign, out=out_sign, where=both_negative) 

422 

423 log_start = _nx.log10(start) 

424 log_stop = _nx.log10(stop) 

425 result = logspace(log_start, log_stop, num=num, 

426 endpoint=endpoint, base=10.0, dtype=dtype) 

427 

428 # Make sure the endpoints match the start and stop arguments. This is 

429 # necessary because np.exp(np.log(x)) is not necessarily equal to x. 

430 if num > 0: 

431 result[0] = start 

432 if num > 1 and endpoint: 

433 result[-1] = stop 

434 

435 result = out_sign * result 

436 

437 if axis != 0: 

438 result = _nx.moveaxis(result, 0, axis) 

439 

440 return result.astype(dtype, copy=False) 

441 

442 

443def _needs_add_docstring(obj): 

444 """ 

445 Returns true if the only way to set the docstring of `obj` from python is 

446 via add_docstring. 

447 

448 This function errs on the side of being overly conservative. 

449 """ 

450 Py_TPFLAGS_HEAPTYPE = 1 << 9 

451 

452 if isinstance(obj, (types.FunctionType, types.MethodType, property)): 452 ↛ 453line 452 didn't jump to line 453, because the condition on line 452 was never true

453 return False 

454 

455 if isinstance(obj, type) and obj.__flags__ & Py_TPFLAGS_HEAPTYPE: 455 ↛ 456line 455 didn't jump to line 456, because the condition on line 455 was never true

456 return False 

457 

458 return True 

459 

460 

461def _add_docstring(obj, doc, warn_on_python): 

462 if warn_on_python and not _needs_add_docstring(obj): 462 ↛ 463line 462 didn't jump to line 463, because the condition on line 462 was never true

463 warnings.warn( 

464 "add_newdoc was used on a pure-python object {}. " 

465 "Prefer to attach it directly to the source." 

466 .format(obj), 

467 UserWarning, 

468 stacklevel=3) 

469 try: 

470 add_docstring(obj, doc) 

471 except Exception: 

472 pass 

473 

474 

475def add_newdoc(place, obj, doc, warn_on_python=True): 

476 """ 

477 Add documentation to an existing object, typically one defined in C 

478 

479 The purpose is to allow easier editing of the docstrings without requiring 

480 a re-compile. This exists primarily for internal use within numpy itself. 

481 

482 Parameters 

483 ---------- 

484 place : str 

485 The absolute name of the module to import from 

486 obj : str 

487 The name of the object to add documentation to, typically a class or 

488 function name 

489 doc : {str, Tuple[str, str], List[Tuple[str, str]]} 

490 If a string, the documentation to apply to `obj` 

491 

492 If a tuple, then the first element is interpreted as an attribute of 

493 `obj` and the second as the docstring to apply - ``(method, docstring)`` 

494 

495 If a list, then each element of the list should be a tuple of length 

496 two - ``[(method1, docstring1), (method2, docstring2), ...]`` 

497 warn_on_python : bool 

498 If True, the default, emit `UserWarning` if this is used to attach 

499 documentation to a pure-python object. 

500 

501 Notes 

502 ----- 

503 This routine never raises an error if the docstring can't be written, but 

504 will raise an error if the object being documented does not exist. 

505 

506 This routine cannot modify read-only docstrings, as appear 

507 in new-style classes or built-in functions. Because this 

508 routine never raises an error the caller must check manually 

509 that the docstrings were changed. 

510 

511 Since this function grabs the ``char *`` from a c-level str object and puts 

512 it into the ``tp_doc`` slot of the type of `obj`, it violates a number of 

513 C-API best-practices, by: 

514 

515 - modifying a `PyTypeObject` after calling `PyType_Ready` 

516 - calling `Py_INCREF` on the str and losing the reference, so the str 

517 will never be released 

518 

519 If possible it should be avoided. 

520 """ 

521 new = getattr(__import__(place, globals(), {}, [obj]), obj) 

522 if isinstance(doc, str): 

523 _add_docstring(new, doc.strip(), warn_on_python) 

524 elif isinstance(doc, tuple): 524 ↛ 527line 524 didn't jump to line 527, because the condition on line 524 was never false

525 attr, docstring = doc 

526 _add_docstring(getattr(new, attr), docstring.strip(), warn_on_python) 

527 elif isinstance(doc, list): 

528 for attr, docstring in doc: 

529 _add_docstring(getattr(new, attr), docstring.strip(), warn_on_python)