Random generator forks

This commit is contained in:
Alexander Nozik 2019-06-09 10:54:45 +03:00
parent fe05fc5a14
commit 88ee3e5ab7
8 changed files with 54 additions and 12 deletions

View File

@ -1,6 +1,7 @@
Bintray: [ ![Download](https://api.bintray.com/packages/mipt-npm/scientifik/kmath-core/images/download.svg) ](https://bintray.com/mipt-npm/scientifik/kmath-core/_latestVersion)
# KMath
Could be pronounced as `key-math`.
The Kotlin MATHematics library is intended as a Kotlin-based analog to Python's `numpy` library. In contrast to `numpy` and `scipy` it is modular and has a lightweight core.
## Features

View File

@ -83,13 +83,12 @@ class DerivativeStructureField(
/**
* A constructs that creates a derivative structure with required order on-demand
*/
class DiffExpression(val function: DerivativeStructureField.() -> DerivativeStructure) :
Expression<Double> {
class DiffExpression(val function: DerivativeStructureField.() -> DerivativeStructure) : Expression<Double> {
override fun invoke(arguments: Map<String, Double>): Double = DerivativeStructureField(
0,
arguments
)
.run(function).value
).run(function).value
/**
* Get the derivative expression with given orders

View File

@ -12,6 +12,10 @@ inline class CMRandomGeneratorWrapper(val generator: CMRandom) : RandomGenerator
override fun nextLong(): Long = generator.nextLong()
override fun nextBlock(size: Int): ByteArray = ByteArray(size).apply { generator.nextBytes(this) }
override fun fork(): RandomGenerator {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
}
fun CMRandom.asKmathGenerator(): RandomGenerator = CMRandomGeneratorWrapper(this)

View File

@ -1,9 +1,7 @@
package scientifik.kmath.commons.expressions
import org.junit.Test
import scientifik.kmath.commons.expressions.DerivativeStructureField
import scientifik.kmath.commons.expressions.DiffExpression
import scientifik.kmath.commons.expressions.derivative
import scientifik.kmath.expressions.invoke
import kotlin.test.assertEquals
inline fun <R> diff(order: Int, vararg parameters: Pair<String, Double>, block: DerivativeStructureField.() -> R) =

View File

@ -24,6 +24,7 @@ class BufferMatrixContext<T : Any, R : Ring<T>>(
}
}
@Suppress("OVERRIDE_BY_INLINE")
object RealMatrixContext : GenericMatrixContext<Double, RealField> {
override val elementContext = RealField

View File

@ -1,11 +1,17 @@
package scientifik.kmath.prob
import scientifik.kmath.chains.Chain
import scientifik.kmath.chains.map
import kotlin.jvm.JvmName
interface Sampler<T : Any> {
fun sample(generator: RandomGenerator): RandomChain<T>
}
/**
* A distribution of typed objects
*/
interface Distribution<T : Any> {
interface Distribution<T : Any> : Sampler<T> {
/**
* A probability value for given argument [arg].
* For continuous distributions returns PDF
@ -16,8 +22,7 @@ interface Distribution<T : Any> {
* Create a chain of samples from this distribution.
* The chain is not guaranteed to be stateless.
*/
fun sample(generator: RandomGenerator): RandomChain<T>
//TODO add sample bunch generator
override fun sample(generator: RandomGenerator): RandomChain<T>
/**
* An empty companion. Distribution factories should be written as its extensions
@ -31,3 +36,33 @@ interface UnivariateDistribution<T : Comparable<T>> : Distribution<T> {
*/
fun cumulative(arg: T): Double
}
/**
* Compute probability integral in an interval
*/
fun <T : Comparable<T>> UnivariateDistribution<T>.integral(from: T, to: T): Double {
require(to > from)
return cumulative(to) - cumulative(from)
}
/**
* Sample a bunch of values
*/
fun <T : Any> Sampler<T>.sampleBunch(generator: RandomGenerator, size: Int): Chain<List<T>> {
require(size > 1)
return sample(generator).map{chain ->
List(size){chain.next()}
}
}
/**
* Generate a bunch of samples from real distributions
*/
@JvmName("realSampleBunch")
fun Sampler<Double>.sampleBunch(generator: RandomGenerator, size: Int): Chain<DoubleArray> {
require(size > 1)
return sample(generator).map{chain ->
DoubleArray(size){chain.next()}
}
}

View File

@ -9,9 +9,8 @@ import scientifik.kmath.chains.Chain
*/
class RandomChain<out R>(val generator: RandomGenerator, private val gen: suspend RandomGenerator.() -> R) : Chain<R> {
private val atomicValue = atomic<R?>(null)
override fun peek(): R? = atomicValue.value
override suspend fun next(): R = generator.gen().also { atomicValue.lazySet(it) }
override fun fork(): Chain<R> = RandomChain(generator, gen)
override fun fork(): Chain<R> = RandomChain(generator.fork(), gen)
}

View File

@ -9,5 +9,10 @@ interface RandomGenerator {
fun nextLong(): Long
fun nextBlock(size: Int): ByteArray
/**
* Fork the current state of generator
*/
fun fork(): RandomGenerator
companion object
}