Use f64 instead.
This commit is contained in:
@@ -113,7 +113,7 @@ pub struct LikelihoodFactor {
|
|||||||
id: usize,
|
id: usize,
|
||||||
mean: VariableId,
|
mean: VariableId,
|
||||||
value: VariableId,
|
value: VariableId,
|
||||||
variance: f32,
|
variance: f64,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LikelihoodFactor {
|
impl LikelihoodFactor {
|
||||||
@@ -122,7 +122,7 @@ impl LikelihoodFactor {
|
|||||||
id: usize,
|
id: usize,
|
||||||
mean: VariableId,
|
mean: VariableId,
|
||||||
value: VariableId,
|
value: VariableId,
|
||||||
variance: f32,
|
variance: f64,
|
||||||
) -> LikelihoodFactor {
|
) -> LikelihoodFactor {
|
||||||
if let Some(variable) = variable_arena.get_mut(mean) {
|
if let Some(variable) = variable_arena.get_mut(mean) {
|
||||||
variable.attach_factor(id);
|
variable.attach_factor(id);
|
||||||
@@ -183,7 +183,7 @@ pub struct SumFactor {
|
|||||||
id: usize,
|
id: usize,
|
||||||
sum: VariableId,
|
sum: VariableId,
|
||||||
terms: Vec<VariableId>,
|
terms: Vec<VariableId>,
|
||||||
coeffs: Vec<f32>,
|
coeffs: Vec<f64>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SumFactor {
|
impl SumFactor {
|
||||||
@@ -192,7 +192,7 @@ impl SumFactor {
|
|||||||
id: usize,
|
id: usize,
|
||||||
sum: VariableId,
|
sum: VariableId,
|
||||||
terms: Vec<VariableId>,
|
terms: Vec<VariableId>,
|
||||||
coeffs: Vec<f32>,
|
coeffs: Vec<f64>,
|
||||||
) -> SumFactor {
|
) -> SumFactor {
|
||||||
if let Some(variable) = variable_arena.get_mut(sum) {
|
if let Some(variable) = variable_arena.get_mut(sum) {
|
||||||
variable.attach_factor(id);
|
variable.attach_factor(id);
|
||||||
@@ -218,7 +218,7 @@ impl SumFactor {
|
|||||||
variable: VariableId,
|
variable: VariableId,
|
||||||
y: Vec<Gaussian>,
|
y: Vec<Gaussian>,
|
||||||
fy: Vec<Gaussian>,
|
fy: Vec<Gaussian>,
|
||||||
a: &Vec<f32>,
|
a: &Vec<f64>,
|
||||||
) {
|
) {
|
||||||
let size = a.len();
|
let size = a.len();
|
||||||
|
|
||||||
@@ -313,21 +313,21 @@ impl SumFactor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn v_win(t: f32, e: f32) -> f32 {
|
fn v_win(t: f64, e: f64) -> f64 {
|
||||||
math::pdf(t - e) / math::cdf(t - e)
|
math::pdf(t - e) / math::cdf(t - e)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn w_win(t: f32, e: f32) -> f32 {
|
fn w_win(t: f64, e: f64) -> f64 {
|
||||||
let vwin = v_win(t, e);
|
let vwin = v_win(t, e);
|
||||||
|
|
||||||
vwin * (vwin + t - e)
|
vwin * (vwin + t - e)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn v_draw(t: f32, e: f32) -> f32 {
|
fn v_draw(t: f64, e: f64) -> f64 {
|
||||||
(math::pdf(-e - t) - math::pdf(e - t)) / (math::cdf(e - t) - math::cdf(-e - t))
|
(math::pdf(-e - t) - math::pdf(e - t)) / (math::cdf(e - t) - math::cdf(-e - t))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn w_draw(t: f32, e: f32) -> f32 {
|
fn w_draw(t: f64, e: f64) -> f64 {
|
||||||
let vdraw = v_draw(t, e);
|
let vdraw = v_draw(t, e);
|
||||||
let n = (vdraw * vdraw) + ((e - t) * math::pdf(e - t) + (e + t) * math::pdf(e + t));
|
let n = (vdraw * vdraw) + ((e - t) * math::pdf(e - t) + (e + t) * math::pdf(e + t));
|
||||||
let d = math::cdf(e - t) - math::cdf(-e - t);
|
let d = math::cdf(e - t) - math::cdf(-e - t);
|
||||||
@@ -338,7 +338,7 @@ fn w_draw(t: f32, e: f32) -> f32 {
|
|||||||
pub struct TruncateFactor {
|
pub struct TruncateFactor {
|
||||||
id: usize,
|
id: usize,
|
||||||
variable: VariableId,
|
variable: VariableId,
|
||||||
epsilon: f32,
|
epsilon: f64,
|
||||||
draw: bool,
|
draw: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -347,7 +347,7 @@ impl TruncateFactor {
|
|||||||
variable_arena: &mut VariableArena,
|
variable_arena: &mut VariableArena,
|
||||||
id: usize,
|
id: usize,
|
||||||
variable: VariableId,
|
variable: VariableId,
|
||||||
epsilon: f32,
|
epsilon: f64,
|
||||||
draw: bool,
|
draw: bool,
|
||||||
) -> TruncateFactor {
|
) -> TruncateFactor {
|
||||||
if let Some(variable) = variable_arena.get_mut(variable) {
|
if let Some(variable) = variable_arena.get_mut(variable) {
|
||||||
|
|||||||
@@ -2,8 +2,8 @@ use std::ops;
|
|||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub struct Gaussian {
|
pub struct Gaussian {
|
||||||
pub pi: f32,
|
pub pi: f64,
|
||||||
pub tau: f32,
|
pub tau: f64,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Gaussian {
|
impl Gaussian {
|
||||||
@@ -11,17 +11,17 @@ impl Gaussian {
|
|||||||
Gaussian::with_pi_tau(0.0, 0.0)
|
Gaussian::with_pi_tau(0.0, 0.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_pi_tau(pi: f32, tau: f32) -> Gaussian {
|
pub fn with_pi_tau(pi: f64, tau: f64) -> Gaussian {
|
||||||
Gaussian { pi, tau }
|
Gaussian { pi, tau }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_mu_sigma(mu: f32, sigma: f32) -> Gaussian {
|
pub fn with_mu_sigma(mu: f64, sigma: f64) -> Gaussian {
|
||||||
let pi = 1.0 / sigma.powi(2);
|
let pi = 1.0 / sigma.powi(2);
|
||||||
|
|
||||||
Gaussian::with_pi_tau(pi, pi * mu)
|
Gaussian::with_pi_tau(pi, pi * mu)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mu(&self) -> f32 {
|
pub fn mu(&self) -> f64 {
|
||||||
if self.pi == 0.0 {
|
if self.pi == 0.0 {
|
||||||
0.0
|
0.0
|
||||||
} else {
|
} else {
|
||||||
@@ -29,7 +29,7 @@ impl Gaussian {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sigma(&self) -> f32 {
|
pub fn sigma(&self) -> f64 {
|
||||||
(1.0 / self.pi).sqrt()
|
(1.0 / self.pi).sqrt()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
18
src/lib.rs
18
src/lib.rs
@@ -8,27 +8,27 @@ use gaussian::Gaussian;
|
|||||||
use matrix::Matrix;
|
use matrix::Matrix;
|
||||||
|
|
||||||
/// Default initial mean of ratings.
|
/// Default initial mean of ratings.
|
||||||
const MU: f32 = 25.0;
|
const MU: f64 = 25.0;
|
||||||
|
|
||||||
/// Default initial standard deviation of ratings.
|
/// Default initial standard deviation of ratings.
|
||||||
const SIGMA: f32 = MU / 3.0;
|
const SIGMA: f64 = MU / 3.0;
|
||||||
|
|
||||||
/// Default distance that guarantees about 76% chance of winning.
|
/// Default distance that guarantees about 76% chance of winning.
|
||||||
const BETA: f32 = SIGMA / 2.0;
|
const BETA: f64 = SIGMA / 2.0;
|
||||||
|
|
||||||
/// Default dynamic factor.
|
/// Default dynamic factor.
|
||||||
const TAU: f32 = SIGMA / 100.0;
|
const TAU: f64 = SIGMA / 100.0;
|
||||||
|
|
||||||
/// Default draw probability of the game.
|
/// Default draw probability of the game.
|
||||||
const DRAW_PROBABILITY: f32 = 0.10;
|
const DRAW_PROBABILITY: f64 = 0.10;
|
||||||
|
|
||||||
/// A basis to check reliability of the result.
|
/// A basis to check reliability of the result.
|
||||||
const DELTA: f32 = 0.0001;
|
const DELTA: f64 = 0.0001;
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub struct Rating {
|
pub struct Rating {
|
||||||
pub mu: f32,
|
pub mu: f64,
|
||||||
pub sigma: f32,
|
pub sigma: f64,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Rating {
|
impl Default for Rating {
|
||||||
@@ -191,7 +191,7 @@ fn rate(rating_groups: &[&[Rating]]) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn quality(rating_groups: &[&[Rating]]) -> f32 {
|
fn quality(rating_groups: &[&[Rating]]) -> f64 {
|
||||||
let flatten_ratings = rating_groups
|
let flatten_ratings = rating_groups
|
||||||
.iter()
|
.iter()
|
||||||
.flat_map(|group| group.iter())
|
.flat_map(|group| group.iter())
|
||||||
|
|||||||
12
src/math.rs
12
src/math.rs
@@ -1,6 +1,6 @@
|
|||||||
use std::f32;
|
use std::f64;
|
||||||
|
|
||||||
fn erfc(x: f32) -> f32 {
|
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);
|
||||||
let r = t
|
let r = t
|
||||||
@@ -21,10 +21,10 @@ fn erfc(x: f32) -> f32 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cdf(x: f32) -> f32 {
|
pub fn cdf(x: f64) -> f64 {
|
||||||
0.5 * erfc(-x / 2.0f32.sqrt())
|
0.5 * erfc(-x / 2.0f64.sqrt())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pdf(x: f32) -> f32 {
|
pub fn pdf(x: f64) -> f64 {
|
||||||
1.0 / (2.0 * f32::consts::PI).sqrt() * (-((x / 1.0).powi(2) / 2.0)).exp()
|
1.0 / (2.0 * f64::consts::PI).sqrt() * (-((x / 1.0).powi(2) / 2.0)).exp()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use std::ops;
|
use std::ops;
|
||||||
|
|
||||||
fn det(m: &[f32], x: usize) -> f32 {
|
fn det(m: &[f64], x: usize) -> f64 {
|
||||||
if x == 1 {
|
if x == 1 {
|
||||||
m[0]
|
m[0]
|
||||||
} else if x == 2 {
|
} else if x == 2 {
|
||||||
@@ -17,7 +17,7 @@ fn det(m: &[f32], x: usize) -> f32 {
|
|||||||
.map(|(_, v)| *v)
|
.map(|(_, v)| *v)
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
d += (-1.0f32).powi(n as i32) * m[n] * det(&ms, x - 1);
|
d += (-1.0f64).powi(n as i32) * m[n] * det(&ms, x - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
d
|
d
|
||||||
@@ -26,7 +26,7 @@ fn det(m: &[f32], x: usize) -> f32 {
|
|||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Matrix {
|
pub struct Matrix {
|
||||||
data: Box<[f32]>,
|
data: Box<[f64]>,
|
||||||
height: usize,
|
height: usize,
|
||||||
width: usize,
|
width: usize,
|
||||||
}
|
}
|
||||||
@@ -80,7 +80,7 @@ impl Matrix {
|
|||||||
matrix
|
matrix
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn determinant(&self) -> f32 {
|
pub fn determinant(&self) -> f64 {
|
||||||
debug_assert!(self.width == self.height);
|
debug_assert!(self.width == self.height);
|
||||||
|
|
||||||
det(&self.data, self.width)
|
det(&self.data, self.width)
|
||||||
@@ -122,7 +122,7 @@ impl Matrix {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl ops::Index<(usize, usize)> for Matrix {
|
impl ops::Index<(usize, usize)> for Matrix {
|
||||||
type Output = f32;
|
type Output = f64;
|
||||||
|
|
||||||
fn index(&self, pos: (usize, usize)) -> &Self::Output {
|
fn index(&self, pos: (usize, usize)) -> &Self::Output {
|
||||||
&self.data[(self.width * pos.0) + pos.1]
|
&self.data[(self.width * pos.0) + pos.1]
|
||||||
@@ -135,7 +135,7 @@ impl ops::IndexMut<(usize, usize)> for Matrix {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> ops::Mul<&'a Matrix> for f32 {
|
impl<'a> ops::Mul<&'a Matrix> for f64 {
|
||||||
type Output = Matrix;
|
type Output = Matrix;
|
||||||
|
|
||||||
fn mul(self, rhs: &'a Matrix) -> Matrix {
|
fn mul(self, rhs: &'a Matrix) -> Matrix {
|
||||||
|
|||||||
Reference in New Issue
Block a user