lib/darkext/statistics.rb in darkhelmet-darkext-0.10.0 vs lib/darkext/statistics.rb in darkhelmet-darkext-0.11.0
- old
+ new
@@ -5,31 +5,34 @@
require 'darkext/symbol'
class Array
# Finds the mean of the array
def mean
+ raise ArgumentError.new('Array size must be > 0') if self.size.zero?
self.sum / self.size.to_f
end
alias :average :mean
alias :ave :mean
def harmonic_mean
+ raise ArgumentError.new('Array size must be > 0') if self.size.zero?
self.size.to_f / self.map { |i| 1 / i.to_f }.sum
end
alias :h_mean :harmonic_mean
def geometric_mean
+ raise ArgumentError.new('Array size must be > 0') if self.size.zero?
self.product.root(self.size)
end
alias :g_mean :geometric_mean
# Finds the median of the array
def median
- return nil if self.size.zero?
+ raise ArgumentError.new('Array size must be > 0') if self.size.zero?
case self.size % 2
when 0
- return self.sort[self.size / (2 - 1), 2].mean
+ return self.sort[(self.size / 2) - 1, 2].mean
when 1
return self.sort[self.size / 2]
end
end
@@ -41,34 +44,40 @@
end
end
# Finds the mode of the array
def mode
+ raise ArgumentError.new('Array size must be > 0') if self.size.zero?
map = self.histogram
max = map.values.max
map.keys.select { |x| map[x] == max }
end
# Variance
def population_variance
+ raise ArgumentError.new('Array size must be > 0') if self.size.zero?
self.sum_of_squares.to_f / (self.size).to_f
end
def sample_variance
+ raise ArgumentError.new('Array size must be > 0') if self.size.zero?
self.sum_of_squares.to_f / (self.size - 1).to_f
end
# Standard deviation
def population_deviation
+ raise ArgumentError.new('Array size must be > 0') if self.size.zero?
self.population_variance.abs.sqrt
end
def sample_deviation
+ raise ArgumentError.new('Array size must be > 0') if self.size.zero?
self.sample_variance.abs.sqrt
end
def geometric_deviation
+ raise ArgumentError.new('Array size must be > 0') if self.size.zero?
gmean = self.g_mean
Math.exp((self.map { |x| (x.ln - gmean.ln).square }.sum.to_f / self.size.to_f).sqrt)
end
alias :gstddev :geometric_deviation
@@ -77,11 +86,14 @@
(1..n).collect { self[rand(self.size)] }
end
# Generates a confidence interval
def ci(opts = { })
+ raise ArgumentError.new('Array size must be > 0') if self.size.zero?
opts.with_defaults!({ :percent => 0.95, :rho => 1, :type => :center })
+ percent = opts[:percent]
+ rho = opts[:rho]
m = self.mean
ret = Array.new
div = (opts[:type] == :center ? 2 : 1)
i = ((Darkext::Statistics::zscore((1 - percent) / div) * rho) /
self.size.sqrt).abs
@@ -108,10 +120,11 @@
rho = self.sample_deviation.to_f
self.map! { |v| (v.to_f - m) / rho }
end
def sum_of_squares
+ raise ArgumentError.new('Array size must be > 0') if self.size.zero?
m = self.mean
self.map { |v| v - m }.squares.sum
end
# Normalize the array
@@ -171,13 +184,14 @@
# * SST (:ss_t)
# * R^2 (:r_2)
# * R (:r)
# * unbiased estimator (:estimator)
# * the equation as a lambda (:equation)
- # Raises an argument error if the arguments are not the same size
+ # Raises an argument error if the arguments are not the same size or either is zero
def self.least_squares(xs,ys)
- raise ArgumentError("Arguments must be of equal size") if xs.size != ys.size
+ raise ArgumentError.new('Arrays must have size > 0') if xs.size.zero? || ys.size.zero?
+ raise ArgumentError.new('Arrays must be of equal size') if xs.size != ys.size
n = xs.size
b_1 = (xs.zip(ys).map(&:product).sum - ((ys.sum * xs.sum)/n))/(xs.map(&:square).sum - (xs.sum.square/n))
b_0 = ys.mean - b_1 * xs.mean
equation = lambda { |x| b_0 + b_1 * x }
predicted = xs.map(&equation)
@@ -185,20 +199,22 @@
ss_e = residuals.map(&:square).sum
ss_t = ys.sum_of_squares
estimator = ss_e/(n - 2)
r_2 = 1 - (ss_e/ss_t)
r = r_2.sqrt
- reg = {:n => n,
+ reg = {
+ :n => n,
:b_1 => b_1,
:b_0 => b_0,
:predicted => predicted,
:residuals => residuals,
:ss_e => ss_e,
:ss_t => ss_t,
:estimator => estimator,
:equation => equation,
:r_2 => r_2,
- :r => r}
+ :r => r
+ }
return reg
end
end
end
end