Skip to content

Instantly share code, notes, and snippets.

@nmk
Last active December 29, 2015 00:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nmk/7584685 to your computer and use it in GitHub Desktop.
Save nmk/7584685 to your computer and use it in GitHub Desktop.
require "minitest/autorun"
class RunningStat
def initialize(opts={})
@nr_of_els = opts.fetch(:nr_of_els, 0)
@old_m = opts.fetch(:old_m, 0.0)
@old_s = opts.fetch(:old_s, 0.0)
end
def push(x)
@nr_of_els += 1
if @nr_of_els == 1
@old_m = @new_m = x
@old_s = 0.0
else
@new_m = @old_m + (x - @old_m) / @nr_of_els
@new_s = @old_s + (x - @old_m) * (x - @new_m)
@old_m = @new_m
@old_s = @new_s
end
end
def mean
@nr_of_els > 0 ? @new_m : 0.0
end
def variance
@nr_of_els > 1 ? @new_s / (@nr_of_els - 1) : 0.0
end
def std_deviation
Math.sqrt(variance)
end
end
class TestRunningStat < MiniTest::Unit::TestCase
# for 13, 23, 12, 44, 55
def setup
@rs = RunningStat.new
[13,23,12,44,55].each { |i| @rs.push(i.to_f) }
end
def test_mean
assert_equal 29.4, @rs.mean
end
def test_variance
assert_equal 370.3, @rs.variance
end
def test_std_deviation
assert_equal 19.24318, @rs.std_deviation.round(5)
end
end
class TestRunningStatIncremental < MiniTest::Unit::TestCase
# by loading the results for 13, 23, 12, 44, 55
# and adding 16 to the set
def setup
@rs = RunningStat.new(nr_of_els: 5, old_m: 29.4, old_s: 1481.2)
@rs.push(16.0)
end
def test_mean
assert_equal 27.16667, @rs.mean.round(5)
end
def test_variance
assert_equal 326.16667, @rs.variance.round(5)
end
def test_std_deviation
assert_equal 18.06008, @rs.std_deviation.round(5)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment