From c4f2a2f72ac43e319067756c7757a5a15ebb172e Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Sun, 29 Dec 2019 13:01:54 -0500 Subject: preroll: Use fewer floating-point operations when calculating variance --- preroll.go | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/preroll.go b/preroll.go index ae9d5a3..ab3d0a0 100644 --- a/preroll.go +++ b/preroll.go @@ -1,4 +1,4 @@ -/* Copyright (C) 2011, 2013-2014, 2017 Luke Shumaker */ +/* Copyright (C) 2011, 2013-2014, 2017, 2019 Luke Shumaker */ package main import ( @@ -35,14 +35,17 @@ func rollSpec(spec string) (mean float64, variance float64) { dice = 1 } - // mean is E(X) + // - Let 'd' be the die_size + // - Let 'X' be the the uniform random variable that is the result of a 1d${d} roll + // - E(X) = (1+d)/2 mean = float64(1 + die_size)/2.0 - - // sum is Σi² for i=1..die_size - sum := (die_size*(die_size+1)*(2*die_size+1))/6 - // mean2 is E(X²) - mean2 := float64(sum)/float64(die_size) - variance = mean2-(mean*mean) + // - Var(X) = E(X²)-E(X)² + // - E(X²) = (Σi² for i=1..d) / d + // = ¹/₆d(d+1)(2d+1) / d + // = d(d+1)(2d+1) / (6d) + // ∴ Var(X) = (d(d+1)(2d+1) / (6d)) - ((1+d)/2)² + // = ¹/₁₂(d+1)(d-1) + variance = float64((die_size+1)*(die_size-1))/12.0 mean *= float64(dice) variance *= float64(dice) -- cgit v1.2.3-54-g00ecf