Handle case where there is no time
This commit is contained in:
@@ -5,3 +5,7 @@ edition = "2021"
|
|||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
approx = "0.5.1"
|
approx = "0.5.1"
|
||||||
|
time = { version = "0.3.9", features = ["parsing"] }
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
debug = true
|
||||||
|
|||||||
447029
examples/atp.csv
Normal file
447029
examples/atp.csv
Normal file
File diff suppressed because it is too large
Load Diff
203
examples/atp.rs
Normal file
203
examples/atp.rs
Normal file
@@ -0,0 +1,203 @@
|
|||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use time::Date;
|
||||||
|
|
||||||
|
use trueskill_tt::{History, BETA, MU, P_DRAW};
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let mut csv = csv::Reader::open("examples/atp.csv").unwrap();
|
||||||
|
|
||||||
|
let mut composition = Vec::new();
|
||||||
|
let mut results = Vec::new();
|
||||||
|
let mut times = Vec::new();
|
||||||
|
|
||||||
|
let time_format = time::format_description::parse("[year]-[month]-[day]").unwrap();
|
||||||
|
|
||||||
|
for row in csv.records() {
|
||||||
|
if &row["double"] == "t" {
|
||||||
|
composition.push(vec![
|
||||||
|
vec![row["w1_id"].to_string(), row["w2_id"].to_string()],
|
||||||
|
vec![row["l1_id"].to_string(), row["l2_id"].to_string()],
|
||||||
|
]);
|
||||||
|
} else {
|
||||||
|
composition.push(vec![
|
||||||
|
vec![row["w1_id"].to_string()],
|
||||||
|
vec![row["l1_id"].to_string()],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
results.push(vec![1, 0]);
|
||||||
|
|
||||||
|
let time = Date::parse(&row["time_start"], &time_format)
|
||||||
|
.unwrap()
|
||||||
|
.midnight()
|
||||||
|
.assume_utc()
|
||||||
|
.unix_timestamp();
|
||||||
|
|
||||||
|
times.push(time as u64);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut h = History::new(
|
||||||
|
composition,
|
||||||
|
results,
|
||||||
|
times,
|
||||||
|
HashMap::new(),
|
||||||
|
MU,
|
||||||
|
1.6,
|
||||||
|
BETA,
|
||||||
|
0.036,
|
||||||
|
P_DRAW,
|
||||||
|
);
|
||||||
|
h.convergence();
|
||||||
|
|
||||||
|
/*
|
||||||
|
composition,
|
||||||
|
results,
|
||||||
|
times,
|
||||||
|
priors,
|
||||||
|
MU,
|
||||||
|
BETA,
|
||||||
|
SIGMA,
|
||||||
|
GAMMA,
|
||||||
|
P_DRAW,
|
||||||
|
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
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,
|
||||||
|
0.15 * 25.0 / 3.0,
|
||||||
|
N_INF,
|
||||||
|
);
|
||||||
|
|
||||||
|
priors.insert(k.to_string(), player);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut h1 = History::new(
|
||||||
|
composition,
|
||||||
|
results,
|
||||||
|
times,
|
||||||
|
priors,
|
||||||
|
MU,
|
||||||
|
BETA,
|
||||||
|
SIGMA,
|
||||||
|
GAMMA,
|
||||||
|
P_DRAW,
|
||||||
|
);
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
let columns = data
|
||||||
|
.lines()
|
||||||
|
.skip(1)
|
||||||
|
.map(|line| {
|
||||||
|
let columns = line.split(',').collect::<Vec<_>>();
|
||||||
|
|
||||||
|
Column {
|
||||||
|
w1_id: columns[3],
|
||||||
|
w2_id: columns[3],
|
||||||
|
l1_id: columns[3],
|
||||||
|
l2_id: columns[3],
|
||||||
|
double: columns[3],
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
*/
|
||||||
|
|
||||||
|
// match_id,double,round_number,w1_id,w1_name,w2_id,w2_name,l1_id,l1_name,l2_id,l2_name,time_start,time_end,ground,tour_id,tour_name
|
||||||
|
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
||||||
|
|
||||||
|
/*
|
||||||
|
import pandas as pd
|
||||||
|
#sudo pip3 install trueskillthroughtime
|
||||||
|
from trueskillthroughtime import *
|
||||||
|
import time
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
# Data
|
||||||
|
df = pd.read_csv('input/history.csv', low_memory=False)
|
||||||
|
|
||||||
|
columns = zip(df.w1_id, df.w2_id, df.l1_id, df.l2_id, df.double)
|
||||||
|
composition = [[[w1,w2],[l1,l2]] if d == 't' else [[w1],[l1]] for w1, w2, l1, l2, d in columns ]
|
||||||
|
times = [ datetime.strptime(t, "%Y-%m-%d").timestamp()/(60*60*24) for t in df.time_start]
|
||||||
|
|
||||||
|
#start = time.time()
|
||||||
|
h = History(composition = composition, times = times, sigma = 1.6, gamma = 0.036)
|
||||||
|
h.convergence(epsilon=0.01, iterations=10)
|
||||||
|
#end = time.time()
|
||||||
|
#print(end-start)
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
mod csv {
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io::{self, BufRead, BufReader, Lines};
|
||||||
|
use std::ops;
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
|
pub struct Reader {
|
||||||
|
header_map: Vec<String>,
|
||||||
|
lines: Lines<BufReader<File>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Reader {
|
||||||
|
pub fn open<P: AsRef<Path>>(path: P) -> Result<Self, io::Error> {
|
||||||
|
let mut lines = File::open(path).map(BufReader::new)?.lines();
|
||||||
|
|
||||||
|
let header_map = if let Some(header) = lines.next() {
|
||||||
|
let header = header?;
|
||||||
|
|
||||||
|
header.split(',').map(Into::into).collect::<Vec<_>>()
|
||||||
|
} else {
|
||||||
|
Vec::new()
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(Self { header_map, lines })
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn records(&mut self) -> Records<'_> {
|
||||||
|
Records {
|
||||||
|
header_map: &self.header_map,
|
||||||
|
lines: &mut self.lines,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Records<'a> {
|
||||||
|
header_map: &'a Vec<String>,
|
||||||
|
lines: &'a mut Lines<BufReader<File>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Iterator for Records<'a> {
|
||||||
|
type Item = Record<'a>;
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
let line = self.lines.next()?;
|
||||||
|
|
||||||
|
Some(Record {
|
||||||
|
header_map: self.header_map,
|
||||||
|
columns: line.unwrap().split(',').map(Into::into).collect::<Vec<_>>(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Record<'a> {
|
||||||
|
header_map: &'a Vec<String>,
|
||||||
|
columns: Vec<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> ops::Index<&str> for Record<'a> {
|
||||||
|
type Output = str;
|
||||||
|
|
||||||
|
fn index(&self, index: &str) -> &Self::Output {
|
||||||
|
&self.columns[self
|
||||||
|
.header_map
|
||||||
|
.iter()
|
||||||
|
.position(|header| header == index)
|
||||||
|
.unwrap()]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
23
src/batch.rs
23
src/batch.rs
@@ -46,19 +46,19 @@ impl Agent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Item {
|
pub struct Item {
|
||||||
name: String,
|
name: String,
|
||||||
likelihood: Gaussian,
|
likelihood: Gaussian,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Team {
|
pub struct Team {
|
||||||
items: Vec<Item>,
|
items: Vec<Item>,
|
||||||
output: u16,
|
output: u16,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Event {
|
pub struct Event {
|
||||||
teams: Vec<Team>,
|
teams: Vec<Team>,
|
||||||
pub evidence: f64,
|
pub evidence: f64,
|
||||||
@@ -91,7 +91,7 @@ fn compute_elapsed(last_time: f64, actual_time: f64) -> f64 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Batch {
|
pub struct Batch {
|
||||||
pub skills: HashMap<String, Skill>,
|
pub skills: HashMap<String, Skill>,
|
||||||
pub events: Vec<Event>,
|
pub events: Vec<Event>,
|
||||||
@@ -100,8 +100,8 @@ pub struct Batch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Batch {
|
impl Batch {
|
||||||
pub fn new(
|
pub fn new<C: AsRef<str> + Clone>(
|
||||||
composition: Vec<Vec<Vec<&str>>>,
|
composition: Vec<Vec<Vec<C>>>,
|
||||||
results: Vec<Vec<u16>>,
|
results: Vec<Vec<u16>>,
|
||||||
time: f64,
|
time: f64,
|
||||||
agents: &mut HashMap<String, Agent>,
|
agents: &mut HashMap<String, Agent>,
|
||||||
@@ -119,9 +119,9 @@ impl Batch {
|
|||||||
this
|
this
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_events(
|
pub fn add_events<C: AsRef<str> + Clone>(
|
||||||
&mut self,
|
&mut self,
|
||||||
composition: Vec<Vec<Vec<&str>>>,
|
composition: Vec<Vec<Vec<C>>>,
|
||||||
results: Vec<Vec<u16>>,
|
results: Vec<Vec<u16>>,
|
||||||
agents: &mut HashMap<String, Agent>,
|
agents: &mut HashMap<String, Agent>,
|
||||||
) {
|
) {
|
||||||
@@ -129,20 +129,21 @@ impl Batch {
|
|||||||
.iter()
|
.iter()
|
||||||
.flatten()
|
.flatten()
|
||||||
.flatten()
|
.flatten()
|
||||||
.cloned()
|
.map(AsRef::as_ref)
|
||||||
.collect::<HashSet<_>>();
|
.collect::<HashSet<_>>();
|
||||||
|
|
||||||
for a in this_agent {
|
for a in this_agent {
|
||||||
let elapsed = compute_elapsed(agents[a].last_time, self.time);
|
let elapsed = compute_elapsed(agents[a].last_time, self.time);
|
||||||
|
|
||||||
if let Some(skill) = self.skills.get_mut(a) {
|
if let Some(skill) = self.skills.get_mut(a) {
|
||||||
skill.elapsed = elapsed;
|
|
||||||
skill.forward = agents[a].receive(elapsed);
|
skill.forward = agents[a].receive(elapsed);
|
||||||
|
skill.elapsed = elapsed;
|
||||||
} else {
|
} else {
|
||||||
self.skills.insert(
|
self.skills.insert(
|
||||||
a.to_string(),
|
a.to_string(),
|
||||||
Skill {
|
Skill {
|
||||||
forward: agents[a].receive(elapsed),
|
forward: agents[a].receive(elapsed),
|
||||||
|
elapsed,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@@ -156,7 +157,7 @@ impl Batch {
|
|||||||
.map(|t| {
|
.map(|t| {
|
||||||
let items = (0..composition[e][t].len())
|
let items = (0..composition[e][t].len())
|
||||||
.map(|a| Item {
|
.map(|a| Item {
|
||||||
name: composition[e][t][a].to_string(),
|
name: composition[e][t][a].as_ref().to_string(),
|
||||||
likelihood: N_INF,
|
likelihood: N_INF,
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|||||||
103
src/history.rs
103
src/history.rs
@@ -4,8 +4,8 @@ use crate::{utils, Agent, Batch, Gaussian, Player, N_INF};
|
|||||||
|
|
||||||
pub struct History {
|
pub struct History {
|
||||||
size: usize,
|
size: usize,
|
||||||
batches: Vec<Batch>,
|
pub batches: Vec<Batch>,
|
||||||
agents: HashMap<String, Agent>,
|
pub agents: HashMap<String, Agent>,
|
||||||
mu: f64,
|
mu: f64,
|
||||||
sigma: f64,
|
sigma: f64,
|
||||||
gamma: f64,
|
gamma: f64,
|
||||||
@@ -14,14 +14,14 @@ pub struct History {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl History {
|
impl History {
|
||||||
pub fn new(
|
pub fn new<C: AsRef<str> + Clone>(
|
||||||
composition: Vec<Vec<Vec<&str>>>,
|
composition: Vec<Vec<Vec<C>>>,
|
||||||
results: Vec<Vec<u16>>,
|
results: Vec<Vec<u16>>,
|
||||||
times: Vec<u64>,
|
times: Vec<u64>,
|
||||||
priors: HashMap<String, Player>,
|
priors: HashMap<String, Player>,
|
||||||
mu: f64,
|
mu: f64,
|
||||||
beta: f64,
|
|
||||||
sigma: f64,
|
sigma: f64,
|
||||||
|
beta: f64,
|
||||||
gamma: f64,
|
gamma: f64,
|
||||||
p_draw: f64,
|
p_draw: f64,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
@@ -29,7 +29,7 @@ impl History {
|
|||||||
.iter()
|
.iter()
|
||||||
.flatten()
|
.flatten()
|
||||||
.flatten()
|
.flatten()
|
||||||
.cloned()
|
.map(AsRef::as_ref)
|
||||||
.collect::<HashSet<_>>();
|
.collect::<HashSet<_>>();
|
||||||
|
|
||||||
let agents = this_agent
|
let agents = this_agent
|
||||||
@@ -67,20 +67,25 @@ impl History {
|
|||||||
this
|
this
|
||||||
}
|
}
|
||||||
|
|
||||||
fn trueskill(
|
fn trueskill<C: AsRef<str> + Clone>(
|
||||||
&mut self,
|
&mut self,
|
||||||
composition: Vec<Vec<Vec<&str>>>,
|
composition: Vec<Vec<Vec<C>>>,
|
||||||
results: Vec<Vec<u16>>,
|
results: Vec<Vec<u16>>,
|
||||||
times: Vec<u64>,
|
times: Vec<u64>,
|
||||||
) {
|
) {
|
||||||
let o = utils::sortperm(×, false);
|
let o = if self.time {
|
||||||
|
utils::sortperm(×, false)
|
||||||
|
} else {
|
||||||
|
(0..composition.len()).collect::<Vec<_>>()
|
||||||
|
};
|
||||||
|
|
||||||
let mut i = 0;
|
let mut i = 0;
|
||||||
|
|
||||||
while i < self.size {
|
while i < self.size {
|
||||||
let mut j = i + 1;
|
let mut j = i + 1;
|
||||||
let t = times[o[i]];
|
let t = if self.time { times[o[i]] } else { i as u64 + 1 };
|
||||||
|
|
||||||
while j < self.size && times[o[j]] == t {
|
while self.time && j < self.size && times[o[j]] == t {
|
||||||
j += 1;
|
j += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -103,7 +108,7 @@ impl History {
|
|||||||
for a in b.skills.keys() {
|
for a in b.skills.keys() {
|
||||||
let agent = self.agents.get_mut(a).unwrap();
|
let agent = self.agents.get_mut(a).unwrap();
|
||||||
|
|
||||||
agent.last_time = t as f64;
|
agent.last_time = if self.time { t as f64 } else { f64::INFINITY };
|
||||||
agent.message = b.forward_prior_out(a);
|
agent.message = b.forward_prior_out(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -443,22 +448,22 @@ mod tests {
|
|||||||
|
|
||||||
assert_ulps_eq!(
|
assert_ulps_eq!(
|
||||||
h2.batches[2].posterior("aj").mu(),
|
h2.batches[2].posterior("aj").mu(),
|
||||||
24.99999999,
|
24.99866831022851,
|
||||||
epsilon = 0.000001
|
epsilon = 0.000001
|
||||||
);
|
);
|
||||||
assert_ulps_eq!(
|
assert_ulps_eq!(
|
||||||
h2.batches[2].posterior("aj").sigma(),
|
h2.batches[2].posterior("aj").sigma(),
|
||||||
5.419212002,
|
5.420053708148435,
|
||||||
epsilon = 0.000001
|
epsilon = 0.000001
|
||||||
);
|
);
|
||||||
assert_ulps_eq!(
|
assert_ulps_eq!(
|
||||||
h2.batches[2].posterior("cj").mu(),
|
h2.batches[2].posterior("cj").mu(),
|
||||||
24.99999999,
|
25.000532179593538,
|
||||||
epsilon = 0.000001
|
epsilon = 0.000001
|
||||||
);
|
);
|
||||||
assert_ulps_eq!(
|
assert_ulps_eq!(
|
||||||
h2.batches[2].posterior("cj").sigma(),
|
h2.batches[2].posterior("cj").sigma(),
|
||||||
5.419212002,
|
5.419827012784138,
|
||||||
epsilon = 0.000001
|
epsilon = 0.000001
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -510,22 +515,80 @@ mod tests {
|
|||||||
|
|
||||||
assert_ulps_eq!(
|
assert_ulps_eq!(
|
||||||
lc["aj"][aj_e - 1].1.mu(),
|
lc["aj"][aj_e - 1].1.mu(),
|
||||||
24.99999999569006,
|
24.99866831022851,
|
||||||
epsilon = 0.000001
|
epsilon = 0.000001
|
||||||
);
|
);
|
||||||
assert_ulps_eq!(
|
assert_ulps_eq!(
|
||||||
lc["aj"][aj_e - 1].1.sigma(),
|
lc["aj"][aj_e - 1].1.sigma(),
|
||||||
5.419212002171145,
|
5.420053708148435,
|
||||||
epsilon = 0.000001
|
epsilon = 0.000001
|
||||||
);
|
);
|
||||||
assert_ulps_eq!(
|
assert_ulps_eq!(
|
||||||
lc["cj"][cj_e - 1].1.mu(),
|
lc["cj"][cj_e - 1].1.mu(),
|
||||||
24.999999998686533,
|
25.000532179593538,
|
||||||
epsilon = 0.000001
|
epsilon = 0.000001
|
||||||
);
|
);
|
||||||
assert_ulps_eq!(
|
assert_ulps_eq!(
|
||||||
lc["cj"][cj_e - 1].1.sigma(),
|
lc["cj"][cj_e - 1].1.sigma(),
|
||||||
5.419212002245715,
|
5.419827012784138,
|
||||||
|
epsilon = 0.000001
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_env_ttt() {
|
||||||
|
let composition = vec![
|
||||||
|
vec![vec!["a"], vec!["b"]],
|
||||||
|
vec![vec!["a"], vec!["c"]],
|
||||||
|
vec![vec!["b"], vec!["c"]],
|
||||||
|
];
|
||||||
|
let results = vec![vec![1, 0], vec![0, 1], vec![1, 0]];
|
||||||
|
|
||||||
|
let mut h = History::new(
|
||||||
|
composition,
|
||||||
|
results,
|
||||||
|
Vec::new(),
|
||||||
|
HashMap::new(),
|
||||||
|
25.0,
|
||||||
|
25.0 / 3.0,
|
||||||
|
25.0 / 6.0,
|
||||||
|
25.0 / 300.0,
|
||||||
|
0.0,
|
||||||
|
);
|
||||||
|
|
||||||
|
let (_step, _i) = h.convergence();
|
||||||
|
|
||||||
|
assert_eq!(h.batches[2].skills["b"].elapsed, 1.0);
|
||||||
|
assert_eq!(h.batches[2].skills["c"].elapsed, 1.0);
|
||||||
|
|
||||||
|
assert_ulps_eq!(
|
||||||
|
h.batches[0].posterior("a").mu(),
|
||||||
|
25.0002673,
|
||||||
|
epsilon = 0.000001
|
||||||
|
);
|
||||||
|
assert_ulps_eq!(
|
||||||
|
h.batches[0].posterior("a").sigma(),
|
||||||
|
5.41938162,
|
||||||
|
epsilon = 0.000001
|
||||||
|
);
|
||||||
|
assert_ulps_eq!(
|
||||||
|
h.batches[0].posterior("b").mu(),
|
||||||
|
24.999465,
|
||||||
|
epsilon = 0.000001
|
||||||
|
);
|
||||||
|
assert_ulps_eq!(
|
||||||
|
h.batches[0].posterior("b").sigma(),
|
||||||
|
5.419425831,
|
||||||
|
epsilon = 0.000001
|
||||||
|
);
|
||||||
|
assert_ulps_eq!(
|
||||||
|
h.batches[2].posterior("b").mu(),
|
||||||
|
25.00053219,
|
||||||
|
epsilon = 0.000001
|
||||||
|
);
|
||||||
|
assert_ulps_eq!(
|
||||||
|
h.batches[2].posterior("b").sigma(),
|
||||||
|
5.419696790,
|
||||||
epsilon = 0.000001
|
epsilon = 0.000001
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
42
src/main.rs
42
src/main.rs
@@ -4,37 +4,25 @@ use trueskill_tt::*;
|
|||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let composition = vec![
|
let composition = vec![
|
||||||
vec![vec!["aj"], vec!["bj"]],
|
vec![vec!["a"], vec!["b"]],
|
||||||
vec![vec!["bj"], vec!["cj"]],
|
vec![vec!["a"], vec!["c"]],
|
||||||
vec![vec!["cj"], vec!["aj"]],
|
vec![vec!["b"], vec!["c"]],
|
||||||
];
|
];
|
||||||
let results = vec![vec![1, 0], vec![1, 0], vec![1, 0]];
|
let results = vec![vec![1, 0], vec![0, 1], vec![1, 0]];
|
||||||
let times = vec![1, 2, 3];
|
|
||||||
|
|
||||||
let mut priors = HashMap::new();
|
let mut h = History::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 h2 = History::new(
|
|
||||||
composition,
|
composition,
|
||||||
results,
|
results,
|
||||||
times,
|
vec![],
|
||||||
priors,
|
HashMap::new(),
|
||||||
MU,
|
25.0,
|
||||||
BETA,
|
25.0 / 3.0,
|
||||||
SIGMA,
|
25.0 / 6.0,
|
||||||
GAMMA,
|
25.0 / 300.0,
|
||||||
P_DRAW,
|
0.0,
|
||||||
);
|
);
|
||||||
|
|
||||||
let (_step, _i) = h2.convergence();
|
let (_step, _i) = h.convergence();
|
||||||
|
|
||||||
|
println!("{:#?}", h.batches);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ pub(crate) fn mu_sigma(tau: f64, pi: f64) -> (f64, f64) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if pi + 1e-5 < 0.0 {
|
if pi + 1e-5 < 0.0 {
|
||||||
panic!("sigma should be greater than 0");
|
panic!("pi should be greater than 0, got: {}", pi + 1e-5);
|
||||||
}
|
}
|
||||||
|
|
||||||
(0.0, f64::INFINITY)
|
(0.0, f64::INFINITY)
|
||||||
|
|||||||
Reference in New Issue
Block a user