Make PlackettLuce a class initialized with model
Assisted-by: Claude Opus 4.6 via pi
diff --git a/lib/open_skill/model.rb b/lib/open_skill/model.rb
index c756628..34809de 100644
--- a/lib/open_skill/model.rb
+++ b/lib/open_skill/model.rb
@@ -19,6 +19,8 @@ module OpenSkill
@target = target
@tau = tau
@limit_sigma = limit_sigma
+
+ @plackett_luce = PlackettLuce.new(self)
end
def rating
@@ -44,7 +46,7 @@ module OpenSkill
ordered_teams = ordered.map(&:first)
sorted_rank = ordered.map(&:last)
- new_ratings = PlackettLuce.rate(ordered_teams, self, rank: sorted_rank)
+ new_ratings = @plackett_luce.rate(ordered_teams, rank: sorted_rank)
result = rank.zip(new_ratings).sort_by(&:first).map(&:last)
diff --git a/lib/open_skill/plackett_luce.rb b/lib/open_skill/plackett_luce.rb
index 75ed34f..dba4e44 100644
--- a/lib/open_skill/plackett_luce.rb
+++ b/lib/open_skill/plackett_luce.rb
@@ -3,12 +3,17 @@
# Port of https://github.com/philihp/openskill.js/blob/main/src/models/plackett-luce.ts
module OpenSkill
- module PlackettLuce
- def self.rate(game, model, rank: nil)
+ class PlackettLuce
+ def initialize(model)
+ @beta_sq = model.beta_sq
+ @epsilon = model.epsilon
+ end
+
+ def rate(game, rank: nil)
return game if game.length <= 1
team_ratings = Util.team_rating(game, rank: rank)
- c = Util.util_c(team_ratings, model.beta_sq)
+ c = Util.util_c(team_ratings, @beta_sq)
sum_q = Util.util_sum_q(team_ratings, c)
a = Util.util_a(team_ratings)
@@ -33,7 +38,7 @@ module OpenSkill
tr.team.map { |player|
share = player.sigma**2 / tr.sigma_sq
new_mu = player.mu + share * omega
- new_sigma = player.sigma * Math.sqrt([1 - share * delta, model.epsilon].max)
+ new_sigma = player.sigma * Math.sqrt([1 - share * delta, @epsilon].max)
Rating.new(new_mu, new_sigma)
}
}
diff --git a/test/test_open_skill.rb b/test/test_open_skill.rb
index 57f6b56..c3744a1 100644
--- a/test/test_open_skill.rb
+++ b/test/test_open_skill.rb
@@ -439,20 +439,20 @@ class TestPlackettLuce < Minitest::Test
def test_solo_game_unchanged
r = @model.rating
- result = OpenSkill::PlackettLuce.rate([[r]], @model)
+ result = OpenSkill::PlackettLuce.new(@model).rate([[r]])
assert_equal [[r]], result
end
def test_2p_ffa
r = @model.rating
- result = OpenSkill::PlackettLuce.rate([[r], [r]], @model)
+ result = OpenSkill::PlackettLuce.new(@model).rate([[r], [r]])
assert_rating 27.63523138347365, 8.065506316323548, result[0][0]
assert_rating 22.36476861652635, 8.065506316323548, result[1][0]
end
def test_3p_ffa
r = @model.rating
- result = OpenSkill::PlackettLuce.rate([[r], [r], [r]], @model)
+ result = OpenSkill::PlackettLuce.new(@model).rate([[r], [r], [r]])
assert_rating 27.868876552746237, 8.204837030780652, result[0][0]
assert_rating 25.717219138186557, 8.057829747583874, result[1][0]
assert_rating 21.413904309067206, 8.057829747583874, result[2][0]
@@ -460,7 +460,7 @@ class TestPlackettLuce < Minitest::Test
def test_4p_ffa
r = @model.rating
- result = OpenSkill::PlackettLuce.rate([[r], [r], [r], [r]], @model)
+ result = OpenSkill::PlackettLuce.new(@model).rate([[r], [r], [r], [r]])
assert_rating 27.795084971874736, 8.263160757613477, result[0][0]
assert_rating 26.552824984374855, 8.179213704945203, result[1][0]
assert_rating 24.68943500312503, 8.083731307186588, result[2][0]
@@ -469,7 +469,7 @@ class TestPlackettLuce < Minitest::Test
def test_5p_ffa
r = @model.rating
- result = OpenSkill::PlackettLuce.rate([[r], [r], [r], [r], [r]], @model)
+ result = OpenSkill::PlackettLuce.new(@model).rate([[r], [r], [r], [r], [r]])
assert_rating 27.666666666666668, 8.290556877154474, result[0][0]
assert_rating 26.833333333333332, 8.240145629781066, result[1][0]
assert_rating 25.72222222222222, 8.179996679645559, result[2][0]
@@ -479,7 +479,7 @@ class TestPlackettLuce < Minitest::Test
def test_3_teams_different_sizes
r = @model.rating
- result = OpenSkill::PlackettLuce.rate([[r, r, r], [r], [r, r]], @model)
+ result = OpenSkill::PlackettLuce.new(@model).rate([[r, r, r], [r], [r, r]])
assert_rating 25.939870821784513, 8.247641552260456, result[0][0]
assert_rating 25.939870821784513, 8.247641552260456, result[0][1]
assert_rating 25.939870821784513, 8.247641552260456, result[0][2]