Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/numpy/core/function_base.py: 31%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

120 statements  

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 :ref:`how-to-partition` 

95 

96 Examples 

97 -------- 

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

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

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

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

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

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

104 

105 Graphical illustration: 

106 

107 >>> import matplotlib.pyplot as plt 

108 >>> N = 8 

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

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

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

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

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

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

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

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

117 (-0.5, 1) 

118 >>> plt.show() 

119 

120 """ 

121 num = operator.index(num) 

122 if num < 0: 

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

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

125 

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

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

128 start = asanyarray(start) * 1.0 

129 stop = asanyarray(stop) * 1.0 

130 

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

132 if dtype is None: 

133 dtype = dt 

134 integer_dtype = False 

135 else: 

136 integer_dtype = _nx.issubdtype(dtype, _nx.integer) 

137 

138 delta = stop - start 

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

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

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

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

143 if div > 0: 

144 _mult_inplace = _nx.isscalar(delta) 

145 step = delta / div 

146 any_step_zero = ( 

147 step == 0 if _mult_inplace else _nx.asanyarray(step == 0).any()) 

148 if any_step_zero: 

149 # Special handling for denormal numbers, gh-5437 

150 y /= div 

151 if _mult_inplace: 

152 y *= delta 

153 else: 

154 y = y * delta 

155 else: 

156 if _mult_inplace: 

157 y *= step 

158 else: 

159 y = y * step 

160 else: 

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

162 # have an undefined step 

163 step = NaN 

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

165 y = y * delta 

166 

167 y += start 

168 

169 if endpoint and num > 1: 

170 y[-1] = stop 

171 

172 if axis != 0: 

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

174 

175 if integer_dtype: 

176 _nx.floor(y, out=y) 

177 

178 if retstep: 

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

180 else: 

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

182 

183 

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

185 dtype=None, axis=None): 

186 return (start, stop) 

187 

188 

189@array_function_dispatch(_logspace_dispatcher) 

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

191 axis=0): 

192 """ 

193 Return numbers spaced evenly on a log scale. 

194 

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

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

197 (see `endpoint` below). 

198 

199 .. versionchanged:: 1.16.0 

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

201 

202 Parameters 

203 ---------- 

204 start : array_like 

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

206 stop : array_like 

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

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

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

210 length `num`) are returned. 

211 num : integer, optional 

212 Number of samples to generate. Default is 50. 

213 endpoint : boolean, optional 

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

215 Default is True. 

216 base : array_like, optional 

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

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

219 Default is 10.0. 

220 dtype : dtype 

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

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

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

224 array of integers. 

225 axis : int, optional 

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

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

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

229 

230 .. versionadded:: 1.16.0 

231 

232 

233 Returns 

234 ------- 

235 samples : ndarray 

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

237 

238 See Also 

239 -------- 

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

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

242 endpoint may or may not be included. 

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

244 in linear space, instead of log space. 

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

246 :ref:`how-to-partition` 

247 

248 Notes 

249 ----- 

250 Logspace is equivalent to the code 

251 

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

253 ... # doctest: +SKIP 

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

255 ... # doctest: +SKIP 

256 

257 Examples 

258 -------- 

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

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

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

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

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

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

265 

266 Graphical illustration: 

267 

268 >>> import matplotlib.pyplot as plt 

269 >>> N = 10 

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

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

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

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

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

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

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

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

278 (-0.5, 1) 

279 >>> plt.show() 

280 

281 """ 

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

283 if dtype is None: 

284 return _nx.power(base, y) 

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

286 

287 

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

289 axis=None): 

290 return (start, stop) 

291 

292 

293@array_function_dispatch(_geomspace_dispatcher) 

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

295 """ 

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

297 

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

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

300 

301 .. versionchanged:: 1.16.0 

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

303 

304 Parameters 

305 ---------- 

306 start : array_like 

307 The starting value of the sequence. 

308 stop : array_like 

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

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

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

312 length `num`) are returned. 

313 num : integer, optional 

314 Number of samples to generate. Default is 50. 

315 endpoint : boolean, optional 

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

317 Default is True. 

318 dtype : dtype 

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

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

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

322 array of integers. 

323 axis : int, optional 

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

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

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

327 

328 .. versionadded:: 1.16.0 

329 

330 Returns 

331 ------- 

332 samples : ndarray 

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

334 

335 See Also 

336 -------- 

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

338 and base. 

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

340 progression. 

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

342 number of samples. 

343 :ref:`how-to-partition` 

344 

345 Notes 

346 ----- 

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

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

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

350 

351 Examples 

352 -------- 

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

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

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

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

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

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

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

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

361 

362 Note that the above may not produce exact integers: 

363 

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

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

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

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

368 

369 Negative, decreasing, and complex inputs are allowed: 

370 

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

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

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

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

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

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

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

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

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

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

381 

382 Graphical illustration of `endpoint` parameter: 

383 

384 >>> import matplotlib.pyplot as plt 

385 >>> N = 10 

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

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

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

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

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

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

392 [0.5, 2000, 0, 3] 

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

394 >>> plt.show() 

395 

396 """ 

397 start = asanyarray(start) 

398 stop = asanyarray(stop) 

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

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

401 

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

403 if dtype is None: 

404 dtype = dt 

405 else: 

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

407 dtype = _nx.dtype(dtype) 

408 

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

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

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

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

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

414 

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

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

417 # positive real, calculating, then undoing rotation 

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

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

420 if _nx.any(all_imag): 

421 start[all_imag] = start[all_imag].imag 

422 stop[all_imag] = stop[all_imag].imag 

423 out_sign[all_imag] = 1j 

424 

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

426 if _nx.any(both_negative): 

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

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

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

430 

431 log_start = _nx.log10(start) 

432 log_stop = _nx.log10(stop) 

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

434 endpoint=endpoint, base=10.0, dtype=dtype) 

435 

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

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

438 if num > 0: 

439 result[0] = start 

440 if num > 1 and endpoint: 

441 result[-1] = stop 

442 

443 result = out_sign * result 

444 

445 if axis != 0: 

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

447 

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

449 

450 

451def _needs_add_docstring(obj): 

452 """ 

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

454 via add_docstring. 

455 

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

457 """ 

458 Py_TPFLAGS_HEAPTYPE = 1 << 9 

459 

460 if isinstance(obj, (types.FunctionType, types.MethodType, property)): 

461 return False 

462 

463 if isinstance(obj, type) and obj.__flags__ & Py_TPFLAGS_HEAPTYPE: 

464 return False 

465 

466 return True 

467 

468 

469def _add_docstring(obj, doc, warn_on_python): 

470 if warn_on_python and not _needs_add_docstring(obj): 

471 warnings.warn( 

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

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

474 .format(obj), 

475 UserWarning, 

476 stacklevel=3) 

477 try: 

478 add_docstring(obj, doc) 

479 except Exception: 

480 pass 

481 

482 

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

484 """ 

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

486 

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

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

489 

490 Parameters 

491 ---------- 

492 place : str 

493 The absolute name of the module to import from 

494 obj : str 

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

496 function name 

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

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

499 

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

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

502 

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

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

505 warn_on_python : bool 

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

507 documentation to a pure-python object. 

508 

509 Notes 

510 ----- 

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

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

513 

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

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

516 routine never raises an error the caller must check manually 

517 that the docstrings were changed. 

518 

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

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

521 C-API best-practices, by: 

522 

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

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

525 will never be released 

526 

527 If possible it should be avoided. 

528 """ 

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

530 if isinstance(doc, str): 

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

532 elif isinstance(doc, tuple): 

533 attr, docstring = doc 

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

535 elif isinstance(doc, list): 

536 for attr, docstring in doc: 

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