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 with pytest.raises(ValueError): uniform(rng_R, (4, ), ndim=2) f_ok = compile.function( [ compile.In( rng_R, value=np.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 assert np.allclose(o4, o1_4) assert np.allclose(o4, o2_4_4[0])
def test_vector_arguments(self): rng_R = random_state_type() low = tensor.vector() post_r, out = uniform(rng_R, low=low, high=1) assert out.ndim == 1 f = compile.function([rng_R, low], [post_r, out], accept_inplace=True) def as_floatX(thing): return np.asarray(thing, dtype=aesara.config.floatX) rng_state0 = np.random.RandomState(utt.fetch_seed()) numpy_rng = np.random.RandomState(utt.fetch_seed()) post0, val0 = f(rng_state0, [-5, 0.5, 0, 1]) post1, val1 = f(post0, as_floatX([0.9])) numpy_val0 = as_floatX(numpy_rng.uniform(low=[-5, 0.5, 0, 1], high=1)) numpy_val1 = as_floatX(numpy_rng.uniform(low=as_floatX([0.9]), high=1)) assert np.all(val0 == numpy_val0) assert np.all(val1 == numpy_val1) high = tensor.vector() post_rb, outb = uniform(rng_R, low=low, high=high) assert outb.ndim == 1 fb = compile.function([rng_R, low, high], [post_rb, outb], accept_inplace=True) post0b, val0b = fb(post1, [-4.0, -2], [-1, 0]) post1b, val1b = fb(post0b, [-4.0], [-1]) numpy_val0b = as_floatX(numpy_rng.uniform(low=[-4.0, -2], high=[-1, 0])) numpy_val1b = as_floatX(numpy_rng.uniform(low=[-4.0], high=[-1])) assert np.all(val0b == numpy_val0b) assert np.all(val1b == numpy_val1b) with pytest.raises(ValueError): fb(post1b, [-4.0, -2], [-1, 0, 1]) # TODO: do we want that? # with pytest.raises(ValueError): # fb(post1b, [-4., -2], [-1]) size = tensor.lvector() post_rc, outc = uniform(rng_R, low=low, high=high, size=size, ndim=1) fc = compile.function([rng_R, low, high, size], [post_rc, outc], accept_inplace=True) post0c, val0c = fc(post1b, [-4.0, -2], [-1, 0], [2]) post1c, val1c = fc(post0c, [-4.0], [-1], [1]) numpy_val0c = as_floatX(numpy_rng.uniform(low=[-4.0, -2], high=[-1, 0])) numpy_val1c = as_floatX(numpy_rng.uniform(low=[-4.0], high=[-1])) assert np.all(val0c == numpy_val0c) assert np.all(val1c == numpy_val1c) with pytest.raises(ValueError): fc(post1c, [-4.0, -2], [-1, 0], [1, 2]) with pytest.raises(ValueError): fc(post1c, [-4.0, -2], [-1, 0], [2, 1]) with pytest.raises(ValueError): fc(post1c, [-4.0, -2], [-1, 0], [1]) with pytest.raises(ValueError): fc(post1c, [-4.0, -2], [-1], [1])
def test_mixed_shape(self): # Test when the provided shape is a tuple of ints and scalar vars rng_R = random_state_type() shape0 = tensor.lscalar() shape = (shape0, 3) post_r, u = uniform(rng_R, size=shape, ndim=2) f = compile.function([rng_R, shape0], u) rng_state0 = np.random.RandomState(utt.fetch_seed()) assert f(rng_state0, 2).shape == (2, 3) assert f(rng_state0, 8).shape == (8, 3) post_r, v = uniform(rng_R, size=shape) g = compile.function([rng_R, shape0], v) assert g(rng_state0, 2).shape == (2, 3) assert g(rng_state0, 8).shape == (8, 3)
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_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_dtype_normal_uniform_687(self): # Regression test for #687. rng_R = random_state_type() assert (uniform(rng_R, low=tensor.constant(0, dtype="float64"), dtype="float32")[1].dtype == "float32") assert (normal(rng_R, avg=tensor.constant(0, dtype="float64"), dtype="float32")[1].dtype == "float32")
def test_uniform_vector(self): rng_R = random_state_type() low = tensor.vector() high = tensor.vector() post_r, out = uniform(rng_R, low=low, high=high) assert out.ndim == 1 f = compile.function([rng_R, low, high], [post_r, out], accept_inplace=True) def as_floatX(thing): return np.asarray(thing, dtype=aesara.config.floatX) low_val = as_floatX([0.1, 0.2, 0.3]) high_val = as_floatX([1.1, 2.2, 3.3]) rng = np.random.RandomState(utt.fetch_seed()) numpy_rng = np.random.RandomState(utt.fetch_seed()) # Arguments of size (3,) rng0, val0 = f(rng, low_val, high_val) numpy_val0 = as_floatX(numpy_rng.uniform(low=low_val, high=high_val)) assert np.all(val0 == numpy_val0) # arguments of size (2,) rng1, val1 = f(rng0, low_val[:-1], high_val[:-1]) numpy_val1 = as_floatX( numpy_rng.uniform(low=low_val[:-1], high=high_val[:-1])) assert np.all(val1 == numpy_val1) # Specifying the size explicitly g = compile.function( [rng_R, low, high], uniform(rng_R, low=low, high=high, size=(3, )), accept_inplace=True, ) rng2, val2 = g(rng1, low_val, high_val) numpy_val2 = as_floatX( numpy_rng.uniform(low=low_val, high=high_val, size=(3, ))) assert np.all(val2 == numpy_val2) with pytest.raises(ValueError): g(rng2, low_val[:-1], high_val[:-1])
def test_symbolic_shape(self): rng_R = random_state_type() shape = tensor.lvector() post_r, out = uniform(rng_R, shape, ndim=2) f = compile.function([rng_R, shape], out) rng_state0 = np.random.RandomState(utt.fetch_seed()) assert f(rng_state0, [2, 3]).shape == (2, 3) assert f(rng_state0, [4, 8]).shape == (4, 8) with pytest.raises(ValueError): f(rng_state0, [4]) with pytest.raises(ValueError): f(rng_state0, [4, 3, 4, 5])
def test_broadcast_arguments(self): rng_R = random_state_type() low = tensor.dvector() high = tensor.dcol() post_r, out = uniform(rng_R, low=low, high=high) assert out.ndim == 2 f = compile.function([rng_R, low, high], [post_r, out], accept_inplace=True) rng_state0 = np.random.RandomState(utt.fetch_seed()) numpy_rng = np.random.RandomState(utt.fetch_seed()) post0, val0 = f(rng_state0, [-5, 0.5, 0, 1], [[1.0]]) post1, val1 = f(post0, [0.9], [[1.0], [1.1], [1.5]]) post2, val2 = f(post1, [-5, 0.5, 0, 1], [[1.0], [1.1], [1.5]]) numpy_val0 = numpy_rng.uniform(low=[-5, 0.5, 0, 1], high=[1.0]) numpy_val1 = numpy_rng.uniform(low=[0.9], high=[[1.0], [1.1], [1.5]]) numpy_val2 = numpy_rng.uniform(low=[-5, 0.5, 0, 1], high=[[1.0], [1.1], [1.5]]) assert np.all(val0 == numpy_val0), (val0, numpy_val0) assert np.all(val1 == numpy_val1) assert np.all(val2 == numpy_val2)
def test_default_shape(self): rng_R = random_state_type() post_r, out = uniform(rng_R) f = compile.function([rng_R], [post_r, out], accept_inplace=True) rng_state0 = np.random.RandomState(utt.fetch_seed()) numpy_rng = np.random.RandomState(utt.fetch_seed()) post0, val0 = f(rng_state0) post1, val1 = f(post0) numpy_val0 = np.asarray(numpy_rng.uniform(), dtype=aesara.config.floatX) numpy_val1 = np.asarray(numpy_rng.uniform(), dtype=aesara.config.floatX) assert np.all(val0 == numpy_val0) assert np.all(val1 == numpy_val1) post_r, out = multinomial(rng_R) g = compile.function([rng_R], [post_r, out], accept_inplace=True) post2, val2 = g(post1) numpy_val2 = np.asarray(numpy_rng.multinomial(n=1, pvals=[0.5, 0.5]), dtype=aesara.config.floatX) assert np.all(val2 == numpy_val2)
def test_infer_shape(self): rng_R = random_state_type() rng_R_val = np.random.RandomState(utt.fetch_seed()) # no shape specified, default args post_r, out = uniform(rng_R) self._compile_and_check([rng_R], [out], [rng_R_val], RandomFunction) post_r, out = uniform(rng_R, size=None, ndim=2) self._compile_and_check([rng_R], [out], [rng_R_val], RandomFunction) """ #infer_shape don't work for multinomial. #The parameter ndim_added is set to 1 and in this case, the infer_shape #inplementation don't know how to infer the shape post_r, out = multinomial(rng_R) self._compile_and_check([rng_R], [out], [rng_R_val], RandomFunction) """ # no shape specified, args have to be broadcasted low = tensor.TensorType(dtype="float64", broadcastable=(False, True, True))() high = tensor.TensorType(dtype="float64", broadcastable=(True, True, True, False))() post_r, out = uniform(rng_R, size=None, ndim=2, low=low, high=high) low_val = [[[3]], [[4]], [[-5]]] high_val = [[[[5, 8]]]] self._compile_and_check([rng_R, low, high], [out], [rng_R_val, low_val, high_val], RandomFunction) # multinomial, specified shape """ #infer_shape don't work for multinomial n = iscalar() pvals = dvector() size_val = (7, 3) n_val = 6 pvals_val = [0.2] * 5 post_r, out = multinomial(rng_R, size=size_val, n=n, pvals=pvals, ndim=2) self._compile_and_check([rng_R, n, pvals], [out], [rng_R_val, n_val, pvals_val], RandomFunction) """ # uniform vector low and high low = dvector() high = dvector() post_r, out = uniform(rng_R, low=low, high=1) low_val = [-5, 0.5, 0, 1] self._compile_and_check([rng_R, low], [out], [rng_R_val, low_val], RandomFunction) low_val = [0.9] self._compile_and_check([rng_R, low], [out], [rng_R_val, low_val], RandomFunction) post_r, out = uniform(rng_R, low=low, high=high) low_val = [-4.0, -2] high_val = [-1, 0] self._compile_and_check([rng_R, low, high], [out], [rng_R_val, low_val, high_val], RandomFunction) low_val = [-4.0] high_val = [-1] self._compile_and_check([rng_R, low, high], [out], [rng_R_val, low_val, high_val], RandomFunction) # uniform broadcasting low and high low = dvector() high = dcol() post_r, out = uniform(rng_R, low=low, high=high) low_val = [-5, 0.5, 0, 1] high_val = [[1.0]] self._compile_and_check([rng_R, low, high], [out], [rng_R_val, low_val, high_val], RandomFunction) low_val = [0.9] high_val = [[1.0], [1.1], [1.5]] self._compile_and_check([rng_R, low, high], [out], [rng_R_val, low_val, high_val], RandomFunction) low_val = [-5, 0.5, 0, 1] high_val = [[1.0], [1.1], [1.5]] self._compile_and_check([rng_R, low, high], [out], [rng_R_val, low_val, high_val], RandomFunction) # uniform with vector slice low = dvector() high = dvector() post_r, out = uniform(rng_R, low=low, high=high) low_val = [0.1, 0.2, 0.3] high_val = [1.1, 2.2, 3.3] size_val = (3, ) self._compile_and_check( [rng_R, low, high], [out], [rng_R_val, low_val[:-1], high_val[:-1]], RandomFunction, ) # uniform with explicit size and size implicit in parameters # NOTE 1: Would it be desirable that size could also be supplied # as a Aesara variable? post_r, out = uniform(rng_R, size=size_val, low=low, high=high) self._compile_and_check([rng_R, low, high], [out], [rng_R_val, low_val, high_val], RandomFunction) # binomial with vector slice n = ivector() prob = dvector() post_r, out = binomial(rng_R, n=n, p=prob) n_val = [1, 2, 3] prob_val = [0.1, 0.2, 0.3] size_val = (3, ) self._compile_and_check( [rng_R, n, prob], [out], [rng_R_val, n_val[:-1], prob_val[:-1]], RandomFunction, ) # binomial with explicit size and size implicit in parameters # cf. NOTE 1 post_r, out = binomial(rng_R, n=n, p=prob, size=size_val) self._compile_and_check([rng_R, n, prob], [out], [rng_R_val, n_val, prob_val], RandomFunction) # normal with vector slice avg = dvector() std = dvector() post_r, out = normal(rng_R, avg=avg, std=std) avg_val = [1, 2, 3] std_val = [0.1, 0.2, 0.3] size_val = (3, ) self._compile_and_check( [rng_R, avg, std], [out], [rng_R_val, avg_val[:-1], std_val[:-1]], RandomFunction, ) # normal with explicit size and size implicit in parameters # cf. NOTE 1 post_r, out = normal(rng_R, avg=avg, std=std, size=size_val) self._compile_and_check([rng_R, avg, std], [out], [rng_R_val, avg_val, std_val], RandomFunction) # multinomial with tensor-3 probabilities """