-
Notifications
You must be signed in to change notification settings - Fork 2
/
common_test.go
66 lines (56 loc) · 1.05 KB
/
common_test.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
// Copyright (C) 2018. See AUTHORS.
package random
import (
"math"
"math/rand"
"time"
)
func init() { rand.Seed(int64(time.Now().UnixNano())) }
func erfInv(val float64) float64 {
if val == 1 {
return math.Inf(1)
}
if val == -1 {
return math.Inf(-1)
}
// bisect to get the value. somewhere between -100 and 100.
min, max := -100.0, 100.0
for {
guess := (min + max) / 2
guess_val := math.Erf(guess)
if math.Abs(val-guess_val) < 0.0000001 {
return guess
}
switch {
case guess_val > val:
max = guess
case guess_val < val:
min = guess
}
}
}
func probit(val float64) float64 {
if val < 0 {
val = 0
}
if val > 1 {
val = 1
}
return math.Sqrt2 * erfInv(2*val-1)
}
func L1Norm(s Summary, cdf func(float64) float64) float64 {
const samples = 100000
sum := 0.0
for i := 0; i < samples; i++ {
ptile := rand.Float64()
approx := s.Query(ptile)
exact := cdf(ptile)
sum += math.Abs(approx - exact)
}
return sum / samples
}
func Seed(r *Random, dist func() float64) {
for i := 0; i < 100000; i++ {
r.Add(dist())
}
}