在ruby中生成正態分佈隨機數的代碼是什麼?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