trueskill 0.9.2 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/HISTORY.md CHANGED
@@ -1,3 +1,9 @@
1
+ v1.0.0
2
+ ------
3
+
4
+ * made draws work
5
+ * fixed source file loading
6
+
1
7
  v0.1.0
2
8
  ------
3
9
 
@@ -1,4 +1,7 @@
1
1
  # -*- encoding : utf-8 -*-
2
- Dir.glob("#{File.dirname(__FILE__)}/gauss/**/*.rb").each do |src|
3
- require src
2
+ %w(
3
+ distribution
4
+ truncated_correction
5
+ ).each do |name|
6
+ require File.expand_path(File.join(File.dirname(__FILE__), "gauss", "#{name}.rb"))
4
7
  end
@@ -74,10 +74,29 @@ module Saulabs
74
74
 
75
75
  # The inverse of the cummulative Gaussian distribution function
76
76
  def quantile_function(x)
77
- -@@sqrt2 * Math.erfc(2.0 * x)
77
+ -@@sqrt2 * inv_erf(2.0 * x)
78
78
  end
79
79
  alias_method :inv_cdf, :quantile_function
80
80
 
81
+ def inv_erf(p)
82
+ return -100 if p >= 2.0
83
+ return 100 if p <= 0.0
84
+
85
+ pp = p < 1.0 ? p : 2 - p
86
+ t = Math.sqrt(-2*Math.log(pp/2.0)) # Initial guess
87
+ x = -0.70711*((2.30753 + t*0.27061)/(1.0 + t*(0.99229 + t*0.04481)) - t)
88
+
89
+ [0,1].each do |j|
90
+ err = erf(x) - pp
91
+ x += err/(1.12837916709551257*Math.exp(-(x*x)) - x*err) # Halley
92
+ end
93
+ p < 1.0 ? x : -x
94
+ end
95
+
96
+ def erf(x)
97
+ Math.erfc(x)
98
+ end
99
+
81
100
  end
82
101
 
83
102
  def value_at(x)
@@ -1,8 +1,42 @@
1
1
  # -*- encoding : utf-8 -*-
2
2
  require 'pp'
3
3
 
4
- require "#{File.dirname(__FILE__)}/gauss.rb"
4
+ require File.expand_path(File.join(File.dirname(__FILE__), "gauss.rb"))
5
5
 
6
- Dir.glob("#{File.dirname(__FILE__)}/trueskill/**/*.rb").sort.each do |src|
7
- require src
6
+ %w(
7
+ base greater_than
8
+ likelihood
9
+ prior
10
+ weighted_sum
11
+ within
12
+ ).each do |name|
13
+ require File.expand_path(File.join(File.dirname(__FILE__), "trueskill", "factors", "#{name}.rb"))
14
+ end
15
+
16
+ %w(
17
+ base
18
+ iterated_team_performances
19
+ performances_to_team_performances
20
+ prior_to_skills
21
+ skills_to_performances
22
+ team_difference_comparision
23
+ team_performance_differences
24
+ ).each do |name|
25
+ require File.expand_path(File.join(File.dirname(__FILE__), "trueskill", "layers", "#{name}.rb"))
26
+ end
27
+
28
+ %w(
29
+ base
30
+ loop
31
+ sequence
32
+ step
33
+ ).each do |name|
34
+ require File.expand_path(File.join(File.dirname(__FILE__), "trueskill", "schedules", "#{name}.rb"))
35
+ end
36
+
37
+ %w(
38
+ rating
39
+ factor_graph
40
+ ).each do |name|
41
+ require File.expand_path(File.join(File.dirname(__FILE__), "trueskill", "#{name}.rb"))
8
42
  end
@@ -46,7 +46,7 @@ module Saulabs
46
46
  # include Saulabs::TrueSkill
47
47
  #
48
48
  # # team 1 has just one player with a mean skill of 27.1, a skill-deviation of 2.13
49
- # # and an play activity of 100 %
49
+ # # and a play activity of 100 %
50
50
  # team1 = [Rating.new(27.1, 2.13, 1.0)]
