matlab中的伪随机数原理
要说matlab的随机函数,就得先说说伪随机数。不过我也只能从matlab应⽤的⾓度,从使⽤时的概念⾓度讲讲,梳理⼀下⾃⼰粗浅的理解。⾄于数理⽅⾯的,就没认真看过。真正的随机数是得通过现实世界中随机发⽣的物理事件来产⽣的,如放射性物质随机数发⽣器是通过某种放射性物质放射出的粒⼦数来获得随机数,还有通过电路产⽣⾼频噪声来获得随机数等。不过这种硬件随机数发⽣器价格都⽐较贵,如使⽤⽐较⼴泛的ComScire的随机数发⽣器价格在895美元,约合⼈民币6000元以上。但是很多软件,PC机都需要使⽤随机数,这么贵的价格对⼀般应⽤来说不能每台PC都买⼀个硬件随机数发⽣器。在这种原因下,就出现了使⽤软件⽅法来产⽣随机数的算法。通过软件⽅法产⽣的随机数都成为伪随机数,因为它们都不是真正的随机数。
所谓伪随机数,就是到⼀组数⽬巨⼤的数,这组数的出现符合⼀定的概率分布,并且这组数能通过相应的随机性测试,这样我们就能使⽤这组数来凑合“顶替”真正的随机数来应⽤了。但是由于其本质仅仅是⽤⼀组确定的数对真随机数所表现出来的相关性质的近似,在有些场合下就⽆法满⾜应⽤要求,或者说是“随机性质不够了”,如现在使⽤最⼴泛的⼀种伪随机数产⽣算法,线性同余算法,⽆法满⾜蒙特卡罗模拟对随机性的要求。matlab默认使⽤的随机数⽣成算法Mersennetwister是⽬前较好的⼀种伪随机数产⽣算法,可以满⾜很多场合的应⽤,如蒙特卡罗模拟等。所有满⾜不同分布的伪随机数,都可以通过对均匀分布伪随机数的数学变换得到,均匀分布伪随机数的产⽣算法,是伪随机数产⽣算法的根基,前
⾯的线性同余算法,Mersennetwister算法,都是均匀分布伪随机数的产⽣算法。
伪随机数的产⽣,⼀般都是这样的情况,⾸先是选取种⼦,然后是在此种⼦基础上根据具体的⽣成算法计算得到⼀个伪随机数,然后利⽤此伪随机数再根据⽣成算法递归计算出下⼀个伪随机数,直到将所有不重复出现的伪随机数全部计算出来。这个伪随机数序列就是我们以后要⽤到的伪随机数序列。上⾯的计算过程可以⼀次性计算完毕,也可以使⽤⼀次递归计算⼀次,每次⽣成的伪随机数就是这个伪随机数序列中的⼀个,不过不管怎么样,只要确定了种⼦,确定了⽣成算法,这个序列就是确定的了。所谓种⼦,就是⼀个对伪随机数计算的初始值。既然是确定的了,那么当我们使⽤某种算法计算给出⼀个伪随机数,那么下⼀次计算时出现的数也就是固定的,有⼈可能会问,既然是固定的,还有什么随机性?这就是伪随机数的“伪”所在了。伪随机数的“随机”在于,虽然下次计算产⽣的数是⼀个固定的数,但是这种出现的模式,以及整个伪随机数序列,却能通过⼤部分随机性测试实验,这说明对随机性测试实验来说,伪随机数的表现同真随机数接近,这样我们在⼀些不是很苛刻的应⽤场合,就能拿这组伪随机数来⽤,使⽤时的外在表现同真随机数是较近似的。
好了,现在才要说matlab的随机函数,matlab的随机函数产⽣的随机数都是根据伪随机数序列获取的,在v7.7以上的版本中,有如下的伪随机数产⽣器:Mersennetwister,Multiplicativecongruentialgenerator,MultiplicativelaggedFibonaccigenerator,Combinedmultiplerecursivegenerator,Shift-registergeneratorsummedwithlinearcongruentialgenerat
or,Modifiedsubtractwithborrowgenerator。相关的指令即可选择不同的产⽣器。默认的情况
下,matlab在启动时总是将各个产⽣器的种⼦设为0,这样造成编写的包含随机函数的程序每次运⾏的结果都是固定的,为了改变这种情况,可以将系统时间设置为种⼦(RandStream.setDefaultStream(RandStream('mt19937ar','Seed',sum(100*clock)))),这样每次matlab启动时种⼦设置的不同会使得计算得到的随机序列不同。在7.7版本以上,随机序列的⽣成通过RandStream对象来实现,与7.7以前的版本不同。
RandStream对象的使⽤可简单总结如下:要⽣成⼀个随机数,⾸先需要⼀个伪随机数序列,这个序列通过设定种⼦和⽣成算法来确定,RandStream的构造函数或ate⽅法即⽤来完成此任务。然后我们需要使⽤RandStream.setDefaultStream函数将确定好的序列对象设置为当前matlab使⽤的序列。然后通过rand等函数就可以⽤此序列⽣成随机数了。当然也可以不⽤将其设置为默认序列,使⽤rand函数可以指定从哪个序列中⽣成随机数:
stream=RandStream('mrg32k3a');
rand(stream,1,5)
使⽤ate函数可以创建独⽴同分布的随机序列,如
[s1,s2,s3]=ate('mrg32k3a','NumStreams',3);
r1=rand(s1,100000,1);r2=rand(s2,100000,1);r3=rand(s3,100000,1);
corrcoef([r1,r2,r3])
要使得前后两次⽣成的随机数保持⼀样,可以将递归计算的过程中的伪随机数状态记录下来,然后下⼀次计算总是基于这个记录下来的伪随机数状态来进⾏,这样每次计算得到的随机数就总是相同的:
DefaultStream;
savedState=defaultStream.State;
u1=rand(1,5)
defaultStream.State=savedState;
u2=rand(1,5)
各个指令具体的使⽤⽅法可以通过helpdesk命令,搜索RandStream来查看。v7.7以上版本为了与旧版本保持兼容,保留了原来如rand('state',0)这种伪随机序列设置⽅法,称之为legacymode,有关legacy
matlab生成随机数mode的内容也可以在RandStream项中到。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论