Added builder for History, and start migrating test to use builder instead.
This commit is contained in:
@@ -4,8 +4,8 @@ use crate::{MU, N_INF, SIGMA};
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Debug)]
|
||||
pub struct Gaussian {
|
||||
pub(crate) mu: f64,
|
||||
pub(crate) sigma: f64,
|
||||
pub mu: f64,
|
||||
pub sigma: f64,
|
||||
}
|
||||
|
||||
impl Gaussian {
|
||||
|
||||
271
src/history.rs
271
src/history.rs
@@ -5,9 +5,102 @@ use crate::{
|
||||
batch::{self, Batch},
|
||||
gaussian::Gaussian,
|
||||
player::Player,
|
||||
sort_time, tuple_gt, tuple_max,
|
||||
sort_time, tuple_gt, tuple_max, BETA, EPSILON, GAMMA, ITERATIONS, MU, P_DRAW, SIGMA,
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct HistoryBuilder {
|
||||
time: bool,
|
||||
mu: f64,
|
||||
sigma: f64,
|
||||
beta: f64,
|
||||
gamma: f64,
|
||||
p_draw: f64,
|
||||
online: bool,
|
||||
epsilon: f64,
|
||||
iterations: usize,
|
||||
}
|
||||
|
||||
impl HistoryBuilder {
|
||||
pub fn time(mut self, time: bool) -> Self {
|
||||
self.time = time;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn mu(mut self, mu: f64) -> Self {
|
||||
self.mu = mu;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn sigma(mut self, sigma: f64) -> Self {
|
||||
self.sigma = sigma;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn beta(mut self, beta: f64) -> Self {
|
||||
self.beta = beta;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn gamma(mut self, gamma: f64) -> Self {
|
||||
self.gamma = gamma;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn p_draw(mut self, p_draw: f64) -> Self {
|
||||
self.p_draw = p_draw;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn online(mut self, online: bool) -> Self {
|
||||
self.online = online;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn epsilon(mut self, epsilon: f64) -> Self {
|
||||
self.epsilon = epsilon;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn iterations(mut self, iterations: usize) -> Self {
|
||||
self.iterations = iterations;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn build(self) -> History {
|
||||
History {
|
||||
size: 0,
|
||||
batches: Vec::new(),
|
||||
agents: HashMap::new(),
|
||||
time: self.time,
|
||||
mu: self.mu,
|
||||
sigma: self.sigma,
|
||||
beta: self.beta,
|
||||
gamma: self.gamma,
|
||||
p_draw: self.p_draw,
|
||||
online: self.online,
|
||||
epsilon: self.epsilon,
|
||||
iterations: self.iterations,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for HistoryBuilder {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
time: true,
|
||||
mu: MU,
|
||||
sigma: SIGMA,
|
||||
beta: BETA,
|
||||
gamma: GAMMA,
|
||||
p_draw: P_DRAW,
|
||||
online: false,
|
||||
epsilon: EPSILON,
|
||||
iterations: ITERATIONS,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct History {
|
||||
size: usize,
|
||||
pub batches: Vec<Batch>,
|
||||
@@ -19,12 +112,15 @@ pub struct History {
|
||||
gamma: f64,
|
||||
p_draw: f64,
|
||||
online: bool,
|
||||
weights: Vec<Vec<Vec<f64>>>,
|
||||
epsilon: f64,
|
||||
iterations: usize,
|
||||
}
|
||||
|
||||
impl History {
|
||||
pub fn builder() -> HistoryBuilder {
|
||||
HistoryBuilder::default()
|
||||
}
|
||||
|
||||
pub fn new(
|
||||
composition: Vec<Vec<Vec<&str>>>,
|
||||
results: Vec<Vec<f64>>,
|
||||
@@ -87,7 +183,6 @@ impl History {
|
||||
gamma,
|
||||
p_draw,
|
||||
online,
|
||||
weights: weights.clone(),
|
||||
epsilon: 0.0,
|
||||
iterations: 10,
|
||||
};
|
||||
@@ -147,9 +242,9 @@ impl History {
|
||||
&mut self.agents,
|
||||
);
|
||||
|
||||
self.batches.push(b);
|
||||
let idx = self.batches.len();
|
||||
|
||||
let idx = self.batches.len() - 1;
|
||||
self.batches.push(b);
|
||||
|
||||
if online {
|
||||
let new = 100.0 * (i as f64 / self.size as f64);
|
||||
@@ -357,7 +452,7 @@ impl History {
|
||||
let mut j = i + 1;
|
||||
let t = if self.time { times[o[i]] } else { i as u64 + 1 };
|
||||
|
||||
while self.time && j < self.size && times[o[j]] == t {
|
||||
while self.time && j < n && times[o[j]] == t {
|
||||
j += 1;
|
||||
}
|
||||
|
||||
@@ -427,7 +522,7 @@ impl History {
|
||||
|
||||
self.batches.insert(k, b);
|
||||
|
||||
let b = &mut self.batches[k];
|
||||
let b = &self.batches[k];
|
||||
|
||||
for a in b.skills.keys() {
|
||||
let agent = self.agents.get_mut(a).unwrap();
|
||||
@@ -467,8 +562,6 @@ impl History {
|
||||
}
|
||||
|
||||
self.size += n;
|
||||
|
||||
self.iteration();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -502,19 +595,9 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
let mut h = History::new(
|
||||
composition,
|
||||
results,
|
||||
vec![1, 2, 3],
|
||||
vec![],
|
||||
priors,
|
||||
MU,
|
||||
SIGMA,
|
||||
BETA,
|
||||
GAMMA,
|
||||
P_DRAW,
|
||||
false,
|
||||
);
|
||||
let mut h = History::builder().build();
|
||||
|
||||
h.add_events(composition, results, vec![1, 2, 3], vec![], priors);
|
||||
|
||||
let p0 = h.batches[0].posteriors();
|
||||
|
||||
@@ -566,19 +649,9 @@ mod tests {
|
||||
priors.insert(k.to_string(), player);
|
||||
}
|
||||
|
||||
let mut h1 = History::new(
|
||||
composition,
|
||||
results,
|
||||
times,
|
||||
vec![],
|
||||
priors,
|
||||
MU,
|
||||
SIGMA,
|
||||
BETA,
|
||||
GAMMA,
|
||||
P_DRAW,
|
||||
false,
|
||||
);
|
||||
let mut h1 = History::builder().build();
|
||||
|
||||
h1.add_events(composition, results, times, vec![], priors);
|
||||
|
||||
assert_ulps_eq!(
|
||||
h1.batches[0].posterior("a"),
|
||||
@@ -591,7 +664,7 @@ mod tests {
|
||||
epsilon = 0.000001
|
||||
);
|
||||
|
||||
let (_step, _i) = h1.convergence(ITERATIONS, EPSILON, false);
|
||||
h1.convergence(ITERATIONS, EPSILON, false);
|
||||
|
||||
assert_ulps_eq!(
|
||||
h1.batches[0].posterior("a"),
|
||||
@@ -620,19 +693,9 @@ mod tests {
|
||||
priors.insert(k.to_string(), player);
|
||||
}
|
||||
|
||||
let mut h2 = History::new(
|
||||
composition,
|
||||
results,
|
||||
times,
|
||||
vec![],
|
||||
priors,
|
||||
MU,
|
||||
SIGMA,
|
||||
BETA,
|
||||
GAMMA,
|
||||
P_DRAW,
|
||||
false,
|
||||
);
|
||||
let mut h2 = History::builder().build();
|
||||
|
||||
h2.add_events(composition, results, times, vec![], priors);
|
||||
|
||||
assert_ulps_eq!(
|
||||
h2.batches[2].posterior("a"),
|
||||
@@ -677,20 +740,9 @@ mod tests {
|
||||
priors.insert(k.to_string(), player);
|
||||
}
|
||||
|
||||
let mut h = History::new(
|
||||
composition,
|
||||
results,
|
||||
times,
|
||||
vec![],
|
||||
priors,
|
||||
MU,
|
||||
SIGMA,
|
||||
BETA,
|
||||
GAMMA,
|
||||
P_DRAW,
|
||||
false,
|
||||
);
|
||||
let mut h = History::builder().build();
|
||||
|
||||
h.add_events(composition, results, times, vec![], priors);
|
||||
h.convergence(ITERATIONS, EPSILON, false);
|
||||
|
||||
let lc = h.learning_curves();
|
||||
@@ -930,6 +982,101 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_only_add_events() {
|
||||
let mut h = History::new(
|
||||
vec![],
|
||||
vec![],
|
||||
vec![],
|
||||
vec![],
|
||||
HashMap::new(),
|
||||
0.0,
|
||||
2.0,
|
||||
1.0,
|
||||
0.0,
|
||||
0.0,
|
||||
false,
|
||||
);
|
||||
|
||||
let composition = vec![
|
||||
vec![vec!["a"], vec!["b"]],
|
||||
vec![vec!["a"], vec!["c"]],
|
||||
vec![vec!["b"], vec!["c"]],
|
||||
];
|
||||
let results = vec![vec![1.0, 0.0], vec![0.0, 1.0], vec![1.0, 0.0]];
|
||||
|
||||
h.add_events(
|
||||
composition.clone(),
|
||||
results.clone(),
|
||||
vec![],
|
||||
vec![],
|
||||
HashMap::new(),
|
||||
);
|
||||
|
||||
let (_step, _i) = h.convergence(ITERATIONS, EPSILON, false);
|
||||
|
||||
assert_eq!(h.batches[2].skills["b"].elapsed, 1);
|
||||
assert_eq!(h.batches[2].skills["c"].elapsed, 1);
|
||||
|
||||
assert_ulps_eq!(
|
||||
h.batches[0].posterior("a"),
|
||||
Gaussian::new(0.0, 1.30061),
|
||||
epsilon = 0.000001
|
||||
);
|
||||
assert_ulps_eq!(
|
||||
h.batches[0].posterior("b"),
|
||||
Gaussian::new(0.0, 1.30061),
|
||||
epsilon = 0.000001
|
||||
);
|
||||
assert_ulps_eq!(
|
||||
h.batches[2].posterior("b"),
|
||||
Gaussian::new(0.0, 1.30061),
|
||||
epsilon = 0.000001
|
||||
);
|
||||
|
||||
h.add_events(composition, results, vec![], vec![], HashMap::new());
|
||||
|
||||
assert_eq!(h.batches.len(), 6);
|
||||
|
||||
assert_eq!(
|
||||
h.batches
|
||||
.iter()
|
||||
.map(|b| b.get_composition())
|
||||
.collect::<Vec<_>>(),
|
||||
vec![
|
||||
vec![vec![vec!["a"], vec!["b"]]],
|
||||
vec![vec![vec!["a"], vec!["c"]]],
|
||||
vec![vec![vec!["b"], vec!["c"]]],
|
||||
vec![vec![vec!["a"], vec!["b"]]],
|
||||
vec![vec![vec!["a"], vec!["c"]]],
|
||||
vec![vec![vec!["b"], vec!["c"]]]
|
||||
]
|
||||
);
|
||||
|
||||
h.convergence(ITERATIONS, EPSILON, false);
|
||||
|
||||
assert_ulps_eq!(
|
||||
h.batches[0].posterior("a"),
|
||||
Gaussian::new(0.0, 0.9312360609998878),
|
||||
epsilon = 0.000001
|
||||
);
|
||||
assert_ulps_eq!(
|
||||
h.batches[3].posterior("a"),
|
||||
Gaussian::new(0.0, 0.9312360609998878),
|
||||
epsilon = 0.000001
|
||||
);
|
||||
assert_ulps_eq!(
|
||||
h.batches[3].posterior("b"),
|
||||
Gaussian::new(0.0, 0.9312360609998878),
|
||||
epsilon = 0.000001
|
||||
);
|
||||
assert_ulps_eq!(
|
||||
h.batches[5].posterior("b"),
|
||||
Gaussian::new(0.0, 0.9312360609998878),
|
||||
epsilon = 0.000001
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_log_evidence() {
|
||||
let composition = vec![vec![vec!["a"], vec!["b"]], vec![vec!["b"], vec!["a"]]];
|
||||
|
||||
11
src/lib.rs
11
src/lib.rs
@@ -11,18 +11,17 @@ mod history;
|
||||
mod message;
|
||||
mod player;
|
||||
|
||||
use gaussian::Gaussian;
|
||||
use message::DiffMessage;
|
||||
|
||||
pub use game::Game;
|
||||
pub use gaussian::Gaussian;
|
||||
pub use history::History;
|
||||
use message::DiffMessage;
|
||||
pub use player::Player;
|
||||
|
||||
const BETA: f64 = 1.0;
|
||||
pub const BETA: f64 = 1.0;
|
||||
pub const MU: f64 = 0.0;
|
||||
pub const SIGMA: f64 = BETA * 6.0;
|
||||
const GAMMA: f64 = BETA * 0.03;
|
||||
const P_DRAW: f64 = 0.0;
|
||||
pub const GAMMA: f64 = BETA * 0.03;
|
||||
pub const P_DRAW: f64 = 0.0;
|
||||
pub const EPSILON: f64 = 1e-6;
|
||||
pub const ITERATIONS: usize = 30;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user