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
package mcorr

import "math/rand"
import "math"

// Bootstrap for one bootstrapping instance.
type Bootstrap struct {
	ID          string
	sampleRatio float64
	collector   *Collector
	isRandom    bool
}

// NewBootstrap creates a new Boot, given id and sample ratio.
// Sample ratio must be a float64 from 0 to 1.
// By default, bootstrap should do random sampling.
func NewBootstrap(id string, sampleRatio float64) *Bootstrap {
	b := Bootstrap{}
	b.ID = id
	if sampleRatio < 0 {
		sampleRatio = 0
	} else if sampleRatio > 1 {
		sampleRatio = 1
	}
	b.sampleRatio = sampleRatio
	b.collector = NewCollector()
	b.isRandom = true
	return &b
}

// SetRandom set random status
func (b *Bootstrap) SetRandom(r bool) {
	b.isRandom = r
}

// Add add one result into the Bootstrap.
func (b *Bootstrap) Add(results CorrResults) {
	if b.isRandom {
		k := poisson(b.sampleRatio)
		for i := 0; i < k; i++ {
			b.collector.Add(results)
		}
	} else {
		b.collector.Add(results)
	}

}

// Results return final results.
func (b *Bootstrap) Results() (results []CorrResult) {
	return b.collector.Results()
}

func poisson(lambda float64) int {
	L := math.Pow(math.E, -lambda)
	k := 0
	p := 1.0
	for p > L {
		k++
		p *= rand.Float64()
	}
	return k - 1
}