Ruby中生成高斯(正态分布)随机数的代码
在ruby中生成正态分布随机数的代码是什么?Ruby中生成高斯(正态分布)随机数的代码
(注:我回答我自己的问题,但接受,看看是否有人有一个更好的答案之前,我会等待几天。)
编辑:
搜索此,我看着所有网页上,来自这两个搜索这样造成:
+“正态分布”红宝石
和
+高斯+随机红宝石
Python的random.gauss()和Boost的normal_distribution都使用Box-Muller transform,所以对于Ruby来说也应该足够好。
def gaussian(mean, stddev, rand)
theta = 2 * Math::PI * rand.call
rho = Math.sqrt(-2 * Math.log(1 - rand.call))
scale = stddev * rho
x = mean + scale * Math.cos(theta)
y = mean + scale * Math.sin(theta)
return x, y
end
该方法可以封装在一个类中,该类可以逐个返回样本。
class RandomGaussian
def initialize(mean, stddev, rand_helper = lambda { Kernel.rand })
@rand_helper = rand_helper
@mean = mean
@stddev = stddev
@valid = false
@next = 0
end
def rand
if @valid then
@valid = false
return @next
else
@valid = true
x, y = self.class.gaussian(@mean, @stddev, @rand_helper)
@next = y
return x
end
end
private
def self.gaussian(mean, stddev, rand)
theta = 2 * Math::PI * rand.call
rho = Math.sqrt(-2 * Math.log(1 - rand.call))
scale = stddev * rho
x = mean + scale * Math.cos(theta)
y = mean + scale * Math.sin(theta)
return x, y
end
end
下法律允许的范围内,antonakos已放弃所有版权及相关或邻接权的RandomGaussian
Ruby类。这项工作发表于:丹麦。
许可证声明并不意味着我关心此代码。相反,我不使用代码,我没有测试它,并且我不用Ruby编程。
原始问题要求提供代码,但作者的后续评论意味着使用现有库的兴趣。我对同样的感兴趣,我的搜索发现了这两个宝石:
gsl - “Ruby接口到GNU科学图书馆”(需要你安装GSL)。对于均值= 0和给定的标准偏差的正态分布的随机数的调用序列是
rng = GSL::Rng.alloc
rng.gaussian(sd) # a single random sample
rng.gaussian(sd, 100) # 100 random samples
rubystats - “从PHPMath统计库的端口”(纯红宝石)。具有给定均值和标准差的正态分布随机数的呼叫顺序为
gen = Rubystats::NormalDistribution.new(mean, sd)
gen.rng # a single random sample
gen.rng(100) # 100 random samples
@ antonakos的回答+1。以下是我一直使用的Box-Muller的实现;它本质上是相同的,但略有收紧代码:
class RandomGaussian
def initialize(mean = 0.0, sd = 1.0, rng = lambda { Kernel.rand })
@mean, @sd, @rng = mean, sd, rng
@compute_next_pair = false
end
def rand
if (@compute_next_pair = [email protected]_next_pair)
# Compute a pair of random values with normal distribution.
# See http://en.wikipedia.org/wiki/Box-Muller_transform
theta = 2 * Math::PI * @rng.call
scale = @sd * Math.sqrt(-2 * Math.log(1 - @rng.call))
@g1 = @mean + scale * Math.sin(theta)
@g0 = @mean + scale * Math.cos(theta)
else
@g1
end
end
end
当然,如果你真的关心速度,你应该实现Ziggurat Algorithm :)。
另一种选择,这一个使用distribution宝石,由一个SciRuby研究员编写。
我觉得使用起来有点简单。
require 'distribution'
normal = Distribution::Normal.rng(1)
norm_distribution = 1_000.times.map {normal.call}
看着这段代码,我不知道预期的标准偏差应该是什么。 – 2013-12-10 20:10:03
转到此处:http://rubydoc.info/gems/distribution/0.7.0/Distribution/Normal/Ruby_ 您会看到rng(1)指定了平均值,并且您可以指定标准偏差你想通过传递额外的参数'Distribution :: Normal.rng(mean,standard_deviation)'来调用该分配中的随机值。 – Ryanmt 2013-12-19 20:24:32
正确的链接是:[distribution](https://rubygems.org/gems/distribution) – pisaruk 2014-11-15 19:26:14
检查相关的问题(见右侧面板)? – Gumbo 2011-04-28 22:19:56
是的,我查了一下,虽然有些地方有算法,但没有人用Ruby编码它。这是一个常见的任务,它确实应该在标准库中。但是如果没有这样做,我认为StackOverflow上应该可以找到复制粘贴代码。 – Eponymous 2011-04-28 22:26:18
提一下你所查的内容可能是一个好主意,这样思考回答的人就不会检查他们,除非他们认为你错过了某些东西。 – 2011-04-28 23:34:27