Skip to content

Commit

Permalink
rewrite based on the F# program by microsoft: http://blogs.technet.co…
Browse files Browse the repository at this point in the history
  • Loading branch information
larskuhnt committed Apr 12, 2010
1 parent 9c83c62 commit 7b4ab29
Show file tree
Hide file tree
Showing 14 changed files with 243 additions and 172 deletions.
42 changes: 0 additions & 42 deletions lib/models/calculation.rb

This file was deleted.

50 changes: 0 additions & 50 deletions lib/models/rating.rb

This file was deleted.

3 changes: 3 additions & 0 deletions lib/saulabs/gauss.rb
@@ -0,0 +1,3 @@
require "#{File.dirname(__FILE__)}/gauss/functions.rb"
require "#{File.dirname(__FILE__)}/gauss/distribution.rb"
require "#{File.dirname(__FILE__)}/gauss/factor_graph.rb"
81 changes: 81 additions & 0 deletions lib/saulabs/gauss/distribution.rb
@@ -0,0 +1,81 @@
module Saulabs
module Gauss
class Distribution

# gaussian normal distribution values
attr_accessor :mean, :deviation, :variance, :precision, :precision_mean

def initialize
@mean = 0.0
@deviation = 0.0
@variance = 0.0
@precision = 0.0
@precision_mean = 0.0
end

class << self

def with_deviation(mean, deviation)
dist = Distribution.new
dist.mean = mean
dist.deviation = deviation
dist.variance = deviation * deviation
dist.precision = 1 / dist.variance.to_f
dist.precision_mean = dist.precision * mean
return dist
end

def with_precision(mean, precision)
Distribution.with_deviation(mean / precision, Math.sqrt(1 / precision))
end

def absolute_difference(x, y)
[(x.precision_mean - y.precision_mean).abs, Math.sqrt((x.precision - y.precision).abs)].max
end

def log_product_normalisation(x, y)
return 0.0 if x.precision == 0.0 || y.precision == 0.0
vsum = x.variance + y.variance
mdiff = x.mean - y.mean
-0.91893853320467267 - Math.log(vsum) / 2.0 - mdiff * mdiff / 2.0 * vsum
end

def log_ratio_normalisation(x, y)
return 0.0 if x.precision == 0.0 || y.precision == 0.0
v2 = y.variance
vdiff = v2 - x.variance
return 0.0 if vdiff == 0.0
mdiff = x.mean - y.mean
Math.log(v2) + 0.91893853320467267 - Math.log(vdiff) / 2.0 + mdiff * mdiff / 2.0 * vdiff
end

end

def *(other)
Rating.with_precision(self.precision_mean + other.precision_mean, self.precision + other.precision)
end

def /(other)
Rating.with_precision(self.precision_mean - other.precision_mean, self.precision - other.precision)
end

# absolute difference
def -(other)
Distribution.absolute_difference(self, other)
end

def +(other)

end

def ==(other)
self.mean == other.mean && self.variance == other.variance
end

def equals(other)
self == other
end

end
end
end
7 changes: 7 additions & 0 deletions lib/saulabs/gauss/factor_graph.rb
@@ -0,0 +1,7 @@
module Saulabs
module Gauss
class FactorGraph

end
end
end
32 changes: 32 additions & 0 deletions lib/saulabs/gauss/functions.rb
@@ -0,0 +1,32 @@
module Saulabs
module Gauss
class Functions

SQRT2 = Math.sqrt(2).freeze
INV_SQRT_2PI = (1 / Math.sqrt(2 * Math::PI)).freeze

class << self

# Computes the cummulative Gaussian distribution at a specified point of interest
def cumulative_distribution_function(x)
0.5 * (1 + Math.erf(x / SQRT2))
end
alias_method :cdf, :cumulative_distribution_function

# Computes the Gaussian density at a specified point of interest
def probability_density_function(x)
INV_SQRT_2PI * Math.exp(-0.5 * (x**2))
end
alias_method :pdf, :probability_density_function

# The inverse of the cummulative Gaussian distribution function
def quantile_function(x)
-SQRT2 * Math.erfc(2.0 * x)
end
alias_method :inv_cdf, :quantile_function

end

end
end
end
22 changes: 22 additions & 0 deletions lib/saulabs/trueskill.rb
@@ -0,0 +1,22 @@
require "#{File.dirname(__FILE__)}/gauss.rb"

module Saulabs

module TrueSkill

# tau: uncertainty of the skill’s standard deviation TODO: interval???
# beta: chance factor (low for low-chance games like go and chess) TODO: interval???
# draw_prob: probalility of a draw game - [0,1(
# skills: the current skills of the participating players
#
def self.update_skills(tau, beta, draw_prob, skills)
tau2 = tau**2
beta2 = beta**2
num_players = skills.size
epsilon = -Math.sqrt(2.0 * beta2) * Gauss::Functions.inv_cdf((1.0 - draw_prob) / 2.0)
factors = []
end

end

end
14 changes: 0 additions & 14 deletions lib/trueskill.rb

This file was deleted.

60 changes: 0 additions & 60 deletions spec/models/rating_spec.rb

This file was deleted.

73 changes: 73 additions & 0 deletions spec/saulabs/gauss_distribution_spec.rb
@@ -0,0 +1,73 @@
require File.dirname(__FILE__) + '/../spec_helper'

describe Saulabs::Gauss::Distribution, "#with_deviation" do

before :each do
@dist = Saulabs::Gauss::Distribution.with_deviation(25.0, 8.333333)
end

it "should have a default mean value of 25.0" do
@dist.mean.should == 25.0
end

it "should have a default deviation of 8.333333" do
@dist.deviation.should be_close(8.333333, 0.000001)
end

it "should set the variance to 69.444438" do
@dist.variance.should be_close(69.4444, 0.0001)
end

it "should set the precision to 0.0144" do
@dist.precision.should be_close(0.0144, 0.0001)
end

it "should set the precision_mean to 0.36" do
@dist.precision_mean.should be_close(0.36, 0.0001)
end

end

describe Saulabs::Gauss::Distribution, "#with_precision" do

before :each do
@dist = Saulabs::Gauss::Distribution.with_precision(0.36, 0.0144)
end

it "should have a default mean value of 25.0" do
@dist.mean.should == 25.0
end

it "should have a default deviation of 8.333333" do
@dist.deviation.should be_close(8.333333, 0.000001)
end

it "should set the variance to 69.444438" do
@dist.variance.should be_close(69.4444, 0.0001)
end

it "should set the precision to 0.0144" do
@dist.precision.should be_close(0.0144, 0.0001)
end

it "should set the precision_mean to 0.36" do
@dist.precision_mean.should be_close(0.36, 0.0001)
end

end

describe Saulabs::Gauss::Distribution, "absolute difference (-)" do

before :each do
@dist = Saulabs::Gauss::Distribution.with_deviation(25.0, 8.333333)
end

it "should be 0.0 for the same distribution" do
(@dist - @dist).should == 0.0
end

it "should equal the precision mean if the 0-distribution is subtracted" do
(@dist - Saulabs::Gauss::Distribution.new).should == @dist.precision_mean
end

end
Empty file.

0 comments on commit 7b4ab29

Please sign in to comment.