tmp
/
pip-install-ghxuqwgs
/numpy_78e94bf2b6094bf9a1f3d92042f9bf46
/build
/lib.linux-x86_64-cpython-310
/numpy
/lib
/shape_base.py
from __future__ import division, absolute_import, print_function | |
import warnings | |
import numpy.core.numeric as _nx | |
from numpy.core.numeric import ( | |
asarray, zeros, outer, concatenate, isscalar, array, asanyarray | |
) | |
from numpy.core.fromnumeric import product, reshape | |
from numpy.core import vstack, atleast_3d | |
__all__ = [ | |
'column_stack', 'row_stack', 'dstack', 'array_split', 'split', | |
'hsplit', 'vsplit', 'dsplit', 'apply_over_axes', 'expand_dims', | |
'apply_along_axis', 'kron', 'tile', 'get_array_wrap' | |
] | |
def apply_along_axis(func1d, axis, arr, *args, **kwargs): | |
""" | |
Apply a function to 1-D slices along the given axis. | |
Execute `func1d(a, *args)` where `func1d` operates on 1-D arrays and `a` | |
is a 1-D slice of `arr` along `axis`. | |
Parameters | |
---------- | |
func1d : function | |
This function should accept 1-D arrays. It is applied to 1-D | |
slices of `arr` along the specified axis. | |
axis : integer | |
Axis along which `arr` is sliced. | |
arr : ndarray | |
Input array. | |
args : any | |
Additional arguments to `func1d`. | |
kwargs: any | |
Additional named arguments to `func1d`. | |
.. versionadded:: 1.9.0 | |
Returns | |
------- | |
apply_along_axis : ndarray | |
The output array. The shape of `outarr` is identical to the shape of | |
`arr`, except along the `axis` dimension, where the length of `outarr` | |
is equal to the size of the return value of `func1d`. If `func1d` | |
returns a scalar `outarr` will have one fewer dimensions than `arr`. | |
See Also | |
-------- | |
apply_over_axes : Apply a function repeatedly over multiple axes. | |
Examples | |
-------- | |
>>> def my_func(a): | |
... \"\"\"Average first and last element of a 1-D array\"\"\" | |
... return (a[0] + a[-1]) * 0.5 | |
>>> b = np.array([[1,2,3], [4,5,6], [7,8,9]]) | |
>>> np.apply_along_axis(my_func, 0, b) | |
array([ 4., 5., 6.]) | |
>>> np.apply_along_axis(my_func, 1, b) | |
array([ 2., 5., 8.]) | |
For a function that doesn't return a scalar, the number of dimensions in | |
`outarr` is the same as `arr`. | |
>>> b = np.array([[8,1,7], [4,3,9], [5,2,6]]) | |
>>> np.apply_along_axis(sorted, 1, b) | |
array([[1, 7, 8], | |
[3, 4, 9], | |
[2, 5, 6]]) | |
""" | |
arr = asarray(arr) | |
nd = arr.ndim | |
if axis < 0: | |
axis += nd | |
if (axis >= nd): | |
raise ValueError("axis must be less than arr.ndim; axis=%d, rank=%d." | |
% (axis, nd)) | |
ind = [0]*(nd-1) | |
i = zeros(nd, 'O') | |
indlist = list(range(nd)) | |
indlist.remove(axis) | |
i[axis] = slice(None, None) | |
outshape = asarray(arr.shape).take(indlist) | |
i.put(indlist, ind) | |
res = func1d(arr[tuple(i.tolist())], *args, **kwargs) | |
# if res is a number, then we have a smaller output array | |
if isscalar(res): | |
outarr = zeros(outshape, asarray(res).dtype) | |
outarr[tuple(ind)] = res | |
Ntot = product(outshape) | |
k = 1 | |
while k < Ntot: | |
# increment the index | |
ind[-1] += 1 | |
n = -1 | |
while (ind[n] >= outshape[n]) and (n > (1-nd)): | |
ind[n-1] += 1 | |
ind[n] = 0 | |
n -= 1 | |
i.put(indlist, ind) | |
res = func1d(arr[tuple(i.tolist())], *args, **kwargs) | |
outarr[tuple(ind)] = res | |
k += 1 | |
return outarr | |
else: | |
Ntot = product(outshape) | |
holdshape = outshape | |
outshape = list(arr.shape) | |
outshape[axis] = len(res) | |
outarr = zeros(outshape, asarray(res).dtype) | |
outarr[tuple(i.tolist())] = res | |
k = 1 | |
while k < Ntot: | |
# increment the index | |
ind[-1] += 1 | |
n = -1 | |
while (ind[n] >= holdshape[n]) and (n > (1-nd)): | |
ind[n-1] += 1 | |
ind[n] = 0 | |
n -= 1 | |
i.put(indlist, ind) | |
res = func1d(arr[tuple(i.tolist())], *args, **kwargs) | |
outarr[tuple(i.tolist())] = res | |
k += 1 | |
return outarr | |
def apply_over_axes(func, a, axes): | |
""" | |
Apply a function repeatedly over multiple axes. | |
`func` is called as `res = func(a, axis)`, where `axis` is the first | |
element of `axes`. The result `res` of the function call must have | |
either the same dimensions as `a` or one less dimension. If `res` | |
has one less dimension than `a`, a dimension is inserted before | |
`axis`. The call to `func` is then repeated for each axis in `axes`, | |
with `res` as the first argument. | |
Parameters | |
---------- | |
func : function | |
This function must take two arguments, `func(a, axis)`. | |
a : array_like | |
Input array. | |
axes : array_like | |
Axes over which `func` is applied; the elements must be integers. | |
Returns | |
------- | |
apply_over_axis : ndarray | |
The output array. The number of dimensions is the same as `a`, | |
but the shape can be different. This depends on whether `func` | |
changes the shape of its output with respect to its input. | |
See Also | |
-------- | |
apply_along_axis : | |
Apply a function to 1-D slices of an array along the given axis. | |
Notes | |
------ | |
This function is equivalent to tuple axis arguments to reorderable ufuncs | |
with keepdims=True. Tuple axis arguments to ufuncs have been availabe since | |
version 1.7.0. | |
Examples | |
-------- | |
>>> a = np.arange(24).reshape(2,3,4) | |
>>> a | |
array([[[ 0, 1, 2, 3], | |
[ 4, 5, 6, 7], | |
[ 8, 9, 10, 11]], | |
[[12, 13, 14, 15], | |
[16, 17, 18, 19], | |
[20, 21, 22, 23]]]) | |
Sum over axes 0 and 2. The result has same number of dimensions | |
as the original array: | |
>>> np.apply_over_axes(np.sum, a, [0,2]) | |
array([[[ 60], | |
[ 92], | |
[124]]]) | |
Tuple axis arguments to ufuncs are equivalent: | |
>>> np.sum(a, axis=(0,2), keepdims=True) | |
array([[[ 60], | |
[ 92], | |
[124]]]) | |
""" | |
val = asarray(a) | |
N = a.ndim | |
if array(axes).ndim == 0: | |
axes = (axes,) | |
for axis in axes: | |
if axis < 0: | |
axis = N + axis | |
args = (val, axis) | |
res = func(*args) | |
if res.ndim == val.ndim: | |
val = res | |
else: | |
res = expand_dims(res, axis) | |
if res.ndim == val.ndim: | |
val = res | |
else: | |
raise ValueError("function is not returning " | |
"an array of the correct shape") | |
return val | |
def expand_dims(a, axis): | |
""" | |
Expand the shape of an array. | |
Insert a new axis, corresponding to a given position in the array shape. | |
Parameters | |
---------- | |
a : array_like | |
Input array. | |
axis : int | |
Position (amongst axes) where new axis is to be inserted. | |
Returns | |
------- | |
res : ndarray | |
Output array. The number of dimensions is one greater than that of | |
the input array. | |
See Also | |
-------- | |
doc.indexing, atleast_1d, atleast_2d, atleast_3d | |
Examples | |
-------- | |
>>> x = np.array([1,2]) | |
>>> x.shape | |
(2,) | |
The following is equivalent to ``x[np.newaxis,:]`` or ``x[np.newaxis]``: | |
>>> y = np.expand_dims(x, axis=0) | |
>>> y | |
array([[1, 2]]) | |
>>> y.shape | |
(1, 2) | |
>>> y = np.expand_dims(x, axis=1) # Equivalent to x[:,newaxis] | |
>>> y | |
array([[1], | |
[2]]) | |
>>> y.shape | |
(2, 1) | |
Note that some examples may use ``None`` instead of ``np.newaxis``. These | |
are the same objects: | |
>>> np.newaxis is None | |
True | |
""" | |
a = asarray(a) | |
shape = a.shape | |
if axis < 0: | |
axis = axis + len(shape) + 1 | |
return a.reshape(shape[:axis] + (1,) + shape[axis:]) | |
row_stack = vstack | |
def column_stack(tup): | |
""" | |
Stack 1-D arrays as columns into a 2-D array. | |
Take a sequence of 1-D arrays and stack them as columns | |
to make a single 2-D array. 2-D arrays are stacked as-is, | |
just like with `hstack`. 1-D arrays are turned into 2-D columns | |
first. | |
Parameters | |
---------- | |
tup : sequence of 1-D or 2-D arrays. | |
Arrays to stack. All of them must have the same first dimension. | |
Returns | |
------- | |
stacked : 2-D array | |
The array formed by stacking the given arrays. | |
See Also | |
-------- | |
hstack, vstack, concatenate | |
Examples | |
-------- | |
>>> a = np.array((1,2,3)) | |
>>> b = np.array((2,3,4)) | |
>>> np.column_stack((a,b)) | |
array([[1, 2], | |
[2, 3], | |
[3, 4]]) | |
""" | |
arrays = [] | |
for v in tup: | |
arr = array(v, copy=False, subok=True) | |
if arr.ndim < 2: | |
arr = array(arr, copy=False, subok=True, ndmin=2).T | |
arrays.append(arr) | |
return _nx.concatenate(arrays, 1) | |
def dstack(tup): | |
""" | |
Stack arrays in sequence depth wise (along third axis). | |
Takes a sequence of arrays and stack them along the third axis | |
to make a single array. Rebuilds arrays divided by `dsplit`. | |
This is a simple way to stack 2D arrays (images) into a single | |
3D array for processing. | |
Parameters | |
---------- | |
tup : sequence of arrays | |
Arrays to stack. All of them must have the same shape along all | |
but the third axis. | |
Returns | |
------- | |
stacked : ndarray | |
The array formed by stacking the given arrays. | |
See Also | |
-------- | |
vstack : Stack along first axis. | |
hstack : Stack along second axis. | |
concatenate : Join arrays. | |
dsplit : Split array along third axis. | |
Notes | |
----- | |
Equivalent to ``np.concatenate(tup, axis=2)``. | |
Examples | |
-------- | |
>>> a = np.array((1,2,3)) | |
>>> b = np.array((2,3,4)) | |
>>> np.dstack((a,b)) | |
array([[[1, 2], | |
[2, 3], | |
[3, 4]]]) | |
>>> a = np.array([[1],[2],[3]]) | |
>>> b = np.array([[2],[3],[4]]) | |
>>> np.dstack((a,b)) | |
array([[[1, 2]], | |
[[2, 3]], | |
[[3, 4]]]) | |
""" | |
return _nx.concatenate([atleast_3d(_m) for _m in tup], 2) | |
def _replace_zero_by_x_arrays(sub_arys): | |
for i in range(len(sub_arys)): | |
if len(_nx.shape(sub_arys[i])) == 0: | |
sub_arys[i] = _nx.empty(0, dtype=sub_arys[i].dtype) | |
elif _nx.sometrue(_nx.equal(_nx.shape(sub_arys[i]), 0)): | |
sub_arys[i] = _nx.empty(0, dtype=sub_arys[i].dtype) | |
return sub_arys | |
def array_split(ary, indices_or_sections, axis=0): | |
""" | |
Split an array into multiple sub-arrays. | |
Please refer to the ``split`` documentation. The only difference | |
between these functions is that ``array_split`` allows | |
`indices_or_sections` to be an integer that does *not* equally | |
divide the axis. | |
See Also | |
-------- | |
split : Split array into multiple sub-arrays of equal size. | |
Examples | |
-------- | |
>>> x = np.arange(8.0) | |
>>> np.array_split(x, 3) | |
[array([ 0., 1., 2.]), array([ 3., 4., 5.]), array([ 6., 7.])] | |
""" | |
try: | |
Ntotal = ary.shape[axis] | |
except AttributeError: | |
Ntotal = len(ary) | |
try: | |
# handle scalar case. | |
Nsections = len(indices_or_sections) + 1 | |
div_points = [0] + list(indices_or_sections) + [Ntotal] | |
except TypeError: | |
# indices_or_sections is a scalar, not an array. | |
Nsections = int(indices_or_sections) | |
if Nsections <= 0: | |
raise ValueError('number sections must be larger than 0.') | |
Neach_section, extras = divmod(Ntotal, Nsections) | |
section_sizes = ([0] + | |
extras * [Neach_section+1] + | |
(Nsections-extras) * [Neach_section]) | |
div_points = _nx.array(section_sizes).cumsum() | |
sub_arys = [] | |
sary = _nx.swapaxes(ary, axis, 0) | |
for i in range(Nsections): | |
st = div_points[i] | |
end = div_points[i + 1] | |
sub_arys.append(_nx.swapaxes(sary[st:end], axis, 0)) | |
# This "kludge" was introduced here to replace arrays shaped (0, 10) | |
# or similar with an array shaped (0,). | |
# There seems no need for this, so give a FutureWarning to remove later. | |
if sub_arys[-1].size == 0 and sub_arys[-1].ndim != 1: | |
warnings.warn("in the future np.array_split will retain the shape of " | |
"arrays with a zero size, instead of replacing them by " | |
"`array([])`, which always has a shape of (0,).", | |
FutureWarning) | |
sub_arys = _replace_zero_by_x_arrays(sub_arys) | |
return sub_arys | |
def split(ary,indices_or_sections,axis=0): | |
""" | |
Split an array into multiple sub-arrays. | |
Parameters | |
---------- | |
ary : ndarray | |
Array to be divided into sub-arrays. | |
indices_or_sections : int or 1-D array | |
If `indices_or_sections` is an integer, N, the array will be divided | |
into N equal arrays along `axis`. If such a split is not possible, | |
an error is raised. | |
If `indices_or_sections` is a 1-D array of sorted integers, the entries | |
indicate where along `axis` the array is split. For example, | |
``[2, 3]`` would, for ``axis=0``, result in | |
- ary[:2] | |
- ary[2:3] | |
- ary[3:] | |
If an index exceeds the dimension of the array along `axis`, | |
an empty sub-array is returned correspondingly. | |
axis : int, optional | |
The axis along which to split, default is 0. | |
Returns | |
------- | |
sub-arrays : list of ndarrays | |
A list of sub-arrays. | |
Raises | |
------ | |
ValueError | |
If `indices_or_sections` is given as an integer, but | |
a split does not result in equal division. | |
See Also | |
-------- | |
array_split : Split an array into multiple sub-arrays of equal or | |
near-equal size. Does not raise an exception if | |
an equal division cannot be made. | |
hsplit : Split array into multiple sub-arrays horizontally (column-wise). | |
vsplit : Split array into multiple sub-arrays vertically (row wise). | |
dsplit : Split array into multiple sub-arrays along the 3rd axis (depth). | |
concatenate : Join arrays together. | |
hstack : Stack arrays in sequence horizontally (column wise). | |
vstack : Stack arrays in sequence vertically (row wise). | |
dstack : Stack arrays in sequence depth wise (along third dimension). | |
Examples | |
-------- | |
>>> x = np.arange(9.0) | |
>>> np.split(x, 3) | |
[array([ 0., 1., 2.]), array([ 3., 4., 5.]), array([ 6., 7., 8.])] | |
>>> x = np.arange(8.0) | |
>>> np.split(x, [3, 5, 6, 10]) | |
[array([ 0., 1., 2.]), | |
array([ 3., 4.]), | |
array([ 5.]), | |
array([ 6., 7.]), | |
array([], dtype=float64)] | |
""" | |
try: | |
len(indices_or_sections) | |
except TypeError: | |
sections = indices_or_sections | |
N = ary.shape[axis] | |
if N % sections: | |
raise ValueError( | |
'array split does not result in an equal division') | |
res = array_split(ary, indices_or_sections, axis) | |
return res | |
def hsplit(ary, indices_or_sections): | |
""" | |
Split an array into multiple sub-arrays horizontally (column-wise). | |
Please refer to the `split` documentation. `hsplit` is equivalent | |
to `split` with ``axis=1``, the array is always split along the second | |
axis regardless of the array dimension. | |
See Also | |
-------- | |
split : Split an array into multiple sub-arrays of equal size. | |
Examples | |
-------- | |
>>> x = np.arange(16.0).reshape(4, 4) | |
>>> x | |
array([[ 0., 1., 2., 3.], | |
[ 4., 5., 6., 7.], | |
[ 8., 9., 10., 11.], | |
[ 12., 13., 14., 15.]]) | |
>>> np.hsplit(x, 2) | |
[array([[ 0., 1.], | |
[ 4., 5.], | |
[ 8., 9.], | |
[ 12., 13.]]), | |
array([[ 2., 3.], | |
[ 6., 7.], | |
[ 10., 11.], | |
[ 14., 15.]])] | |
>>> np.hsplit(x, np.array([3, 6])) | |
[array([[ 0., 1., 2.], | |
[ 4., 5., 6.], | |
[ 8., 9., 10.], | |
[ 12., 13., 14.]]), | |
array([[ 3.], | |
[ 7.], | |
[ 11.], | |
[ 15.]]), | |
array([], dtype=float64)] | |
With a higher dimensional array the split is still along the second axis. | |
>>> x = np.arange(8.0).reshape(2, 2, 2) | |
>>> x | |
array([[[ 0., 1.], | |
[ 2., 3.]], | |
[[ 4., 5.], | |
[ 6., 7.]]]) | |
>>> np.hsplit(x, 2) | |
[array([[[ 0., 1.]], | |
[[ 4., 5.]]]), | |
array([[[ 2., 3.]], | |
[[ 6., 7.]]])] | |
""" | |
if len(_nx.shape(ary)) == 0: | |
raise ValueError('hsplit only works on arrays of 1 or more dimensions') | |
if len(ary.shape) > 1: | |
return split(ary, indices_or_sections, 1) | |
else: | |
return split(ary, indices_or_sections, 0) | |
def vsplit(ary, indices_or_sections): | |
""" | |
Split an array into multiple sub-arrays vertically (row-wise). | |
Please refer to the ``split`` documentation. ``vsplit`` is equivalent | |
to ``split`` with `axis=0` (default), the array is always split along the | |
first axis regardless of the array dimension. | |
See Also | |
-------- | |
split : Split an array into multiple sub-arrays of equal size. | |
Examples | |
-------- | |
>>> x = np.arange(16.0).reshape(4, 4) | |
>>> x | |
array([[ 0., 1., 2., 3.], | |
[ 4., 5., 6., 7.], | |
[ 8., 9., 10., 11.], | |
[ 12., 13., 14., 15.]]) | |
>>> np.vsplit(x, 2) | |
[array([[ 0., 1., 2., 3.], | |
[ 4., 5., 6., 7.]]), | |
array([[ 8., 9., 10., 11.], | |
[ 12., 13., 14., 15.]])] | |
>>> np.vsplit(x, np.array([3, 6])) | |
[array([[ 0., 1., 2., 3.], | |
[ 4., 5., 6., 7.], | |
[ 8., 9., 10., 11.]]), | |
array([[ 12., 13., 14., 15.]]), | |
array([], dtype=float64)] | |
With a higher dimensional array the split is still along the first axis. | |
>>> x = np.arange(8.0).reshape(2, 2, 2) | |
>>> x | |
array([[[ 0., 1.], | |
[ 2., 3.]], | |
[[ 4., 5.], | |
[ 6., 7.]]]) | |
>>> np.vsplit(x, 2) | |
[array([[[ 0., 1.], | |
[ 2., 3.]]]), | |
array([[[ 4., 5.], | |
[ 6., 7.]]])] | |
""" | |
if len(_nx.shape(ary)) < 2: | |
raise ValueError('vsplit only works on arrays of 2 or more dimensions') | |
return split(ary, indices_or_sections, 0) | |
def dsplit(ary, indices_or_sections): | |
""" | |
Split array into multiple sub-arrays along the 3rd axis (depth). | |
Please refer to the `split` documentation. `dsplit` is equivalent | |
to `split` with ``axis=2``, the array is always split along the third | |
axis provided the array dimension is greater than or equal to 3. | |
See Also | |
-------- | |
split : Split an array into multiple sub-arrays of equal size. | |
Examples | |
-------- | |
>>> x = np.arange(16.0).reshape(2, 2, 4) | |
>>> x | |
array([[[ 0., 1., 2., 3.], | |
[ 4., 5., 6., 7.]], | |
[[ 8., 9., 10., 11.], | |
[ 12., 13., 14., 15.]]]) | |
>>> np.dsplit(x, 2) | |
[array([[[ 0., 1.], | |
[ 4., 5.]], | |
[[ 8., 9.], | |
[ 12., 13.]]]), | |
array([[[ 2., 3.], | |
[ 6., 7.]], | |
[[ 10., 11.], | |
[ 14., 15.]]])] | |
>>> np.dsplit(x, np.array([3, 6])) | |
[array([[[ 0., 1., 2.], | |
[ 4., 5., 6.]], | |
[[ 8., 9., 10.], | |
[ 12., 13., 14.]]]), | |
array([[[ 3.], | |
[ 7.]], | |
[[ 11.], | |
[ 15.]]]), | |
array([], dtype=float64)] | |
""" | |
if len(_nx.shape(ary)) < 3: | |
raise ValueError('dsplit only works on arrays of 3 or more dimensions') | |
return split(ary, indices_or_sections, 2) | |
def get_array_prepare(*args): | |
"""Find the wrapper for the array with the highest priority. | |
In case of ties, leftmost wins. If no wrapper is found, return None | |
""" | |
wrappers = sorted((getattr(x, '__array_priority__', 0), -i, | |
x.__array_prepare__) for i, x in enumerate(args) | |
if hasattr(x, '__array_prepare__')) | |
if wrappers: | |
return wrappers[-1][-1] | |
return None | |
def get_array_wrap(*args): | |
"""Find the wrapper for the array with the highest priority. | |
In case of ties, leftmost wins. If no wrapper is found, return None | |
""" | |
wrappers = sorted((getattr(x, '__array_priority__', 0), -i, | |
x.__array_wrap__) for i, x in enumerate(args) | |
if hasattr(x, '__array_wrap__')) | |
if wrappers: | |
return wrappers[-1][-1] | |
return None | |
def kron(a, b): | |
""" | |
Kronecker product of two arrays. | |
Computes the Kronecker product, a composite array made of blocks of the | |
second array scaled by the first. | |
Parameters | |
---------- | |
a, b : array_like | |
Returns | |
------- | |
out : ndarray | |
See Also | |
-------- | |
outer : The outer product | |
Notes | |
----- | |
The function assumes that the number of dimenensions of `a` and `b` | |
are the same, if necessary prepending the smallest with ones. | |
If `a.shape = (r0,r1,..,rN)` and `b.shape = (s0,s1,...,sN)`, | |
the Kronecker product has shape `(r0*s0, r1*s1, ..., rN*SN)`. | |
The elements are products of elements from `a` and `b`, organized | |
explicitly by:: | |
kron(a,b)[k0,k1,...,kN] = a[i0,i1,...,iN] * b[j0,j1,...,jN] | |
where:: | |
kt = it * st + jt, t = 0,...,N | |
In the common 2-D case (N=1), the block structure can be visualized:: | |
[[ a[0,0]*b, a[0,1]*b, ... , a[0,-1]*b ], | |
[ ... ... ], | |
[ a[-1,0]*b, a[-1,1]*b, ... , a[-1,-1]*b ]] | |
Examples | |
-------- | |
>>> np.kron([1,10,100], [5,6,7]) | |
array([ 5, 6, 7, 50, 60, 70, 500, 600, 700]) | |
>>> np.kron([5,6,7], [1,10,100]) | |
array([ 5, 50, 500, 6, 60, 600, 7, 70, 700]) | |
>>> np.kron(np.eye(2), np.ones((2,2))) | |
array([[ 1., 1., 0., 0.], | |
[ 1., 1., 0., 0.], | |
[ 0., 0., 1., 1.], | |
[ 0., 0., 1., 1.]]) | |
>>> a = np.arange(100).reshape((2,5,2,5)) | |
>>> b = np.arange(24).reshape((2,3,4)) | |
>>> c = np.kron(a,b) | |
>>> c.shape | |
(2, 10, 6, 20) | |
>>> I = (1,3,0,2) | |
>>> J = (0,2,1) | |
>>> J1 = (0,) + J # extend to ndim=4 | |
>>> S1 = (1,) + b.shape | |
>>> K = tuple(np.array(I) * np.array(S1) + np.array(J1)) | |
>>> c[K] == a[I]*b[J] | |
True | |
""" | |
b = asanyarray(b) | |
a = array(a, copy=False, subok=True, ndmin=b.ndim) | |
ndb, nda = b.ndim, a.ndim | |
if (nda == 0 or ndb == 0): | |
return _nx.multiply(a, b) | |
as_ = a.shape | |
bs = b.shape | |
if not a.flags.contiguous: | |
a = reshape(a, as_) | |
if not b.flags.contiguous: | |
b = reshape(b, bs) | |
nd = ndb | |
if (ndb != nda): | |
if (ndb > nda): | |
as_ = (1,)*(ndb-nda) + as_ | |
else: | |
bs = (1,)*(nda-ndb) + bs | |
nd = nda | |
result = outer(a, b).reshape(as_+bs) | |
axis = nd-1 | |
for _ in range(nd): | |
result = concatenate(result, axis=axis) | |
wrapper = get_array_prepare(a, b) | |
if wrapper is not None: | |
result = wrapper(result) | |
wrapper = get_array_wrap(a, b) | |
if wrapper is not None: | |
result = wrapper(result) | |
return result | |
def tile(A, reps): | |
""" | |
Construct an array by repeating A the number of times given by reps. | |
If `reps` has length ``d``, the result will have dimension of | |
``max(d, A.ndim)``. | |
If ``A.ndim < d``, `A` is promoted to be d-dimensional by prepending new | |
axes. So a shape (3,) array is promoted to (1, 3) for 2-D replication, | |
or shape (1, 1, 3) for 3-D replication. If this is not the desired | |
behavior, promote `A` to d-dimensions manually before calling this | |
function. | |
If ``A.ndim > d``, `reps` is promoted to `A`.ndim by pre-pending 1's to it. | |
Thus for an `A` of shape (2, 3, 4, 5), a `reps` of (2, 2) is treated as | |
(1, 1, 2, 2). | |
Parameters | |
---------- | |
A : array_like | |
The input array. | |
reps : array_like | |
The number of repetitions of `A` along each axis. | |
Returns | |
------- | |
c : ndarray | |
The tiled output array. | |
See Also | |
-------- | |
repeat : Repeat elements of an array. | |
Examples | |
-------- | |
>>> a = np.array([0, 1, 2]) | |
>>> np.tile(a, 2) | |
array([0, 1, 2, 0, 1, 2]) | |
>>> np.tile(a, (2, 2)) | |
array([[0, 1, 2, 0, 1, 2], | |
[0, 1, 2, 0, 1, 2]]) | |
>>> np.tile(a, (2, 1, 2)) | |
array([[[0, 1, 2, 0, 1, 2]], | |
[[0, 1, 2, 0, 1, 2]]]) | |
>>> b = np.array([[1, 2], [3, 4]]) | |
>>> np.tile(b, 2) | |
array([[1, 2, 1, 2], | |
[3, 4, 3, 4]]) | |
>>> np.tile(b, (2, 1)) | |
array([[1, 2], | |
[3, 4], | |
[1, 2], | |
[3, 4]]) | |
""" | |
try: | |
tup = tuple(reps) | |
except TypeError: | |
tup = (reps,) | |
d = len(tup) | |
c = _nx.array(A, copy=False, subok=True, ndmin=d) | |
shape = list(c.shape) | |
n = max(c.size, 1) | |
if (d < c.ndim): | |
tup = (1,)*(c.ndim-d) + tup | |
for i, nrep in enumerate(tup): | |
if nrep != 1: | |
c = c.reshape(-1, n).repeat(nrep, 0) | |
dim_in = shape[i] | |
dim_out = dim_in*nrep | |
shape[i] = dim_out | |
n //= max(dim_in, 1) | |
return c.reshape(shape) | |