#coding=utf-8
"""
1.对每一个随机数变量实际是分配了一个Numpy的RandomStream对象
2.随机数流,伪随机数
3.本质是shared变量
4.seed设置来随机数发生器的起点,state是当前的状态
"""
#以下都是公仔在cpu上的
from theano.tensor.shared_randomstreams import RandomStreams
from theano import function
srng=RandomStreams(seed=234)
rv_u=srng.uniform((2,2))
rv_n=srng.normal((2,2))#mean=2,std=2
#当调用f时,随机数发生的状态自动改变
f=function([],rv_u)
#当使用形参no_default_updates=True时,随机数发生器的状态不会被调用的函数影响
g=function([],rv_n,no_default_updates=True)
#一个randow变量在每次执行函数时只提取一个数
nearly_zeros = function([], rv_u + rv_u - 2 * rv_u)
#f_val1和f_val0的值不同
f_val0 = f()
f_val1 = f()
#不同
g_val0 = g()
g_val1 = g()
print(f_val0,f_val1,g_val0,g_val1)
"""
种子流
随机变量可以使用单个种子或者同一个种子。
可以使用.rng.set_value()函数设置.rng属性或者使用.seed()给一个随机变量做 种子。
"""
rng_val=rv_u.rng.get_value(borrow=True)
rng_val.seed(89234)
rv_u.rng.set_value(rng_val,borrow=True)
#可以使用.seed()函数给RandomStreams分配的所有随机变量做种子。
srng.seed(902340)
"""
在函数之间共享流
和共享变量一样,随机变量使用的随机数发生器在函数之间是共用的
"""
#nearly_zeros 函数将会更新函数f使用的发生器的状态
state_after_v0=rv_u.rng.get_value().get_state()
print nearly_zeros()
v1=f()
rng=rv_u.rng.get_value(borrow=True)
rng.set_state(state_after_v0)
rv_u.rng.set_value(rng,borrow=True)
v2=f()#回到了v1之前的那个状态
v3=f()
#v1!=v2
#v1==v3
print v1
print v2
print v3