Skip to content
This repository has been archived by the owner on Nov 17, 2023. It is now read-only.

[numpy] add op flipud, fliplr #17192

Merged
merged 6 commits into from
Dec 31, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 107 additions & 4 deletions python/mxnet/ndarray/numpy/_op.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,11 @@
'logspace', 'expand_dims', 'tile', 'arange', 'array_split', 'split', 'vsplit', 'concatenate', 'append',
'stack', 'vstack', 'column_stack', 'dstack', 'average', 'mean', 'maximum', 'minimum', 'swapaxes', 'clip',
'argmax', 'argmin', 'std', 'var', 'indices', 'copysign', 'ravel', 'unravel_index', 'hanning', 'hamming',
'blackman', 'flip', 'around', 'round', 'hypot', 'bitwise_xor', 'bitwise_or', 'rad2deg', 'deg2rad',
'unique', 'lcm', 'tril', 'identity', 'take', 'ldexp', 'vdot', 'inner', 'outer', 'equal', 'not_equal',
'greater', 'less', 'greater_equal', 'less_equal', 'hsplit', 'rot90', 'einsum', 'true_divide', 'nonzero',
'shares_memory', 'may_share_memory', 'diff', 'resize', 'nan_to_num', 'where', 'bincount']
'blackman', 'flip', 'flipud', 'fliplr', 'around', 'round', 'hypot', 'bitwise_xor', 'bitwise_or',
'rad2deg', 'deg2rad', 'unique', 'lcm', 'tril', 'identity', 'take', 'ldexp', 'vdot', 'inner', 'outer',
'equal', 'not_equal', 'greater', 'less', 'greater_equal', 'less_equal', 'hsplit', 'rot90', 'einsum',
'true_divide', 'nonzero', 'shares_memory', 'may_share_memory', 'diff', 'resize', 'nan_to_num', 'where',
'bincount']


@set_module('mxnet.ndarray.numpy')
Expand Down Expand Up @@ -4813,6 +4814,108 @@ def flip(m, axis=None, out=None):
raise TypeError('type {} not supported'.format(str(type(m))))


@set_module('mxnet.ndarray.numpy')
def flipud(m):
r"""
flipud(*args, **kwargs)

Flip array in the up/down direction.

Flip the entries in each column in the up/down direction.
Rows are preserved, but appear in a different order than before.

Parameters
----------
m : array_like
Input array.

Returns
-------
out : array_like
A view of `m` with the rows reversed. Since a view is
returned, this operation is :math:`\mathcal O(1)`.

See Also
--------
fliplr : Flip array in the left/right direction.
rot90 : Rotate array counterclockwise.

Notes
-----
Equivalent to ``m[::-1,...]``.
Does not require the array to be two-dimensional.

Examples
--------
>>> A = np.diag(np.array([1.0, 2, 3]))
>>> A
array([[1., 0., 0.],
[0., 2., 0.],
[0., 0., 3.]])
>>> np.flipud(A)
array([[0., 0., 3.],
[0., 2., 0.],
[1., 0., 0.]])

>>> A = np.random.randn(2,3,5)
>>> np.all(np.flipud(A) == A[::-1,...])
array(True)

>>> np.flipud(np.array([1,2]))
array([2., 1.])
"""
return flip(m, 0)


@set_module('mxnet.ndarray.numpy')
def fliplr(m):
r"""
fliplr(*args, **kwargs)

Flip array in the left/right direction.

Flip the entries in each row in the left/right direction.
Columns are preserved, but appear in a different order than before.

Parameters
----------
m : array_like
Input array, must be at least 2-D.

Returns
-------
f : ndarray
A view of `m` with the columns reversed. Since a view
is returned, this operation is :math:`\mathcal O(1)`.

See Also
--------
flipud : Flip array in the up/down direction.
rot90 : Rotate array counterclockwise.

Notes
-----
Equivalent to m[:,::-1]. Requires the array to be at least 2-D.

Examples
--------
>>> A = np.diag(np.array([1.,2.,3.]))
>>> A
array([[1., 0., 0.],
[0., 2., 0.],
[0., 0., 3.]])
>>> np.fliplr(A)
array([[0., 0., 1.],
[0., 2., 0.],
[3., 0., 0.]])

>>> A = np.random.randn(2,3,5)
>>> np.all(np.fliplr(A) == A[:,::-1,...])
array(True)
"""
return flip(m, 1)


