-
Notifications
You must be signed in to change notification settings - Fork 70
/
rand.go
250 lines (212 loc) · 7.15 KB
/
rand.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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
// Copyright (c) 2023, Cogent Core. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package randx
//go:generate core generate -add-types
import "math/rand"
// Rand provides an interface with most of the standard
// rand.Rand methods, to support the use of either the
// global rand generator or a separate Rand source.
type Rand interface {
// Seed uses the provided seed value to initialize the generator to a deterministic state.
// Seed should not be called concurrently with any other Rand method.
Seed(seed int64)
// Int63 returns a non-negative pseudo-random 63-bit integer as an int64.
Int63() int64
// Uint32 returns a pseudo-random 32-bit value as a uint32.
Uint32() uint32
// Uint64 returns a pseudo-random 64-bit value as a uint64.
Uint64() uint64
// Int31 returns a non-negative pseudo-random 31-bit integer as an int32.
Int31() int32
// Int returns a non-negative pseudo-random int.
Int() int
// Int63n returns, as an int64, a non-negative pseudo-random number in the half-open interval [0,n).
// It panics if n <= 0.
Int63n(n int64) int64
// Int31n returns, as an int32, a non-negative pseudo-random number in the half-open interval [0,n).
// It panics if n <= 0.
Int31n(n int32) int32
// Intn returns, as an int, a non-negative pseudo-random number in the half-open interval [0,n).
// It panics if n <= 0.
Intn(n int) int
// Float64 returns, as a float64, a pseudo-random number in the half-open interval [0.0,1.0).
Float64() float64
// Float32 returns, as a float32, a pseudo-random number in the half-open interval [0.0,1.0).
Float32() float32
// NormFloat64 returns a normally distributed float64 in the range
// [-math.MaxFloat64, +math.MaxFloat64] with
// standard normal distribution (mean = 0, stddev = 1)
// from the default Source.
// To produce a different normal distribution, callers can
// adjust the output using:
//
// sample = NormFloat64() * desiredStdDev + desiredMean
NormFloat64() float64
// ExpFloat64 returns an exponentially distributed float64 in the range
// (0, +math.MaxFloat64] with an exponential distribution whose rate parameter
// (lambda) is 1 and whose mean is 1/lambda (1) from the default Source.
// To produce a distribution with a different rate parameter,
// callers can adjust the output using:
//
// sample = ExpFloat64() / desiredRateParameter
ExpFloat64() float64
// Perm returns, as a slice of n ints, a pseudo-random permutation of the integers
// in the half-open interval [0,n).
Perm(n int) []int
// Shuffle pseudo-randomizes the order of elements.
// n is the number of elements. Shuffle panics if n < 0.
// swap swaps the elements with indexes i and j.
Shuffle(n int, swap func(i, j int))
}
// SysRand supports the system random number generator
// for either a separate rand.Rand source, or, if that
// is nil, the global rand stream.
type SysRand struct {
// if non-nil, use this random number source instead of the global default one
Rand *rand.Rand `view:"-"`
}
// NewGlobalRand returns a new SysRand that implements the
// randx.Rand interface, with the system global rand source.
func NewGlobalRand() *SysRand {
r := &SysRand{}
return r
}
// NewSysRand returns a new SysRand with a new
// rand.Rand random source with given initial seed.
func NewSysRand(seed int64) *SysRand {
r := &SysRand{}
r.NewRand(seed)
return r
}
// NewRand sets Rand to a new rand.Rand source using given seed.
func (r *SysRand) NewRand(seed int64) {
r.Rand = rand.New(rand.NewSource(seed))
}
// Seed uses the provided seed value to initialize the generator to a deterministic state.
// Seed should not be called concurrently with any other Rand method.
func (r *SysRand) Seed(seed int64) {
if r.Rand == nil {
rand.Seed(seed)
return
}
r.Rand.Seed(seed)
}
// Int63 returns a non-negative pseudo-random 63-bit integer as an int64.
func (r *SysRand) Int63() int64 {
if r.Rand == nil {
return rand.Int63()
}
return r.Rand.Int63()
}
// Uint32 returns a pseudo-random 32-bit value as a uint32.
func (r *SysRand) Uint32() uint32 {
if r.Rand == nil {
return rand.Uint32()
}
return r.Rand.Uint32()
}
// Uint64 returns a pseudo-random 64-bit value as a uint64.
func (r *SysRand) Uint64() uint64 {
if r.Rand == nil {
return rand.Uint64()
}
return r.Rand.Uint64()
}
// Int31 returns a non-negative pseudo-random 31-bit integer as an int32.
func (r *SysRand) Int31() int32 {
if r.Rand == nil {
return rand.Int31()
}
return r.Rand.Int31()
}
// Int returns a non-negative pseudo-random int.
func (r *SysRand) Int() int {
if r.Rand == nil {
return rand.Int()
}
return r.Rand.Int()
}
// Int63n returns, as an int64, a non-negative pseudo-random number in the half-open interval [0,n).
// It panics if n <= 0.
func (r *SysRand) Int63n(n int64) int64 {
if r.Rand == nil {
return rand.Int63n(n)
}
return r.Rand.Int63n(n)
}
// Int31n returns, as an int32, a non-negative pseudo-random number in the half-open interval [0,n).
// It panics if n <= 0.
func (r *SysRand) Int31n(n int32) int32 {
if r.Rand == nil {
return rand.Int31n(n)
}
return r.Rand.Int31n(n)
}
// Intn returns, as an int, a non-negative pseudo-random number in the half-open interval [0,n).
// It panics if n <= 0.
func (r *SysRand) Intn(n int) int {
if r.Rand == nil {
return rand.Intn(n)
}
return r.Rand.Intn(n)
}
// Float64 returns, as a float64, a pseudo-random number in the half-open interval [0.0,1.0).
func (r *SysRand) Float64() float64 {
if r.Rand == nil {
return rand.Float64()
}
return r.Rand.Float64()
}
// Float32 returns, as a float32, a pseudo-random number in the half-open interval [0.0,1.0).
func (r *SysRand) Float32() float32 {
if r.Rand == nil {
return rand.Float32()
}
return r.Rand.Float32()
}
// NormFloat64 returns a normally distributed float64 in the range
// [-math.MaxFloat64, +math.MaxFloat64] with
// standard normal distribution (mean = 0, stddev = 1)
// from the default Source.
// To produce a different normal distribution, callers can
// adjust the output using:
//
// sample = NormFloat64() * desiredStdDev + desiredMean
func (r *SysRand) NormFloat64() float64 {
if r.Rand == nil {
return rand.NormFloat64()
}
return r.Rand.NormFloat64()
}
// ExpFloat64 returns an exponentially distributed float64 in the range
// (0, +math.MaxFloat64] with an exponential distribution whose rate parameter
// (lambda) is 1 and whose mean is 1/lambda (1) from the default Source.
// To produce a distribution with a different rate parameter,
// callers can adjust the output using:
//
// sample = ExpFloat64() / desiredRateParameter
func (r *SysRand) ExpFloat64() float64 {
if r.Rand == nil {
return rand.ExpFloat64()
}
return r.Rand.ExpFloat64()
}
// Perm returns, as a slice of n ints, a pseudo-random permutation of the integers
// in the half-open interval [0,n).
func (r *SysRand) Perm(n int) []int {
if r.Rand == nil {
return rand.Perm(n)
}
return r.Rand.Perm(n)
}
// Shuffle pseudo-randomizes the order of elements.
// n is the number of elements. Shuffle panics if n < 0.
// swap swaps the elements with indexes i and j.
func (r *SysRand) Shuffle(n int, swap func(i, j int)) {
if r.Rand == nil {
rand.Shuffle(n, swap)
return
}
r.Rand.Shuffle(n, swap)
}