Enumerableモジュールに追加する。(と、Array, Dir, File, Hash, IO, Range, Stringなどがインクルードしてるので、それらのオブジェクトで使える)
module Enumerable def sum inject(0){ |accum, i| accum + i } end def mean sum / length.to_f end def variance m = mean sum = inject(0){ |accum, i| accum + ( i - m ) ** 2 } sum / (length - 1).to_f end def standard_deviation return Math::sqrt(variance) end end
参考:How can I do standard deviation in Ruby? - Stack Overflow
実行
pry(main)> a =
=>
pry(main)> (0..99).each do |i|
pry(main)* a[i] = rand(100)
pry(main)* end
=> 0..99
pry(main)> a
=> [85,
42,
12,
:
0,
61]
pry(main)> a.sum
=> 5011
pry(main)> a.mean
=> 50.11
pry(main)> a.variance
=> 999.61404040404
pry(main)> a.standard_deviation
=> 31.616673455694862
実行2(正規分布乱数)
ボックス=ミュラー法を使うと平均0, 標準偏差1の正規分布乱数を発生できる。ので、この乱数を元に平均m, 標準偏差sdの正規分布の乱数が生成できる。
参考:
n個の正規分布乱数を生成するメソッドbox_muller_s_method
def box_muller_s_method(m, sd, mrand = [], n) srand (0..(n - 1).to_i).map do |i| mrand[i] = m + sd * (Math::sqrt(-2 * Math::log(rand)) * Math::sin(2 * Math::PI * rand)) end end
box_muller_s_methodを使ってstandard_deviationメソッドの確認。
pry(main)> b =
=>
pry(main)> box_muller_s_method(50, 25, b, 100)
=> [9.056138861433922,
49.49541365976993,
76.88970439479608,
:
14.827272039422489,
55.93021717456249]
pry(main)> b.size
=> 100
pry(main)> b.sum
=> 4944.478430698326
pry(main)> b.mean
=> 49.44478430698326
pry(main)> b.variance
=> 715.5954394141993
pry(main)> b.standard_deviation
=> 26.7506156828997