diff --git a/src/game.rs b/src/game.rs index 12e818f..e2f0e76 100644 --- a/src/game.rs +++ b/src/game.rs @@ -500,4 +500,123 @@ mod tests { assert_ulps_eq!(p[0][0], p[1][0], epsilon = 0.000001); } + + #[test] + fn test_2vs2_weighted() { + let t_a = vec![ + Player::new(Gaussian::new(25.0, 25.0 / 3.0), 25.0 / 6.0, 0.0), + Player::new(Gaussian::new(25.0, 25.0 / 3.0), 25.0 / 6.0, 0.0), + ]; + let w_a = vec![0.4, 0.8]; + + let t_b = vec![ + Player::new(Gaussian::new(25.0, 25.0 / 3.0), 25.0 / 6.0, 0.0), + Player::new(Gaussian::new(25.0, 25.0 / 3.0), 25.0 / 6.0, 0.0), + ]; + let w_b = vec![0.9, 0.6]; + + let g = Game::new(vec![t_a.clone(), t_b.clone()], vec![], vec![w_a, w_b], 0.0); + let p = g.posteriors(); + + assert_ulps_eq!( + p[0][0], + Gaussian::new(27.539023, 8.129639), + epsilon = 0.000001 + ); + assert_ulps_eq!( + p[0][1], + Gaussian::new(30.078046, 7.485372), + epsilon = 0.000001 + ); + assert_ulps_eq!( + p[1][0], + Gaussian::new(19.287197, 7.243465), + epsilon = 0.000001 + ); + assert_ulps_eq!( + p[1][1], + Gaussian::new(21.191465, 7.867608), + epsilon = 0.000001 + ); + + let w_a = vec![1.3, 1.5]; + let w_b = vec![0.7, 0.4]; + + let g = Game::new(vec![t_a.clone(), t_b.clone()], vec![], vec![w_a, w_b], 0.0); + let p = g.posteriors(); + + assert_ulps_eq!( + p[0][0], + Gaussian::new(25.190190, 8.220511), + epsilon = 0.000001 + ); + assert_ulps_eq!( + p[0][1], + Gaussian::new(25.219450, 8.182783), + epsilon = 0.000001 + ); + assert_ulps_eq!( + p[1][0], + Gaussian::new(24.897589, 8.300779), + epsilon = 0.000001 + ); + assert_ulps_eq!( + p[1][1], + Gaussian::new(24.941479, 8.322717), + epsilon = 0.000001 + ); + + let w_a = vec![1.6, 0.2]; + let w_b = vec![0.7, 2.4]; + + let g = Game::new(vec![t_a.clone(), t_b.clone()], vec![], vec![w_a, w_b], 0.0); + let p = g.posteriors(); + + assert_ulps_eq!( + p[0][0], + Gaussian::new(31.674697, 7.501180), + epsilon = 0.000001 + ); + assert_ulps_eq!( + p[0][1], + Gaussian::new(25.834337, 8.320970), + epsilon = 0.000001 + ); + assert_ulps_eq!( + p[1][0], + Gaussian::new(22.079819, 8.180607), + epsilon = 0.000001 + ); + assert_ulps_eq!( + p[1][1], + Gaussian::new(14.987953, 6.308469), + epsilon = 0.000001 + ); + + let g = Game::new( + vec![ + t_a.clone(), + vec![Player::new( + Gaussian::new(25.0, 25.0 / 3.0), + 25.0 / 6.0, + 0.0, + )], + ], + vec![], + vec![], + 0.0, + ); + let post_2vs1 = g.posteriors(); + + let w_a = vec![1.0, 1.0]; + let w_b = vec![1.0, 0.0]; + + let g = Game::new(vec![t_a, t_b.clone()], vec![], vec![w_a, w_b], 0.0); + let p = g.posteriors(); + + assert_ulps_eq!(p[0][0], post_2vs1[0][0], epsilon = 0.000001); + assert_ulps_eq!(p[0][1], post_2vs1[0][1], epsilon = 0.000001); + assert_ulps_eq!(p[1][0], post_2vs1[1][0], epsilon = 0.000001); + assert_ulps_eq!(p[1][1], t_b[1].prior, epsilon = 0.000001); + } } diff --git a/src/history.rs b/src/history.rs index 0a29eff..c9fe99e 100644 --- a/src/history.rs +++ b/src/history.rs @@ -930,6 +930,80 @@ mod tests { ); } + #[test] + fn test_log_evidence() { + let composition = vec![vec![vec!["a"], vec!["b"]], vec![vec!["b"], vec!["a"]]]; + + let mut h = History::new( + composition.clone(), + vec![], + vec![], + vec![], + HashMap::new(), + MU, + SIGMA, + BETA, + GAMMA, + P_DRAW, + false, + ); + + let p_d_m_2 = h.log_evidence(false, &vec![]).exp() * 2.0; + + assert_ulps_eq!(p_d_m_2, 0.17650911, epsilon = 0.000001); + assert_ulps_eq!( + p_d_m_2, + h.log_evidence(true, &vec![]).exp() * 2.0, + epsilon = 0.000001 + ); + assert_ulps_eq!( + p_d_m_2, + h.log_evidence(true, &vec!["a"]).exp() * 2.0, + epsilon = 0.000001 + ); + assert_ulps_eq!( + p_d_m_2, + h.log_evidence(false, &vec!["a"]).exp() * 2.0, + epsilon = 0.000001 + ); + + h.convergence(11, EPSILON, false); + + let loocv_approx_2 = h.log_evidence(false, &vec![]).exp().sqrt(); + + assert_ulps_eq!(loocv_approx_2, 0.001976774, epsilon = 0.000001); + + let p_d_m_approx_2 = h.log_evidence(true, &vec![]).exp() * 2.0; + + assert!(loocv_approx_2 - p_d_m_approx_2 < 1e-4); + + assert_ulps_eq!( + loocv_approx_2, + h.log_evidence(true, &vec!["b"]).exp() * 2.0, + epsilon = 0.00001 + ); + + let mut h = History::new( + composition, + vec![], + vec![], + vec![], + HashMap::new(), + MU, + SIGMA, + BETA, + GAMMA, + P_DRAW, + true, + ); + + assert_ulps_eq!( + ((0.5f64 * 0.1765).ln() / 2.0).exp(), + (h.log_evidence(false, &vec![]) / 2.0).exp(), + epsilon = 1e-4 + ); + } + #[test] fn test_add_events_with_time() { let composition = vec![ @@ -1123,4 +1197,56 @@ mod tests { epsilon = 0.000001 ); } + + #[test] + fn test_1vs1_weighted() { + let composition = vec![vec![vec!["a"], vec!["b"]], vec![vec!["b"], vec!["a"]]]; + let weights = vec![vec![vec![5.0], vec![4.0]], vec![vec![5.0], vec![4.0]]]; + + let mut h = History::new( + composition.clone(), + vec![], + vec![], + weights, + HashMap::new(), + 2.0, + 6.0, + 1.0, + 0.0, + 0.0, + false, + ); + + let lc = h.learning_curves(); + + assert_ulps_eq!( + lc["a"][0].1, + Gaussian::new(5.53765944, 4.758722), + epsilon = 0.000001 + ); + assert_ulps_eq!( + lc["b"][0].1, + Gaussian::new(-0.83012755, 5.2395689), + epsilon = 0.000001 + ); + assert_ulps_eq!( + lc["a"][1].1, + Gaussian::new(1.7922776, 4.099566689), + epsilon = 0.000001 + ); + assert_ulps_eq!( + lc["b"][1].1, + Gaussian::new(4.8455331752, 3.7476161), + epsilon = 0.000001 + ); + + h.convergence(ITERATIONS, EPSILON, false); + + let lc = h.learning_curves(); + + assert_ulps_eq!(lc["a"][0].1, lc["a"][0].1, epsilon = 0.000001); + assert_ulps_eq!(lc["b"][0].1, lc["a"][0].1, epsilon = 0.000001); + assert_ulps_eq!(lc["a"][1].1, lc["a"][0].1, epsilon = 0.000001); + assert_ulps_eq!(lc["b"][1].1, lc["a"][0].1, epsilon = 0.000001); + } }