51
51
  #
52
52
  # # team 2 has two players
@@ -1,5 +1,5 @@
1
1
  # -*- encoding : utf-8 -*-
2
- require File.dirname(__FILE__) + '/../../spec_helper'
2
+ require File.expand_path('spec/spec_helper.rb')
3
3
 
4
4
  describe Gauss::Distribution, "#initialize" do
5
5
 
@@ -130,7 +130,7 @@ describe Gauss::Distribution, "functions" do
130
130
 
131
131
  describe 'value = 0.27' do
132
132
 
133
- it "#cumulative_distribution_function should return 0.6064198" do
133
+ it "#cumulative_distribution_function should return 0.6064198 for 0.27" do
134
134
  Gauss::Distribution.cumulative_distribution_function(0.27).should be_close(0.6064198, 0.00001)
135
135
  Gauss::Distribution.cdf(2.0).should be_close(0.9772498, 0.00001)
136
136
  end
@@ -139,8 +139,36 @@ describe Gauss::Distribution, "functions" do
139
139
  Gauss::Distribution.probability_density_function(0.27).should be_close(0.384662, 0.0001)
140
140
  end
141
141
 
142
- it "#quantile_function should return -0.62941" do
143
- Gauss::Distribution.quantile_function(0.27).should be_close(-0.62941, 0.00001)
142
+ it "#quantile_function should return ~ -0.6128123 at 0.27" do
143
+ Gauss::Distribution.quantile_function(0.27).should be_close(-0.6128123, 0.00001)
144
+ end
145
+
146
+ it "#quantile_function should return ~ 1.281551 at 0.9" do
147
+ Gauss::Distribution.quantile_function(0.9).should be_close(1.281551, 0.00001)
148
+ end
149
+
150
+ it "#erf_inv should return 0.0888559 at 0.9" do
151
+ Gauss::Distribution.inv_erf(0.9).should be_close(0.0888559, 0.00001)
152
+ end
153
+
154
+ it "#erf_inv should return 0.779983 at 0.27" do
155
+ Gauss::Distribution.inv_erf(0.27).should be_close(0.779983, 0.00001)
156
+ end
157
+
158
+ it "#erf_inv should return 100 at -0.5" do
159
+ Gauss::Distribution.inv_erf(-0.5).should be_close(100, 0.00001)
160
+ end
161
+
162
+ it "#erf should return 0.203091 at 0.9" do
163
+ Gauss::Distribution.erf(0.9).should be_close(0.203091, 0.00001)
164
+ end
165
+
166
+ it "#erf should return 0.702581 at 0.27" do
167
+ Gauss::Distribution.erf(0.27).should be_close(0.702581, 0.00001)
168
+ end
169
+
170
+ it "#erf should return 1.520499 at -0.5" do
171
+ Gauss::Distribution.erf(-0.5).should be_close(1.520499, 0.00001)
144
172
  end
145
173
 
146
174
  end
@@ -1,5 +1,5 @@
1
1
  # -*- encoding : utf-8 -*-
2
- require File.dirname(__FILE__) + '/../../spec_helper'
2
+ require File.expand_path('spec/spec_helper.rb')
3
3
 
4
4
  describe Gauss::TruncatedCorrection do
5
5
 
@@ -24,6 +24,7 @@ describe Gauss::TruncatedCorrection do
24
24
  describe "#w_exceeds_margin" do
25
25
 
26
26
  it "should return 0.657847 for (0.2, 0.3)" do
27
+ Gauss::TruncatedCorrection.w_exceeds_margin(0.0, 0.740466).should be_close(0.76774506, tolerance)
27
28
  Gauss::TruncatedCorrection.w_exceeds_margin(0.2, 0.3).should be_close(0.657847, tolerance)
28
29
  Gauss::TruncatedCorrection.w_exceeds_margin(0.1, 0.03).should be_close(0.621078, tolerance)
29
30
  end
