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

Commit 8ce625d

Browse files
author
Ying
committed
numpy operator ravel, derive from reshape
* it is the same as reshape(x, -1) * register reshape with prefix _npi_ * fix format error * edit examples in doc * fix error in review
1 parent 9675a2d commit 8ce625d

File tree

5 files changed

+213
-3
lines changed

5 files changed

+213
-3
lines changed

python/mxnet/ndarray/numpy/_op.py

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
'rint', 'radians', 'reciprocal', 'square', 'negative', 'fix', 'ceil', 'floor',
3434
'trunc', 'logical_not', 'arcsinh', 'arccosh', 'arctanh', 'tensordot',
3535
'linspace', 'expand_dims', 'tile', 'arange', 'split', 'concatenate', 'stack', 'mean',
36-
'maximum', 'minimum', 'swapaxes', 'clip', 'argmax', 'std', 'var']
36+
'maximum', 'minimum', 'swapaxes', 'clip', 'argmax', 'std', 'var', 'ravel']
3737

3838

3939
@set_module('mxnet.ndarray.numpy')
@@ -2363,3 +2363,55 @@ def var(a, axis=None, dtype=None, out=None, ddof=0, keepdims=False): # pylint:
23632363
0.2025
23642364
"""
23652365
return _npi.var(a, axis=axis, dtype=dtype, ddof=ddof, keepdims=keepdims, out=out)
2366+
2367+
2368+
@set_module('mxnet.ndarray.numpy')
2369+
def ravel(x, out=None):
2370+
r"""
2371+
ravel(x, out=None)
2372+
2373+
Return a contiguous flattened array.
2374+
A 1-D array, containing the elements of the input, is returned. A copy is
2375+
made only if needed.
2376+
2377+
Parameters
2378+
----------
2379+
x : ndarray
2380+
Input array. The elements in `x` are read in row-major, C-style order and
2381+
packed as a 1-D array.
2382+
out : ndarray or None, optional
2383+
A location into which the result is stored. If not provided or `None`,
2384+
a freshly-allocated array is returned.
2385+
2386+
Returns
2387+
-------
2388+
y : ndarray
2389+
y is an array of the same subtype as `x`, with shape ``(x.size,)``.
2390+
Note that matrices are special cased for backward compatibility, if `x`
2391+
is a matrix, then y is a 1-D ndarray.
2392+
2393+
Notes
2394+
-----
2395+
This function differs from the original numpy.arange in the following aspects:
2396+
- Only support row-major, C-style order.
2397+
2398+
Examples
2399+
--------
2400+
It is equivalent to ``reshape(x, -1)``.
2401+
2402+
>>> x = np.array([[1, 2, 3], [4, 5, 6]])
2403+
>>> print(np.ravel(x))
2404+
[1. 2. 3. 4. 5. 6.]
2405+
2406+
>>> print(x.reshape(-1))
2407+
[1. 2. 3. 4. 5. 6.]
2408+
2409+
>>> print(np.ravel(x.T))
2410+
[1. 4. 2. 5. 3. 6.]
2411+
"""
2412+
if isinstance(x, numeric_types):
2413+
return _np.reshape(x, -1)
2414+
elif isinstance(x, NDArray):
2415+
return _npi.reshape(x, -1)
2416+
else:
2417+
raise TypeError('type {} not supported'.format(str(type(x))))

python/mxnet/numpy/multiarray.py

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@
5252
'degrees', 'log2', 'log1p', 'rint', 'radians', 'reciprocal', 'square', 'negative',
5353
'fix', 'ceil', 'floor', 'trunc', 'logical_not', 'arcsinh', 'arccosh', 'arctanh',
5454
'tensordot', 'linspace', 'expand_dims', 'tile', 'arange', 'split', 'concatenate',
55-
'stack', 'mean', 'maximum', 'minimum', 'swapaxes', 'clip', 'argmax', 'std', 'var']
55+
'stack', 'mean', 'maximum', 'minimum', 'swapaxes', 'clip', 'argmax', 'std', 'var', 'ravel']
5656

5757
# Return code for dispatching indexing function call
5858
_NDARRAY_UNSUPPORTED_INDEXING = -1
@@ -3808,3 +3808,50 @@ def var(a, axis=None, dtype=None, out=None, ddof=0, keepdims=None):
38083808
0.2025
38093809
"""
38103810
return _npi.var(a, axis=axis, dtype=dtype, ddof=ddof, keepdims=keepdims, out=out)
3811+
3812+
3813+
@set_module('mxnet.numpy')
3814+
def ravel(x, out=None):
3815+
r"""
3816+
ravel(x, out=None)
3817+
3818+
Return a contiguous flattened array.
3819+
A 1-D array, containing the elements of the input, is returned. A copy is
3820+
made only if needed.
3821+
3822+
Parameters
3823+
----------
3824+
x : ndarray
3825+
Input array. The elements in `x` are read in row-major, C-style order and
3826+
packed as a 1-D array.
3827+
out : ndarray or None, optional
3828+
A location into which the result is stored. If not provided or `None`,
3829+
a freshly-allocated array is returned.
3830+
3831+
Returns
3832+
-------
3833+
y : ndarray
3834+
y is an array of the same subtype as `x`, with shape ``(x.size,)``.
3835+
Note that matrices are special cased for backward compatibility, if `x`
3836+
is a matrix, then y is a 1-D ndarray.
3837+
3838+
Notes
3839+
-----
3840+
This function differs from the original numpy.arange in the following aspects:
3841+
- Only support row-major, C-style order.
3842+
3843+
Examples
3844+
--------
3845+
It is equivalent to ``reshape(x, -1)``.
3846+
3847+
>>> x = np.array([[1, 2, 3], [4, 5, 6]])
3848+
>>> print(np.ravel(x))
3849+
[1. 2. 3. 4. 5. 6.]
3850+
3851+
>>> print(x.reshape(-1))
3852+
[1. 2. 3. 4. 5. 6.]
3853+
3854+
>>> print(np.ravel(x.T))
3855+
[1. 4. 2. 5. 3. 6.]
3856+
"""
3857+
return _mx_nd_np.ravel(x, out=out)

