Provide PCG XSH RR random implementation
This commit is contained in:
parent
ed8a5edcda
commit
7d00896b46
@ -4,7 +4,7 @@ kotlin.code.style=official
|
|||||||
specifyKotlinAsDependency=false
|
specifyKotlinAsDependency=false
|
||||||
|
|
||||||
projectGroup=ru.dbotthepony.kommons
|
projectGroup=ru.dbotthepony.kommons
|
||||||
projectVersion=3.2.1
|
projectVersion=3.3.0
|
||||||
|
|
||||||
guavaDepVersion=33.0.0
|
guavaDepVersion=33.0.0
|
||||||
gsonDepVersion=2.8.9
|
gsonDepVersion=2.8.9
|
||||||
|
28
src/main/kotlin/ru/dbotthepony/kommons/random/PCG32Random.kt
Normal file
28
src/main/kotlin/ru/dbotthepony/kommons/random/PCG32Random.kt
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
package ru.dbotthepony.kommons.random
|
||||||
|
|
||||||
|
import java.util.random.RandomGenerator
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PCG XSH RR 32-bit (64-bit state) random generator, which has better statistical properties
|
||||||
|
* than plain [LCG64Random] generator
|
||||||
|
*/
|
||||||
|
open class PCG32Random(protected var seed: Long) : RandomGenerator {
|
||||||
|
final override fun nextInt(): Int {
|
||||||
|
var x = this.seed
|
||||||
|
this.seed = LCG64Random.MULTIPLIER * this.seed + LCG64Random.INCREMENT
|
||||||
|
|
||||||
|
val rot = x.ushr(59) and MASK
|
||||||
|
x = x.xor(x.ushr(18))
|
||||||
|
return x.ushr(27).toInt().rotateLeft(rot.toInt())
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun nextLong(): Long {
|
||||||
|
val a = nextInt().toLong()
|
||||||
|
val b = nextInt().toLong() and 0xFFFFFFFFL
|
||||||
|
return a.shl(32) or b
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val MASK = (1L shl 5) - 1L
|
||||||
|
}
|
||||||
|
}
|
@ -2,6 +2,11 @@ package ru.dbotthepony.kommons.random
|
|||||||
|
|
||||||
import java.util.random.RandomGenerator
|
import java.util.random.RandomGenerator
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Excellent PRNG with expected period of 2^255 - 1, a slightly faster version than [Xoshiro256StarStarRandom].
|
||||||
|
*
|
||||||
|
* Where [Xoshiro256PlusPlusRandom] is used consider using [Xoshiro256StarStarRandom] instead.
|
||||||
|
*/
|
||||||
open class Xoshiro256PlusPlusRandom protected constructor(
|
open class Xoshiro256PlusPlusRandom protected constructor(
|
||||||
protected var s0: Long,
|
protected var s0: Long,
|
||||||
protected var s1: Long,
|
protected var s1: Long,
|
||||||
@ -25,14 +30,14 @@ open class Xoshiro256PlusPlusRandom protected constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
constructor(seed: Long) : this(1L, 0L, 0L, 0L, null) {
|
constructor(seed: Long) : this(1L, 0L, 0L, 0L, null) {
|
||||||
val rng = LCG64Random(seed)
|
val rng = PCG32Random(seed)
|
||||||
s0 = rng.nextLong()
|
s0 = rng.nextLong()
|
||||||
s1 = rng.nextLong()
|
s1 = rng.nextLong()
|
||||||
s2 = rng.nextLong()
|
s2 = rng.nextLong()
|
||||||
s3 = rng.nextLong()
|
s3 = rng.nextLong()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun nextLong(): Long {
|
final override fun nextLong(): Long {
|
||||||
val result = (s0 + s3).rotateLeft(23) + s1
|
val result = (s0 + s3).rotateLeft(23) + s1
|
||||||
val t = s1.shl(17)
|
val t = s1.shl(17)
|
||||||
s2 = s2.xor(s0)
|
s2 = s2.xor(s0)
|
||||||
|
@ -2,6 +2,11 @@ package ru.dbotthepony.kommons.random
|
|||||||
|
|
||||||
import java.util.random.RandomGenerator
|
import java.util.random.RandomGenerator
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Excellent PRNG with expected period of 2^255 - 1, which is de-facto standard PRNG
|
||||||
|
* used in many applications and programming languages (where not restricted
|
||||||
|
* by backward compatibility)
|
||||||
|
*/
|
||||||
open class Xoshiro256StarStarRandom protected constructor(
|
open class Xoshiro256StarStarRandom protected constructor(
|
||||||
protected var s0: Long,
|
protected var s0: Long,
|
||||||
protected var s1: Long,
|
protected var s1: Long,
|
||||||
@ -25,14 +30,14 @@ open class Xoshiro256StarStarRandom protected constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
constructor(seed: Long) : this(1L, 0L, 0L, 0L, null) {
|
constructor(seed: Long) : this(1L, 0L, 0L, 0L, null) {
|
||||||
val rng = LCG64Random(seed)
|
val rng = PCG32Random(seed)
|
||||||
s0 = rng.nextLong()
|
s0 = rng.nextLong()
|
||||||
s1 = rng.nextLong()
|
s1 = rng.nextLong()
|
||||||
s2 = rng.nextLong()
|
s2 = rng.nextLong()
|
||||||
s3 = rng.nextLong()
|
s3 = rng.nextLong()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun nextLong(): Long {
|
final override fun nextLong(): Long {
|
||||||
val result = (s1 * 5).rotateLeft(7) * 9
|
val result = (s1 * 5).rotateLeft(7) * 9
|
||||||
val t = s1.shl(17)
|
val t = s1.shl(17)
|
||||||
s2 = s2.xor(s0)
|
s2 = s2.xor(s0)
|
||||||
|
Loading…
Reference in New Issue
Block a user