@@ -33,6 +34,7 @@ describe Gauss::TruncatedCorrection do
33
34
  describe "#v_exceeds_margin" do
34
35
 
35
36
  it "should return 0.8626174 for (0.2, 0.3)" do
37
+ Gauss::TruncatedCorrection.v_exceeds_margin(0.0, 0.740466).should be_close(1.32145197, tolerance)
36
38
  Gauss::TruncatedCorrection.v_exceeds_margin(0.2, 0.3).should be_close(0.8626174, tolerance)
37
39
  Gauss::TruncatedCorrection.v_exceeds_margin(0.1, 0.03).should be_close(0.753861, tolerance)
38
40
  end
@@ -1,5 +1,5 @@
1
1
  # -*- encoding : utf-8 -*-
2
- require File.dirname(__FILE__) + '/../../spec_helper'
2
+ require File.expand_path('spec/spec_helper.rb')
3
3
 
4
4
  describe Saulabs::TrueSkill::FactorGraph do
5
5
 
@@ -11,48 +11,100 @@ describe Saulabs::TrueSkill::FactorGraph do
11
11
 
12
12
  describe "#update_skills" do
13
13
 
14
- it "should update the mean of the first player in team1 to 29.61452" do
14
+ it "should update the mean of the first player in team1 to 30.38345" do
15
15
  @graph.update_skills
16
- @skill.mean.should be_close(29.61452, tolerance)
16
+ @skill.mean.should be_close(30.38345, tolerance)
17
17
  end
18
18
 
19
- it "should update the deviation of the first player in team1 to 3.5036" do
19
+ it "should update the deviation of the first player in team1 to 3.46421" do
20
20
  @graph.update_skills
21
- @skill.deviation.should be_close(3.5036, tolerance)
21
+ @skill.deviation.should be_close(3.46421, tolerance)
22
22
  end
23
23
 
24
24
  end
25
25
 
26
26
  describe "#draw_margin" do
27
27
 
28
- it "should be -0.998291" do
29
- @graph.draw_margin.should be_close(-0.998291, tolerance)
28
+ it "should be -0.998291 for diff 0.740466" do
29
+ @graph.draw_margin.should be_close(0.740466, tolerance)
30
30
  end
31
31
 
32
32
  end
33
33
 
34
34
  end
35
35
 
36
- describe Saulabs::TrueSkill::FactorGraph do
36
+ describe Saulabs::TrueSkill::FactorGraph, "two players" do
37
+
38
+ before :each do
39
+ @teams = [
40
+ [TrueSkill::Rating.new(25.0, 25.0/3.0, 1.0, 25.0/300.0)],
41
+ [TrueSkill::Rating.new(25.0, 25.0/3.0, 1.0, 25.0/300.0)]
42
+ ]
43
+ end
44
+
45
+ describe 'win with standard rating' do
46
+
47
+ before :each do
48
+ TrueSkill::FactorGraph.new(@teams, [1,2]).update_skills
49
+ end
50
+
51
+ it "should change first players rating to [29.395832, 7.1714755]" do
52
+ @teams[0][0].should eql_rating(29.395832, 7.1714755)
53
+ end
54
+
55
+ it "should change second players rating to [20.6041679, 7.1714755]" do
56
+ @teams[1][0].should eql_rating(20.6041679, 7.1714755)
57
+ end
58
+
59
+ end
60
+
61
+ describe 'draw with standard rating' do
62
+
63
+ before :each do
64
+ TrueSkill::FactorGraph.new(@teams, [1,1]).update_skills
65
+ end
66
+
67
+ it "should change first players rating to [25.0, 6.4575196]" do
68
+ @teams[0][0].should eql_rating(25.0, 6.4575196)
69
+ end
70
+
71
+ it "should change second players rating to [25.0, 6.4575196]" do
72
+ @teams[1][0].should eql_rating(25.0, 6.4575196)
73
+ end
74
+
75
+ end
76
+
77
+ describe 'draw with different ratings' do
78
+
79
+ before :each do
80
+ @teams[1][0] = TrueSkill::Rating.new(50.0, 12.5, 1.0, 25.0/300.0)
81
+ TrueSkill::FactorGraph.new(@teams, [1,1]).update_skills
82
+ end
83
+
84
+ it "should change first players rating to [31.6623, 7.1374]" do
85
+ @teams[0][0].should eql_rating(31.662301, 7.1374459)
86
+ end
87
+
88
+ it "should change second players mean to [35.0107, 7.9101]" do
89
+ @teams[1][0].should eql_rating(35.010653, 7.910077)
90
+ end
91
+
92
+ end
93
+
94
+ end
95
+
96
+ describe Saulabs::TrueSkill::FactorGraph, "two on two" do
37
97
 
