def test_permutation(self): # Test that raw_random.permutation generates the same results as numpy. rng_R = random_state_type() post_r, out = permutation(rng_R, size=(9,), n=6) f = compile.function( [compile.In(rng_R, value=np.random.RandomState(utt.fetch_seed()), update=post_r, mutable=True)], [out], accept_inplace=True) numpy_rng = np.random.RandomState(utt.fetch_seed()) # Check over two calls to see if the random state is correctly updated. # numpy_rng.permutation outputs one vector at a time, # so we call it iteratively to generate all the samples. val0 = f() val1 = f() numpy_val0 = np.asarray([numpy_rng.permutation(6) for i in range(9)]) numpy_val1 = np.asarray([numpy_rng.permutation(6) for i in range(9)]) self.assertTrue(np.all(val0 == numpy_val0)) self.assertTrue(np.all(val1 == numpy_val1)) # Test that we can generate a list: have size=None or (). for ndim in [1, None]: post_r, out = permutation(rng_R, n=10, size=None, ndim=ndim) inp = compile.In(rng_R, value=np.random.RandomState(utt.fetch_seed()), update=post_r, mutable=True) f = theano.function([inp], out) o = f() assert o.shape == (10,) assert (np.sort(o) == np.arange(10)).all() # Wrong number of dimensions asked self.assertRaises(TypeError, permutation, rng_R, size=None, ndim=2)
def test_permutation_helper(self): """Test that raw_random.permutation_helper generates the same results as numpy, and that the 'ndim_added' keyword behaves correctly.""" # permutation_helper needs "ndim_added=1", because its output # is one dimension more than its "shape" argument (and there's # no way to determine that automatically). # Check the working case, over two calls to see if the random # state is correctly updated. rf = RandomFunction(permutation_helper, tensor.imatrix, 8, ndim_added=1) rng_R = random_state_type() post_r, out = rf(rng_R, (7,), 8) f = compile.function( [compile.In(rng_R, value=numpy.random.RandomState(utt.fetch_seed()), update=post_r, mutable=True)], [out], accept_inplace=True) numpy_rng = numpy.random.RandomState(utt.fetch_seed()) val0 = f() val1 = f() # numpy_rng.permutation outputs one vector at a time, # so we call it iteratively to generate all the samples. numpy_val0 = numpy.asarray([numpy_rng.permutation(8) for i in range(7)]) numpy_val1 = numpy.asarray([numpy_rng.permutation(8) for i in range(7)]) print val0 print numpy_val0 print val1 print numpy_val1 self.assertTrue(numpy.all(val0 == numpy_val0)) self.assertTrue(numpy.all(val1 == numpy_val1)) # This call lacks "ndim_added=1", so ndim_added defaults to 0. # A ValueError should be raised. rf0 = RandomFunction(permutation_helper, tensor.imatrix, 8) post_r0, out0 = rf0(rng_R, (7,), 8) f0 = compile.function( [compile.In(rng_R, value=numpy.random.RandomState(utt.fetch_seed()), update=post_r0, mutable=True)], [out0], accept_inplace=True) self.assertRaises(ValueError, f0) # Here, ndim_added is 2 instead of 1. A ValueError should be raised. rf2 = RandomFunction(permutation_helper, tensor.imatrix, 8, ndim_added=2) post_r2, out2 = rf2(rng_R, (7,), 8) f2 = compile.function( [compile.In(rng_R, value=numpy.random.RandomState(utt.fetch_seed()), update=post_r2, mutable=True)], [out2], accept_inplace=True) self.assertRaises(ValueError, f2)
def test_no_inplace(self): """Test that when not running inplace, the RandomState is not updated""" rf = RandomFunction('uniform', tensor.dvector) rng_R = random_state_type() post_r, out = rf(rng_R, (3, ), 0., 1.) f = compile.function([rng_R], [post_r, out]) rng = numpy.random.RandomState(utt.fetch_seed()) rng0, val0 = f(rng) rng_ = numpy.random.RandomState(utt.fetch_seed()) # rng should still be in a fresh state self.assertTrue(rng_R.type.values_eq(rng, rng_)) # rng0 should be in an updated state self.assertFalse(rng_R.type.values_eq(rng, rng0)) f2 = compile.function( [compile.In(rng_R, value=rng, update=post_r, mutable=False)], [post_r, out]) rng2, val2 = f2() # rng should be in a fresh state self.assertTrue(rng_R.type.values_eq(rng, rng_)) # rng2 should be in an updated state self.assertFalse(rng_R.type.values_eq(rng, rng2)) # The updated state should be the same for both functions self.assertTrue(rng_R.type.values_eq(rng2, rng0)) rng3, val3 = f2() # rng2 should not have changed self.assertTrue(rng_R.type.values_eq(rng2, rng0)) # rng3 should be an updated again version of rng2 self.assertFalse(rng_R.type.values_eq(rng3, rng2)) self.assertFalse(rng_R.type.values_eq(rng3, rng))
def test_poisson(self): # Test that raw_random.poisson generates the same results as numpy. # Check over two calls to see if the random state is correctly updated. rng_R = random_state_type() # Use non-default parameters, and larger dimensions because of # the integer nature of the result post_r, out = poisson(rng_R, lam=5, size=(11, 8)) f = compile.function( [ compile.In( rng_R, value=np.random.RandomState(utt.fetch_seed()), update=post_r, mutable=True, ) ], [out], accept_inplace=True, ) numpy_rng = np.random.RandomState(utt.fetch_seed()) val0 = f() val1 = f() numpy_val0 = numpy_rng.poisson(5, size=(11, 8)) numpy_val1 = numpy_rng.poisson(5, size=(11, 8)) assert np.allclose(val0, numpy_val0) assert np.allclose(val1, numpy_val1)
def test_uniform(self): # Test that raw_random.uniform generates the same results as numpy. # Check over two calls to see if the random state is correctly updated. rng_R = random_state_type() # Use non-default parameters post_r, out = uniform(rng_R, (4, ), -2.0, 2.0) f = compile.function( [ compile.In( rng_R, value=np.random.RandomState(utt.fetch_seed()), update=post_r, mutable=True, ) ], [out], accept_inplace=True, ) numpy_rng = np.random.RandomState(utt.fetch_seed()) val0 = f() val1 = f() numpy_val0 = numpy_rng.uniform(-2.0, 2.0, size=(4, )) numpy_val1 = numpy_rng.uniform(-2.0, 2.0, size=(4, )) assert np.allclose(val0, numpy_val0) assert np.allclose(val1, numpy_val1)
def test_normal(self): """Test that raw_random.normal generates the same results as numpy.""" # Check over two calls to see if the random state is correctly updated. rng_R = random_state_type() # Use non-default parameters post_r, out = normal(rng_R, (2, 3), 4.0, 2.0) f = compile.function([ compile.In(rng_R, value=numpy.random.RandomState(utt.fetch_seed()), update=post_r, mutable=True) ], [out], accept_inplace=True) numpy_rng = numpy.random.RandomState(utt.fetch_seed()) val0 = f() val1 = f() numpy_val0 = numpy_rng.normal(4.0, 2.0, size=(2, 3)) numpy_val1 = numpy_rng.normal(4.0, 2.0, size=(2, 3)) print(val0) print(numpy_val0) print(val1) print(numpy_val1) self.assertTrue(numpy.allclose(val0, numpy_val0)) self.assertTrue(numpy.allclose(val1, numpy_val1))
def test_choice(self): """Test that raw_random.choice generates the same results as numpy.""" # numpy.random.choice is only available for numpy versions >= 1.7 major, minor, _ = numpy.version.short_version.split('.') if (int(major), int(minor)) < (1, 7): raise utt.SkipTest('choice requires at NumPy version >= 1.7 ' '(%s)' % numpy.__version__) # Check over two calls to see if the random state is correctly updated. rng_R = random_state_type() # Use non-default parameters, and larger dimensions because of # the integer nature of the result post_r, out = choice(rng_R, (11, 8), 10, 1, 0) f = compile.function([ compile.In(rng_R, value=numpy.random.RandomState(utt.fetch_seed()), update=post_r, mutable=True) ], [out], accept_inplace=True) numpy_rng = numpy.random.RandomState(utt.fetch_seed()) val0 = f() val1 = f() numpy_val0 = numpy_rng.choice(10, (11, 8), True, None) numpy_val1 = numpy_rng.choice(10, (11, 8), True, None) print(val0) print(numpy_val0) print(val1) print(numpy_val1) self.assertTrue(numpy.allclose(val0, numpy_val0)) self.assertTrue(numpy.allclose(val1, numpy_val1))
def test_inplace_optimization(self): """Test that FAST_RUN includes the random_make_inplace optimization""" #inplace = False rf2 = RandomFunction(numpy.random.RandomState.uniform, tensor.dvector) rng_R = random_state_type() # If calling RandomFunction directly, all args have to be specified, # because shape will have to be moved to the end post_r2, out2 = rf2(rng_R, (4,), 0., 1.) f = compile.function( [compile.In(rng_R, value=numpy.random.RandomState(utt.fetch_seed()), update=post_r2, mutable=True)], out2, mode='FAST_RUN') # DEBUG_MODE can't pass the id-based # test below # test that the RandomState object stays the same from function call to # function call, but that the values returned change from call to call. id0 = id(f[rng_R]) val0 = f() assert id0 == id(f[rng_R]) val1 = f() assert id0 == id(f[rng_R]) assert not numpy.allclose(val0, val1)
def test_multinomial(self): """Test that raw_random.multinomial generates the same results as numpy.""" # Check over two calls to see if the random state is correctly updated. rng_R = random_state_type() post_r, out = multinomial(rng_R, (7, 3), 6, [0.2] * 5) f = compile.function( [compile.In(rng_R, value=numpy.random.RandomState(utt.fetch_seed()), update=post_r, mutable=True)], [out], accept_inplace=True) numpy_rng = numpy.random.RandomState(utt.fetch_seed()) val0, = f() val1, = f() numpy_val0 = numpy_rng.multinomial(6, [0.2] * 5, (7, 3)) numpy_val1 = numpy_rng.multinomial(6, [0.2] * 5, (7, 3)) print val0 print numpy_val0 print val1 print numpy_val1 self.assertTrue(numpy.all(val0 == numpy_val0)) self.assertTrue(numpy.all(val1 == numpy_val1)) self.assertTrue(val0.shape == (7, 3, 5)) self.assertTrue(val1.shape == (7, 3, 5))
def test_random_integers(self): """Test that raw_random.random_integers generates the same results as numpy.""" # Check over two calls to see if the random state is correctly updated. rng_R = random_state_type() # Use non-default parameters, and larger dimensions because of # the integer nature of the result post_r, out = random_integers(rng_R, (11, 8), -3, 16) f = compile.function( [compile.In(rng_R, value=numpy.random.RandomState(utt.fetch_seed()), update=post_r, mutable=True)], [out], accept_inplace=True) numpy_rng = numpy.random.RandomState(utt.fetch_seed()) val0 = f() val1 = f() numpy_val0 = numpy_rng.random_integers(-3, 16, size=(11, 8)) numpy_val1 = numpy_rng.random_integers(-3, 16, size=(11, 8)) print val0 print numpy_val0 print val1 print numpy_val1 self.assertTrue(numpy.allclose(val0, numpy_val0)) self.assertTrue(numpy.allclose(val1, numpy_val1))
def test_permutation(self): """Test that raw_random.permutation generates the same results as numpy.""" rng_R = random_state_type() post_r, out = permutation(rng_R, size=(9,), n=6) print 'OUT NDIM', out.ndim f = compile.function( [compile.In(rng_R, value=numpy.random.RandomState(utt.fetch_seed()), update=post_r, mutable=True)], [out], accept_inplace=True) numpy_rng = numpy.random.RandomState(utt.fetch_seed()) # Check over two calls to see if the random state is correctly updated. # numpy_rng.permutation outputs one vector at a time, # so we call it iteratively to generate all the samples. val0 = f() val1 = f() numpy_val0 = numpy.asarray([numpy_rng.permutation(6) for i in range(9)]) numpy_val1 = numpy.asarray([numpy_rng.permutation(6) for i in range(9)]) print val0 print numpy_val0 print val1 print numpy_val1 self.assertTrue(numpy.all(val0 == numpy_val0)) self.assertTrue(numpy.all(val1 == numpy_val1))
def test_binomial(self): """Test that raw_random.binomial generates the same results as numpy.""" # Check over two calls to see if the random state is correctly updated. rng_R = random_state_type() # Use non-default parameters, and larger dimensions because of # the integer nature of the result post_r, bin = binomial(rng_R, (7, 12), 5, 0.8) f = compile.function( [compile.In(rng_R, value=numpy.random.RandomState(utt.fetch_seed()), update=post_r, mutable=True)], [bin], accept_inplace=True) numpy_rng = numpy.random.RandomState(utt.fetch_seed()) val0 = f() val1 = f() numpy_val0 = numpy_rng.binomial(5, 0.8, size=(7, 12)) numpy_val1 = numpy_rng.binomial(5, 0.8, size=(7, 12)) print val0 print numpy_val0 print val1 print numpy_val1 self.assertTrue(numpy.all(val0 == numpy_val0)) self.assertTrue(numpy.all(val1 == numpy_val1))
def test_random_function_ndim(self): """Test that random_function helper function accepts argument ndim""" rng_R = random_state_type() # ndim is an optional argument indicating the length of the 'shape' # ndim not specified, OK post_out4, out4 = uniform(rng_R, (4,)) # ndim specified, consistent with shape, OK post_out1_4, out1_4 = uniform(rng_R, (4, ), ndim=1) post_out2_4_4, out2_4_4 = uniform(rng_R, (4, 4), ndim=2) # ndim specified, but not compatible with shape self.assertRaises(ValueError, uniform, rng_R, (4,), ndim=2) f_ok = compile.function( [compile.In(rng_R, value=numpy.random.RandomState(utt.fetch_seed()), update=post_out2_4_4, mutable=True)], [out4, out1_4, out2_4_4], accept_inplace=True) # The correct cases should execute properly o4, o1_4, o2_4_4 = f_ok() # Check the sanity of the answers self.assertTrue(numpy.allclose(o4, o1_4)) self.assertTrue(numpy.allclose(o4, o2_4_4[0]))
def test_random_function_noshape_args(self): # Test if random_function helper works with args but without shape rng_R = random_state_type() # No shape, default args -> OK post_out, out = uniform(rng_R, size=None, ndim=2) f = compile.function( [ compile.In( rng_R, value=np.random.RandomState(utt.fetch_seed()), update=post_out, mutable=True, ) ], [out], accept_inplace=True, ) (o, ) = f() # No shape, args that have to be broadcasted -> OK low = tensor.TensorType(dtype="float64", broadcastable=(False, True, True))() high = tensor.TensorType(dtype="float64", broadcastable=(True, True, True, False))() post_out2, out2 = uniform(rng_R, size=None, ndim=2, low=low, high=high) assert out2.ndim == 4 assert out2.broadcastable == (True, False, True, False) g = compile.function( [ low, high, compile.In( rng_R, value=np.random.RandomState(utt.fetch_seed()), update=post_out2, mutable=True, ), ], [out2], accept_inplace=True, ) low_v = [[[3]], [[4]], [[-5]]] high_v = [[[[5, 8]]]] (o2, ) = g(low_v, high_v) assert o2.shape == (1, 3, 1, 2)
def test_args(self): # Test that arguments to RandomFunction are honored rf2 = RandomFunction(np.random.RandomState.uniform, tensor.dvector) rf4 = RandomFunction(np.random.RandomState.uniform, tensor.dvector, inplace=True) rng_R = random_state_type() # use make_node to override some of the self.args post_r2, out2 = rf2(rng_R, (4, ), -2, 2) # NOT INPLACE post_r4, out4 = rf4(rng_R, (4, ), -4, 4) # INPLACE post_r2_4, out2_4 = rf2(rng_R, (4, ), -4.0, 2) # NOT INPLACE post_r2_4_4, out2_4_4 = rf2(rng_R, (4, ), -4.0, 4.0) # NOT INPLACE # configure out4 to be computed inplace # The update expression means that the random state rng_R will # be maintained by post_r4 f = compile.function( [ compile.In( rng_R, value=np.random.RandomState(utt.fetch_seed()), update=post_r4, mutable=True, ) ], [out2, out4, out2_4, out2_4_4], accept_inplace=True, ) f2, f4, f2_4, f2_4_4 = f() f2b, f4b, f2_4b, f2_4_4b = f() # print f2 # print f4 # print f2_4 # print f2_4_4 # print f2b # print f4b # print f2_4b # print f2_4_4b # setting bounds is same as multiplying by 2 assert np.allclose(f2 * 2, f4), (f2, f4) # retrieving from non-inplace generator # is same as inplace one for first call assert np.allclose(f2_4_4, f4), (f2_4_4, f4) # f4 changes from call to call, that the update has worked assert not np.allclose(f4, f4b), (f4, f4b)
def test_choice(self): # Test that raw_random.choice generates the same results as numpy. # Check over two calls to see if the random state is correctly updated. rng_R = random_state_type() # Use non-default parameters, and larger dimensions because of # the integer nature of the result post_r, out = choice(rng_R, (11, 8), 10, 1, 0) f = compile.function( [compile.In(rng_R, value=np.random.RandomState(utt.fetch_seed()), update=post_r, mutable=True)], [out], accept_inplace=True) numpy_rng = np.random.RandomState(utt.fetch_seed()) val0 = f() val1 = f() numpy_val0 = numpy_rng.choice(10, (11, 8), True, None) numpy_val1 = numpy_rng.choice(10, (11, 8), True, None) self.assertTrue(np.allclose(val0, numpy_val0)) self.assertTrue(np.allclose(val1, numpy_val1))
def test_random_function_ndim_added(self): """Test that random_function helper function accepts ndim_added as keyword argument""" # If using numpy's uniform distribution, ndim_added should be 0, # because the shape provided as argument is the output shape. # Specifying a different ndim_added will change the Op's output ndim, # so numpy.uniform will produce a result of incorrect shape, # and a ValueError should be raised. def ndim_added_deco(ndim_added): def randomfunction(random_state, size=(), low=0.0, high=0.0, ndim=None): ndim, size, bcast = raw_random._infer_ndim_bcast(ndim, size) if ndim_added < 0: bcast = bcast[:ndim_added] else: bcast = bcast + ((False,) * ndim_added) assert len(bcast) == ndim + ndim_added op = RandomFunction('uniform', tensor.TensorType(dtype='float64', broadcastable=bcast), ndim_added=ndim_added) return op(random_state, size, low, high) return randomfunction uni_1 = ndim_added_deco(1) uni_0 = ndim_added_deco(0) uni_m1 = ndim_added_deco(-1) rng_R = random_state_type() p_uni11, uni11 = uni_1(rng_R, size=(4,)) p_uni12, uni12 = uni_1(rng_R, size=(3, 4)) p_uni01, uni01 = uni_0(rng_R, size=(4,)) p_uni02, uni02 = uni_0(rng_R, size=(3, 4)) p_unim11, unim11 = uni_m1(rng_R, size=(4,)) p_unim12, unim12 = uni_m1(rng_R, size=(3, 4)) self.assertEqual(uni11.ndim, 2) self.assertEqual(uni12.ndim, 3) self.assertEqual(uni01.ndim, 1) self.assertEqual(uni02.ndim, 2) self.assertEqual(unim11.ndim, 0) self.assertEqual(unim12.ndim, 1) f11 = compile.function( [compile.In(rng_R, value=numpy.random.RandomState(utt.fetch_seed()), update=p_uni11, mutable=True)], [uni11], accept_inplace=True) f12 = compile.function( [compile.In(rng_R, value=numpy.random.RandomState(utt.fetch_seed()), update=p_uni12, mutable=True)], [uni12], accept_inplace=True) fm11 = compile.function( [compile.In(rng_R, value=numpy.random.RandomState(utt.fetch_seed()), update=p_unim11, mutable=True)], [unim11], accept_inplace=True) fm12 = compile.function( [compile.In(rng_R, value=numpy.random.RandomState(utt.fetch_seed()), update=p_unim12, mutable=True)], [unim12], accept_inplace=True) f0 = compile.function( [compile.In(rng_R, value=numpy.random.RandomState(utt.fetch_seed()), update=p_uni02, mutable=True)], [uni01, uni02], accept_inplace=True) self.assertRaises(ValueError, f11) self.assertRaises(ValueError, f12) self.assertRaises(ValueError, fm11) self.assertRaises(ValueError, fm12) u01, u02 = f0() print u01 print u02 self.assertTrue(numpy.allclose(u01, u02[0]))