python/mxnet/symbol/numpy/_symbol.py

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
'rint', 'radians', 'reciprocal', 'square', 'negative', 'fix', 'ceil', 'floor',
3636
'trunc', 'logical_not', 'arcsinh', 'arccosh', 'arctanh', 'tensordot',
3737
'linspace', 'expand_dims', 'tile', 'arange', 'split', 'concatenate', 'stack', 'mean',
38-
'maximum', 'minimum', 'swapaxes', 'clip', 'argmax', 'std', 'var']
38+
'maximum', 'minimum', 'swapaxes', 'clip', 'argmax', 'std', 'var', 'ravel']
3939

4040

4141
def _num_outputs(sym):
@@ -2678,4 +2678,42 @@ def var(a, axis=None, dtype=None, out=None, ddof=0, keepdims=False): # pylint:
26782678
return _npi.var(a, axis=axis, dtype=dtype, ddof=ddof, keepdims=keepdims, out=out)
26792679

26802680

2681+
@set_module('mxnet.symbol.numpy')
2682+
def ravel(x, out=None):
2683+
r"""
2684+
ravel(x, out=None)
2685+
2686+
Return a contiguous flattened array.
2687+
A 1-D array, containing the elements of the input, is returned. A copy is
2688+
made only if needed.
2689+
2690+
Parameters
2691+
----------
2692+
x : ndarray
2693+
Input array. The elements in `x` are read in row-major, C-style order and
2694+
packed as a 1-D array.
2695+
out : ndarray or None, optional
2696+
A location into which the result is stored. If not provided or `None`,
2697+
a freshly-allocated array is returned.
2698+
2699+
Returns
2700+
-------
2701+
y : ndarray
2702+
y is an array of the same subtype as `x`, with shape ``(x.size,)``.
2703+
Note that matrices are special cased for backward compatibility, if `x`
2704+
is a matrix, then y is a 1-D ndarray.
2705+
2706+
Notes
2707+
-----
2708+
This function differs from the original numpy.arange in the following aspects:
2709+
- Only support row-major, C-style order.
2710+
"""
2711+
if isinstance(x, numeric_types):
2712+
return _np.reshape(x, -1)
2713+
elif isinstance(x, _Symbol):
2714+
return _npi.reshape(x, -1, out=out)
2715+
else:
2716+
raise TypeError('type {} not supported'.format(str(type(x))))
2717+
2718+
26812719
_set_np_symbol_class(_Symbol)

