Provide Xoshiro256**, Xoshiro256++ and LCG64 PRNGs
This commit is contained in:
parent
80708868d5
commit
5bd1717636
@ -4,7 +4,7 @@ kotlin.code.style=official
|
|||||||
specifyKotlinAsDependency=false
|
specifyKotlinAsDependency=false
|
||||||
|
|
||||||
projectGroup=ru.dbotthepony.kommons
|
projectGroup=ru.dbotthepony.kommons
|
||||||
projectVersion=3.1.3
|
projectVersion=3.2.0
|
||||||
|
|
||||||
guavaDepVersion=33.0.0
|
guavaDepVersion=33.0.0
|
||||||
gsonDepVersion=2.8.9
|
gsonDepVersion=2.8.9
|
||||||
|
27
src/main/kotlin/ru/dbotthepony/kommons/random/LCG64Random.kt
Normal file
27
src/main/kotlin/ru/dbotthepony/kommons/random/LCG64Random.kt
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
package ru.dbotthepony.kommons.random
|
||||||
|
|
||||||
|
import java.util.random.RandomGenerator
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Classical LCG PRNG, utilizing [MULTIPLIER] and [INCREMENT] as constants.
|
||||||
|
*
|
||||||
|
* Internal state is presented as 64-bit integer, and high-order bits of internal state are
|
||||||
|
* used to generate numbers.
|
||||||
|
*/
|
||||||
|
open class LCG64Random(private var seed: Long) : RandomGenerator {
|
||||||
|
final override fun nextLong(): Long {
|
||||||
|
val a = nextInt().toLong()
|
||||||
|
val b = nextInt().toLong() and 0xFFFFFFFFL
|
||||||
|
return a.shl(32) or b
|
||||||
|
}
|
||||||
|
|
||||||
|
final override fun nextInt(): Int {
|
||||||
|
this.seed = MULTIPLIER * this.seed + INCREMENT
|
||||||
|
return this.seed.ushr(32).toInt()
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val MULTIPLIER = 6364136223846793005
|
||||||
|
const val INCREMENT = 1442695040888963407
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,58 @@
|
|||||||
|
package ru.dbotthepony.kommons.random
|
||||||
|
|
||||||
|
import java.util.random.RandomGenerator
|
||||||
|
|
||||||
|
open class Xoshiro256PlusPlusRandom protected constructor(
|
||||||
|
private var s0: Long,
|
||||||
|
private var s1: Long,
|
||||||
|
private var s2: Long,
|
||||||
|
private var s3: Long,
|
||||||
|
mark: Nothing?
|
||||||
|
) : RandomGenerator {
|
||||||
|
init {
|
||||||
|
if (s0 or s1 or s2 or s3 == 0L) {
|
||||||
|
s0 = 0x73CF3D83FFF44FF3L
|
||||||
|
s1 = 0x6412312B70F3CD37L
|
||||||
|
s2 = -0X6BB4C4E1327BFDCFL
|
||||||
|
s3 = -0X4BE0F5BB5F3F5240L
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(s0: Long, s1: Long, s2: Long, s3: Long) : this(s0, s1, s2, s3, null) {
|
||||||
|
// discard some values so generator can get going if provided seed was "weak"
|
||||||
|
for (i in 0 until 32)
|
||||||
|
nextLong()
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(seed: Long) : this(1L, 0L, 0L, 0L, null) {
|
||||||
|
val rng = LCG64Random(seed)
|
||||||
|
s0 = rng.nextLong()
|
||||||
|
s1 = rng.nextLong()
|
||||||
|
s2 = rng.nextLong()
|
||||||
|
s3 = rng.nextLong()
|
||||||
|
}
|
||||||
|
|
||||||
|
final override fun nextLong(): Long {
|
||||||
|
val result = (s0 + s3).rotateLeft(23) + s1
|
||||||
|
val t = s1.shl(17)
|
||||||
|
s2 = s2.xor(s0)
|
||||||
|
s3 = s3.xor(s1)
|
||||||
|
s1 = s1.xor(s2)
|
||||||
|
s0 = s0.xor(s3)
|
||||||
|
s2 = s2.xor(t)
|
||||||
|
s3 = s3.rotateLeft(45)
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
@JvmStatic
|
||||||
|
fun raw(
|
||||||
|
s0: Long,
|
||||||
|
s1: Long,
|
||||||
|
s2: Long,
|
||||||
|
s3: Long,
|
||||||
|
): Xoshiro256PlusPlusRandom {
|
||||||
|
return Xoshiro256PlusPlusRandom(s0, s1, s2, s3, null)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,58 @@
|
|||||||
|
package ru.dbotthepony.kommons.random
|
||||||
|
|
||||||
|
import java.util.random.RandomGenerator
|
||||||
|
|
||||||
|
open class Xoshiro256StarStarRandom protected constructor(
|
||||||
|
private var s0: Long,
|
||||||
|
private var s1: Long,
|
||||||
|
private var s2: Long,
|
||||||
|
private var s3: Long,
|
||||||
|
mark: Nothing?
|
||||||
|
) : RandomGenerator {
|
||||||
|
init {
|
||||||
|
if (s0 or s1 or s2 or s3 == 0L) {
|
||||||
|
s0 = 0x73CF3D83FFF44FF3L
|
||||||
|
s1 = 0x6412312B70F3CD37L
|
||||||
|
s2 = -0X6BB4C4E1327BFDCFL
|
||||||
|
s3 = -0X4BE0F5BB5F3F5240L
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(s0: Long, s1: Long, s2: Long, s3: Long) : this(s0, s1, s2, s3, null) {
|
||||||
|
// discard some values so generator can get going if provided seed was "weak"
|
||||||
|
for (i in 0 until 32)
|
||||||
|
nextLong()
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(seed: Long) : this(1L, 0L, 0L, 0L, null) {
|
||||||
|
val rng = LCG64Random(seed)
|
||||||
|
s0 = rng.nextLong()
|
||||||
|
s1 = rng.nextLong()
|
||||||
|
s2 = rng.nextLong()
|
||||||
|
s3 = rng.nextLong()
|
||||||
|
}
|
||||||
|
|
||||||
|
final override fun nextLong(): Long {
|
||||||
|
val result = (s1 * 5).rotateLeft(7) * 9
|
||||||
|
val t = s1.shl(17)
|
||||||
|
s2 = s2.xor(s0)
|
||||||
|
s3 = s3.xor(s1)
|
||||||
|
s1 = s1.xor(s2)
|
||||||
|
s0 = s0.xor(s3)
|
||||||
|
s2 = s2.xor(t)
|
||||||
|
s3 = s3.rotateLeft(45)
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
@JvmStatic
|
||||||
|
fun raw(
|
||||||
|
s0: Long,
|
||||||
|
s1: Long,
|
||||||
|
s2: Long,
|
||||||
|
s3: Long,
|
||||||
|
): Xoshiro256StarStarRandom {
|
||||||
|
return Xoshiro256StarStarRandom(s0, s1, s2, s3, null)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user