modulepackage
0.0.0-20191001073902-db4fd80633df
Repository: https://github.com/pa-m/randomkit.git
Documentation: pkg.go.dev
# README
randomkit
generate random sequences like numpy ones
Example
var (
state *RKState
a, expected []float64
tol = 1e-8
ok bool
)
// np.random.seed(7)
// np.random.sample(5)
state = NewRandomkitSource(7)
a = make([]float64, 5)
for i := range a {
a[i] = state.Float64()
}
expected = []float64{0.07630829, 0.77991879, 0.43840923, 0.72346518, 0.97798951}
ok = true
for i := range a {
ok = ok && math.Abs(expected[i]-a[i]) < tol
}
if !ok {
fmt.Printf("expected %g got %g", expected, a)
}
expected = []float64{0.07630829, 0.77991879, 0.43840923, 0.72346518, 0.97798951}
ok = true
for i := range a {
ok = ok && math.Abs(expected[i]-a[i]) < tol
}
if !ok {
fmt.Printf("expected %g got %g", expected, a)
}
// test normal dist
// np.random.seed(7)
// np.random.standard_normal(5)
state.Seed(7)
for i := range a {
a[i] = state.NormFloat64()
}
expected = []float64{1.6905257, -0.46593737, 0.03282016, 0.40751628, -0.78892303}
ok = true
for i := range a {
ok = ok && math.Abs(expected[i]-a[i]) < tol
}
if !ok {
fmt.Printf("expected %g got %g", expected, a)
}
// duplicate state have same future
stateCopy := state.Clone()
if state.Uint64() != stateCopy.Uint64() {
fmt.Println("clone failure")
}
warning
RKState is a suitable Source for golang.org/x/exp/rand but using rand.Float64 don't provide numpy-like sequences because rand.Float64 operations differ form RKState.Float64
The only way to get numpy-like sequences is to use RKState.Float64 or RKState.NormFloat64 directly
# Functions
NewRandomkitSource create a new randomkit source.
# Constants
Thomas Wang 32 bits integer hash function */
func rkHash(key uint64) uint64 {
key += ^(key << 15)
key ^= (key >> 10)
key += (key << 3)
key ^= (key >> 6)
key += ^(key << 11)
key ^= (key >> 16)
return key
}
func rkDevfill(buffer interface{}, size int, strong bool) error {
var rfile *os.File
var err error
if strong {
rfile, err = os.Open("/dev/random")
} else {
rfile, err = os.Open("/dev/urandom")
}
if err != nil {
return errNoDev
}
err = binary.Read(rfile, binary.LittleEndian, buffer)
if err == nil {
return nil
}
return errNoDev
}
*/
func rkRandomseed(state *RKState) error {
if rkDevfill(state.key, rkStateLen*4, false) == nil {
// ensures non-zero key
state.key[0] |= 0x80000000
state.pos = rkStateLen
state.gauss = 0
state.hasGauss = false
state.hasBinomial = false
for i := range state.key {
state.key[i] &= 0xffffffff
}
return nil
}
state.Seed(uint64(time.Now().UnixNano()))
return errNoDev
}
*/ Magic Mersenne Twister constants */.
Thomas Wang 32 bits integer hash function */
func rkHash(key uint64) uint64 {
key += ^(key << 15)
key ^= (key >> 10)
key += (key << 3)
key ^= (key >> 6)
key += ^(key << 11)
key ^= (key >> 16)
return key
}
func rkDevfill(buffer interface{}, size int, strong bool) error {
var rfile *os.File
var err error
if strong {
rfile, err = os.Open("/dev/random")
} else {
rfile, err = os.Open("/dev/urandom")
}
if err != nil {
return errNoDev
}
err = binary.Read(rfile, binary.LittleEndian, buffer)
if err == nil {
return nil
}
return errNoDev
}
*/
func rkRandomseed(state *RKState) error {
if rkDevfill(state.key, rkStateLen*4, false) == nil {
// ensures non-zero key
state.key[0] |= 0x80000000
state.pos = rkStateLen
state.gauss = 0
state.hasGauss = false
state.hasBinomial = false
for i := range state.key {
state.key[i] &= 0xffffffff
}
return nil
}
state.Seed(uint64(time.Now().UnixNano()))
return errNoDev
}
*/ Magic Mersenne Twister constants */.
Thomas Wang 32 bits integer hash function */
func rkHash(key uint64) uint64 {
key += ^(key << 15)
key ^= (key >> 10)
key += (key << 3)
key ^= (key >> 6)
key += ^(key << 11)
key ^= (key >> 16)
return key
}
func rkDevfill(buffer interface{}, size int, strong bool) error {
var rfile *os.File
var err error
if strong {
rfile, err = os.Open("/dev/random")
} else {
rfile, err = os.Open("/dev/urandom")
}
if err != nil {
return errNoDev
}
err = binary.Read(rfile, binary.LittleEndian, buffer)
if err == nil {
return nil
}
return errNoDev
}
*/
func rkRandomseed(state *RKState) error {
if rkDevfill(state.key, rkStateLen*4, false) == nil {
// ensures non-zero key
state.key[0] |= 0x80000000
state.pos = rkStateLen
state.gauss = 0
state.hasGauss = false
state.hasBinomial = false
for i := range state.key {
state.key[i] &= 0xffffffff
}
return nil
}
state.Seed(uint64(time.Now().UnixNano()))
return errNoDev
}
*/ Magic Mersenne Twister constants */.
Thomas Wang 32 bits integer hash function */
func rkHash(key uint64) uint64 {
key += ^(key << 15)
key ^= (key >> 10)
key += (key << 3)
key ^= (key >> 6)
key += ^(key << 11)
key ^= (key >> 16)
return key
}
func rkDevfill(buffer interface{}, size int, strong bool) error {
var rfile *os.File
var err error
if strong {
rfile, err = os.Open("/dev/random")
} else {
rfile, err = os.Open("/dev/urandom")
}
if err != nil {
return errNoDev
}
err = binary.Read(rfile, binary.LittleEndian, buffer)
if err == nil {
return nil
}
return errNoDev
}
*/
func rkRandomseed(state *RKState) error {
if rkDevfill(state.key, rkStateLen*4, false) == nil {
// ensures non-zero key
state.key[0] |= 0x80000000
state.pos = rkStateLen
state.gauss = 0
state.hasGauss = false
state.hasBinomial = false
for i := range state.key {
state.key[i] &= 0xffffffff
}
return nil
}
state.Seed(uint64(time.Now().UnixNano()))
return errNoDev
}
*/ Magic Mersenne Twister constants */.
Thomas Wang 32 bits integer hash function */
func rkHash(key uint64) uint64 {
key += ^(key << 15)
key ^= (key >> 10)
key += (key << 3)
key ^= (key >> 6)
key += ^(key << 11)
key ^= (key >> 16)
return key
}
func rkDevfill(buffer interface{}, size int, strong bool) error {
var rfile *os.File
var err error
if strong {
rfile, err = os.Open("/dev/random")
} else {
rfile, err = os.Open("/dev/urandom")
}
if err != nil {
return errNoDev
}
err = binary.Read(rfile, binary.LittleEndian, buffer)
if err == nil {
return nil
}
return errNoDev
}
*/
func rkRandomseed(state *RKState) error {
if rkDevfill(state.key, rkStateLen*4, false) == nil {
// ensures non-zero key
state.key[0] |= 0x80000000
state.pos = rkStateLen
state.gauss = 0
state.hasGauss = false
state.hasBinomial = false
for i := range state.key {
state.key[i] &= 0xffffffff
}
return nil
}
state.Seed(uint64(time.Now().UnixNano()))
return errNoDev
}
*/ Magic Mersenne Twister constants */.
# Structs
RKMathRandSource is a wrapper to adapt RKState to math/rand.
RKState is a random source based on numpy's randomkit it implements "golang.org/x/exp/rand".Source and can be used as "math/rand".Source via AsMathRandSource but RKState Float64 and NormFloat64 methods must be used directly to reproduce original randomkit numpy sequences.