Skip to content

Instantly share code, notes, and snippets.

@pokutuna
Created May 15, 2009 02:19
Show Gist options
  • Save pokutuna/112027 to your computer and use it in GitHub Desktop.
Save pokutuna/112027 to your computer and use it in GitHub Desktop.
class BoxMuller
def initialize(average, deviation)
@pos = -1
@ave = average
@dev = deviation
@buf = Array.new
end
def get(position = @pos)
return @buf[position]
end
def rand()
@pos += 1
if(@buf.size <= @pos) then
u1 = Kernel.rand()
u2 = Kernel.rand()
z1 = Math.sqrt(-2*Math.log(u1))*Math.cos(2*Math::PI*u2)
z2 = Math.sqrt(-2*Math.log(u1))*Math.sin(2*Math::PI*u2)
@buf.push(dev*z1+ave)
@buf.push(dev*z2+ave)
end
return @buf[@pos]
end
attr_accessor :pos, :ave, :dev
end
if $0 == __FILE__
a = BoxMuller.new(3.5, 6.5) #=> 平均3.5、標準偏差6.5の正規乱数生成器をつくる
10.times do #=> 10回表示する
p a.rand
end
puts '---'
p a.get #=> 引数なしで最後に発生させた乱数
puts '---'
p a.get(0) #=> インデックスを指定して過去に発生させた乱数を取得
p a.get(-1) #=> Arrayに保存してるから-1で最後の要素がとれる
puts '---'
p a #=> オブジェクトを表示
puts '---'
#乱数を検証
ary = Array.new
100000.times do
ary.push(a.rand)
end
average = ary.inject(0){ |result, item| result + item} / ary.size
p average #=> ほとんど3.5
deviation = (ary.inject(0){ |result, item| result + ((item-average) ** 2)} / ary.size) ** 0.5
p deviation #=> かなり6.5
end
10.2386449841632
6.58711144602461
1.40884794428801
3.80554302727257
12.0442824386394
1.08170065882519
-2.42671185900799
-3.84561577915485
17.9580055773683
0.373837235167363
---
0.373837235167363
---
10.2386449841632
0.373837235167363
---
#<BoxMuller:0xb7dadfec @pos=9, @buf=[10.2386449841632, 6.58711144602461, 1.40884794428801, 3.80554302727257, 12.0442824386394, 1.08170065882519, -2.42671185900799, -3.84561577915485, 17.9580055773683, 0.373837235167363], @dev=6.5, @ave=3.5>
---
3.50856036548772
6.48495536413411
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment