Spaces:
Paused
Paused
import functools | |
import itertools | |
import operator | |
import sys | |
import warnings | |
import numbers | |
import numpy as np | |
from . import multiarray | |
from .multiarray import ( | |
_fastCopyAndTranspose as fastCopyAndTranspose, ALLOW_THREADS, | |
BUFSIZE, CLIP, MAXDIMS, MAY_SHARE_BOUNDS, MAY_SHARE_EXACT, RAISE, | |
WRAP, arange, array, asarray, asanyarray, ascontiguousarray, | |
asfortranarray, broadcast, can_cast, compare_chararrays, | |
concatenate, copyto, dot, dtype, empty, | |
empty_like, flatiter, frombuffer, fromfile, fromiter, fromstring, | |
inner, lexsort, matmul, may_share_memory, | |
min_scalar_type, ndarray, nditer, nested_iters, promote_types, | |
putmask, result_type, set_numeric_ops, shares_memory, vdot, where, | |
zeros, normalize_axis_index) | |
from . import overrides | |
from . import umath | |
from . import shape_base | |
from .overrides import set_array_function_like_doc, set_module | |
from .umath import (multiply, invert, sin, PINF, NAN) | |
from . import numerictypes | |
from .numerictypes import longlong, intc, int_, float_, complex_, bool_ | |
from ._exceptions import TooHardError, AxisError | |
from ._ufunc_config import errstate | |
bitwise_not = invert | |
ufunc = type(sin) | |
newaxis = None | |
array_function_dispatch = functools.partial( | |
overrides.array_function_dispatch, module='numpy') | |
__all__ = [ | |
'newaxis', 'ndarray', 'flatiter', 'nditer', 'nested_iters', 'ufunc', | |
'arange', 'array', 'asarray', 'asanyarray', 'ascontiguousarray', | |
'asfortranarray', 'zeros', 'count_nonzero', 'empty', 'broadcast', 'dtype', | |
'fromstring', 'fromfile', 'frombuffer', 'where', | |
'argwhere', 'copyto', 'concatenate', 'fastCopyAndTranspose', 'lexsort', | |
'set_numeric_ops', 'can_cast', 'promote_types', 'min_scalar_type', | |
'result_type', 'isfortran', 'empty_like', 'zeros_like', 'ones_like', | |
'correlate', 'convolve', 'inner', 'dot', 'outer', 'vdot', 'roll', | |
'rollaxis', 'moveaxis', 'cross', 'tensordot', 'little_endian', | |
'fromiter', 'array_equal', 'array_equiv', 'indices', 'fromfunction', | |
'isclose', 'isscalar', 'binary_repr', 'base_repr', 'ones', | |
'identity', 'allclose', 'compare_chararrays', 'putmask', | |
'flatnonzero', 'Inf', 'inf', 'infty', 'Infinity', 'nan', 'NaN', | |
'False_', 'True_', 'bitwise_not', 'CLIP', 'RAISE', 'WRAP', 'MAXDIMS', | |
'BUFSIZE', 'ALLOW_THREADS', 'ComplexWarning', 'full', 'full_like', | |
'matmul', 'shares_memory', 'may_share_memory', 'MAY_SHARE_BOUNDS', | |
'MAY_SHARE_EXACT', 'TooHardError', 'AxisError'] | |
class ComplexWarning(RuntimeWarning): | |
""" | |
The warning raised when casting a complex dtype to a real dtype. | |
As implemented, casting a complex number to a real discards its imaginary | |
part, but this behavior may not be what the user actually wants. | |
""" | |
pass | |
def _zeros_like_dispatcher(a, dtype=None, order=None, subok=None, shape=None): | |
return (a,) | |
def zeros_like(a, dtype=None, order='K', subok=True, shape=None): | |
""" | |
Return an array of zeros with the same shape and type as a given array. | |
Parameters | |
---------- | |
a : array_like | |
The shape and data-type of `a` define these same attributes of | |
the returned array. | |
dtype : data-type, optional | |
Overrides the data type of the result. | |
.. versionadded:: 1.6.0 | |
order : {'C', 'F', 'A', or 'K'}, optional | |
Overrides the memory layout of the result. 'C' means C-order, | |
'F' means F-order, 'A' means 'F' if `a` is Fortran contiguous, | |
'C' otherwise. 'K' means match the layout of `a` as closely | |
as possible. | |
.. versionadded:: 1.6.0 | |
subok : bool, optional. | |
If True, then the newly created array will use the sub-class | |
type of `a`, otherwise it will be a base-class array. Defaults | |
to True. | |
shape : int or sequence of ints, optional. | |
Overrides the shape of the result. If order='K' and the number of | |
dimensions is unchanged, will try to keep order, otherwise, | |
order='C' is implied. | |
.. versionadded:: 1.17.0 | |
Returns | |
------- | |
out : ndarray | |
Array of zeros with the same shape and type as `a`. | |
See Also | |
-------- | |
empty_like : Return an empty array with shape and type of input. | |
ones_like : Return an array of ones with shape and type of input. | |
full_like : Return a new array with shape of input filled with value. | |
zeros : Return a new array setting values to zero. | |
Examples | |
-------- | |
>>> x = np.arange(6) | |
>>> x = x.reshape((2, 3)) | |
>>> x | |
array([[0, 1, 2], | |
[3, 4, 5]]) | |
>>> np.zeros_like(x) | |
array([[0, 0, 0], | |
[0, 0, 0]]) | |
>>> y = np.arange(3, dtype=float) | |
>>> y | |
array([0., 1., 2.]) | |
>>> np.zeros_like(y) | |
array([0., 0., 0.]) | |
""" | |
res = empty_like(a, dtype=dtype, order=order, subok=subok, shape=shape) | |
# needed instead of a 0 to get same result as zeros for for string dtypes | |
z = zeros(1, dtype=res.dtype) | |
multiarray.copyto(res, z, casting='unsafe') | |
return res | |
def _ones_dispatcher(shape, dtype=None, order=None, *, like=None): | |
return(like,) | |
def ones(shape, dtype=None, order='C', *, like=None): | |
""" | |
Return a new array of given shape and type, filled with ones. | |
Parameters | |
---------- | |
shape : int or sequence of ints | |
Shape of the new array, e.g., ``(2, 3)`` or ``2``. | |
dtype : data-type, optional | |
The desired data-type for the array, e.g., `numpy.int8`. Default is | |
`numpy.float64`. | |
order : {'C', 'F'}, optional, default: C | |
Whether to store multi-dimensional data in row-major | |
(C-style) or column-major (Fortran-style) order in | |
memory. | |
${ARRAY_FUNCTION_LIKE} | |
.. versionadded:: 1.20.0 | |
Returns | |
------- | |
out : ndarray | |
Array of ones with the given shape, dtype, and order. | |
See Also | |
-------- | |
ones_like : Return an array of ones with shape and type of input. | |
empty : Return a new uninitialized array. | |
zeros : Return a new array setting values to zero. | |
full : Return a new array of given shape filled with value. | |
Examples | |
-------- | |
>>> np.ones(5) | |
array([1., 1., 1., 1., 1.]) | |
>>> np.ones((5,), dtype=int) | |
array([1, 1, 1, 1, 1]) | |
>>> np.ones((2, 1)) | |
array([[1.], | |
[1.]]) | |
>>> s = (2,2) | |
>>> np.ones(s) | |
array([[1., 1.], | |
[1., 1.]]) | |
""" | |
if like is not None: | |
return _ones_with_like(shape, dtype=dtype, order=order, like=like) | |
a = empty(shape, dtype, order) | |
multiarray.copyto(a, 1, casting='unsafe') | |
return a | |
_ones_with_like = array_function_dispatch( | |
_ones_dispatcher | |
)(ones) | |
def _ones_like_dispatcher(a, dtype=None, order=None, subok=None, shape=None): | |
return (a,) | |
def ones_like(a, dtype=None, order='K', subok=True, shape=None): | |
""" | |
Return an array of ones with the same shape and type as a given array. | |
Parameters | |
---------- | |
a : array_like | |
The shape and data-type of `a` define these same attributes of | |
the returned array. | |
dtype : data-type, optional | |
Overrides the data type of the result. | |
.. versionadded:: 1.6.0 | |
order : {'C', 'F', 'A', or 'K'}, optional | |
Overrides the memory layout of the result. 'C' means C-order, | |
'F' means F-order, 'A' means 'F' if `a` is Fortran contiguous, | |
'C' otherwise. 'K' means match the layout of `a` as closely | |
as possible. | |
.. versionadded:: 1.6.0 | |
subok : bool, optional. | |
If True, then the newly created array will use the sub-class | |
type of `a`, otherwise it will be a base-class array. Defaults | |
to True. | |
shape : int or sequence of ints, optional. | |
Overrides the shape of the result. If order='K' and the number of | |
dimensions is unchanged, will try to keep order, otherwise, | |
order='C' is implied. | |
.. versionadded:: 1.17.0 | |
Returns | |
------- | |
out : ndarray | |
Array of ones with the same shape and type as `a`. | |
See Also | |
-------- | |
empty_like : Return an empty array with shape and type of input. | |
zeros_like : Return an array of zeros with shape and type of input. | |
full_like : Return a new array with shape of input filled with value. | |
ones : Return a new array setting values to one. | |
Examples | |
-------- | |
>>> x = np.arange(6) | |
>>> x = x.reshape((2, 3)) | |
>>> x | |
array([[0, 1, 2], | |
[3, 4, 5]]) | |
>>> np.ones_like(x) | |
array([[1, 1, 1], | |
[1, 1, 1]]) | |
>>> y = np.arange(3, dtype=float) | |
>>> y | |
array([0., 1., 2.]) | |
>>> np.ones_like(y) | |
array([1., 1., 1.]) | |
""" | |
res = empty_like(a, dtype=dtype, order=order, subok=subok, shape=shape) | |
multiarray.copyto(res, 1, casting='unsafe') | |
return res | |
def _full_dispatcher(shape, fill_value, dtype=None, order=None, *, like=None): | |
return(like,) | |
def full(shape, fill_value, dtype=None, order='C', *, like=None): | |
""" | |
Return a new array of given shape and type, filled with `fill_value`. | |
Parameters | |
---------- | |
shape : int or sequence of ints | |
Shape of the new array, e.g., ``(2, 3)`` or ``2``. | |
fill_value : scalar or array_like | |
Fill value. | |
dtype : data-type, optional | |
The desired data-type for the array The default, None, means | |
``np.array(fill_value).dtype``. | |
order : {'C', 'F'}, optional | |
Whether to store multidimensional data in C- or Fortran-contiguous | |
(row- or column-wise) order in memory. | |
${ARRAY_FUNCTION_LIKE} | |
.. versionadded:: 1.20.0 | |
Returns | |
------- | |
out : ndarray | |
Array of `fill_value` with the given shape, dtype, and order. | |
See Also | |
-------- | |
full_like : Return a new array with shape of input filled with value. | |
empty : Return a new uninitialized array. | |
ones : Return a new array setting values to one. | |
zeros : Return a new array setting values to zero. | |
Examples | |
-------- | |
>>> np.full((2, 2), np.inf) | |
array([[inf, inf], | |
[inf, inf]]) | |
>>> np.full((2, 2), 10) | |
array([[10, 10], | |
[10, 10]]) | |
>>> np.full((2, 2), [1, 2]) | |
array([[1, 2], | |
[1, 2]]) | |
""" | |
if like is not None: | |
return _full_with_like(shape, fill_value, dtype=dtype, order=order, like=like) | |
if dtype is None: | |
fill_value = asarray(fill_value) | |
dtype = fill_value.dtype | |
a = empty(shape, dtype, order) | |
multiarray.copyto(a, fill_value, casting='unsafe') | |
return a | |
_full_with_like = array_function_dispatch( | |
_full_dispatcher | |
)(full) | |
def _full_like_dispatcher(a, fill_value, dtype=None, order=None, subok=None, shape=None): | |
return (a,) | |
def full_like(a, fill_value, dtype=None, order='K', subok=True, shape=None): | |
""" | |
Return a full array with the same shape and type as a given array. | |
Parameters | |
---------- | |
a : array_like | |
The shape and data-type of `a` define these same attributes of | |
the returned array. | |
fill_value : scalar | |
Fill value. | |
dtype : data-type, optional | |
Overrides the data type of the result. | |
order : {'C', 'F', 'A', or 'K'}, optional | |
Overrides the memory layout of the result. 'C' means C-order, | |
'F' means F-order, 'A' means 'F' if `a` is Fortran contiguous, | |
'C' otherwise. 'K' means match the layout of `a` as closely | |
as possible. | |
subok : bool, optional. | |
If True, then the newly created array will use the sub-class | |
type of `a`, otherwise it will be a base-class array. Defaults | |
to True. | |
shape : int or sequence of ints, optional. | |
Overrides the shape of the result. If order='K' and the number of | |
dimensions is unchanged, will try to keep order, otherwise, | |
order='C' is implied. | |
.. versionadded:: 1.17.0 | |
Returns | |
------- | |
out : ndarray | |
Array of `fill_value` with the same shape and type as `a`. | |
See Also | |
-------- | |
empty_like : Return an empty array with shape and type of input. | |
ones_like : Return an array of ones with shape and type of input. | |
zeros_like : Return an array of zeros with shape and type of input. | |
full : Return a new array of given shape filled with value. | |
Examples | |
-------- | |
>>> x = np.arange(6, dtype=int) | |
>>> np.full_like(x, 1) | |
array([1, 1, 1, 1, 1, 1]) | |
>>> np.full_like(x, 0.1) | |
array([0, 0, 0, 0, 0, 0]) | |
>>> np.full_like(x, 0.1, dtype=np.double) | |
array([0.1, 0.1, 0.1, 0.1, 0.1, 0.1]) | |
>>> np.full_like(x, np.nan, dtype=np.double) | |
array([nan, nan, nan, nan, nan, nan]) | |
>>> y = np.arange(6, dtype=np.double) | |
>>> np.full_like(y, 0.1) | |
array([0.1, 0.1, 0.1, 0.1, 0.1, 0.1]) | |
""" | |
res = empty_like(a, dtype=dtype, order=order, subok=subok, shape=shape) | |
multiarray.copyto(res, fill_value, casting='unsafe') | |
return res | |
def _count_nonzero_dispatcher(a, axis=None, *, keepdims=None): | |
return (a,) | |
def count_nonzero(a, axis=None, *, keepdims=False): | |
""" | |
Counts the number of non-zero values in the array ``a``. | |
The word "non-zero" is in reference to the Python 2.x | |
built-in method ``__nonzero__()`` (renamed ``__bool__()`` | |
in Python 3.x) of Python objects that tests an object's | |
"truthfulness". For example, any number is considered | |
truthful if it is nonzero, whereas any string is considered | |
truthful if it is not the empty string. Thus, this function | |
(recursively) counts how many elements in ``a`` (and in | |
sub-arrays thereof) have their ``__nonzero__()`` or ``__bool__()`` | |
method evaluated to ``True``. | |
Parameters | |
---------- | |
a : array_like | |
The array for which to count non-zeros. | |
axis : int or tuple, optional | |
Axis or tuple of axes along which to count non-zeros. | |
Default is None, meaning that non-zeros will be counted | |
along a flattened version of ``a``. | |
.. versionadded:: 1.12.0 | |
keepdims : bool, optional | |
If this is set to True, the axes that are counted are left | |
in the result as dimensions with size one. With this option, | |
the result will broadcast correctly against the input array. | |
.. versionadded:: 1.19.0 | |
Returns | |
------- | |
count : int or array of int | |
Number of non-zero values in the array along a given axis. | |
Otherwise, the total number of non-zero values in the array | |
is returned. | |
See Also | |
-------- | |
nonzero : Return the coordinates of all the non-zero values. | |
Examples | |
-------- | |
>>> np.count_nonzero(np.eye(4)) | |
4 | |
>>> a = np.array([[0, 1, 7, 0], | |
... [3, 0, 2, 19]]) | |
>>> np.count_nonzero(a) | |
5 | |
>>> np.count_nonzero(a, axis=0) | |
array([1, 1, 2, 1]) | |
>>> np.count_nonzero(a, axis=1) | |
array([2, 3]) | |
>>> np.count_nonzero(a, axis=1, keepdims=True) | |
array([[2], | |
[3]]) | |
""" | |
if axis is None and not keepdims: | |
return multiarray.count_nonzero(a) | |
a = asanyarray(a) | |
# TODO: this works around .astype(bool) not working properly (gh-9847) | |
if np.issubdtype(a.dtype, np.character): | |
a_bool = a != a.dtype.type() | |
else: | |
a_bool = a.astype(np.bool_, copy=False) | |
return a_bool.sum(axis=axis, dtype=np.intp, keepdims=keepdims) | |
def isfortran(a): | |
""" | |
Check if the array is Fortran contiguous but *not* C contiguous. | |
This function is obsolete and, because of changes due to relaxed stride | |
checking, its return value for the same array may differ for versions | |
of NumPy >= 1.10.0 and previous versions. If you only want to check if an | |
array is Fortran contiguous use ``a.flags.f_contiguous`` instead. | |
Parameters | |
---------- | |
a : ndarray | |
Input array. | |
Returns | |
------- | |
isfortran : bool | |
Returns True if the array is Fortran contiguous but *not* C contiguous. | |
Examples | |
-------- | |
np.array allows to specify whether the array is written in C-contiguous | |
order (last index varies the fastest), or FORTRAN-contiguous order in | |
memory (first index varies the fastest). | |
>>> a = np.array([[1, 2, 3], [4, 5, 6]], order='C') | |
>>> a | |
array([[1, 2, 3], | |
[4, 5, 6]]) | |
>>> np.isfortran(a) | |
False | |
>>> b = np.array([[1, 2, 3], [4, 5, 6]], order='F') | |
>>> b | |
array([[1, 2, 3], | |
[4, 5, 6]]) | |
>>> np.isfortran(b) | |
True | |
The transpose of a C-ordered array is a FORTRAN-ordered array. | |
>>> a = np.array([[1, 2, 3], [4, 5, 6]], order='C') | |
>>> a | |
array([[1, 2, 3], | |
[4, 5, 6]]) | |
>>> np.isfortran(a) | |
False | |
>>> b = a.T | |
>>> b | |
array([[1, 4], | |
[2, 5], | |
[3, 6]]) | |
>>> np.isfortran(b) | |
True | |
C-ordered arrays evaluate as False even if they are also FORTRAN-ordered. | |
>>> np.isfortran(np.array([1, 2], order='F')) | |
False | |
""" | |
return a.flags.fnc | |
def _argwhere_dispatcher(a): | |
return (a,) | |
def argwhere(a): | |
""" | |
Find the indices of array elements that are non-zero, grouped by element. | |
Parameters | |
---------- | |
a : array_like | |
Input data. | |
Returns | |
------- | |
index_array : (N, a.ndim) ndarray | |
Indices of elements that are non-zero. Indices are grouped by element. | |
This array will have shape ``(N, a.ndim)`` where ``N`` is the number of | |
non-zero items. | |
See Also | |
-------- | |
where, nonzero | |
Notes | |
----- | |
``np.argwhere(a)`` is almost the same as ``np.transpose(np.nonzero(a))``, | |
but produces a result of the correct shape for a 0D array. | |
The output of ``argwhere`` is not suitable for indexing arrays. | |
For this purpose use ``nonzero(a)`` instead. | |
Examples | |
-------- | |
>>> x = np.arange(6).reshape(2,3) | |
>>> x | |
array([[0, 1, 2], | |
[3, 4, 5]]) | |
>>> np.argwhere(x>1) | |
array([[0, 2], | |
[1, 0], | |
[1, 1], | |
[1, 2]]) | |
""" | |
# nonzero does not behave well on 0d, so promote to 1d | |
if np.ndim(a) == 0: | |
a = shape_base.atleast_1d(a) | |
# then remove the added dimension | |
return argwhere(a)[:,:0] | |
return transpose(nonzero(a)) | |
def _flatnonzero_dispatcher(a): | |
return (a,) | |
def flatnonzero(a): | |
""" | |
Return indices that are non-zero in the flattened version of a. | |
This is equivalent to np.nonzero(np.ravel(a))[0]. | |
Parameters | |
---------- | |
a : array_like | |
Input data. | |
Returns | |
------- | |
res : ndarray | |
Output array, containing the indices of the elements of `a.ravel()` | |
that are non-zero. | |
See Also | |
-------- | |
nonzero : Return the indices of the non-zero elements of the input array. | |
ravel : Return a 1-D array containing the elements of the input array. | |
Examples | |
-------- | |
>>> x = np.arange(-2, 3) | |
>>> x | |
array([-2, -1, 0, 1, 2]) | |
>>> np.flatnonzero(x) | |
array([0, 1, 3, 4]) | |
Use the indices of the non-zero elements as an index array to extract | |
these elements: | |
>>> x.ravel()[np.flatnonzero(x)] | |
array([-2, -1, 1, 2]) | |
""" | |
return np.nonzero(np.ravel(a))[0] | |
def _correlate_dispatcher(a, v, mode=None): | |
return (a, v) | |
def correlate(a, v, mode='valid'): | |
""" | |
Cross-correlation of two 1-dimensional sequences. | |
This function computes the correlation as generally defined in signal | |
processing texts:: | |
c_{av}[k] = sum_n a[n+k] * conj(v[n]) | |
with a and v sequences being zero-padded where necessary and conj being | |
the conjugate. | |
Parameters | |
---------- | |
a, v : array_like | |
Input sequences. | |
mode : {'valid', 'same', 'full'}, optional | |
Refer to the `convolve` docstring. Note that the default | |
is 'valid', unlike `convolve`, which uses 'full'. | |
old_behavior : bool | |
`old_behavior` was removed in NumPy 1.10. If you need the old | |
behavior, use `multiarray.correlate`. | |
Returns | |
------- | |
out : ndarray | |
Discrete cross-correlation of `a` and `v`. | |
See Also | |
-------- | |
convolve : Discrete, linear convolution of two one-dimensional sequences. | |
multiarray.correlate : Old, no conjugate, version of correlate. | |
scipy.signal.correlate : uses FFT which has superior performance on large arrays. | |
Notes | |
----- | |
The definition of correlation above is not unique and sometimes correlation | |
may be defined differently. Another common definition is:: | |
c'_{av}[k] = sum_n a[n] conj(v[n+k]) | |
which is related to ``c_{av}[k]`` by ``c'_{av}[k] = c_{av}[-k]``. | |
`numpy.correlate` may perform slowly in large arrays (i.e. n = 1e5) because it does | |
not use the FFT to compute the convolution; in that case, `scipy.signal.correlate` might | |
be preferable. | |
Examples | |
-------- | |
>>> np.correlate([1, 2, 3], [0, 1, 0.5]) | |
array([3.5]) | |
>>> np.correlate([1, 2, 3], [0, 1, 0.5], "same") | |
array([2. , 3.5, 3. ]) | |
>>> np.correlate([1, 2, 3], [0, 1, 0.5], "full") | |
array([0.5, 2. , 3.5, 3. , 0. ]) | |
Using complex sequences: | |
>>> np.correlate([1+1j, 2, 3-1j], [0, 1, 0.5j], 'full') | |
array([ 0.5-0.5j, 1.0+0.j , 1.5-1.5j, 3.0-1.j , 0.0+0.j ]) | |
Note that you get the time reversed, complex conjugated result | |
when the two input sequences change places, i.e., | |
``c_{va}[k] = c^{*}_{av}[-k]``: | |
>>> np.correlate([0, 1, 0.5j], [1+1j, 2, 3-1j], 'full') | |
array([ 0.0+0.j , 3.0+1.j , 1.5+1.5j, 1.0+0.j , 0.5+0.5j]) | |
""" | |
return multiarray.correlate2(a, v, mode) | |
def _convolve_dispatcher(a, v, mode=None): | |
return (a, v) | |
def convolve(a, v, mode='full'): | |
""" | |
Returns the discrete, linear convolution of two one-dimensional sequences. | |
The convolution operator is often seen in signal processing, where it | |
models the effect of a linear time-invariant system on a signal [1]_. In | |
probability theory, the sum of two independent random variables is | |
distributed according to the convolution of their individual | |
distributions. | |
If `v` is longer than `a`, the arrays are swapped before computation. | |
Parameters | |
---------- | |
a : (N,) array_like | |
First one-dimensional input array. | |
v : (M,) array_like | |
Second one-dimensional input array. | |
mode : {'full', 'valid', 'same'}, optional | |
'full': | |
By default, mode is 'full'. This returns the convolution | |
at each point of overlap, with an output shape of (N+M-1,). At | |
the end-points of the convolution, the signals do not overlap | |
completely, and boundary effects may be seen. | |
'same': | |
Mode 'same' returns output of length ``max(M, N)``. Boundary | |
effects are still visible. | |
'valid': | |
Mode 'valid' returns output of length | |
``max(M, N) - min(M, N) + 1``. The convolution product is only given | |
for points where the signals overlap completely. Values outside | |
the signal boundary have no effect. | |
Returns | |
------- | |
out : ndarray | |
Discrete, linear convolution of `a` and `v`. | |
See Also | |
-------- | |
scipy.signal.fftconvolve : Convolve two arrays using the Fast Fourier | |
Transform. | |
scipy.linalg.toeplitz : Used to construct the convolution operator. | |
polymul : Polynomial multiplication. Same output as convolve, but also | |
accepts poly1d objects as input. | |
Notes | |
----- | |
The discrete convolution operation is defined as | |
.. math:: (a * v)[n] = \\sum_{m = -\\infty}^{\\infty} a[m] v[n - m] | |
It can be shown that a convolution :math:`x(t) * y(t)` in time/space | |
is equivalent to the multiplication :math:`X(f) Y(f)` in the Fourier | |
domain, after appropriate padding (padding is necessary to prevent | |
circular convolution). Since multiplication is more efficient (faster) | |
than convolution, the function `scipy.signal.fftconvolve` exploits the | |
FFT to calculate the convolution of large data-sets. | |
References | |
---------- | |
.. [1] Wikipedia, "Convolution", | |
https://en.wikipedia.org/wiki/Convolution | |
Examples | |
-------- | |
Note how the convolution operator flips the second array | |
before "sliding" the two across one another: | |
>>> np.convolve([1, 2, 3], [0, 1, 0.5]) | |
array([0. , 1. , 2.5, 4. , 1.5]) | |
Only return the middle values of the convolution. | |
Contains boundary effects, where zeros are taken | |
into account: | |
>>> np.convolve([1,2,3],[0,1,0.5], 'same') | |
array([1. , 2.5, 4. ]) | |
The two arrays are of the same length, so there | |
is only one position where they completely overlap: | |
>>> np.convolve([1,2,3],[0,1,0.5], 'valid') | |
array([2.5]) | |
""" | |
a, v = array(a, copy=False, ndmin=1), array(v, copy=False, ndmin=1) | |
if (len(v) > len(a)): | |
a, v = v, a | |
if len(a) == 0: | |
raise ValueError('a cannot be empty') | |
if len(v) == 0: | |
raise ValueError('v cannot be empty') | |
return multiarray.correlate(a, v[::-1], mode) | |
def _outer_dispatcher(a, b, out=None): | |
return (a, b, out) | |
def outer(a, b, out=None): | |
""" | |
Compute the outer product of two vectors. | |
Given two vectors, ``a = [a0, a1, ..., aM]`` and | |
``b = [b0, b1, ..., bN]``, | |
the outer product [1]_ is:: | |
[[a0*b0 a0*b1 ... a0*bN ] | |
[a1*b0 . | |
[ ... . | |
[aM*b0 aM*bN ]] | |
Parameters | |
---------- | |
a : (M,) array_like | |
First input vector. Input is flattened if | |
not already 1-dimensional. | |
b : (N,) array_like | |
Second input vector. Input is flattened if | |
not already 1-dimensional. | |
out : (M, N) ndarray, optional | |
A location where the result is stored | |
.. versionadded:: 1.9.0 | |
Returns | |
------- | |
out : (M, N) ndarray | |
``out[i, j] = a[i] * b[j]`` | |
See also | |
-------- | |
inner | |
einsum : ``einsum('i,j->ij', a.ravel(), b.ravel())`` is the equivalent. | |
ufunc.outer : A generalization to dimensions other than 1D and other | |
operations. ``np.multiply.outer(a.ravel(), b.ravel())`` | |
is the equivalent. | |
tensordot : ``np.tensordot(a.ravel(), b.ravel(), axes=((), ()))`` | |
is the equivalent. | |
References | |
---------- | |
.. [1] : G. H. Golub and C. F. Van Loan, *Matrix Computations*, 3rd | |
ed., Baltimore, MD, Johns Hopkins University Press, 1996, | |
pg. 8. | |
Examples | |
-------- | |
Make a (*very* coarse) grid for computing a Mandelbrot set: | |
>>> rl = np.outer(np.ones((5,)), np.linspace(-2, 2, 5)) | |
>>> rl | |
array([[-2., -1., 0., 1., 2.], | |
[-2., -1., 0., 1., 2.], | |
[-2., -1., 0., 1., 2.], | |
[-2., -1., 0., 1., 2.], | |
[-2., -1., 0., 1., 2.]]) | |
>>> im = np.outer(1j*np.linspace(2, -2, 5), np.ones((5,))) | |
>>> im | |
array([[0.+2.j, 0.+2.j, 0.+2.j, 0.+2.j, 0.+2.j], | |
[0.+1.j, 0.+1.j, 0.+1.j, 0.+1.j, 0.+1.j], | |
[0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j], | |
[0.-1.j, 0.-1.j, 0.-1.j, 0.-1.j, 0.-1.j], | |
[0.-2.j, 0.-2.j, 0.-2.j, 0.-2.j, 0.-2.j]]) | |
>>> grid = rl + im | |
>>> grid | |
array([[-2.+2.j, -1.+2.j, 0.+2.j, 1.+2.j, 2.+2.j], | |
[-2.+1.j, -1.+1.j, 0.+1.j, 1.+1.j, 2.+1.j], | |
[-2.+0.j, -1.+0.j, 0.+0.j, 1.+0.j, 2.+0.j], | |
[-2.-1.j, -1.-1.j, 0.-1.j, 1.-1.j, 2.-1.j], | |
[-2.-2.j, -1.-2.j, 0.-2.j, 1.-2.j, 2.-2.j]]) | |
An example using a "vector" of letters: | |
>>> x = np.array(['a', 'b', 'c'], dtype=object) | |
>>> np.outer(x, [1, 2, 3]) | |
array([['a', 'aa', 'aaa'], | |
['b', 'bb', 'bbb'], | |
['c', 'cc', 'ccc']], dtype=object) | |
""" | |
a = asarray(a) | |
b = asarray(b) | |
return multiply(a.ravel()[:, newaxis], b.ravel()[newaxis, :], out) | |
def _tensordot_dispatcher(a, b, axes=None): | |
return (a, b) | |
def tensordot(a, b, axes=2): | |
""" | |
Compute tensor dot product along specified axes. | |
Given two tensors, `a` and `b`, and an array_like object containing | |
two array_like objects, ``(a_axes, b_axes)``, sum the products of | |
`a`'s and `b`'s elements (components) over the axes specified by | |
``a_axes`` and ``b_axes``. The third argument can be a single non-negative | |
integer_like scalar, ``N``; if it is such, then the last ``N`` dimensions | |
of `a` and the first ``N`` dimensions of `b` are summed over. | |
Parameters | |
---------- | |
a, b : array_like | |
Tensors to "dot". | |
axes : int or (2,) array_like | |
* integer_like | |
If an int N, sum over the last N axes of `a` and the first N axes | |
of `b` in order. The sizes of the corresponding axes must match. | |
* (2,) array_like | |
Or, a list of axes to be summed over, first sequence applying to `a`, | |
second to `b`. Both elements array_like must be of the same length. | |
Returns | |
------- | |
output : ndarray | |
The tensor dot product of the input. | |
See Also | |
-------- | |
dot, einsum | |
Notes | |
----- | |
Three common use cases are: | |
* ``axes = 0`` : tensor product :math:`a\\otimes b` | |
* ``axes = 1`` : tensor dot product :math:`a\\cdot b` | |
* ``axes = 2`` : (default) tensor double contraction :math:`a:b` | |
When `axes` is integer_like, the sequence for evaluation will be: first | |
the -Nth axis in `a` and 0th axis in `b`, and the -1th axis in `a` and | |
Nth axis in `b` last. | |
When there is more than one axis to sum over - and they are not the last | |
(first) axes of `a` (`b`) - the argument `axes` should consist of | |
two sequences of the same length, with the first axis to sum over given | |
first in both sequences, the second axis second, and so forth. | |
The shape of the result consists of the non-contracted axes of the | |
first tensor, followed by the non-contracted axes of the second. | |
Examples | |
-------- | |
A "traditional" example: | |
>>> a = np.arange(60.).reshape(3,4,5) | |
>>> b = np.arange(24.).reshape(4,3,2) | |
>>> c = np.tensordot(a,b, axes=([1,0],[0,1])) | |
>>> c.shape | |
(5, 2) | |
>>> c | |
array([[4400., 4730.], | |
[4532., 4874.], | |
[4664., 5018.], | |
[4796., 5162.], | |
[4928., 5306.]]) | |
>>> # A slower but equivalent way of computing the same... | |
>>> d = np.zeros((5,2)) | |
>>> for i in range(5): | |
... for j in range(2): | |
... for k in range(3): | |
... for n in range(4): | |
... d[i,j] += a[k,n,i] * b[n,k,j] | |
>>> c == d | |
array([[ True, True], | |
[ True, True], | |
[ True, True], | |
[ True, True], | |
[ True, True]]) | |
An extended example taking advantage of the overloading of + and \\*: | |
>>> a = np.array(range(1, 9)) | |
>>> a.shape = (2, 2, 2) | |
>>> A = np.array(('a', 'b', 'c', 'd'), dtype=object) | |
>>> A.shape = (2, 2) | |
>>> a; A | |
array([[[1, 2], | |
[3, 4]], | |
[[5, 6], | |
[7, 8]]]) | |
array([['a', 'b'], | |
['c', 'd']], dtype=object) | |
>>> np.tensordot(a, A) # third argument default is 2 for double-contraction | |
array(['abbcccdddd', 'aaaaabbbbbbcccccccdddddddd'], dtype=object) | |
>>> np.tensordot(a, A, 1) | |
array([[['acc', 'bdd'], | |
['aaacccc', 'bbbdddd']], | |
[['aaaaacccccc', 'bbbbbdddddd'], | |
['aaaaaaacccccccc', 'bbbbbbbdddddddd']]], dtype=object) | |
>>> np.tensordot(a, A, 0) # tensor product (result too long to incl.) | |
array([[[[['a', 'b'], | |
['c', 'd']], | |
... | |
>>> np.tensordot(a, A, (0, 1)) | |
array([[['abbbbb', 'cddddd'], | |
['aabbbbbb', 'ccdddddd']], | |
[['aaabbbbbbb', 'cccddddddd'], | |
['aaaabbbbbbbb', 'ccccdddddddd']]], dtype=object) | |
>>> np.tensordot(a, A, (2, 1)) | |
array([[['abb', 'cdd'], | |
['aaabbbb', 'cccdddd']], | |
[['aaaaabbbbbb', 'cccccdddddd'], | |
['aaaaaaabbbbbbbb', 'cccccccdddddddd']]], dtype=object) | |
>>> np.tensordot(a, A, ((0, 1), (0, 1))) | |
array(['abbbcccccddddddd', 'aabbbbccccccdddddddd'], dtype=object) | |
>>> np.tensordot(a, A, ((2, 1), (1, 0))) | |
array(['acccbbdddd', 'aaaaacccccccbbbbbbdddddddd'], dtype=object) | |
""" | |
try: | |
iter(axes) | |
except Exception: | |
axes_a = list(range(-axes, 0)) | |
axes_b = list(range(0, axes)) | |
else: | |
axes_a, axes_b = axes | |
try: | |
na = len(axes_a) | |
axes_a = list(axes_a) | |
except TypeError: | |
axes_a = [axes_a] | |
na = 1 | |
try: | |
nb = len(axes_b) | |
axes_b = list(axes_b) | |
except TypeError: | |
axes_b = [axes_b] | |
nb = 1 | |
a, b = asarray(a), asarray(b) | |
as_ = a.shape | |
nda = a.ndim | |
bs = b.shape | |
ndb = b.ndim | |
equal = True | |
if na != nb: | |
equal = False | |
else: | |
for k in range(na): | |
if as_[axes_a[k]] != bs[axes_b[k]]: | |
equal = False | |
break | |
if axes_a[k] < 0: | |
axes_a[k] += nda | |
if axes_b[k] < 0: | |
axes_b[k] += ndb | |
if not equal: | |
raise ValueError("shape-mismatch for sum") | |
# Move the axes to sum over to the end of "a" | |
# and to the front of "b" | |
notin = [k for k in range(nda) if k not in axes_a] | |
newaxes_a = notin + axes_a | |
N2 = 1 | |
for axis in axes_a: | |
N2 *= as_[axis] | |
newshape_a = (int(multiply.reduce([as_[ax] for ax in notin])), N2) | |
olda = [as_[axis] for axis in notin] | |
notin = [k for k in range(ndb) if k not in axes_b] | |
newaxes_b = axes_b + notin | |
N2 = 1 | |
for axis in axes_b: | |
N2 *= bs[axis] | |
newshape_b = (N2, int(multiply.reduce([bs[ax] for ax in notin]))) | |
oldb = [bs[axis] for axis in notin] | |
at = a.transpose(newaxes_a).reshape(newshape_a) | |
bt = b.transpose(newaxes_b).reshape(newshape_b) | |
res = dot(at, bt) | |
return res.reshape(olda + oldb) | |
def _roll_dispatcher(a, shift, axis=None): | |
return (a,) | |
def roll(a, shift, axis=None): | |
""" | |
Roll array elements along a given axis. | |
Elements that roll beyond the last position are re-introduced at | |
the first. | |
Parameters | |
---------- | |
a : array_like | |
Input array. | |
shift : int or tuple of ints | |
The number of places by which elements are shifted. If a tuple, | |
then `axis` must be a tuple of the same size, and each of the | |
given axes is shifted by the corresponding number. If an int | |
while `axis` is a tuple of ints, then the same value is used for | |
all given axes. | |
axis : int or tuple of ints, optional | |
Axis or axes along which elements are shifted. By default, the | |
array is flattened before shifting, after which the original | |
shape is restored. | |
Returns | |
------- | |
res : ndarray | |
Output array, with the same shape as `a`. | |
See Also | |
-------- | |
rollaxis : Roll the specified axis backwards, until it lies in a | |
given position. | |
Notes | |
----- | |
.. versionadded:: 1.12.0 | |
Supports rolling over multiple dimensions simultaneously. | |
Examples | |
-------- | |
>>> x = np.arange(10) | |
>>> np.roll(x, 2) | |
array([8, 9, 0, 1, 2, 3, 4, 5, 6, 7]) | |
>>> np.roll(x, -2) | |
array([2, 3, 4, 5, 6, 7, 8, 9, 0, 1]) | |
>>> x2 = np.reshape(x, (2,5)) | |
>>> x2 | |
array([[0, 1, 2, 3, 4], | |
[5, 6, 7, 8, 9]]) | |
>>> np.roll(x2, 1) | |
array([[9, 0, 1, 2, 3], | |
[4, 5, 6, 7, 8]]) | |
>>> np.roll(x2, -1) | |
array([[1, 2, 3, 4, 5], | |
[6, 7, 8, 9, 0]]) | |
>>> np.roll(x2, 1, axis=0) | |
array([[5, 6, 7, 8, 9], | |
[0, 1, 2, 3, 4]]) | |
>>> np.roll(x2, -1, axis=0) | |
array([[5, 6, 7, 8, 9], | |
[0, 1, 2, 3, 4]]) | |
>>> np.roll(x2, 1, axis=1) | |
array([[4, 0, 1, 2, 3], | |
[9, 5, 6, 7, 8]]) | |
>>> np.roll(x2, -1, axis=1) | |
array([[1, 2, 3, 4, 0], | |
[6, 7, 8, 9, 5]]) | |
""" | |
a = asanyarray(a) | |
if axis is None: | |
return roll(a.ravel(), shift, 0).reshape(a.shape) | |
else: | |
axis = normalize_axis_tuple(axis, a.ndim, allow_duplicate=True) | |
broadcasted = broadcast(shift, axis) | |
if broadcasted.ndim > 1: | |
raise ValueError( | |
"'shift' and 'axis' should be scalars or 1D sequences") | |
shifts = {ax: 0 for ax in range(a.ndim)} | |
for sh, ax in broadcasted: | |
shifts[ax] += sh | |
rolls = [((slice(None), slice(None)),)] * a.ndim | |
for ax, offset in shifts.items(): | |
offset %= a.shape[ax] or 1 # If `a` is empty, nothing matters. | |
if offset: | |
# (original, result), (original, result) | |
rolls[ax] = ((slice(None, -offset), slice(offset, None)), | |
(slice(-offset, None), slice(None, offset))) | |
result = empty_like(a) | |
for indices in itertools.product(*rolls): | |
arr_index, res_index = zip(*indices) | |
result[res_index] = a[arr_index] | |
return result | |
def _rollaxis_dispatcher(a, axis, start=None): | |
return (a,) | |
def rollaxis(a, axis, start=0): | |
""" | |
Roll the specified axis backwards, until it lies in a given position. | |
This function continues to be supported for backward compatibility, but you | |
should prefer `moveaxis`. The `moveaxis` function was added in NumPy | |
1.11. | |
Parameters | |
---------- | |
a : ndarray | |
Input array. | |
axis : int | |
The axis to be rolled. The positions of the other axes do not | |
change relative to one another. | |
start : int, optional | |
When ``start <= axis``, the axis is rolled back until it lies in | |
this position. When ``start > axis``, the axis is rolled until it | |
lies before this position. The default, 0, results in a "complete" | |
roll. The following table describes how negative values of ``start`` | |
are interpreted: | |
.. table:: | |
:align: left | |
+-------------------+----------------------+ | |
| ``start`` | Normalized ``start`` | | |
+===================+======================+ | |
| ``-(arr.ndim+1)`` | raise ``AxisError`` | | |
+-------------------+----------------------+ | |
| ``-arr.ndim`` | 0 | | |
+-------------------+----------------------+ | |
| |vdots| | |vdots| | | |
+-------------------+----------------------+ | |
| ``-1`` | ``arr.ndim-1`` | | |
+-------------------+----------------------+ | |
| ``0`` | ``0`` | | |
+-------------------+----------------------+ | |
| |vdots| | |vdots| | | |
+-------------------+----------------------+ | |
| ``arr.ndim`` | ``arr.ndim`` | | |
+-------------------+----------------------+ | |
| ``arr.ndim + 1`` | raise ``AxisError`` | | |
+-------------------+----------------------+ | |
.. |vdots| unicode:: U+22EE .. Vertical Ellipsis | |
Returns | |
------- | |
res : ndarray | |
For NumPy >= 1.10.0 a view of `a` is always returned. For earlier | |
NumPy versions a view of `a` is returned only if the order of the | |
axes is changed, otherwise the input array is returned. | |
See Also | |
-------- | |
moveaxis : Move array axes to new positions. | |
roll : Roll the elements of an array by a number of positions along a | |
given axis. | |
Examples | |
-------- | |
>>> a = np.ones((3,4,5,6)) | |
>>> np.rollaxis(a, 3, 1).shape | |
(3, 6, 4, 5) | |
>>> np.rollaxis(a, 2).shape | |
(5, 3, 4, 6) | |
>>> np.rollaxis(a, 1, 4).shape | |
(3, 5, 6, 4) | |
""" | |
n = a.ndim | |
axis = normalize_axis_index(axis, n) | |
if start < 0: | |
start += n | |
msg = "'%s' arg requires %d <= %s < %d, but %d was passed in" | |
if not (0 <= start < n + 1): | |
raise AxisError(msg % ('start', -n, 'start', n + 1, start)) | |
if axis < start: | |
# it's been removed | |
start -= 1 | |
if axis == start: | |
return a[...] | |
axes = list(range(0, n)) | |
axes.remove(axis) | |
axes.insert(start, axis) | |
return a.transpose(axes) | |
def normalize_axis_tuple(axis, ndim, argname=None, allow_duplicate=False): | |
""" | |
Normalizes an axis argument into a tuple of non-negative integer axes. | |
This handles shorthands such as ``1`` and converts them to ``(1,)``, | |
as well as performing the handling of negative indices covered by | |
`normalize_axis_index`. | |
By default, this forbids axes from being specified multiple times. | |
Used internally by multi-axis-checking logic. | |
.. versionadded:: 1.13.0 | |
Parameters | |
---------- | |
axis : int, iterable of int | |
The un-normalized index or indices of the axis. | |
ndim : int | |
The number of dimensions of the array that `axis` should be normalized | |
against. | |
argname : str, optional | |
A prefix to put before the error message, typically the name of the | |
argument. | |
allow_duplicate : bool, optional | |
If False, the default, disallow an axis from being specified twice. | |
Returns | |
------- | |
normalized_axes : tuple of int | |
The normalized axis index, such that `0 <= normalized_axis < ndim` | |
Raises | |
------ | |
AxisError | |
If any axis provided is out of range | |
ValueError | |
If an axis is repeated | |
See also | |
-------- | |
normalize_axis_index : normalizing a single scalar axis | |
""" | |
# Optimization to speed-up the most common cases. | |
if type(axis) not in (tuple, list): | |
try: | |
axis = [operator.index(axis)] | |
except TypeError: | |
pass | |
# Going via an iterator directly is slower than via list comprehension. | |
axis = tuple([normalize_axis_index(ax, ndim, argname) for ax in axis]) | |
if not allow_duplicate and len(set(axis)) != len(axis): | |
if argname: | |
raise ValueError('repeated axis in `{}` argument'.format(argname)) | |
else: | |
raise ValueError('repeated axis') | |
return axis | |
def _moveaxis_dispatcher(a, source, destination): | |
return (a,) | |
def moveaxis(a, source, destination): | |
""" | |
Move axes of an array to new positions. | |
Other axes remain in their original order. | |
.. versionadded:: 1.11.0 | |
Parameters | |
---------- | |
a : np.ndarray | |
The array whose axes should be reordered. | |
source : int or sequence of int | |
Original positions of the axes to move. These must be unique. | |
destination : int or sequence of int | |
Destination positions for each of the original axes. These must also be | |
unique. | |
Returns | |
------- | |
result : np.ndarray | |
Array with moved axes. This array is a view of the input array. | |
See Also | |
-------- | |
transpose : Permute the dimensions of an array. | |
swapaxes : Interchange two axes of an array. | |
Examples | |
-------- | |
>>> x = np.zeros((3, 4, 5)) | |
>>> np.moveaxis(x, 0, -1).shape | |
(4, 5, 3) | |
>>> np.moveaxis(x, -1, 0).shape | |
(5, 3, 4) | |
These all achieve the same result: | |
>>> np.transpose(x).shape | |
(5, 4, 3) | |
>>> np.swapaxes(x, 0, -1).shape | |
(5, 4, 3) | |
>>> np.moveaxis(x, [0, 1], [-1, -2]).shape | |
(5, 4, 3) | |
>>> np.moveaxis(x, [0, 1, 2], [-1, -2, -3]).shape | |
(5, 4, 3) | |
""" | |
try: | |
# allow duck-array types if they define transpose | |
transpose = a.transpose | |
except AttributeError: | |
a = asarray(a) | |
transpose = a.transpose | |
source = normalize_axis_tuple(source, a.ndim, 'source') | |
destination = normalize_axis_tuple(destination, a.ndim, 'destination') | |
if len(source) != len(destination): | |
raise ValueError('`source` and `destination` arguments must have ' | |
'the same number of elements') | |
order = [n for n in range(a.ndim) if n not in source] | |
for dest, src in sorted(zip(destination, source)): | |
order.insert(dest, src) | |
result = transpose(order) | |
return result | |
# fix hack in scipy which imports this function | |
def _move_axis_to_0(a, axis): | |
return moveaxis(a, axis, 0) | |
def _cross_dispatcher(a, b, axisa=None, axisb=None, axisc=None, axis=None): | |
return (a, b) | |
def cross(a, b, axisa=-1, axisb=-1, axisc=-1, axis=None): | |
""" | |
Return the cross product of two (arrays of) vectors. | |
The cross product of `a` and `b` in :math:`R^3` is a vector perpendicular | |
to both `a` and `b`. If `a` and `b` are arrays of vectors, the vectors | |
are defined by the last axis of `a` and `b` by default, and these axes | |
can have dimensions 2 or 3. Where the dimension of either `a` or `b` is | |
2, the third component of the input vector is assumed to be zero and the | |
cross product calculated accordingly. In cases where both input vectors | |
have dimension 2, the z-component of the cross product is returned. | |
Parameters | |
---------- | |
a : array_like | |
Components of the first vector(s). | |
b : array_like | |
Components of the second vector(s). | |
axisa : int, optional | |
Axis of `a` that defines the vector(s). By default, the last axis. | |
axisb : int, optional | |
Axis of `b` that defines the vector(s). By default, the last axis. | |
axisc : int, optional | |
Axis of `c` containing the cross product vector(s). Ignored if | |
both input vectors have dimension 2, as the return is scalar. | |
By default, the last axis. | |
axis : int, optional | |
If defined, the axis of `a`, `b` and `c` that defines the vector(s) | |
and cross product(s). Overrides `axisa`, `axisb` and `axisc`. | |
Returns | |
------- | |
c : ndarray | |
Vector cross product(s). | |
Raises | |
------ | |
ValueError | |
When the dimension of the vector(s) in `a` and/or `b` does not | |
equal 2 or 3. | |
See Also | |
-------- | |
inner : Inner product | |
outer : Outer product. | |
ix_ : Construct index arrays. | |
Notes | |
----- | |
.. versionadded:: 1.9.0 | |
Supports full broadcasting of the inputs. | |
Examples | |
-------- | |
Vector cross-product. | |
>>> x = [1, 2, 3] | |
>>> y = [4, 5, 6] | |
>>> np.cross(x, y) | |
array([-3, 6, -3]) | |
One vector with dimension 2. | |
>>> x = [1, 2] | |
>>> y = [4, 5, 6] | |
>>> np.cross(x, y) | |
array([12, -6, -3]) | |
Equivalently: | |
>>> x = [1, 2, 0] | |
>>> y = [4, 5, 6] | |
>>> np.cross(x, y) | |
array([12, -6, -3]) | |
Both vectors with dimension 2. | |
>>> x = [1,2] | |
>>> y = [4,5] | |
>>> np.cross(x, y) | |
array(-3) | |
Multiple vector cross-products. Note that the direction of the cross | |
product vector is defined by the `right-hand rule`. | |
>>> x = np.array([[1,2,3], [4,5,6]]) | |
>>> y = np.array([[4,5,6], [1,2,3]]) | |
>>> np.cross(x, y) | |
array([[-3, 6, -3], | |
[ 3, -6, 3]]) | |
The orientation of `c` can be changed using the `axisc` keyword. | |
>>> np.cross(x, y, axisc=0) | |
array([[-3, 3], | |
[ 6, -6], | |
[-3, 3]]) | |
Change the vector definition of `x` and `y` using `axisa` and `axisb`. | |
>>> x = np.array([[1,2,3], [4,5,6], [7, 8, 9]]) | |
>>> y = np.array([[7, 8, 9], [4,5,6], [1,2,3]]) | |
>>> np.cross(x, y) | |
array([[ -6, 12, -6], | |
[ 0, 0, 0], | |
[ 6, -12, 6]]) | |
>>> np.cross(x, y, axisa=0, axisb=0) | |
array([[-24, 48, -24], | |
[-30, 60, -30], | |
[-36, 72, -36]]) | |
""" | |
if axis is not None: | |
axisa, axisb, axisc = (axis,) * 3 | |
a = asarray(a) | |
b = asarray(b) | |
# Check axisa and axisb are within bounds | |
axisa = normalize_axis_index(axisa, a.ndim, msg_prefix='axisa') | |
axisb = normalize_axis_index(axisb, b.ndim, msg_prefix='axisb') | |
# Move working axis to the end of the shape | |
a = moveaxis(a, axisa, -1) | |
b = moveaxis(b, axisb, -1) | |
msg = ("incompatible dimensions for cross product\n" | |
"(dimension must be 2 or 3)") | |
if a.shape[-1] not in (2, 3) or b.shape[-1] not in (2, 3): | |
raise ValueError(msg) | |
# Create the output array | |
shape = broadcast(a[..., 0], b[..., 0]).shape | |
if a.shape[-1] == 3 or b.shape[-1] == 3: | |
shape += (3,) | |
# Check axisc is within bounds | |
axisc = normalize_axis_index(axisc, len(shape), msg_prefix='axisc') | |
dtype = promote_types(a.dtype, b.dtype) | |
cp = empty(shape, dtype) | |
# create local aliases for readability | |
a0 = a[..., 0] | |
a1 = a[..., 1] | |
if a.shape[-1] == 3: | |
a2 = a[..., 2] | |
b0 = b[..., 0] | |
b1 = b[..., 1] | |
if b.shape[-1] == 3: | |
b2 = b[..., 2] | |
if cp.ndim != 0 and cp.shape[-1] == 3: | |
cp0 = cp[..., 0] | |
cp1 = cp[..., 1] | |
cp2 = cp[..., 2] | |
if a.shape[-1] == 2: | |
if b.shape[-1] == 2: | |
# a0 * b1 - a1 * b0 | |
multiply(a0, b1, out=cp) | |
cp -= a1 * b0 | |
return cp | |
else: | |
assert b.shape[-1] == 3 | |
# cp0 = a1 * b2 - 0 (a2 = 0) | |
# cp1 = 0 - a0 * b2 (a2 = 0) | |
# cp2 = a0 * b1 - a1 * b0 | |
multiply(a1, b2, out=cp0) | |
multiply(a0, b2, out=cp1) | |
negative(cp1, out=cp1) | |
multiply(a0, b1, out=cp2) | |
cp2 -= a1 * b0 | |
else: | |
assert a.shape[-1] == 3 | |
if b.shape[-1] == 3: | |
# cp0 = a1 * b2 - a2 * b1 | |
# cp1 = a2 * b0 - a0 * b2 | |
# cp2 = a0 * b1 - a1 * b0 | |
multiply(a1, b2, out=cp0) | |
tmp = array(a2 * b1) | |
cp0 -= tmp | |
multiply(a2, b0, out=cp1) | |
multiply(a0, b2, out=tmp) | |
cp1 -= tmp | |
multiply(a0, b1, out=cp2) | |
multiply(a1, b0, out=tmp) | |
cp2 -= tmp | |
else: | |
assert b.shape[-1] == 2 | |
# cp0 = 0 - a2 * b1 (b2 = 0) | |
# cp1 = a2 * b0 - 0 (b2 = 0) | |
# cp2 = a0 * b1 - a1 * b0 | |
multiply(a2, b1, out=cp0) | |
negative(cp0, out=cp0) | |
multiply(a2, b0, out=cp1) | |
multiply(a0, b1, out=cp2) | |
cp2 -= a1 * b0 | |
return moveaxis(cp, -1, axisc) | |
little_endian = (sys.byteorder == 'little') | |
def indices(dimensions, dtype=int, sparse=False): | |
""" | |
Return an array representing the indices of a grid. | |
Compute an array where the subarrays contain index values 0, 1, ... | |
varying only along the corresponding axis. | |
Parameters | |
---------- | |
dimensions : sequence of ints | |
The shape of the grid. | |
dtype : dtype, optional | |
Data type of the result. | |
sparse : boolean, optional | |
Return a sparse representation of the grid instead of a dense | |
representation. Default is False. | |
.. versionadded:: 1.17 | |
Returns | |
------- | |
grid : one ndarray or tuple of ndarrays | |
If sparse is False: | |
Returns one array of grid indices, | |
``grid.shape = (len(dimensions),) + tuple(dimensions)``. | |
If sparse is True: | |
Returns a tuple of arrays, with | |
``grid[i].shape = (1, ..., 1, dimensions[i], 1, ..., 1)`` with | |
dimensions[i] in the ith place | |
See Also | |
-------- | |
mgrid, ogrid, meshgrid | |
Notes | |
----- | |
The output shape in the dense case is obtained by prepending the number | |
of dimensions in front of the tuple of dimensions, i.e. if `dimensions` | |
is a tuple ``(r0, ..., rN-1)`` of length ``N``, the output shape is | |
``(N, r0, ..., rN-1)``. | |
The subarrays ``grid[k]`` contains the N-D array of indices along the | |
``k-th`` axis. Explicitly:: | |
grid[k, i0, i1, ..., iN-1] = ik | |
Examples | |
-------- | |
>>> grid = np.indices((2, 3)) | |
>>> grid.shape | |
(2, 2, 3) | |
>>> grid[0] # row indices | |
array([[0, 0, 0], | |
[1, 1, 1]]) | |
>>> grid[1] # column indices | |
array([[0, 1, 2], | |
[0, 1, 2]]) | |
The indices can be used as an index into an array. | |
>>> x = np.arange(20).reshape(5, 4) | |
>>> row, col = np.indices((2, 3)) | |
>>> x[row, col] | |
array([[0, 1, 2], | |
[4, 5, 6]]) | |
Note that it would be more straightforward in the above example to | |
extract the required elements directly with ``x[:2, :3]``. | |
If sparse is set to true, the grid will be returned in a sparse | |
representation. | |
>>> i, j = np.indices((2, 3), sparse=True) | |
>>> i.shape | |
(2, 1) | |
>>> j.shape | |
(1, 3) | |
>>> i # row indices | |
array([[0], | |
[1]]) | |
>>> j # column indices | |
array([[0, 1, 2]]) | |
""" | |
dimensions = tuple(dimensions) | |
N = len(dimensions) | |
shape = (1,)*N | |
if sparse: | |
res = tuple() | |
else: | |
res = empty((N,)+dimensions, dtype=dtype) | |
for i, dim in enumerate(dimensions): | |
idx = arange(dim, dtype=dtype).reshape( | |
shape[:i] + (dim,) + shape[i+1:] | |
) | |
if sparse: | |
res = res + (idx,) | |
else: | |
res[i] = idx | |
return res | |
def _fromfunction_dispatcher(function, shape, *, dtype=None, like=None, **kwargs): | |
return (like,) | |
def fromfunction(function, shape, *, dtype=float, like=None, **kwargs): | |
""" | |
Construct an array by executing a function over each coordinate. | |
The resulting array therefore has a value ``fn(x, y, z)`` at | |
coordinate ``(x, y, z)``. | |
Parameters | |
---------- | |
function : callable | |
The function is called with N parameters, where N is the rank of | |
`shape`. Each parameter represents the coordinates of the array | |
varying along a specific axis. For example, if `shape` | |
were ``(2, 2)``, then the parameters would be | |
``array([[0, 0], [1, 1]])`` and ``array([[0, 1], [0, 1]])`` | |
shape : (N,) tuple of ints | |
Shape of the output array, which also determines the shape of | |
the coordinate arrays passed to `function`. | |
dtype : data-type, optional | |
Data-type of the coordinate arrays passed to `function`. | |
By default, `dtype` is float. | |
${ARRAY_FUNCTION_LIKE} | |
.. versionadded:: 1.20.0 | |
Returns | |
------- | |
fromfunction : any | |
The result of the call to `function` is passed back directly. | |
Therefore the shape of `fromfunction` is completely determined by | |
`function`. If `function` returns a scalar value, the shape of | |
`fromfunction` would not match the `shape` parameter. | |
See Also | |
-------- | |
indices, meshgrid | |
Notes | |
----- | |
Keywords other than `dtype` are passed to `function`. | |
Examples | |
-------- | |
>>> np.fromfunction(lambda i, j: i == j, (3, 3), dtype=int) | |
array([[ True, False, False], | |
[False, True, False], | |
[False, False, True]]) | |
>>> np.fromfunction(lambda i, j: i + j, (3, 3), dtype=int) | |
array([[0, 1, 2], | |
[1, 2, 3], | |
[2, 3, 4]]) | |
""" | |
if like is not None: | |
return _fromfunction_with_like(function, shape, dtype=dtype, like=like, **kwargs) | |
args = indices(shape, dtype=dtype) | |
return function(*args, **kwargs) | |
_fromfunction_with_like = array_function_dispatch( | |
_fromfunction_dispatcher | |
)(fromfunction) | |
def _frombuffer(buf, dtype, shape, order): | |
return frombuffer(buf, dtype=dtype).reshape(shape, order=order) | |
def isscalar(element): | |
""" | |
Returns True if the type of `element` is a scalar type. | |
Parameters | |
---------- | |
element : any | |
Input argument, can be of any type and shape. | |
Returns | |
------- | |
val : bool | |
True if `element` is a scalar type, False if it is not. | |
See Also | |
-------- | |
ndim : Get the number of dimensions of an array | |
Notes | |
----- | |
If you need a stricter way to identify a *numerical* scalar, use | |
``isinstance(x, numbers.Number)``, as that returns ``False`` for most | |
non-numerical elements such as strings. | |
In most cases ``np.ndim(x) == 0`` should be used instead of this function, | |
as that will also return true for 0d arrays. This is how numpy overloads | |
functions in the style of the ``dx`` arguments to `gradient` and the ``bins`` | |
argument to `histogram`. Some key differences: | |
+--------------------------------------+---------------+-------------------+ | |
| x |``isscalar(x)``|``np.ndim(x) == 0``| | |
+======================================+===============+===================+ | |
| PEP 3141 numeric objects (including | ``True`` | ``True`` | | |
| builtins) | | | | |
+--------------------------------------+---------------+-------------------+ | |
| builtin string and buffer objects | ``True`` | ``True`` | | |
+--------------------------------------+---------------+-------------------+ | |
| other builtin objects, like | ``False`` | ``True`` | | |
| `pathlib.Path`, `Exception`, | | | | |
| the result of `re.compile` | | | | |
+--------------------------------------+---------------+-------------------+ | |
| third-party objects like | ``False`` | ``True`` | | |
| `matplotlib.figure.Figure` | | | | |
+--------------------------------------+---------------+-------------------+ | |
| zero-dimensional numpy arrays | ``False`` | ``True`` | | |
+--------------------------------------+---------------+-------------------+ | |
| other numpy arrays | ``False`` | ``False`` | | |
+--------------------------------------+---------------+-------------------+ | |
| `list`, `tuple`, and other sequence | ``False`` | ``False`` | | |
| objects | | | | |
+--------------------------------------+---------------+-------------------+ | |
Examples | |
-------- | |
>>> np.isscalar(3.1) | |
True | |
>>> np.isscalar(np.array(3.1)) | |
False | |
>>> np.isscalar([3.1]) | |
False | |
>>> np.isscalar(False) | |
True | |
>>> np.isscalar('numpy') | |
True | |
NumPy supports PEP 3141 numbers: | |
>>> from fractions import Fraction | |
>>> np.isscalar(Fraction(5, 17)) | |
True | |
>>> from numbers import Number | |
>>> np.isscalar(Number()) | |
True | |
""" | |
return (isinstance(element, generic) | |
or type(element) in ScalarType | |
or isinstance(element, numbers.Number)) | |
def binary_repr(num, width=None): | |
""" | |
Return the binary representation of the input number as a string. | |
For negative numbers, if width is not given, a minus sign is added to the | |
front. If width is given, the two's complement of the number is | |
returned, with respect to that width. | |
In a two's-complement system negative numbers are represented by the two's | |
complement of the absolute value. This is the most common method of | |
representing signed integers on computers [1]_. A N-bit two's-complement | |
system can represent every integer in the range | |
:math:`-2^{N-1}` to :math:`+2^{N-1}-1`. | |
Parameters | |
---------- | |
num : int | |
Only an integer decimal number can be used. | |
width : int, optional | |
The length of the returned string if `num` is positive, or the length | |
of the two's complement if `num` is negative, provided that `width` is | |
at least a sufficient number of bits for `num` to be represented in the | |
designated form. | |
If the `width` value is insufficient, it will be ignored, and `num` will | |
be returned in binary (`num` > 0) or two's complement (`num` < 0) form | |
with its width equal to the minimum number of bits needed to represent | |
the number in the designated form. This behavior is deprecated and will | |
later raise an error. | |
.. deprecated:: 1.12.0 | |
Returns | |
------- | |
bin : str | |
Binary representation of `num` or two's complement of `num`. | |
See Also | |
-------- | |
base_repr: Return a string representation of a number in the given base | |
system. | |
bin: Python's built-in binary representation generator of an integer. | |
Notes | |
----- | |
`binary_repr` is equivalent to using `base_repr` with base 2, but about 25x | |
faster. | |
References | |
---------- | |
.. [1] Wikipedia, "Two's complement", | |
https://en.wikipedia.org/wiki/Two's_complement | |
Examples | |
-------- | |
>>> np.binary_repr(3) | |
'11' | |
>>> np.binary_repr(-3) | |
'-11' | |
>>> np.binary_repr(3, width=4) | |
'0011' | |
The two's complement is returned when the input number is negative and | |
width is specified: | |
>>> np.binary_repr(-3, width=3) | |
'101' | |
>>> np.binary_repr(-3, width=5) | |
'11101' | |
""" | |
def warn_if_insufficient(width, binwidth): | |
if width is not None and width < binwidth: | |
warnings.warn( | |
"Insufficient bit width provided. This behavior " | |
"will raise an error in the future.", DeprecationWarning, | |
stacklevel=3) | |
# Ensure that num is a Python integer to avoid overflow or unwanted | |
# casts to floating point. | |
num = operator.index(num) | |
if num == 0: | |
return '0' * (width or 1) | |
elif num > 0: | |
binary = bin(num)[2:] | |
binwidth = len(binary) | |
outwidth = (binwidth if width is None | |
else max(binwidth, width)) | |
warn_if_insufficient(width, binwidth) | |
return binary.zfill(outwidth) | |
else: | |
if width is None: | |
return '-' + bin(-num)[2:] | |
else: | |
poswidth = len(bin(-num)[2:]) | |
# See gh-8679: remove extra digit | |
# for numbers at boundaries. | |
if 2**(poswidth - 1) == -num: | |
poswidth -= 1 | |
twocomp = 2**(poswidth + 1) + num | |
binary = bin(twocomp)[2:] | |
binwidth = len(binary) | |
outwidth = max(binwidth, width) | |
warn_if_insufficient(width, binwidth) | |
return '1' * (outwidth - binwidth) + binary | |
def base_repr(number, base=2, padding=0): | |
""" | |
Return a string representation of a number in the given base system. | |
Parameters | |
---------- | |
number : int | |
The value to convert. Positive and negative values are handled. | |
base : int, optional | |
Convert `number` to the `base` number system. The valid range is 2-36, | |
the default value is 2. | |
padding : int, optional | |
Number of zeros padded on the left. Default is 0 (no padding). | |
Returns | |
------- | |
out : str | |
String representation of `number` in `base` system. | |
See Also | |
-------- | |
binary_repr : Faster version of `base_repr` for base 2. | |
Examples | |
-------- | |
>>> np.base_repr(5) | |
'101' | |
>>> np.base_repr(6, 5) | |
'11' | |
>>> np.base_repr(7, base=5, padding=3) | |
'00012' | |
>>> np.base_repr(10, base=16) | |
'A' | |
>>> np.base_repr(32, base=16) | |
'20' | |
""" | |
digits = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ' | |
if base > len(digits): | |
raise ValueError("Bases greater than 36 not handled in base_repr.") | |
elif base < 2: | |
raise ValueError("Bases less than 2 not handled in base_repr.") | |
num = abs(number) | |
res = [] | |
while num: | |
res.append(digits[num % base]) | |
num //= base | |
if padding: | |
res.append('0' * padding) | |
if number < 0: | |
res.append('-') | |
return ''.join(reversed(res or '0')) | |
# These are all essentially abbreviations | |
# These might wind up in a special abbreviations module | |
def _maketup(descr, val): | |
dt = dtype(descr) | |
# Place val in all scalar tuples: | |
fields = dt.fields | |
if fields is None: | |
return val | |
else: | |
res = [_maketup(fields[name][0], val) for name in dt.names] | |
return tuple(res) | |
def _identity_dispatcher(n, dtype=None, *, like=None): | |
return (like,) | |
def identity(n, dtype=None, *, like=None): | |
""" | |
Return the identity array. | |
The identity array is a square array with ones on | |
the main diagonal. | |
Parameters | |
---------- | |
n : int | |
Number of rows (and columns) in `n` x `n` output. | |
dtype : data-type, optional | |
Data-type of the output. Defaults to ``float``. | |
${ARRAY_FUNCTION_LIKE} | |
.. versionadded:: 1.20.0 | |
Returns | |
------- | |
out : ndarray | |
`n` x `n` array with its main diagonal set to one, | |
and all other elements 0. | |
Examples | |
-------- | |
>>> np.identity(3) | |
array([[1., 0., 0.], | |
[0., 1., 0.], | |
[0., 0., 1.]]) | |
""" | |
if like is not None: | |
return _identity_with_like(n, dtype=dtype, like=like) | |
from numpy import eye | |
return eye(n, dtype=dtype, like=like) | |
_identity_with_like = array_function_dispatch( | |
_identity_dispatcher | |
)(identity) | |
def _allclose_dispatcher(a, b, rtol=None, atol=None, equal_nan=None): | |
return (a, b) | |
def allclose(a, b, rtol=1.e-5, atol=1.e-8, equal_nan=False): | |
""" | |
Returns True if two arrays are element-wise equal within a tolerance. | |
The tolerance values are positive, typically very small numbers. The | |
relative difference (`rtol` * abs(`b`)) and the absolute difference | |
`atol` are added together to compare against the absolute difference | |
between `a` and `b`. | |
NaNs are treated as equal if they are in the same place and if | |
``equal_nan=True``. Infs are treated as equal if they are in the same | |
place and of the same sign in both arrays. | |
Parameters | |
---------- | |
a, b : array_like | |
Input arrays to compare. | |
rtol : float | |
The relative tolerance parameter (see Notes). | |
atol : float | |
The absolute tolerance parameter (see Notes). | |
equal_nan : bool | |
Whether to compare NaN's as equal. If True, NaN's in `a` will be | |
considered equal to NaN's in `b` in the output array. | |
.. versionadded:: 1.10.0 | |
Returns | |
------- | |
allclose : bool | |
Returns True if the two arrays are equal within the given | |
tolerance; False otherwise. | |
See Also | |
-------- | |
isclose, all, any, equal | |
Notes | |
----- | |
If the following equation is element-wise True, then allclose returns | |
True. | |
absolute(`a` - `b`) <= (`atol` + `rtol` * absolute(`b`)) | |
The above equation is not symmetric in `a` and `b`, so that | |
``allclose(a, b)`` might be different from ``allclose(b, a)`` in | |
some rare cases. | |
The comparison of `a` and `b` uses standard broadcasting, which | |
means that `a` and `b` need not have the same shape in order for | |
``allclose(a, b)`` to evaluate to True. The same is true for | |
`equal` but not `array_equal`. | |
`allclose` is not defined for non-numeric data types. | |
Examples | |
-------- | |
>>> np.allclose([1e10,1e-7], [1.00001e10,1e-8]) | |
False | |
>>> np.allclose([1e10,1e-8], [1.00001e10,1e-9]) | |
True | |
>>> np.allclose([1e10,1e-8], [1.0001e10,1e-9]) | |
False | |
>>> np.allclose([1.0, np.nan], [1.0, np.nan]) | |
False | |
>>> np.allclose([1.0, np.nan], [1.0, np.nan], equal_nan=True) | |
True | |
""" | |
res = all(isclose(a, b, rtol=rtol, atol=atol, equal_nan=equal_nan)) | |
return bool(res) | |
def _isclose_dispatcher(a, b, rtol=None, atol=None, equal_nan=None): | |
return (a, b) | |
def isclose(a, b, rtol=1.e-5, atol=1.e-8, equal_nan=False): | |
""" | |
Returns a boolean array where two arrays are element-wise equal within a | |
tolerance. | |
The tolerance values are positive, typically very small numbers. The | |
relative difference (`rtol` * abs(`b`)) and the absolute difference | |
`atol` are added together to compare against the absolute difference | |
between `a` and `b`. | |
.. warning:: The default `atol` is not appropriate for comparing numbers | |
that are much smaller than one (see Notes). | |
Parameters | |
---------- | |
a, b : array_like | |
Input arrays to compare. | |
rtol : float | |
The relative tolerance parameter (see Notes). | |
atol : float | |
The absolute tolerance parameter (see Notes). | |
equal_nan : bool | |
Whether to compare NaN's as equal. If True, NaN's in `a` will be | |
considered equal to NaN's in `b` in the output array. | |
Returns | |
------- | |
y : array_like | |
Returns a boolean array of where `a` and `b` are equal within the | |
given tolerance. If both `a` and `b` are scalars, returns a single | |
boolean value. | |
See Also | |
-------- | |
allclose | |
math.isclose | |
Notes | |
----- | |
.. versionadded:: 1.7.0 | |
For finite values, isclose uses the following equation to test whether | |
two floating point values are equivalent. | |
absolute(`a` - `b`) <= (`atol` + `rtol` * absolute(`b`)) | |
Unlike the built-in `math.isclose`, the above equation is not symmetric | |
in `a` and `b` -- it assumes `b` is the reference value -- so that | |
`isclose(a, b)` might be different from `isclose(b, a)`. Furthermore, | |
the default value of atol is not zero, and is used to determine what | |
small values should be considered close to zero. The default value is | |
appropriate for expected values of order unity: if the expected values | |
are significantly smaller than one, it can result in false positives. | |
`atol` should be carefully selected for the use case at hand. A zero value | |
for `atol` will result in `False` if either `a` or `b` is zero. | |
`isclose` is not defined for non-numeric data types. | |
Examples | |
-------- | |
>>> np.isclose([1e10,1e-7], [1.00001e10,1e-8]) | |
array([ True, False]) | |
>>> np.isclose([1e10,1e-8], [1.00001e10,1e-9]) | |
array([ True, True]) | |
>>> np.isclose([1e10,1e-8], [1.0001e10,1e-9]) | |
array([False, True]) | |
>>> np.isclose([1.0, np.nan], [1.0, np.nan]) | |
array([ True, False]) | |
>>> np.isclose([1.0, np.nan], [1.0, np.nan], equal_nan=True) | |
array([ True, True]) | |
>>> np.isclose([1e-8, 1e-7], [0.0, 0.0]) | |
array([ True, False]) | |
>>> np.isclose([1e-100, 1e-7], [0.0, 0.0], atol=0.0) | |
array([False, False]) | |
>>> np.isclose([1e-10, 1e-10], [1e-20, 0.0]) | |
array([ True, True]) | |
>>> np.isclose([1e-10, 1e-10], [1e-20, 0.999999e-10], atol=0.0) | |
array([False, True]) | |
""" | |
def within_tol(x, y, atol, rtol): | |
with errstate(invalid='ignore'): | |
return less_equal(abs(x-y), atol + rtol * abs(y)) | |
x = asanyarray(a) | |
y = asanyarray(b) | |
# Make sure y is an inexact type to avoid bad behavior on abs(MIN_INT). | |
# This will cause casting of x later. Also, make sure to allow subclasses | |
# (e.g., for numpy.ma). | |
# NOTE: We explicitly allow timedelta, which used to work. This could | |
# possibly be deprecated. See also gh-18286. | |
# timedelta works if `atol` is an integer or also a timedelta. | |
# Although, the default tolerances are unlikely to be useful | |
if y.dtype.kind != "m": | |
dt = multiarray.result_type(y, 1.) | |
y = asanyarray(y, dtype=dt) | |
xfin = isfinite(x) | |
yfin = isfinite(y) | |
if all(xfin) and all(yfin): | |
return within_tol(x, y, atol, rtol) | |
else: | |
finite = xfin & yfin | |
cond = zeros_like(finite, subok=True) | |
# Because we're using boolean indexing, x & y must be the same shape. | |
# Ideally, we'd just do x, y = broadcast_arrays(x, y). It's in | |
# lib.stride_tricks, though, so we can't import it here. | |
x = x * ones_like(cond) | |
y = y * ones_like(cond) | |
# Avoid subtraction with infinite/nan values... | |
cond[finite] = within_tol(x[finite], y[finite], atol, rtol) | |
# Check for equality of infinite values... | |
cond[~finite] = (x[~finite] == y[~finite]) | |
if equal_nan: | |
# Make NaN == NaN | |
both_nan = isnan(x) & isnan(y) | |
# Needed to treat masked arrays correctly. = True would not work. | |
cond[both_nan] = both_nan[both_nan] | |
return cond[()] # Flatten 0d arrays to scalars | |
def _array_equal_dispatcher(a1, a2, equal_nan=None): | |
return (a1, a2) | |
def array_equal(a1, a2, equal_nan=False): | |
""" | |
True if two arrays have the same shape and elements, False otherwise. | |
Parameters | |
---------- | |
a1, a2 : array_like | |
Input arrays. | |
equal_nan : bool | |
Whether to compare NaN's as equal. If the dtype of a1 and a2 is | |
complex, values will be considered equal if either the real or the | |
imaginary component of a given value is ``nan``. | |
.. versionadded:: 1.19.0 | |
Returns | |
------- | |
b : bool | |
Returns True if the arrays are equal. | |
See Also | |
-------- | |
allclose: Returns True if two arrays are element-wise equal within a | |
tolerance. | |
array_equiv: Returns True if input arrays are shape consistent and all | |
elements equal. | |
Examples | |
-------- | |
>>> np.array_equal([1, 2], [1, 2]) | |
True | |
>>> np.array_equal(np.array([1, 2]), np.array([1, 2])) | |
True | |
>>> np.array_equal([1, 2], [1, 2, 3]) | |
False | |
>>> np.array_equal([1, 2], [1, 4]) | |
False | |
>>> a = np.array([1, np.nan]) | |
>>> np.array_equal(a, a) | |
False | |
>>> np.array_equal(a, a, equal_nan=True) | |
True | |
When ``equal_nan`` is True, complex values with nan components are | |
considered equal if either the real *or* the imaginary components are nan. | |
>>> a = np.array([1 + 1j]) | |
>>> b = a.copy() | |
>>> a.real = np.nan | |
>>> b.imag = np.nan | |
>>> np.array_equal(a, b, equal_nan=True) | |
True | |
""" | |
try: | |
a1, a2 = asarray(a1), asarray(a2) | |
except Exception: | |
return False | |
if a1.shape != a2.shape: | |
return False | |
if not equal_nan: | |
return bool(asarray(a1 == a2).all()) | |
# Handling NaN values if equal_nan is True | |
a1nan, a2nan = isnan(a1), isnan(a2) | |
# NaN's occur at different locations | |
if not (a1nan == a2nan).all(): | |
return False | |
# Shapes of a1, a2 and masks are guaranteed to be consistent by this point | |
return bool(asarray(a1[~a1nan] == a2[~a1nan]).all()) | |
def _array_equiv_dispatcher(a1, a2): | |
return (a1, a2) | |
def array_equiv(a1, a2): | |
""" | |
Returns True if input arrays are shape consistent and all elements equal. | |
Shape consistent means they are either the same shape, or one input array | |
can be broadcasted to create the same shape as the other one. | |
Parameters | |
---------- | |
a1, a2 : array_like | |
Input arrays. | |
Returns | |
------- | |
out : bool | |
True if equivalent, False otherwise. | |
Examples | |
-------- | |
>>> np.array_equiv([1, 2], [1, 2]) | |
True | |
>>> np.array_equiv([1, 2], [1, 3]) | |
False | |
Showing the shape equivalence: | |
>>> np.array_equiv([1, 2], [[1, 2], [1, 2]]) | |
True | |
>>> np.array_equiv([1, 2], [[1, 2, 1, 2], [1, 2, 1, 2]]) | |
False | |
>>> np.array_equiv([1, 2], [[1, 2], [1, 3]]) | |
False | |
""" | |
try: | |
a1, a2 = asarray(a1), asarray(a2) | |
except Exception: | |
return False | |
try: | |
multiarray.broadcast(a1, a2) | |
except Exception: | |
return False | |
return bool(asarray(a1 == a2).all()) | |
Inf = inf = infty = Infinity = PINF | |
nan = NaN = NAN | |
False_ = bool_(False) | |
True_ = bool_(True) | |
def extend_all(module): | |
existing = set(__all__) | |
mall = getattr(module, '__all__') | |
for a in mall: | |
if a not in existing: | |
__all__.append(a) | |
from .umath import * | |
from .numerictypes import * | |
from . import fromnumeric | |
from .fromnumeric import * | |
from . import arrayprint | |
from .arrayprint import * | |
from . import _asarray | |
from ._asarray import * | |
from . import _ufunc_config | |
from ._ufunc_config import * | |
extend_all(fromnumeric) | |
extend_all(umath) | |
extend_all(numerictypes) | |
extend_all(arrayprint) | |
extend_all(_asarray) | |
extend_all(_ufunc_config) | |