@set_module('mxnet.ndarray.numpy')
def around(x, decimals=0, out=None, **kwargs):
r"""
Expand Down
112 changes: 107 additions & 5 deletions python/mxnet/numpy/multiarray.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,11 @@
'tensordot', 'eye', 'linspace', 'logspace', 'expand_dims', 'tile', 'arange', 'array_split',
'split', 'vsplit', 'concatenate', 'stack', 'vstack', 'column_stack', 'dstack', 'average', 'mean',
'maximum', 'minimum', 'swapaxes', 'clip', 'argmax', 'argmin', 'std', 'var', 'indices', 'copysign',
'ravel', 'unravel_index', 'hanning', 'hamming', 'blackman', 'flip', 'around', 'round', 'arctan2',
'hypot', 'bitwise_xor', 'bitwise_or', 'rad2deg', 'deg2rad', 'unique', 'lcm', 'tril', 'identity',
'take', 'ldexp', 'vdot', 'inner', 'outer', 'equal', 'not_equal', 'greater', 'less', 'greater_equal',
'less_equal', 'hsplit', 'rot90', 'einsum', 'true_divide', 'nonzero', 'shares_memory',
'may_share_memory', 'diff', 'resize', 'nan_to_num', 'where', 'bincount']
'ravel', 'unravel_index', 'hanning', 'hamming', 'blackman', 'flip', 'flipud', 'fliplr', 'around',
'round', 'arctan2', 'hypot', 'bitwise_xor', 'bitwise_or', 'rad2deg', 'deg2rad', 'unique', 'lcm',
'tril', 'identity', 'take', 'ldexp', 'vdot', 'inner', 'outer', 'equal', 'not_equal', 'greater',
'less', 'greater_equal', 'less_equal', 'hsplit', 'rot90', 'einsum', 'true_divide', 'nonzero',
'shares_memory', 'may_share_memory', 'diff', 'resize', 'nan_to_num', 'where', 'bincount']

# Return code for dispatching indexing function call
_NDARRAY_UNSUPPORTED_INDEXING = -1
Expand Down Expand Up @@ -6513,6 +6513,108 @@ def flip(m, axis=None, out=None):
return _mx_nd_np.flip(m, axis, out=out)


@set_module('mxnet.numpy')
def flipud(m):
r"""
flipud(*args, **kwargs)

Flip array in the up/down direction.

Flip the entries in each column in the up/down direction.
Rows are preserved, but appear in a different order than before.

Parameters
----------
m : array_like
Input array.

Returns
-------
out : array_like
A view of `m` with the rows reversed. Since a view is
returned, this operation is :math:`\mathcal O(1)`.

See Also
--------
fliplr : Flip array in the left/right direction.
rot90 : Rotate array counterclockwise.

Notes
-----
Equivalent to ``m[::-1,...]``.
Does not require the array to be two-dimensional.

Examples
--------
>>> A = np.diag(np.array([1.0, 2, 3]))
>>> A
array([[1., 0., 0.],
[0., 2., 0.],
[0., 0., 3.]])
>>> np.flipud(A)
array([[0., 0., 3.],
[0., 2., 0.],
[1., 0., 0.]])

>>> A = np.random.randn(2,3,5)
>>> np.all(np.flipud(A) == A[::-1,...])
array(True)

>>> np.flipud(np.array([1,2]))
array([2., 1.])
"""
return flip(m, 0)


@set_module('mxnet.numpy')
def fliplr(m):
r"""
fliplr(*args, **kwargs)

Flip array in the left/right direction.

Flip the entries in each row in the left/right direction.
Columns are preserved, but appear in a different order than before.

Parameters
----------
m : array_like
Input array, must be at least 2-D.

Returns
-------
f : ndarray
A view of `m` with the columns reversed. Since a view
is returned, this operation is :math:`\mathcal O(1)`.

See Also
--------
flipud : Flip array in the up/down direction.
rot90 : Rotate array counterclockwise.

Notes
-----
Equivalent to m[:,::-1]. Requires the array to be at least 2-D.

Examples
--------
>>> A = np.diag([1.,2.,3.])
>>> A
array([[1., 0., 0.],
[0., 2., 0.],
[0., 0., 3.]])
>>> np.fliplr(A)
array([[0., 0., 1.],
[0., 2., 0.],
[3., 0., 0.]])