38
98
  before :each do
39
99
  @teams = [
40
- [
41
- TrueSkill::Rating.new(8.3, 3.1, 0.8, 0.02),
42
- TrueSkill::Rating.new(3.0, 3.1, 0.8, 0.02),
43
- TrueSkill::Rating.new(2.2, 3.2, 0.8, 0.02)
44
- ],
45
- [
46
- TrueSkill::Rating.new(25.0, 8.3333, 0.8, 0.02)
47
- ]
100
+ [TrueSkill::Rating.new(25.0, 25.0/3.0, 1.0, 25.0/300.0),TrueSkill::Rating.new(25.0, 25.0/3.0, 1.0, 25.0/300.0)],
101
+ [TrueSkill::Rating.new(25.0, 25.0/3.0, 1.0, 25.0/300.0),TrueSkill::Rating.new(25.0, 25.0/3.0, 1.0, 25.0/300.0)]
48
102
  ]
49
- @skill = @teams.last.first
50
- @graph = TrueSkill::FactorGraph.new(@teams, [1,2], :beta => 25.0, :draw_probability => 0.0)
51
103
  end
52
104
 
53
- it "should do something" do
54
- 40.times { TrueSkill::FactorGraph.new(@teams, [1,2], :beta => 15.0, :draw_probability => 0.0).update_skills }
55
- puts "#{@skill.to_s}"
105
+ describe 'win with standard rating' do
106
+
107
+
56
108
  end
57
109
 
58
110
  end
@@ -1,5 +1,5 @@
1
1
  # -*- encoding : utf-8 -*-
2
- require File.dirname(__FILE__) + '/../../../spec_helper'
2
+ require File.expand_path('spec/spec_helper.rb')
3
3
 
4
4
  describe TrueSkill::Factors::GreaterThan do
5
5
 
@@ -1,5 +1,5 @@
1
1
  # -*- encoding : utf-8 -*-
2
- require File.dirname(__FILE__) + '/../../../spec_helper'
2
+ require File.expand_path('spec/spec_helper.rb')
3
3
 
4
4
  describe TrueSkill::Factors::Likelihood do
5
5
 
@@ -1,5 +1,5 @@
1
1
  # -*- encoding : utf-8 -*-
2
- require File.dirname(__FILE__) + '/../../../spec_helper'
2
+ require File.expand_path('spec/spec_helper.rb')
3
3
 
4
4
  describe TrueSkill::Factors::Prior do
5
5
 
@@ -1,5 +1,5 @@
1
1
  # -*- encoding : utf-8 -*-
2
- require File.dirname(__FILE__) + '/../../../spec_helper'
2
+ require File.expand_path('spec/spec_helper.rb')
3
3
 
4
4
  describe TrueSkill::Factors::Prior do
5
5
 
@@ -1,5 +1,5 @@
1
1
  # -*- encoding : utf-8 -*-
2
- require File.dirname(__FILE__) + '/../../../spec_helper'
2
+ require File.expand_path('spec/spec_helper.rb')
3
3
 
4
4
  describe TrueSkill::Factors::Within do
5
5
 
@@ -1,5 +1,5 @@
1
1
  # -*- encoding : utf-8 -*-
2
- require File.dirname(__FILE__) + '/../../../spec_helper'
2
+ require File.expand_path('spec/spec_helper.rb')
3
3
 