src/operator/numpy/np_matrix_op.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ bool NumpyReshapeShape(const nnvm::NodeAttrs& attrs,
163163

164164
NNVM_REGISTER_OP(_np_reshape)
165165
.describe(R"code()code" ADD_FILELINE)
166+
.add_alias("_npi_reshape")
166167
.set_num_inputs(1)
167168
.set_num_outputs(1)
168169
.set_attr_parser(ParamParser<NumpyReshapeParam>)

tests/python/unittest/test_numpy_op.py

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1323,6 +1323,39 @@ def hybrid_forward(self, F, a, *args):
13231323
assert same(mx_out.asnumpy(), np_out)
13241324

13251325

1326+
@with_seed()
1327+
@use_np
1328+
def test_np_ravel():
1329+
class TestRavel(HybridBlock):
1330+
def __init__(self):
1331+
super(TestRavel, self).__init__()
1332+
1333+
def hybrid_forward(self, F, a):
1334+
return F.np.ravel(a)
1335+
1336+
types = ['float64', 'float32', 'float16', 'int64', 'int32', 'int8']
1337+
for oneType in types:
1338+
for hybridize in [True, False]:
1339+
for shape in [(), (2,), (2, 2), (1, 2, 3), (3, 0), (1, 0, 2)]:
1340+
test_ravel = TestRavel()
1341+
if hybridize:
1342+
test_ravel.hybridize()
1343+
x = rand_ndarray(shape, dtype=oneType).as_np_ndarray()
1344+
x.attach_grad()
1345+
np_out = _np.ravel(x.asnumpy())
1346+
with mx.autograd.record():
1347+
mx_out = test_ravel(x)
1348+
assert mx_out.shape == np_out.shape
1349+
assert_almost_equal(mx_out.asnumpy(), np_out, rtol=1e-3, atol=1e-5)
1350+
mx_out.backward()
1351+
np_backward = _np.ones(shape)
1352+
assert_almost_equal(x.grad.asnumpy(), np_backward, rtol=1e-3, atol=1e-5)
1353+
1354+
mx_out = np.ravel(x)
1355+
np_out = _np.ravel(x.asnumpy())
1356+
assert_almost_equal(mx_out.asnumpy(), np_out, rtol=1e-3, atol=1e-5)
1357+
1358+
13261359
@with_seed()
13271360
@use_np
13281361
def test_np_randint():
@@ -1744,6 +1777,45 @@ def test_indexing_mode(sampler, set_size, samples_size, replace, weight=None):
17441777
test_indexing_mode(test_choice_weighted, num_classes, num_classes // 2, replace, weight)
17451778

17461779

1780+
@with_seed()
1781+
@use_np
1782+
def test_np_ravel():
1783+
class TestRavel(HybridBlock):
1784+
def __init__(self):
1785+
super(TestRavel, self).__init__()
1786+
1787+
def hybrid_forward(self, F, a):
1788+
return F.np.ravel(a)
1789+
1790+
types = ['float64', 'float32', 'float16', 'int64', 'int32', 'int8']
1791+
for oneType in types:
1792+
for hybridize in [True, False]:
1793+
for shape in [(),
1794+
(2,),
1795+
(2, 2),
1796+
(1, 2, 3),
1797+
(3, 0),
1798+
(1, 0, 2)
1799+
]:
1800+
test_ravel = TestRavel()
1801+
if hybridize:
1802+
test_ravel.hybridize()
1803+
x = rand_ndarray(shape, dtype=oneType).as_np_ndarray()
1804+
x.attach_grad()
1805+
np_out = _np.ravel(x.asnumpy())
1806+
with mx.autograd.record():
1807+
mx_out = test_ravel(x)
1808+
assert mx_out.shape == np_out.shape
1809+
assert_almost_equal(mx_out.asnumpy(), np_out, rtol=1e-3, atol=1e-5)
1810+
mx_out.backward()
1811+
np_backward = _np.ones(shape)
1812+
assert_almost_equal(x.grad.asnumpy(), np_backward, rtol=1e-3, atol=1e-5)
1813+
1814+
mx_out = np.ravel(x)
1815+
np_out = _np.ravel(x.asnumpy())
1816+
assert_almost_equal(mx_out.asnumpy(), np_out, rtol=1e-3, atol=1e-5)
1817+
1818+
17471819
if __name__ == '__main__':
17481820
import nose
17491821
nose.runmodule()

0 commit comments

Comments
 (0)