Inline a lot of functions
This commit is contained in:
@@ -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))"
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -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());
|
||||||
|
|
||||||
|
|||||||
12
src/utils.rs
12
src/utils.rs
@@ -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()
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user