-
Notifications
You must be signed in to change notification settings - Fork 1
/
statistics.go
82 lines (66 loc) · 1.45 KB
/
statistics.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
package openskill
import (
"math"
"github.com/samber/lo"
)
const mean float64 = 0.0
const variance float64 = 1.0
// phiMinor
func pdf(x float64) float64 {
standardDeviation := math.Sqrt(variance)
m := standardDeviation * math.Sqrt(2*math.Pi)
e := math.Exp(-math.Pow(x-mean, 2) / (2 * variance))
return e / m
}
// phiMajor
func cdf(x float64) float64 {
standardDeviation := math.Sqrt(variance)
return 0.5 * math.Erfc(-(x-mean)/(standardDeviation*math.Sqrt(2)))
}
// phiMajorInverse
func ppf(x float64) float64 {
standardDeviation := math.Sqrt(variance)
return mean - standardDeviation*math.Sqrt(2)*math.Erfcinv(2*x)
}
func v(x, t float64) float64 {
xt := x - t
denom := cdf(xt)
epsilon := math.Nextafter(1.0, 2.0) - 1.0
if denom < epsilon {
return -xt
}
return pdf(xt) / denom
}
func vt(x, t float64) float64 {
xx := math.Abs(x)
b := cdf((t - xx)) - cdf((-t - xx))
if b < 1e-5 {
if x < 0 {
return -x - t
}
return -x + t
}
a := pdf((-t - xx)) - pdf((t - xx))
return lo.Ternary(x < 0, a, -a) / b
}
func w(x, t float64) float64 {
xt := x - t
denom := cdf(xt)
epsilon := math.Nextafter(1.0, 2.0) - 1.0
if denom < epsilon {
if x < 0 {
return 1
}
return 0
}
return v(x, t) * (v(x, t) + xt)
}
func wt(x, t float64) float64 {
xx := math.Abs(x)
b := cdf((t - xx)) - cdf((-t - xx))
epsilon := math.Nextafter(1.0, 2.0) - 1.0
if b < epsilon {
return 1.0
}
return ((t-xx)*pdf(t-xx)+(t+xx)*pdf(-t-xx))/b + vt(x, t)*vt(x, t)
}