>>> A = np.random.randn(2,3,5)
>>> np.all(np.fliplr(A) == A[:,::-1,...])
array(True)
"""
return flip(m, 1)


@set_module('mxnet.numpy')
def around(x, decimals=0, out=None, **kwargs):
r"""
Expand Down
2 changes: 2 additions & 0 deletions python/mxnet/numpy_dispatch_protocol.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ def _run_with_array_ufunc_proto(*args, **kwargs):
'expand_dims',
'fix',
'flip',
'flipud',
'fliplr',
'inner',
'max',
'amax',
Expand Down
56 changes: 52 additions & 4 deletions python/mxnet/symbol/numpy/_symbol.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,10 @@
'logspace', 'expand_dims', 'tile', 'arange', 'array_split', 'split', 'vsplit', 'concatenate', 'append',
'stack', 'vstack', 'column_stack', 'dstack', 'average', 'mean', 'maximum', 'minimum', 'swapaxes', 'clip',
'argmax', 'argmin', 'std', 'var', 'indices', 'copysign', 'ravel', 'unravel_index', 'hanning', 'hamming',
'blackman', 'flip', 'around', 'round', 'hypot', 'bitwise_xor', 'bitwise_or', 'rad2deg', 'deg2rad',
'unique', 'lcm', 'tril', 'identity', 'take', 'ldexp', 'vdot', 'inner', 'outer', 'equal', 'not_equal',
'greater', 'less', 'greater_equal', 'less_equal', 'hsplit', 'rot90', 'einsum', 'true_divide',
'shares_memory', 'may_share_memory', 'diff', 'resize', 'nan_to_num', 'where', 'bincount']
'blackman', 'flip', 'flipud', 'fliplr', 'around', 'round', 'hypot', 'bitwise_xor', 'bitwise_or',
'rad2deg', 'deg2rad', 'unique', 'lcm', 'tril', 'identity', 'take', 'ldexp', 'vdot', 'inner', 'outer',
'equal', 'not_equal', 'greater', 'less', 'greater_equal', 'less_equal', 'hsplit', 'rot90', 'einsum',
'true_divide', 'shares_memory', 'may_share_memory', 'diff', 'resize', 'nan_to_num', 'where', 'bincount']


@set_module('mxnet.symbol.numpy')
Expand Down Expand Up @@ -4581,6 +4581,54 @@ def flip(m, axis=None, out=None):
raise TypeError('type {} not supported'.format(str(type(m))))


@set_module('mxnet.symbol.numpy')
def flipud(m):
r"""
flipud(*args, **kwargs)

Flip array in the up/down direction.

Flip the entries in each column in the up/down direction.
Rows are preserved, but appear in a different order than before.

Parameters
----------
m : array_like
Input array.

Returns
-------
out : array_like
A view of `m` with the rows reversed. Since a view is
returned, this operation is :math:`\mathcal O(1)`.
"""
return flip(m, 0)


@set_module('mxnet.symbol.numpy')
def fliplr(m):
r"""
fliplr(*args, **kwargs)

Flip array in the left/right direction.

Flip the entries in each row in the left/right direction.
Columns are preserved, but appear in a different order than before.

Parameters
----------
m : array_like
Input array, must be at least 2-D.

Returns
-------
f : ndarray
A view of `m` with the columns reversed. Since a view
is returned, this operation is :math:`\mathcal O(1)`.
"""
return flip(m, 1)


@set_module('mxnet.symbol.numpy')
def around(x, decimals=0, out=None, **kwargs):
r"""
Expand Down
3 changes: 2 additions & 1 deletion src/operator/numpy/np_matrix_op-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -498,7 +498,8 @@ void NumpyFlipForward(const nnvm::NodeAttrs& attrs,
std::vector<index_t> trailing_(axistemp.ndim());
index_t flip_index = 0;
for (int axis : axistemp) {
CHECK_LT(axis, ishape.ndim());
CHECK_LT(axis, ishape.ndim()) << "axis " << axis
<< " is out of bounds for array of dimension " << ishape.ndim() << std::endl;
stride_[flip_index] = ishape[axis];
trailing_[flip_index] = 1;
for (int i2 = axis + 1; i2 < ishape.ndim(); ++i2) {
Expand Down
14 changes: 14 additions & 0 deletions tests/python/unittest/test_numpy_interoperability.py
Original file line number Diff line number Diff line change
Expand Up @@ -787,6 +787,18 @@ def _add_workload_flip():
OpArgMngr.add_workload('flip', np.array([[[0, 1], [2, 3]], [[4, 5], [6, 7]]]), (1, 2))


def _add_workload_flipud():
OpArgMngr.add_workload('flipud', np.random.normal(size=(4, 4)))
OpArgMngr.add_workload('flipud', np.array([[0, 1, 2], [3, 4, 5]]))
OpArgMngr.add_workload('flipud', np.array([[[0, 1], [2, 3]], [[4, 5], [6, 7]]]))


def _add_workload_fliplr():
OpArgMngr.add_workload('fliplr', np.random.normal(size=(4, 4)))
OpArgMngr.add_workload('fliplr', np.array([[0, 1, 2], [3, 4, 5]]))
OpArgMngr.add_workload('fliplr', np.array([[[0, 1], [2, 3]], [[4, 5], [6, 7]]]))


def _add_workload_max(array_pool):
OpArgMngr.add_workload('max', array_pool['4x1'])

Expand Down Expand Up @@ -1606,6 +1618,8 @@ def _prepare_workloads():
_add_workload_expand_dims()
_add_workload_fix()
_add_workload_flip()
_add_workload_flipud()
_add_workload_fliplr()
_add_workload_max(array_pool)
_add_workload_amax(array_pool)
_add_workload_min(array_pool)
Expand Down
Loading