This repository was archived by the owner on Sep 12, 2019. It is now read-only.
forked from leesper/go_rng
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathuniform.go
More file actions
131 lines (111 loc) · 3.53 KB
/
uniform.go
File metadata and controls
131 lines (111 loc) · 3.53 KB
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
// Package rng implements a series of pseudo-random number generator
// based on a variety of common probability distributions
// Author: Leesper
// Email: pascal7718@gmail.com 394683518@qq.com
package rng
import (
"fmt"
"math"
"math/rand"
)
// UniformGenerator is a random number generator for uniform distribution.
// The zero value is invalid, use NewUniformGenerator to create a generator
type UniformGenerator struct {
rd *rand.Rand
}
// NewUniformGenerator returns a uniform-distribution generator
// it is recommended using time.Now().UnixNano() as the seed, for example:
// urng := rng.NewUniformGenerator(time.Now().UnixNano())
func NewUniformGenerator(seed int64) *UniformGenerator {
return &UniformGenerator{ rand.New(rand.NewSource(seed)) }
}
// Int32 returns a random uint32
func (ung UniformGenerator) Int32() int32 {
return ung.rd.Int31()
}
// Int64 returns a random uint64
func (ung UniformGenerator) Int64() int64 {
return ung.rd.Int63()
}
// Int32n returns a random uint32 in [0, n)
func (ung UniformGenerator) Int32n(n int32) int32 {
if n <= 0 {
panic(fmt.Sprintf("Illegal parameter n: %d", n))
}
return ung.rd.Int31n(n)
}
// Int64n returns a random uint64 in [0, n)
func (ung UniformGenerator) Int64n(n int64) int64 {
if n <= 0 {
panic(fmt.Sprintf("Illegal parameter n: %d", n))
}
return ung.rd.Int63n(n)
}
// Int32Range returns a random uint32 in [a, b)
func (ung UniformGenerator) Int32Range(a, b int32) int32 {
if b <= a {
panic(fmt.Sprintf("Illegal parameter a, b: %d, %d", a, b))
}
if b - a > math.MaxInt32 {
panic(fmt.Sprintf("Illegal parameter a, b: %d, %d", a, b))
}
return a + ung.Int32n(b - a)
}
// Int64Range returns a random uint64 in [a, b)
func (ung UniformGenerator) Int64Range(a, b int64) int64 {
if b <= a {
panic(fmt.Sprintf("Illegal parameter a, b: %d, %d", a, b))
}
if b - a > math.MaxInt32 {
panic(fmt.Sprintf("Illegal parameter a, b: %d, %d", a, b))
}
return a + ung.Int64n(b - a)
}
// Float32 returns a random float32 in [0.0, 1.0)
func (ung UniformGenerator) Float32() float32 {
return ung.rd.Float32()
}
// Float64 returns a random float64 in [0.0, 1.0)
func (ung UniformGenerator) Float64() float64 {
return ung.rd.Float64()
}
// Float32Range returns a random float32 in [a, b)
func (ung UniformGenerator) Float32Range(a, b float32) float32 {
if !( a < b ) {
panic(fmt.Sprintf("Invalid range: %.2f ~ %.2f", a, b))
}
return a + ung.Float32() * (b - a)
}
// Float32Range returns a random float32 in [a, b)
func (ung UniformGenerator) Float64Range(a, b float64) float64 {
if !( a < b ) {
panic(fmt.Sprintf("Invalid range: %.2f ~ %.2f", a, b))
}
return a + ung.Float64() * (b - a)
}
// Float32n returns a random float32 in [0.0, n)
func (ung UniformGenerator) Float32n(n float32) float32 {
return ung.Float32Range(0.0, n)
}
// Float64n returns a random float64 in [0.0, n)
func (ung UniformGenerator) Float64n(n float64) float64 {
return ung.Float64Range(0.0, n)
}
// Shuffle rearrange the elements of an array in random order
func (ung UniformGenerator) Shuffle(arr []interface{}) {
N := len(arr)
for i := range arr {
r := int32(i) + ung.Int32n( int32(N - i) )
arr[i], arr[r] = arr[r], arr[i]
}
}
// Shuffle rearrange the elements of the subarray[low..high] in random order
func (ung UniformGenerator) ShuffleRange(arr []interface{}, low, high int) {
if low < 0 || low > high || high >= len(arr) {
panic(fmt.Sprintf("Illegal subarray range %d ~ %d", low, high))
}
for i := low; i <= high; i++ {
r := int32(i) + ung.Int32n( int32(high - i + 1) )
arr[i], arr[r] = arr[r], arr[i]
}
}