commonMain.korlibs.math.random.RandomExt.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of korma Show documentation
Show all versions of korma Show documentation
Mathematic library for Multiplatform Kotlin 1.3
package korlibs.math.random
import korlibs.math.geom.*
import korlibs.math.interpolation.*
import kotlin.math.pow
import kotlin.random.Random
fun Random.ints(): Sequence = sequence { while (true) yield(nextInt()) }
fun Random.ints(from: Int, until: Int): Sequence = sequence { while (true) yield(nextInt(from, until)) }
fun Random.ints(range: IntRange): Sequence = ints(range.start, range.endInclusive + 1)
fun Random.doubles(): Sequence = sequence { while (true) yield(nextDouble()) }
fun Random.floats(): Sequence = sequence { while (true) yield(nextFloat()) }
fun List.random(random: Random = Random): T {
if (this.isEmpty()) throw IllegalArgumentException("Empty list")
return this[random.nextInt(this.size)]
}
fun List.randomWithWeights(weights: List, random: Random = Random): T = random.weighted(this.zip(weights).toMap())
fun Random.nextDoubleInclusive() = (this.nextInt(0x1000001).toDouble() / 0x1000000.toDouble())
fun Random.nextRatio(): Ratio = nextDouble().toRatio()
fun Random.nextRatioInclusive(): Ratio = nextDoubleInclusive().toRatio()
operator fun Random.get(min: Ratio, max: Ratio): Ratio = Ratio(get(min.valueD, max.valueD))
operator fun Random.get(min: Double, max: Double): Double = min + nextDouble() * (max - min)
operator fun Random.get(min: Float, max: Float): Float = min + nextFloat() * (max - min)
operator fun Random.get(min: Int, max: Int): Int = min + nextInt(max - min)
operator fun Random.get(range: IntRange): Int = range.start + this.nextInt(range.endInclusive - range.start + 1)
operator fun Random.get(range: LongRange): Long = range.start + this.nextLong() % (range.endInclusive - range.start + 1)
operator fun > Random.get(l: T, r: T): T = (this.nextDoubleInclusive()).toRatio().interpolate(l, r)
operator fun Random.get(l: Angle, r: Angle): Angle = this.nextRatioInclusive().interpolateAngleDenormalized(l, r)
operator fun Random.get(list: List): T = list[this[list.indices]]
operator fun Random.get(rectangle: Rectangle): Point = Point(this[rectangle.left, rectangle.right], this[rectangle.top, rectangle.bottom])
fun > T.setToRandom(min: T, max: T, random: Random = Random) { this.setToInterpolated(random.nextDouble().toRatio(), min, max) }
fun Random.weighted(weights: Map): T = shuffledWeighted(weights).first()
fun Random.weighted(weights: RandomWeights): T = shuffledWeighted(weights).first()
fun Random.shuffledWeighted(weights: Map): List = shuffledWeighted(RandomWeights(weights))
fun Random.shuffledWeighted(values: List, weights: List): List = shuffledWeighted(RandomWeights(values, weights))
fun Random.shuffledWeighted(weights: RandomWeights): List {
val randoms = (0 until weights.items.size).map { -(nextDouble().pow(1.0 / weights.normalizedWeights[it])) }
val sortedIndices = (0 until weights.items.size).sortedWith(Comparator { a, b -> randoms[a].compareTo(randoms[b]) })
return sortedIndices.map { weights.items[it] }
}
data class RandomWeights(val weightsMap: Map) {
constructor(vararg pairs: Pair) : this(mapOf(*pairs))
constructor(values: List, weights: List) : this(values.zip(weights).toMap())
val items = weightsMap.keys.toList()
val weights = weightsMap.values.toList()
val normalizedWeights = normalizeWeights(weights)
companion object {
private fun normalizeWeights(weights: List): List {
val min = weights.minOrNull() ?: 0.0
return weights.map { (it + min) + 1 }
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy