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
« prev ^ index » next coverage.py v6.4.4, created at 2023-07-17 14:22 -0600
1import functools
2import warnings
3import operator
4import types
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
11__all__ = ['logspace', 'linspace', 'geomspace']
14array_function_dispatch = functools.partial(
15 overrides.array_function_dispatch, module='numpy')
18def _linspace_dispatcher(start, stop, num=None, endpoint=None, retstep=None,
19 dtype=None, axis=None):
20 return (start, stop)
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.
29 Returns `num` evenly spaced samples, calculated over the
30 interval [`start`, `stop`].
32 The endpoint of the interval can optionally be excluded.
34 .. versionchanged:: 1.16.0
35 Non-scalar `start` and `stop` are now supported.
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)``
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.
65 .. versionadded:: 1.9.0
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.
72 .. versionadded:: 1.16.0
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
83 Size of spacing between samples.
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.
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)
104 Graphical illustration:
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()
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
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
130 dt = result_type(start, stop, float(num))
131 if dtype is None:
132 dtype = dt
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
161 y += start
163 if endpoint and num > 1:
164 y[-1] = stop
166 if axis != 0:
167 y = _nx.moveaxis(y, 0, axis)
169 if _nx.issubdtype(dtype, _nx.integer):
170 _nx.floor(y, out=y)
172 if retstep:
173 return y.astype(dtype, copy=False), step
174 else:
175 return y.astype(dtype, copy=False)
178def _logspace_dispatcher(start, stop, num=None, endpoint=None, base=None,
179 dtype=None, axis=None):
180 return (start, stop)
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.
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).
193 .. versionchanged:: 1.16.0
194 Non-scalar `start` and `stop` are now supported.
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.
224 .. versionadded:: 1.16.0
227 Returns
228 -------
229 samples : ndarray
230 `num` samples, equally spaced on a log scale.
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.
241 Notes
242 -----
243 Logspace is equivalent to the code
245 >>> y = np.linspace(start, stop, num=num, endpoint=endpoint)
246 ... # doctest: +SKIP
247 >>> power(base, y).astype(dtype)
248 ... # doctest: +SKIP
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. ])
259 Graphical illustration:
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()
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)
281def _geomspace_dispatcher(start, stop, num=None, endpoint=None, dtype=None,
282 axis=None):
283 return (start, stop)
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).
291 This is similar to `logspace`, but with endpoints specified directly.
292 Each output sample is a constant multiple of the previous.
294 .. versionchanged:: 1.16.0
295 Non-scalar `start` and `stop` are now supported.
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.
321 .. versionadded:: 1.16.0
323 Returns
324 -------
325 samples : ndarray
326 `num` samples, equally spaced on a log scale.
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.
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.)
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.])
354 Note that the above may not produce exact integers:
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])
361 Negative, decreasing, and complex inputs are allowed:
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])
374 Graphical illustration of `endpoint` parameter:
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()
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')
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)
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)
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
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)
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)
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
435 result = out_sign * result
437 if axis != 0:
438 result = _nx.moveaxis(result, 0, axis)
440 return result.astype(dtype, copy=False)
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.
448 This function errs on the side of being overly conservative.
449 """
450 Py_TPFLAGS_HEAPTYPE = 1 << 9
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
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
458 return True
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
475def add_newdoc(place, obj, doc, warn_on_python=True):
476 """
477 Add documentation to an existing object, typically one defined in C
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.
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`
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)``
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.
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.
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.
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:
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
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)