Added more functions to History

This commit is contained in:
2022-06-13 11:27:49 +02:00
parent 4a13e4dcd2
commit 87a64acb83
5 changed files with 99 additions and 20 deletions

View File

@@ -1,3 +1,7 @@
# TrueSkill - Through Time # TrueSkill - Through Time
Rust port of [TrueSkillThroughTime.py](https://github.com/glandfried/TrueSkillThroughTime.py). Rust port of [TrueSkillThroughTime.py](https://github.com/glandfried/TrueSkillThroughTime.py).
## Todo
- [ ] Change `time` to always be a u64 (or usize)?

View File

@@ -61,7 +61,7 @@ pub struct Team {
#[derive(Clone)] #[derive(Clone)]
pub struct Event { pub struct Event {
teams: Vec<Team>, teams: Vec<Team>,
evidence: f64, pub evidence: f64,
} }
impl Event { impl Event {
@@ -94,8 +94,8 @@ fn compute_elapsed(last_time: f64, actual_time: f64) -> f64 {
#[derive(Clone)] #[derive(Clone)]
pub struct Batch { pub struct Batch {
pub skills: HashMap<String, Skill>, pub skills: HashMap<String, Skill>,
events: Vec<Event>, pub events: Vec<Event>,
time: f64, pub time: f64,
p_draw: f64, p_draw: f64,
} }

View File

@@ -1,17 +1,7 @@
use std::fmt; use std::fmt;
use std::ops; use std::ops;
use crate::utils; use crate::{utils, MU, SIGMA};
pub const BETA: f64 = 1.0;
pub const MU: f64 = 0.0;
pub const SIGMA: f64 = BETA * 6.0;
pub const GAMMA: f64 = BETA * 0.03;
pub const N01: Gaussian = Gaussian::new(0.0, 1.0);
pub const N00: Gaussian = Gaussian::new(0.0, 0.0);
pub const N_INF: Gaussian = Gaussian::new(0.0, f64::INFINITY);
pub const N_MS: Gaussian = Gaussian::new(MU, SIGMA);
#[derive(Clone, Copy, PartialEq, Debug)] #[derive(Clone, Copy, PartialEq, Debug)]
pub struct Gaussian { pub struct Gaussian {

View File

@@ -170,7 +170,7 @@ impl History {
pub fn convergence(&mut self) -> ((f64, f64), usize) { pub fn convergence(&mut self) -> ((f64, f64), usize) {
let epsilon = 1e-6; let epsilon = 1e-6;
let iterations = 30; let iterations = 30;
let verbose = false; let verbose = true;
let mut step = (f64::INFINITY, f64::INFINITY); let mut step = (f64::INFINITY, f64::INFINITY);
let mut i = 0; let mut i = 0;
@@ -196,12 +196,30 @@ impl History {
(step, i) (step, i)
} }
fn learning_curves(&self) { pub fn learning_curves(&self) -> HashMap<String, Vec<(f64, Gaussian)>> {
todo!() let mut data: HashMap<String, Vec<(f64, Gaussian)>> = HashMap::new();
for b in &self.batches {
for agent in b.skills.keys() {
let point = (b.time, b.posterior(agent));
if let Some(entry) = data.get_mut(agent) {
entry.push(point);
} else {
data.insert(agent.to_string(), vec![point]);
}
}
}
data
} }
fn log_evidence(&self) { pub fn log_evidence(&self) -> f64 {
todo!() self.batches
.iter()
.flat_map(|batch| batch.events.iter())
.map(|event| event.evidence.ln())
.sum()
} }
} }
@@ -444,4 +462,71 @@ mod tests {
epsilon = 0.000001 epsilon = 0.000001
); );
} }
#[test]
fn test_learning_curves() {
let composition = vec![
vec![vec!["aj"], vec!["bj"]],
vec![vec!["bj"], vec!["cj"]],
vec![vec!["cj"], vec!["aj"]],
];
let results = vec![vec![1, 0], vec![1, 0], vec![1, 0]];
let times = vec![5, 6, 7];
let mut priors = HashMap::new();
for k in ["aj", "bj", "cj"] {
let player = Player::new(
Gaussian::new(25.0, 25.0 / 3.0),
25.0 / 6.0,
25.0 / 300.0,
N_INF,
);
priors.insert(k.to_string(), player);
}
let mut h = History::new(
composition,
results,
times,
priors,
MU,
BETA,
SIGMA,
GAMMA,
P_DRAW,
);
h.convergence();
let lc = h.learning_curves();
let aj_e = lc["aj"].len();
let cj_e = lc["cj"].len();
assert_eq!(lc["aj"][0].0, 5.0);
assert_eq!(lc["aj"][aj_e - 1].0, 7.0);
assert_ulps_eq!(
lc["aj"][aj_e - 1].1.mu(),
24.99999999569006,
epsilon = 0.000001
);
assert_ulps_eq!(
lc["aj"][aj_e - 1].1.sigma(),
5.419212002171145,
epsilon = 0.000001
);
assert_ulps_eq!(
lc["cj"][cj_e - 1].1.mu(),
24.999999998686533,
epsilon = 0.000001
);
assert_ulps_eq!(
lc["cj"][cj_e - 1].1.sigma(),
5.419212002245715,
epsilon = 0.000001
);
}
} }

View File

@@ -36,5 +36,5 @@ fn main() {
P_DRAW, P_DRAW,
); );
let (step, i) = h2.convergence(); let (_step, _i) = h2.convergence();
} }