Inline a lot of functions

This commit is contained in:
2022-06-14 23:00:21 +02:00
parent 9b025fb53a
commit 811a4ca418
3 changed files with 27 additions and 4 deletions

View File

@@ -13,16 +13,16 @@ pub struct Game {
impl Game { impl Game {
pub fn new(teams: Vec<Vec<Player>>, result: Vec<u16>, p_draw: f64) -> Self { pub fn new(teams: Vec<Vec<Player>>, result: Vec<u16>, p_draw: f64) -> Self {
if !result.is_empty() { if !result.is_empty() {
assert!( debug_assert!(
teams.len() == result.len(), teams.len() == result.len(),
"len(result) and (len(teams) != len(result))" "len(result) and (len(teams) != len(result))"
); );
} }
assert!(p_draw >= 0.0 && p_draw < 1.0, "0.0 <= p_draw < 1.0"); debug_assert!(p_draw >= 0.0 && p_draw < 1.0, "0.0 <= p_draw < 1.0");
if p_draw == 0.0 { if p_draw == 0.0 {
assert!( debug_assert!(
result.iter().collect::<HashSet<_>>().len() == result.len(), result.iter().collect::<HashSet<_>>().len() == result.len(),
"(p_draw == 0.0) and (len(result) > 0) and (len(set(result)) != len(result))" "(p_draw == 0.0) and (len(result) > 0) and (len(set(result)) != len(result))"
); );

View File

@@ -9,34 +9,42 @@ pub struct Gaussian {
} }
impl Gaussian { impl Gaussian {
#[inline]
pub const fn new(mu: f64, sigma: f64) -> Self { pub const fn new(mu: f64, sigma: f64) -> Self {
Gaussian { mu, sigma } Gaussian { mu, sigma }
} }
#[inline]
pub fn mu(&self) -> f64 { pub fn mu(&self) -> f64 {
self.mu self.mu
} }
#[inline]
pub fn sigma(&self) -> f64 { pub fn sigma(&self) -> f64 {
self.sigma self.sigma
} }
#[inline]
pub fn tau(&self) -> f64 { pub fn tau(&self) -> f64 {
self.mu * self.pi() self.mu * self.pi()
} }
#[inline]
pub fn pi(&self) -> f64 { pub fn pi(&self) -> f64 {
self.sigma.powi(-2) self.sigma.powi(-2)
} }
#[inline]
pub fn forget(&self, gamma: f64, t: f64) -> Self { pub fn forget(&self, gamma: f64, t: f64) -> Self {
Self::new(self.mu, (self.sigma().powi(2) + t * gamma.powi(2)).sqrt()) Self::new(self.mu, (self.sigma().powi(2) + t * gamma.powi(2)).sqrt())
} }
#[inline]
pub fn delta(&self, m: Gaussian) -> (f64, f64) { pub fn delta(&self, m: Gaussian) -> (f64, f64) {
((self.mu() - m.mu()).abs(), (self.sigma() - m.sigma()).abs()) ((self.mu() - m.mu()).abs(), (self.sigma() - m.sigma()).abs())
} }
#[inline]
pub fn exclude(&self, m: Gaussian) -> Self { pub fn exclude(&self, m: Gaussian) -> Self {
Self::new( Self::new(
self.mu() - m.mu(), self.mu() - m.mu(),
@@ -46,6 +54,7 @@ impl Gaussian {
} }
impl Default for Gaussian { impl Default for Gaussian {
#[inline]
fn default() -> Self { fn default() -> Self {
Gaussian { Gaussian {
mu: MU, mu: MU,
@@ -57,6 +66,7 @@ impl Default for Gaussian {
impl ops::Add<Gaussian> for Gaussian { impl ops::Add<Gaussian> for Gaussian {
type Output = Gaussian; type Output = Gaussian;
#[inline]
fn add(self, rhs: Gaussian) -> Self::Output { fn add(self, rhs: Gaussian) -> Self::Output {
Gaussian { Gaussian {
mu: self.mu + rhs.mu, mu: self.mu + rhs.mu,
@@ -68,6 +78,7 @@ impl ops::Add<Gaussian> for Gaussian {
impl ops::Sub<Gaussian> for Gaussian { impl ops::Sub<Gaussian> for Gaussian {
type Output = Gaussian; type Output = Gaussian;
#[inline]
fn sub(self, rhs: Gaussian) -> Self::Output { fn sub(self, rhs: Gaussian) -> Self::Output {
Gaussian { Gaussian {
mu: self.mu - rhs.mu, mu: self.mu - rhs.mu,
@@ -79,6 +90,7 @@ impl ops::Sub<Gaussian> for Gaussian {
impl ops::Mul<Gaussian> for Gaussian { impl ops::Mul<Gaussian> for Gaussian {
type Output = Gaussian; type Output = Gaussian;
#[inline]
fn mul(self, rhs: Gaussian) -> Self::Output { fn mul(self, rhs: Gaussian) -> Self::Output {
let (mu, sigma) = utils::mu_sigma(self.tau() + rhs.tau(), self.pi() + rhs.pi()); let (mu, sigma) = utils::mu_sigma(self.tau() + rhs.tau(), self.pi() + rhs.pi());
@@ -89,6 +101,7 @@ impl ops::Mul<Gaussian> for Gaussian {
impl ops::Div<Gaussian> for Gaussian { impl ops::Div<Gaussian> for Gaussian {
type Output = Gaussian; type Output = Gaussian;
#[inline]
fn div(self, rhs: Gaussian) -> Self::Output { fn div(self, rhs: Gaussian) -> Self::Output {
let (mu, sigma) = utils::mu_sigma(self.tau() - rhs.tau(), self.pi() - rhs.pi()); let (mu, sigma) = utils::mu_sigma(self.tau() - rhs.tau(), self.pi() - rhs.pi());

View File

@@ -1,10 +1,11 @@
use std::cmp::{Ordering, Reverse}; use std::cmp::Reverse;
use std::f64::consts::{FRAC_1_SQRT_2, FRAC_2_SQRT_PI, SQRT_2}; use std::f64::consts::{FRAC_1_SQRT_2, FRAC_2_SQRT_PI, SQRT_2};
use crate::Gaussian; use crate::Gaussian;
const SQRT_TAU: f64 = 2.5066282746310002; const SQRT_TAU: f64 = 2.5066282746310002;
#[inline]
fn erfc(x: f64) -> f64 { fn erfc(x: f64) -> f64 {
let z = x.abs(); let z = x.abs();
let t = 1.0 / (1.0 + z / 2.0); let t = 1.0 / (1.0 + z / 2.0);
@@ -27,6 +28,7 @@ fn erfc(x: f64) -> f64 {
} }
} }
#[inline]
fn erfc_inv(mut y: f64) -> f64 { fn erfc_inv(mut y: f64) -> f64 {
if y >= 2.0 { if y >= 2.0 {
return f64::NEG_INFINITY; return f64::NEG_INFINITY;
@@ -59,10 +61,12 @@ fn erfc_inv(mut y: f64) -> f64 {
} }
} }
#[inline]
fn ppf(p: f64, mu: f64, sigma: f64) -> f64 { fn ppf(p: f64, mu: f64, sigma: f64) -> f64 {
mu - sigma * SQRT_2 * erfc_inv(2.0 * p) mu - sigma * SQRT_2 * erfc_inv(2.0 * p)
} }
#[inline]
pub(crate) fn mu_sigma(tau: f64, pi: f64) -> (f64, f64) { pub(crate) fn mu_sigma(tau: f64, pi: f64) -> (f64, f64) {
if pi > 0.0 { if pi > 0.0 {
return (tau / pi, (1.0 / pi).sqrt()); return (tau / pi, (1.0 / pi).sqrt());
@@ -75,12 +79,14 @@ pub(crate) fn mu_sigma(tau: f64, pi: f64) -> (f64, f64) {
(0.0, f64::INFINITY) (0.0, f64::INFINITY)
} }
#[inline]
pub(crate) fn cdf(x: f64, mu: f64, sigma: f64) -> f64 { pub(crate) fn cdf(x: f64, mu: f64, sigma: f64) -> f64 {
let z = -(x - mu) / (sigma * SQRT_2); let z = -(x - mu) / (sigma * SQRT_2);
0.5 * erfc(z) 0.5 * erfc(z)
} }
#[inline]
fn pdf(x: f64, mu: f64, sigma: f64) -> f64 { fn pdf(x: f64, mu: f64, sigma: f64) -> f64 {
let normalizer = (SQRT_TAU * sigma).powi(-1); let normalizer = (SQRT_TAU * sigma).powi(-1);
let functional = (-((x - mu).powi(2)) / (2.0 * sigma.powi(2))).exp(); let functional = (-((x - mu).powi(2)) / (2.0 * sigma.powi(2))).exp();
@@ -93,6 +99,7 @@ def ppf(p, mu, sigma):
return mu - sigma * sqrt2 * erfcinv(2 * p) return mu - sigma * sqrt2 * erfcinv(2 * p)
*/ */
#[inline]
fn v_w(mu: f64, sigma: f64, margin: f64, tie: bool) -> (f64, f64) { fn v_w(mu: f64, sigma: f64, margin: f64, tie: bool) -> (f64, f64) {
if !tie { if !tie {
let alpha = (margin - mu) / sigma; let alpha = (margin - mu) / sigma;
@@ -115,6 +122,7 @@ fn v_w(mu: f64, sigma: f64, margin: f64, tie: bool) -> (f64, f64) {
} }
} }
#[inline]
pub(crate) fn trunc(mu: f64, sigma: f64, margin: f64, tie: bool) -> (f64, f64) { pub(crate) fn trunc(mu: f64, sigma: f64, margin: f64, tie: bool) -> (f64, f64) {
let (v, w) = v_w(mu, sigma, margin, tie); let (v, w) = v_w(mu, sigma, margin, tie);
@@ -124,12 +132,14 @@ pub(crate) fn trunc(mu: f64, sigma: f64, margin: f64, tie: bool) -> (f64, f64) {
(mu_trunc, sigma_trunc) (mu_trunc, sigma_trunc)
} }
#[inline]
pub(crate) fn approx(n: Gaussian, margin: f64, tie: bool) -> Gaussian { pub(crate) fn approx(n: Gaussian, margin: f64, tie: bool) -> Gaussian {
let (mu, sigma) = trunc(n.mu(), n.sigma(), margin, tie); let (mu, sigma) = trunc(n.mu(), n.sigma(), margin, tie);
Gaussian::new(mu, sigma) Gaussian::new(mu, sigma)
} }
#[inline]
pub(crate) fn compute_margin(p_draw: f64, sd: f64) -> f64 { pub(crate) fn compute_margin(p_draw: f64, sd: f64) -> f64 {
ppf(0.5 - p_draw / 2.0, 0.0, sd).abs() ppf(0.5 - p_draw / 2.0, 0.0, sd).abs()
} }