From aaf33ed3b0cd77c640cc3e88dba0caa0b0ac30a9 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 2 Nov 2024 12:32:16 +0100 Subject: [PATCH] fix broken instant glicko --- research/src/bin/replay_encounters.rs | 40 ++++++++++++--------------- src/instant.rs | 14 ++++++++++ src/rating_system.rs | 36 +++++------------------- 3 files changed, 38 insertions(+), 52 deletions(-) diff --git a/research/src/bin/replay_encounters.rs b/research/src/bin/replay_encounters.rs index 63602ae..a4e45b1 100644 --- a/research/src/bin/replay_encounters.rs +++ b/research/src/bin/replay_encounters.rs @@ -370,19 +370,18 @@ fn write_report( writeln!( writer, - "min_deviation,max_deviation,default_volatility,tau,first_advantage,preview_opponent_deviation,rating_periods_per_day,avg_deviance" + "min_deviation,max_deviation,default_volatility,tau,first_advantage,rating_periods_per_day,avg_deviance" )?; for experiment in experiments.iter() { writeln!( writer, - "{},{},{},{},{},{},{},{}", + "{},{},{},{},{},{},{}", f64::from(experiment.rating_system.min_deviation()), f64::from(experiment.rating_system.max_deviation()), f64::from(experiment.rating_system.default_volatility()), experiment.rating_system.tau(), f64::from(experiment.rating_system.first_advantage()), - experiment.rating_system.preview_opponent_deviation(), experiment.rating_periods_per_day, experiment.avg_deviance() )?; @@ -461,8 +460,6 @@ struct Opt { tau: Vec, #[clap(long, value_delimiter = ',', num_args = 1.., default_value = "0")] first_advantage: Vec, - #[clap(long, value_delimiter = ',', num_args = 1.., default_value = "1")] - preview_opponent_deviation: Vec, #[clap(long, value_delimiter = ',', num_args = 1.., default_value = "0.21436")] rating_periods_per_day: Vec, } @@ -479,24 +476,21 @@ fn main() -> Result<(), Box> { for &default_volatility in &opt.default_volatility { for &tau in &opt.tau { for &first_advantage in &opt.first_advantage { - for &preview_opponent_deviation in &opt.preview_opponent_deviation { - for &rating_periods_per_day in &opt.rating_periods_per_day { - experiments.push(Experiment { - rating_system: RatingSystem::builder() - .rating_regulator_factor(1.0) - .min_rating(RatingScalar(-f64::INFINITY)) - .max_rating(RatingScalar(f64::INFINITY)) - .min_deviation(RatingDifference(min_deviation)) - .max_deviation(RatingDifference(max_deviation)) - .default_volatility(Volatility(default_volatility)) - .tau(tau) - .first_advantage(RatingDifference(first_advantage)) - .preview_opponent_deviation(preview_opponent_deviation != 0) - .build(), - rating_periods_per_day, - ..Default::default() - }); - } + for &rating_periods_per_day in &opt.rating_periods_per_day { + experiments.push(Experiment { + rating_system: RatingSystem::builder() + .rating_regulator_factor(1.0) + .min_rating(RatingScalar(-f64::INFINITY)) + .max_rating(RatingScalar(f64::INFINITY)) + .min_deviation(RatingDifference(min_deviation)) + .max_deviation(RatingDifference(max_deviation)) + .default_volatility(Volatility(default_volatility)) + .tau(tau) + .first_advantage(RatingDifference(first_advantage)) + .build(), + rating_periods_per_day, + ..Default::default() + }); } } } diff --git a/src/instant.rs b/src/instant.rs index 5efec81..5be97ce 100644 --- a/src/instant.rs +++ b/src/instant.rs @@ -85,6 +85,20 @@ impl From for Periods { } } +impl Periods { + #[must_use] + #[inline] + pub fn max(self, other: Periods) -> Periods { + Periods(f64::max(self.0, other.0)) + } + + #[must_use] + #[inline] + pub fn min(self, other: Periods) -> Periods { + Periods(f64::min(self.0, other.0)) + } +} + impl Add for Periods { type Output = Periods; diff --git a/src/rating_system.rs b/src/rating_system.rs index 6ccc186..6a355fd 100644 --- a/src/rating_system.rs +++ b/src/rating_system.rs @@ -34,8 +34,6 @@ pub struct RatingSystemBuilder { first_advantage: RatingDifference, - preview_opponent_deviation: bool, - tau: f64, convergence_tolerance: f64, @@ -115,13 +113,6 @@ impl RatingSystemBuilder { self } - /// Set whether to apply time decay to the second rating deviation when - /// updating the first rating and vice versa. The default is `false`. - pub fn preview_opponent_deviation(&mut self, preview_opponent_deviation: bool) -> &mut Self { - self.preview_opponent_deviation = preview_opponent_deviation; - self - } - /// Set the tolerance for the convergence in step 5.4 of the Glicko-2 /// algorithm. The default is `1e-6`. pub fn convergence_tolerance(&mut self, convergence_tolerance: f64) -> &mut Self { @@ -173,8 +164,6 @@ impl RatingSystemBuilder { first_advantage: self.first_advantage, - preview_opponent_deviation: self.preview_opponent_deviation, - tau: self.tau, convergence_tolerance: self.convergence_tolerance, @@ -207,8 +196,6 @@ pub struct RatingSystem { first_advantage: RatingDifference, - preview_opponent_deviation: bool, - tau: f64, convergence_tolerance: f64, @@ -245,8 +232,6 @@ impl RatingSystem { first_advantage: RatingDifference(0.0), - preview_opponent_deviation: false, - tau: 0.75, convergence_tolerance: 1e-6, @@ -297,10 +282,6 @@ impl RatingSystem { self.first_advantage } - pub fn preview_opponent_deviation(&self) -> bool { - self.preview_opponent_deviation - } - pub fn tau(&self) -> f64 { self.tau } @@ -401,16 +382,13 @@ impl RatingSystem { advantage: RatingDifference, ) -> Result { // Step 2 - let phi = us.deviation.to_internal(); + let phi = self.preview_deviation(us, now - Periods(1.0)).to_internal(); // Notable change! // Step 3 - let their_g = g(RatingDifference::to_internal( - if self.preview_opponent_deviation { - self.preview_deviation(them, now) - } else { - them.deviation - }, - )); + let their_g = g(self + .preview_deviation(them, now - Periods(1.0)) // Notable change! + .to_internal()); + let expected = expectation_value((us.rating - them.rating + advantage).to_internal(), their_g); let v = 1.0 / (their_g.powi(2) * expected.value() * expected.opposite().value()); @@ -471,7 +449,7 @@ impl RatingSystem { let phi_star = new_deviation( us.deviation.to_internal(), sigma_prime, - now.elapsed_since(us.at), + Periods::min(now.elapsed_since(us.at), Periods(1.0)), // Notable change! ); // Step 7 @@ -527,7 +505,7 @@ fn new_deviation( elapsed: Periods, ) -> InternalRatingDifference { InternalRatingDifference(f64::sqrt( - deviation.sq() + f64::max(elapsed.0, 0.0) * volatility.sq(), + deviation.sq() + Periods::max(elapsed, Periods(0.0)).0 * volatility.sq(), )) }