-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathestimator.go
96 lines (86 loc) · 2.62 KB
/
estimator.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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
package hyperopt
import (
"gonum.org/v1/gonum/floats"
"math"
)
type estimator struct {
weights []float64
mus []float64
sigmas []float64
}
func buildEstimator(mus []float64, low float64, high float64, s *sampler) estimator {
considerPrior := true
considerMagicClip := false
considerEndpoints := true
priorWeight := s.priorWeight
var sortedWeights []float64
var sortedMus []float64
var sigma []float64
var order []int
var priorPos int
var priorSigma float64
if considerPrior {
priorMu := 0.5 * (low + high)
priorSigma = 1.0 * (high - low)
if len(mus) == 0 {
sortedMus = []float64{priorMu}
sigma = []float64{priorSigma}
priorPos = 0
order = make([]int, 0)
} else {
order = make([]int, len(mus))
floats.Argsort(mus, order)
priorPos = location(choice(mus, order), priorMu)
sortedMus = make([]float64, 0, len(mus)+1)
sortedMus = append(sortedMus, choice(mus, order[:priorPos])...)
sortedMus = append(sortedMus, priorMu)
sortedMus = append(sortedMus, choice(mus, order[priorPos:])...)
}
} else {
order = make([]int, len(mus))
floats.Argsort(mus, order)
sortedMus = choice(mus, order)
}
// we decide the sigma.
if len(mus) > 0 {
lowSortedMusHigh := append(sortedMus, high)
lowSortedMusHigh = append([]float64{low}, lowSortedMusHigh...)
l := len(lowSortedMusHigh)
sigma = make([]float64, l)
for i := 0; i < l-2; i++ {
sigma[i+1] = math.Max(lowSortedMusHigh[i+1]-lowSortedMusHigh[i], lowSortedMusHigh[i+2]-lowSortedMusHigh[i+1])
}
if !considerEndpoints && len(lowSortedMusHigh) > 2 {
sigma[1] = lowSortedMusHigh[2] - lowSortedMusHigh[1]
sigma[l-2] = lowSortedMusHigh[l-2] - lowSortedMusHigh[l-3]
}
sigma = sigma[1 : l-1]
}
// we decide the weights.
unsortedWeights := weights(len(mus))
if considerPrior {
sortedWeights = make([]float64, 0, len(sortedMus))
sortedWeights = append(sortedWeights, choice(unsortedWeights, order[:priorPos])...)
sortedWeights = append(sortedWeights, priorWeight)
sortedWeights = append(sortedWeights, choice(unsortedWeights, order[priorPos:])...)
} else {
sortedWeights = choice(unsortedWeights, order)
}
sumSortedWeights := floats.Sum(sortedWeights)
for i := range sortedWeights {
sortedWeights[i] /= sumSortedWeights
}
// We adjust the range of the 'sigma' according to the 'consider_magic_clip' flag.
maxSigma := 1.0 * (high - low)
var minSigma float64
if considerMagicClip {
minSigma = 1.0 * (high - low) / math.Min(100.0, 1.0+float64(len(sortedMus)))
} else {
minSigma = epsilon
}
clip(sigma, minSigma, maxSigma)
if considerPrior {
sigma[priorPos] = priorSigma
}
return estimator{sortedWeights, sortedMus, sigma}
}