You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mxnet.apache.org by zh...@apache.org on 2018/08/23 01:14:31 UTC

[incubator-mxnet] branch master updated: Add randn to random module (#12156)

This is an automated email from the ASF dual-hosted git repository.

zhasheng pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-mxnet.git


The following commit(s) were added to refs/heads/master by this push:
     new 1ffb3f5  Add randn to random module (#12156)
1ffb3f5 is described below

commit 1ffb3f58a35461bac62f9ae637f36ebbfd580883
Author: Alexander Zai <az...@gmail.com>
AuthorDate: Wed Aug 22 21:14:19 2018 -0400

    Add randn to random module (#12156)
    
    * add randn to random
    
    * reorder args
    
    * update comments
    
    * add test for randn
    
    * fix ordering of params
    
    * update test name
    
    * fix params
    
    * remove dup param
    
    * restrict loc and scale for randn method
    
    * test should only use single loc / scale
    
    * pop out kwargs
    
    * fix lint
    
    * use normal symbol from randn test
    
    * update randn test
    
    * retrigger
---
 python/mxnet/ndarray/random.py       | 57 ++++++++++++++++++++++++++++++++++--
 tests/python/unittest/test_random.py | 25 +++++++++++++---
 2 files changed, 76 insertions(+), 6 deletions(-)

diff --git a/python/mxnet/ndarray/random.py b/python/mxnet/ndarray/random.py
index d0c83c1..1e941f7 100644
--- a/python/mxnet/ndarray/random.py
+++ b/python/mxnet/ndarray/random.py
@@ -23,8 +23,9 @@ from . import _internal
 from .ndarray import NDArray
 
 
-__all__ = ['uniform', 'normal', 'poisson', 'exponential', 'gamma', 'multinomial',
-           'negative_binomial', 'generalized_negative_binomial', 'shuffle']
+__all__ = ['uniform', 'normal', 'randn', 'poisson', 'exponential', 'gamma',
+           'multinomial', 'negative_binomial', 'generalized_negative_binomial',
+           'shuffle']
 
 
 def _random_helper(random, sampler, params, shape, dtype, ctx, out, kwargs):
@@ -151,6 +152,58 @@ def normal(loc=0, scale=1, shape=_Null, dtype=_Null, ctx=None, out=None, **kwarg
                           [loc, scale], shape, dtype, ctx, out, kwargs)
 
 
+def randn(*shape, **kwargs):
+    """Draw random samples from a normal (Gaussian) distribution.
+
+    Samples are distributed according to a normal distribution parametrized
+    by *loc* (mean) and *scale* (standard deviation).
+
+
+    Parameters
+    ----------
+    loc : float or NDArray
+        Mean (centre) of the distribution.
+    scale : float or NDArray
+        Standard deviation (spread or width) of the distribution.
+    shape : int or tuple of ints
+        The number of samples to draw. If shape is, e.g., `(m, n)` and `loc` and
+        `scale` are scalars, output shape will be `(m, n)`. If `loc` and `scale`
+        are NDArrays with shape, e.g., `(x, y)`, then output will have shape
+        `(x, y, m, n)`, where `m*n` samples are drawn for each `[loc, scale)` pair.
+    dtype : {'float16','float32', 'float64'}
+        Data type of output samples. Default is 'float32'
+    ctx : Context
+        Device context of output. Default is current context. Overridden by
+        `loc.context` when `loc` is an NDArray.
+    out : NDArray
+        Store output to an existing NDArray.
+
+
+    Examples
+    --------
+    >>> mx.nd.random.randn()
+    2.21220636
+    <NDArray 1 @cpu(0)>
+    >>> mx.nd.random.randn(2, 2)
+    [[-1.856082   -1.9768796 ]
+    [-0.20801921  0.2444218 ]]
+    <NDArray 2x2 @cpu(0)>
+    >>> mx.nd.random.randn(2, 3, loc=5, scale=1)
+    [[4.19962   4.8311777 5.936328 ]
+    [5.357444  5.7793283 3.9896927]]
+    <NDArray 2x3 @cpu(0)>
+    """
+    loc = kwargs.pop('loc', 0)
+    scale = kwargs.pop('scale', 1)
+    dtype = kwargs.pop('dtype', _Null)
+    ctx = kwargs.pop('ctx', None)
+    out = kwargs.pop('out', None)
+    assert isinstance(loc, (int, float))
+    assert isinstance(scale, (int, float))
+    return _random_helper(_internal._random_normal, _internal._sample_normal,
+                          [loc, scale], shape, dtype, ctx, out, kwargs)
+
+
 def poisson(lam=1, shape=_Null, dtype=_Null, ctx=None, out=None, **kwargs):
     """Draw random samples from a Poisson distribution.
 
diff --git a/tests/python/unittest/test_random.py b/tests/python/unittest/test_random.py
index 575fcdd..4310658 100644
--- a/tests/python/unittest/test_random.py
+++ b/tests/python/unittest/test_random.py
@@ -46,6 +46,15 @@ def check_with_device(device, dtype):
             ]
         },
         {
+            'name': 'randn',
+            'ndop': mx.nd.random.randn,
+            'params': { 'loc': 10.0, 'scale': 0.5 },
+            'checks': [
+                ('mean', lambda x, params: np.mean(x.astype(np.float64) - params['loc']),  tol),
+                ('std',  lambda x, params: np.std(x.astype(np.float64)) - params['scale'], tol)
+            ]
+        },
+        {
             'name': 'uniform',
             'symbol': mx.sym.random.uniform,
             'ndop': mx.nd.random.uniform,
@@ -123,10 +132,14 @@ def check_with_device(device, dtype):
         # check directly
         params = symbdic['params'].copy()
         params.update(shape=shape, dtype=dtype, ctx=device)
+        args = ()
+        if name == 'randn':
+            params.pop('shape')  # randn does not accept shape param
+            args = shape
         mx.random.seed(128)
-        ret1 = ndop(**params).asnumpy()
+        ret1 = ndop(*args, **params).asnumpy()
         mx.random.seed(128)
-        ret2 = ndop(**params).asnumpy()
+        ret2 = ndop(*args, **params).asnumpy()
         assert same(ret1, ret2), \
                 "ndarray test: `%s` should give the same result with the same seed" % name
 
@@ -134,12 +147,14 @@ def check_with_device(device, dtype):
             assert np.abs(check_func(ret1, params)) < tol, "ndarray test: %s check for `%s` did not pass" % (check_name, name)
 
         # check multi-distribution sampling
+        if 'inputs' not in symbdic: continue  # randn does not support multi-distribution sampling
+
         params = {'shape': shape, 'dtype': dtype, 'ctx': device}
         params.update({k : mx.nd.array(v, ctx=device, dtype=dtype) for k, v in symbdic['inputs']})
         mx.random.seed(128)
-        ret1 = ndop(**params).asnumpy()
+        ret1 = ndop(*args, **params).asnumpy()
         mx.random.seed(128)
-        ret2 = ndop(**params).asnumpy()
+        ret2 = ndop(*args, **params).asnumpy()
         assert same(ret1, ret2), \
                 "ndarray test: `%s` should give the same result with the same seed" % name
         for i in range(2):
@@ -149,6 +164,8 @@ def check_with_device(device, dtype):
                     err = np.abs(check_func(ret2[i,j], stats))
                     assert err < tol, "%f vs %f: symbolic test: %s check for `%s` did not pass" % (err, tol, check_name, name)
 
+        if 'symbol' not in symbdic: continue  # randn does not have symbol
+
         # check symbolic
         symbol = symbdic['symbol']
         X = mx.sym.Variable("X")