4
4
  describe TrueSkill::Layers::PriorToSkills do
5
5
 
@@ -1,5 +1,5 @@
1
1
  # -*- encoding : utf-8 -*-
2
- require File.dirname(__FILE__) + '/../../spec_helper'
2
+ require File.expand_path('spec/spec_helper.rb')
3
3
 
4
4
  describe "Schedules" do
5
5
 
@@ -2,12 +2,13 @@
2
2
  require 'rubygems'
3
3
  require 'spec'
4
4
  require 'spec/autorun'
5
- require "#{File.dirname(__FILE__)}/../lib/saulabs/trueskill.rb"
5
+ require File.expand_path(File.join(File.dirname(__FILE__), "..", "lib", "saulabs", "trueskill.rb"))
6
+ require File.expand_path(File.join(File.dirname(__FILE__), "true_skill_matchers.rb"))
6
7
 
7
8
  include Saulabs
8
9
 
9
10
  Spec::Runner.configure do |config|
10
-
11
+ config.include(TrueSkillMatchers)
11
12
  end
12
13
 
13
14
  def tolerance
@@ -0,0 +1,39 @@
1
+ # -*- encoding : utf-8 -*-
2
+ module TrueSkillMatchers
3
+
4
+ class EqualRating
5
+
6
+ def initialize(mean, deviation, precision)
7
+ @expected = TrueSkill::Rating.new(mean, deviation)
8
+ @precision = 10**precision
9
+ end
10
+
11
+ def matches?(target)
12
+ @target = target
13
+ @mean_diff = @expected.mean - @target.mean
14
+ @deviation_diff = @expected.deviation - @target.deviation
15
+ (@mean_diff*@precision).to_i + (@deviation_diff*@precision).to_i == 0
16
+ end
17
+
18
+ def failure_message
19
+ "expected rating #{@target.to_s} to be equal to #{@expected.to_s} #{failure_info}"
20
+ end
21
+
22
+ def negative_failure_message
23
+ "expected rating #{@target.to_s} not to be equal to #{@expected.to_s} #{failure_info}"
24
+ end
25
+
26
+ def failure_info
27
+ msg = []
28
+ msg << "mean differs by #{@mean_diff}" if @mean_diff != 0.0
29
+ msg << "deviation differs by #{@deviation_diff}" if @deviation_diff != 0.0
30
+ " (#{msg.join(', ')})"
31
+ end
32
+
33
+ end
34
+
35
+ def eql_rating(target_mean, target_deviation, precision = 5)
36
+ EqualRating.new(target_mean, target_deviation, precision)
37
+ end
38
+
39
+ end
metadata CHANGED
@@ -3,10 +3,10 @@ name: trueskill
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
+ - 1
6
7
  - 0
7
- - 9
8
- - 2
9
- version: 0.9.2
8
+ - 0
9
+ version: 1.0.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Lars Kuhnt
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-07-20 00:00:00 +02:00
17
+ date: 2011-01-19 00:00:00 +01:00
18
18
  default_executable:
19
19
  dependencies: []
20
20
 
@@ -65,8 +65,9 @@ files:
65
65
  - spec/saulabs/trueskill/layers/prior_to_skills_spec.rb
66
66
  - spec/saulabs/trueskill/schedules_spec.rb
67
67
  - spec/spec_helper.rb
68
+ - spec/true_skill_matchers.rb
68
69
  - spec/spec.opts
69
- has_rdoc: true
70
+ has_rdoc: false
70
71
  homepage: http://github.com/saulabs/trueskill
71
72
  licenses: []
72
73
 
@@ -110,4 +111,5 @@ test_files:
110
111
  - spec/saulabs/trueskill/layers/prior_to_skills_spec.rb
111
112
  - spec/saulabs/trueskill/schedules_spec.rb
112
113
  - spec/spec_helper.rb
114
+ - spec/true_skill_matchers.rb
113
115
  - spec/spec.opts