feat: added a Drift trait and a "default" ConstantDrift implementation
This commit is contained in:
164
src/game.rs
164
src/game.rs
@@ -1,14 +1,16 @@
|
||||
use crate::{
|
||||
approx, compute_margin, evidence,
|
||||
N_INF, N00, approx, compute_margin,
|
||||
drift::Drift,
|
||||
evidence,
|
||||
gaussian::Gaussian,
|
||||
message::{DiffMessage, TeamMessage},
|
||||
player::Player,
|
||||
sort_perm, tuple_gt, tuple_max, N00, N_INF,
|
||||
sort_perm, tuple_gt, tuple_max,
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Game<'a> {
|
||||
teams: Vec<Vec<Player>>,
|
||||
pub struct Game<'a, D: Drift> {
|
||||
teams: Vec<Vec<Player<D>>>,
|
||||
result: &'a [f64],
|
||||
weights: &'a [Vec<f64>],
|
||||
p_draw: f64,
|
||||
@@ -16,9 +18,9 @@ pub struct Game<'a> {
|
||||
pub(crate) evidence: f64,
|
||||
}
|
||||
|
||||
impl<'a> Game<'a> {
|
||||
impl<'a, D: Drift> Game<'a, D> {
|
||||
pub fn new(
|
||||
teams: Vec<Vec<Player>>,
|
||||
teams: Vec<Vec<Player<D>>>,
|
||||
result: &'a [f64],
|
||||
weights: &'a [Vec<f64>],
|
||||
p_draw: f64,
|
||||
@@ -176,7 +178,7 @@ impl<'a> Game<'a> {
|
||||
.zip(w.iter())
|
||||
.map(|(p, &w)| {
|
||||
((m - performance.exclude(p.performance() * w)) * (1.0 / w))
|
||||
.forget(p.beta, 1)
|
||||
.forget(p.beta.powi(2))
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
})
|
||||
@@ -201,7 +203,7 @@ impl<'a> Game<'a> {
|
||||
mod tests {
|
||||
use ::approx::assert_ulps_eq;
|
||||
|
||||
use crate::{Gaussian, Player, GAMMA, N_INF};
|
||||
use crate::{ConstantDrift, GAMMA, Gaussian, N_INF, Player};
|
||||
|
||||
use super::*;
|
||||
|
||||
@@ -210,12 +212,12 @@ mod tests {
|
||||
let t_a = Player::new(
|
||||
Gaussian::from_ms(25.0, 25.0 / 3.0),
|
||||
25.0 / 6.0,
|
||||
25.0 / 300.0,
|
||||
ConstantDrift(25.0 / 300.0),
|
||||
);
|
||||
let t_b = Player::new(
|
||||
Gaussian::from_ms(25.0, 25.0 / 3.0),
|
||||
25.0 / 6.0,
|
||||
25.0 / 300.0,
|
||||
ConstantDrift(25.0 / 300.0),
|
||||
);
|
||||
|
||||
let w = [vec![1.0], vec![1.0]];
|
||||
@@ -228,8 +230,16 @@ mod tests {
|
||||
assert_ulps_eq!(a, Gaussian::from_ms(20.794779, 7.194481), epsilon = 1e-6);
|
||||
assert_ulps_eq!(b, Gaussian::from_ms(29.205220, 7.194481), epsilon = 1e-6);
|
||||
|
||||
let t_a = Player::new(Gaussian::from_ms(29.0, 1.0), 25.0 / 6.0, GAMMA);
|
||||
let t_b = Player::new(Gaussian::from_ms(25.0, 25.0 / 3.0), 25.0 / 6.0, GAMMA);
|
||||
let t_a = Player::new(
|
||||
Gaussian::from_ms(29.0, 1.0),
|
||||
25.0 / 6.0,
|
||||
ConstantDrift(GAMMA),
|
||||
);
|
||||
let t_b = Player::new(
|
||||
Gaussian::from_ms(25.0, 25.0 / 3.0),
|
||||
25.0 / 6.0,
|
||||
ConstantDrift(GAMMA),
|
||||
);
|
||||
|
||||
let w = [vec![1.0], vec![1.0]];
|
||||
let g = Game::new(vec![vec![t_a], vec![t_b]], &[0.0, 1.0], &w, 0.0);
|
||||
@@ -241,8 +251,8 @@ mod tests {
|
||||
assert_ulps_eq!(a, Gaussian::from_ms(28.896475, 0.996604), epsilon = 1e-6);
|
||||
assert_ulps_eq!(b, Gaussian::from_ms(32.189211, 6.062063), epsilon = 1e-6);
|
||||
|
||||
let t_a = Player::new(Gaussian::from_ms(1.139, 0.531), 1.0, 0.2125);
|
||||
let t_b = Player::new(Gaussian::from_ms(15.568, 0.51), 1.0, 0.2125);
|
||||
let t_a = Player::new(Gaussian::from_ms(1.139, 0.531), 1.0, ConstantDrift(0.2125));
|
||||
let t_b = Player::new(Gaussian::from_ms(15.568, 0.51), 1.0, ConstantDrift(0.2125));
|
||||
|
||||
let w = [vec![1.0], vec![1.0]];
|
||||
let g = Game::new(vec![vec![t_a], vec![t_b]], &[0.0, 1.0], &w, 0.0);
|
||||
@@ -257,17 +267,17 @@ mod tests {
|
||||
vec![Player::new(
|
||||
Gaussian::from_ms(25.0, 25.0 / 3.0),
|
||||
25.0 / 6.0,
|
||||
25.0 / 300.0,
|
||||
ConstantDrift(25.0 / 300.0),
|
||||
)],
|
||||
vec![Player::new(
|
||||
Gaussian::from_ms(25.0, 25.0 / 3.0),
|
||||
25.0 / 6.0,
|
||||
25.0 / 300.0,
|
||||
ConstantDrift(25.0 / 300.0),
|
||||
)],
|
||||
vec![Player::new(
|
||||
Gaussian::from_ms(25.0, 25.0 / 3.0),
|
||||
25.0 / 6.0,
|
||||
25.0 / 300.0,
|
||||
ConstantDrift(25.0 / 300.0),
|
||||
)],
|
||||
];
|
||||
|
||||
@@ -309,12 +319,12 @@ mod tests {
|
||||
let t_a = Player::new(
|
||||
Gaussian::from_ms(25.0, 25.0 / 3.0),
|
||||
25.0 / 6.0,
|
||||
25.0 / 300.0,
|
||||
ConstantDrift(25.0 / 300.0),
|
||||
);
|
||||
let t_b = Player::new(
|
||||
Gaussian::from_ms(25.0, 25.0 / 3.0),
|
||||
25.0 / 6.0,
|
||||
25.0 / 300.0,
|
||||
ConstantDrift(25.0 / 300.0),
|
||||
);
|
||||
|
||||
let w = [vec![1.0], vec![1.0]];
|
||||
@@ -327,8 +337,16 @@ mod tests {
|
||||
assert_ulps_eq!(a, Gaussian::from_ms(24.999999, 6.469480), epsilon = 1e-6);
|
||||
assert_ulps_eq!(b, Gaussian::from_ms(24.999999, 6.469480), epsilon = 1e-6);
|
||||
|
||||
let t_a = Player::new(Gaussian::from_ms(25.0, 3.0), 25.0 / 6.0, 25.0 / 300.0);
|
||||
let t_b = Player::new(Gaussian::from_ms(29.0, 2.0), 25.0 / 6.0, 25.0 / 300.0);
|
||||
let t_a = Player::new(
|
||||
Gaussian::from_ms(25.0, 3.0),
|
||||
25.0 / 6.0,
|
||||
ConstantDrift(25.0 / 300.0),
|
||||
);
|
||||
let t_b = Player::new(
|
||||
Gaussian::from_ms(29.0, 2.0),
|
||||
25.0 / 6.0,
|
||||
ConstantDrift(25.0 / 300.0),
|
||||
);
|
||||
|
||||
let w = [vec![1.0], vec![1.0]];
|
||||
let g = Game::new(vec![vec![t_a], vec![t_b]], &[0.0, 0.0], &w, 0.25);
|
||||
@@ -346,17 +364,17 @@ mod tests {
|
||||
let t_a = Player::new(
|
||||
Gaussian::from_ms(25.0, 25.0 / 3.0),
|
||||
25.0 / 6.0,
|
||||
25.0 / 300.0,
|
||||
ConstantDrift(25.0 / 300.0),
|
||||
);
|
||||
let t_b = Player::new(
|
||||
Gaussian::from_ms(25.0, 25.0 / 3.0),
|
||||
25.0 / 6.0,
|
||||
25.0 / 300.0,
|
||||
ConstantDrift(25.0 / 300.0),
|
||||
);
|
||||
let t_c = Player::new(
|
||||
Gaussian::from_ms(25.0, 25.0 / 3.0),
|
||||
25.0 / 6.0,
|
||||
25.0 / 300.0,
|
||||
ConstantDrift(25.0 / 300.0),
|
||||
);
|
||||
|
||||
let w = [vec![1.0], vec![1.0], vec![1.0]];
|
||||
@@ -376,9 +394,21 @@ mod tests {
|
||||
assert_ulps_eq!(b, Gaussian::from_ms(25.000000, 5.707423), epsilon = 1e-6);
|
||||
assert_ulps_eq!(c, Gaussian::from_ms(24.999999, 5.729068), epsilon = 1e-6);
|
||||
|
||||
let t_a = Player::new(Gaussian::from_ms(25.0, 3.0), 25.0 / 6.0, 25.0 / 300.0);
|
||||
let t_b = Player::new(Gaussian::from_ms(25.0, 3.0), 25.0 / 6.0, 25.0 / 300.0);
|
||||
let t_c = Player::new(Gaussian::from_ms(29.0, 2.0), 25.0 / 6.0, 25.0 / 300.0);
|
||||
let t_a = Player::new(
|
||||
Gaussian::from_ms(25.0, 3.0),
|
||||
25.0 / 6.0,
|
||||
ConstantDrift(25.0 / 300.0),
|
||||
);
|
||||
let t_b = Player::new(
|
||||
Gaussian::from_ms(25.0, 3.0),
|
||||
25.0 / 6.0,
|
||||
ConstantDrift(25.0 / 300.0),
|
||||
);
|
||||
let t_c = Player::new(
|
||||
Gaussian::from_ms(29.0, 2.0),
|
||||
25.0 / 6.0,
|
||||
ConstantDrift(25.0 / 300.0),
|
||||
);
|
||||
|
||||
let w = [vec![1.0], vec![1.0], vec![1.0]];
|
||||
let g = Game::new(
|
||||
@@ -401,17 +431,33 @@ mod tests {
|
||||
#[test]
|
||||
fn test_2vs1vs2_mixed() {
|
||||
let t_a = vec![
|
||||
Player::new(Gaussian::from_ms(12.0, 3.0), 25.0 / 6.0, 25.0 / 300.0),
|
||||
Player::new(Gaussian::from_ms(18.0, 3.0), 25.0 / 6.0, 25.0 / 300.0),
|
||||
Player::new(
|
||||
Gaussian::from_ms(12.0, 3.0),
|
||||
25.0 / 6.0,
|
||||
ConstantDrift(25.0 / 300.0),
|
||||
),
|
||||
Player::new(
|
||||
Gaussian::from_ms(18.0, 3.0),
|
||||
25.0 / 6.0,
|
||||
ConstantDrift(25.0 / 300.0),
|
||||
),
|
||||
];
|
||||
let t_b = vec![Player::new(
|
||||
Gaussian::from_ms(30.0, 3.0),
|
||||
25.0 / 6.0,
|
||||
25.0 / 300.0,
|
||||
ConstantDrift(25.0 / 300.0),
|
||||
)];
|
||||
let t_c = vec![
|
||||
Player::new(Gaussian::from_ms(14.0, 3.0), 25.0 / 6.0, 25.0 / 300.0),
|
||||
Player::new(Gaussian::from_ms(16., 3.0), 25.0 / 6.0, 25.0 / 300.0),
|
||||
Player::new(
|
||||
Gaussian::from_ms(14.0, 3.0),
|
||||
25.0 / 6.0,
|
||||
ConstantDrift(25.0 / 300.0),
|
||||
),
|
||||
Player::new(
|
||||
Gaussian::from_ms(16., 3.0),
|
||||
25.0 / 6.0,
|
||||
ConstantDrift(25.0 / 300.0),
|
||||
),
|
||||
];
|
||||
|
||||
let w = [vec![1.0, 1.0], vec![1.0], vec![1.0, 1.0]];
|
||||
@@ -433,12 +479,12 @@ mod tests {
|
||||
let t_a = vec![Player::new(
|
||||
Gaussian::from_ms(25.0, 25.0 / 3.0),
|
||||
25.0 / 6.0,
|
||||
0.0,
|
||||
ConstantDrift(0.0),
|
||||
)];
|
||||
let t_b = vec![Player::new(
|
||||
Gaussian::from_ms(25.0, 25.0 / 3.0),
|
||||
25.0 / 6.0,
|
||||
0.0,
|
||||
ConstantDrift(0.0),
|
||||
)];
|
||||
|
||||
let w = [w_a, w_b];
|
||||
@@ -495,8 +541,16 @@ mod tests {
|
||||
let w_a = vec![1.0];
|
||||
let w_b = vec![0.0];
|
||||
|
||||
let t_a = vec![Player::new(Gaussian::from_ms(2.0, 6.0), 1.0, 0.0)];
|
||||
let t_b = vec![Player::new(Gaussian::from_ms(2.0, 6.0), 1.0, 0.0)];
|
||||
let t_a = vec![Player::new(
|
||||
Gaussian::from_ms(2.0, 6.0),
|
||||
1.0,
|
||||
ConstantDrift(0.0),
|
||||
)];
|
||||
let t_b = vec![Player::new(
|
||||
Gaussian::from_ms(2.0, 6.0),
|
||||
1.0,
|
||||
ConstantDrift(0.0),
|
||||
)];
|
||||
|
||||
let w = [w_a, w_b];
|
||||
let g = Game::new(vec![t_a, t_b], &[1.0, 0.0], &w, 0.0);
|
||||
@@ -516,8 +570,16 @@ mod tests {
|
||||
let w_a = vec![1.0];
|
||||
let w_b = vec![-1.0];
|
||||
|
||||
let t_a = vec![Player::new(Gaussian::from_ms(2.0, 6.0), 1.0, 0.0)];
|
||||
let t_b = vec![Player::new(Gaussian::from_ms(2.0, 6.0), 1.0, 0.0)];
|
||||
let t_a = vec![Player::new(
|
||||
Gaussian::from_ms(2.0, 6.0),
|
||||
1.0,
|
||||
ConstantDrift(0.0),
|
||||
)];
|
||||
let t_b = vec![Player::new(
|
||||
Gaussian::from_ms(2.0, 6.0),
|
||||
1.0,
|
||||
ConstantDrift(0.0),
|
||||
)];
|
||||
|
||||
let w = [w_a, w_b];
|
||||
let g = Game::new(vec![t_a, t_b], &[1.0, 0.0], &w, 0.0);
|
||||
@@ -529,14 +591,30 @@ mod tests {
|
||||
#[test]
|
||||
fn test_2vs2_weighted() {
|
||||
let t_a = vec![
|
||||
Player::new(Gaussian::from_ms(25.0, 25.0 / 3.0), 25.0 / 6.0, 0.0),
|
||||
Player::new(Gaussian::from_ms(25.0, 25.0 / 3.0), 25.0 / 6.0, 0.0),
|
||||
Player::new(
|
||||
Gaussian::from_ms(25.0, 25.0 / 3.0),
|
||||
25.0 / 6.0,
|
||||
ConstantDrift(0.0),
|
||||
),
|
||||
Player::new(
|
||||
Gaussian::from_ms(25.0, 25.0 / 3.0),
|
||||
25.0 / 6.0,
|
||||
ConstantDrift(0.0),
|
||||
),
|
||||
];
|
||||
let w_a = vec![0.4, 0.8];
|
||||
|
||||
let t_b = vec![
|
||||
Player::new(Gaussian::from_ms(25.0, 25.0 / 3.0), 25.0 / 6.0, 0.0),
|
||||
Player::new(Gaussian::from_ms(25.0, 25.0 / 3.0), 25.0 / 6.0, 0.0),
|
||||
Player::new(
|
||||
Gaussian::from_ms(25.0, 25.0 / 3.0),
|
||||
25.0 / 6.0,
|
||||
ConstantDrift(0.0),
|
||||
),
|
||||
Player::new(
|
||||
Gaussian::from_ms(25.0, 25.0 / 3.0),
|
||||
25.0 / 6.0,
|
||||
ConstantDrift(0.0),
|
||||
),
|
||||
];
|
||||
let w_b = vec![0.9, 0.6];
|
||||
|
||||
@@ -628,7 +706,7 @@ mod tests {
|
||||
vec![Player::new(
|
||||
Gaussian::from_ms(25.0, 25.0 / 3.0),
|
||||
25.0 / 6.0,
|
||||
0.0,
|
||||
ConstantDrift(0.0),
|
||||
)],
|
||||
],
|
||||
&[1.0, 0.0],
|
||||
|
||||
Reference in New Issue
Block a user