class Nuggets::Array::RegressionMixin::IncrementalLinearRegression

Inspired by Incremental Simple Linear Regression in Ruby.

Use push to add a single {x,y} pair, add to add a list of y values, and << to add a single y value. Whenever a single y value is added, it's associated with an x value of its position (rank) in the data series.

Call to_a (or any Enumerable method) to work with the regression points.

Public Class Methods

new(*ys) click to toggle source
# File lib/nuggets/array/regression_mixin.rb, line 80
def initialize(*ys)
  clear
  add(*ys)
end

Public Instance Methods

<<(y) click to toggle source
# File lib/nuggets/array/regression_mixin.rb, line 107
def <<(y)
  push(@cnt + 1, y)
end
[](x)
Alias for: at
add(*ys) click to toggle source
# File lib/nuggets/array/regression_mixin.rb, line 102
def add(*ys)
  ys.each { |y| self << y }
  self
end
at(x) click to toggle source
# File lib/nuggets/array/regression_mixin.rb, line 119
def at(x)
  @y + slope * (x - @x)
end
Also aliased as: []
clear() click to toggle source
# File lib/nuggets/array/regression_mixin.rb, line 85
def clear
  @x = @y = @xx = @xy = 0.0
  @cnt, @slope = 0, nil
  self
end
each() { |x = i + 1, at(x)| ... } click to toggle source
# File lib/nuggets/array/regression_mixin.rb, line 125
def each
  @cnt.times { |i| yield [x = i + 1, at(x)] }
  self
end
intercept() click to toggle source
# File lib/nuggets/array/regression_mixin.rb, line 115
def intercept
  at(0)
end
push(x, y) click to toggle source
# File lib/nuggets/array/regression_mixin.rb, line 91
def push(x, y)
  cnt, @slope = @cnt += 1, nil

  @x  += (x     - @x)  / cnt
  @y  += (y     - @y)  / cnt
  @xx += (x * x - @xx) / cnt
  @xy += (x * y - @xy) / cnt

  self
end
slope() click to toggle source
# File lib/nuggets/array/regression_mixin.rb, line 111
def slope
  @slope ||= @cnt < 2 ? 0 : (@xy - @x * @y) / (@xx - @x * @x)
end
to_a(range = nil) click to toggle source
Calls superclass method
# File lib/nuggets/array/regression_mixin.rb, line 130
def to_a(range = nil)
  range ? range.map { |x| [x, at(x)] } : super()
end
to_s() click to toggle source
# File lib/nuggets/array/regression_mixin.rb, line 134
def to_s
  s, i = slope, intercept

  y = s == 0 ? i : begin
    x = s.abs == 1 ? "#{'-' if s < 0}x" : "#{s} * x"
    i == 0 ? x : "#{x} #{i < 0 ? '-' : '+'} #{i.abs}"
  end

  "y := #{y}".gsub(/\.0\b/, '')
end