-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsobol.go
56 lines (48 loc) · 1.23 KB
/
sobol.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
package sequence
// Sobol represents a Sobol sequence. The maximal number of dimensions is 21201,
// and the maximal number of points is 2^32.
//
// https://en.wikipedia.org/wiki/Sobol_sequence
type Sobol struct {
dimensions uint
offset uint
cursor []uint32
}
// NewSobol returns a new Sobol sequence.
func NewSobol(dimensions uint, scramble int64) *Sobol {
return &Sobol{
dimensions: dimensions,
cursor: newCursor(dimensions, scramble),
}
}
// Next advances the sequence and returns the traversed points.
func (self *Sobol) Next(points uint) []float64 {
const (
bits = 32
)
dimensions, offset, cursor := self.dimensions, self.offset, self.cursor
data := make([]float64, points*dimensions)
for i := uint(0); i < points; i++ {
k := uint(0)
for j := offset + i; j&1 != 0; j >>= 1 {
k++
}
for j := uint(0); j < dimensions; j++ {
data[i*dimensions+j] = float64(cursor[j]) / (1 << bits)
cursor[j] ^= sobolData[j*bits+k]
}
}
self.offset += points
return data
}
func newCursor(dimensions uint, scramble int64) []uint32 {
cursor := make([]uint32, dimensions)
for i := range cursor {
if i%2 == 0 {
cursor[i] = uint32(scramble)
} else {
cursor[i] = uint32(scramble >> 32)
}
}
return cursor
}