Dev #280
@ -106,6 +106,7 @@ kotlin.sourceSets.all {
|
||||
with(languageSettings) {
|
||||
useExperimentalAnnotation("kotlin.contracts.ExperimentalContracts")
|
||||
useExperimentalAnnotation("kotlin.ExperimentalUnsignedTypes")
|
||||
useExperimentalAnnotation("space.kscience.kmath.misc.UnstableKMathAPI")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,20 +1,22 @@
|
||||
package kscience.kmath.commons.fit
|
||||
package space.kscience.kmath.commons.fit
|
||||
|
||||
import kotlinx.html.br
|
||||
import kotlinx.html.h3
|
||||
import kscience.kmath.commons.optimization.chiSquared
|
||||
import kscience.kmath.commons.optimization.minimize
|
||||
import kscience.kmath.expressions.symbol
|
||||
import kscience.kmath.real.RealVector
|
||||
import kscience.kmath.real.map
|
||||
import kscience.kmath.real.step
|
||||
import kscience.kmath.stat.*
|
||||
import kscience.kmath.stat.distributions.NormalDistribution
|
||||
import kscience.kmath.structures.asIterable
|
||||
import kscience.kmath.structures.toList
|
||||
import kscience.plotly.*
|
||||
import kscience.plotly.models.ScatterMode
|
||||
import kscience.plotly.models.TraceValues
|
||||
import space.kscience.kmath.commons.optimization.chiSquared
|
||||
import space.kscience.kmath.commons.optimization.minimize
|
||||
import space.kscience.kmath.misc.symbol
|
||||
import space.kscience.kmath.optimization.FunctionOptimization
|
||||
import space.kscience.kmath.optimization.OptimizationResult
|
||||
import space.kscience.kmath.real.DoubleVector
|
||||
import space.kscience.kmath.real.map
|
||||
import space.kscience.kmath.real.step
|
||||
import space.kscience.kmath.stat.RandomGenerator
|
||||
import space.kscience.kmath.stat.distributions.NormalDistribution
|
||||
import space.kscience.kmath.structures.asIterable
|
||||
import space.kscience.kmath.structures.toList
|
||||
import kotlin.math.pow
|
||||
import kotlin.math.sqrt
|
||||
|
||||
@ -27,7 +29,7 @@ private val c by symbol
|
||||
/**
|
||||
* Shortcut to use buffers in plotly
|
||||
*/
|
||||
operator fun TraceValues.invoke(vector: RealVector) {
|
||||
operator fun TraceValues.invoke(vector: DoubleVector) {
|
||||
numbers = vector.asIterable()
|
||||
}
|
||||
|
||||
@ -58,12 +60,12 @@ suspend fun main() {
|
||||
val yErr = y.map { sqrt(it) }//RealVector.same(x.size, sigma)
|
||||
|
||||
// compute differentiable chi^2 sum for given model ax^2 + bx + c
|
||||
val chi2 = Fitting.chiSquared(x, y, yErr) { x1 ->
|
||||
val chi2 = FunctionOptimization.chiSquared(x, y, yErr) { x1 ->
|
||||
//bind variables to autodiff context
|
||||
val a = bind(a)
|
||||
val b = bind(b)
|
||||
//Include default value for c if it is not provided as a parameter
|
||||
val c = bindOrNull(c) ?: one
|
||||
val c = bindSymbolOrNull(c) ?: one
|
||||
a * x1.pow(2) + b * x1 + c
|
||||
}
|
||||
|
||||
@ -90,10 +92,10 @@ suspend fun main() {
|
||||
}
|
||||
}
|
||||
br()
|
||||
h3{
|
||||
h3 {
|
||||
+"Fit result: $result"
|
||||
}
|
||||
h3{
|
||||
h3 {
|
||||
+"Chi2/dof = ${result.value / (x.size - 3)}"
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
package kscience.kmath.stat
|
||||
package space.kscience.kmath.stat
|
||||
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kscience.kmath.stat.samplers.GaussianSampler
|
||||
import space.kscience.kmath.stat.samplers.GaussianSampler
|
||||
import org.apache.commons.rng.simple.RandomSource
|
||||
import java.time.Duration
|
||||
import java.time.Instant
|
||||
|
@ -1,9 +1,9 @@
|
||||
package kscience.kmath.stat
|
||||
package space.kscience.kmath.stat
|
||||
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kscience.kmath.chains.Chain
|
||||
import kscience.kmath.chains.collectWithState
|
||||
import kscience.kmath.stat.distributions.NormalDistribution
|
||||
import space.kscience.kmath.chains.Chain
|
||||
import space.kscience.kmath.chains.collectWithState
|
||||
import space.kscience.kmath.stat.distributions.NormalDistribution
|
||||
|
||||
/**
|
||||
* The state of distribution averager.
|
||||
|
@ -1,13 +1,13 @@
|
||||
package kscience.kmath.commons.optimization
|
||||
package space.kscience.kmath.commons.optimization
|
||||
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kscience.kmath.commons.expressions.DerivativeStructureExpression
|
||||
import kscience.kmath.expressions.symbol
|
||||
import kscience.kmath.stat.Fitting
|
||||
import kscience.kmath.stat.RandomGenerator
|
||||
import kscience.kmath.stat.distributions.NormalDistribution
|
||||
import org.junit.jupiter.api.Test
|
||||
import space.kscience.kmath.commons.expressions.DerivativeStructureExpression
|
||||
import space.kscience.kmath.misc.symbol
|
||||
import space.kscience.kmath.optimization.FunctionOptimization
|
||||
import space.kscience.kmath.stat.RandomGenerator
|
||||
import space.kscience.kmath.stat.distributions.NormalDistribution
|
||||
import kotlin.math.pow
|
||||
import kotlin.test.Test
|
||||
|
||||
internal class OptimizeTest {
|
||||
val x by symbol
|
||||
@ -34,6 +34,7 @@ internal class OptimizeTest {
|
||||
simplexSteps(x to 2.0, y to 0.5)
|
||||
//this sets simplex optimizer
|
||||
}
|
||||
|
||||
println(result.point)
|
||||
println(result.value)
|
||||
}
|
||||
@ -43,15 +44,20 @@ internal class OptimizeTest {
|
||||
val a by symbol
|
||||
val b by symbol
|
||||
val c by symbol
|
||||
|
||||
val sigma = 1.0
|
||||
val generator = NormalDistribution(0.0, sigma)
|
||||
val chain = generator.sample(RandomGenerator.default(112667))
|
||||
val x = (1..100).map(Int::toDouble)
|
||||
val y = x.map { it.pow(2) + it + 1.0 + chain.next() }
|
||||
|
||||
val y = x.map {
|
||||
it.pow(2) + it + 1 + chain.next()
|
||||
}
|
||||
|
||||
val yErr = List(x.size) { sigma }
|
||||
|
||||
val chi2 = Fitting.chiSquared(x, y, yErr) { x1 ->
|
||||
val cWithDefault = bindOrNull(c) ?: one
|
||||
val chi2 = FunctionOptimization.chiSquared(x, y, yErr) { x1 ->
|
||||
val cWithDefault = bindSymbolOrNull(c) ?: one
|
||||
bind(a) * x1.pow(2) + bind(b) * x1 + cWithDefault
|
||||
}
|
||||
|
||||
@ -59,5 +65,4 @@ internal class OptimizeTest {
|
||||
println(result)
|
||||
println("Chi2/dof = ${result.value / (x.size - 3)}")
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
package kscience.kmath.structures
|
||||
package space.kscience.kmath.structures
|
||||
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
@ -17,11 +17,13 @@ public typealias BufferFactory<T> = (Int, (Int) -> T) -> Buffer<T>
|
||||
public typealias MutableBufferFactory<T> = (Int, (Int) -> T) -> MutableBuffer<T>
|
||||
|
||||
/**
|
||||
* A generic immutable random-access structure for both primitives and objects.
|
||||
* A generic read-only random-access structure for both primitives and objects.
|
||||
*
|
||||
* [Buffer] is in general identity-free. [Buffer.contentEquals] should be used for content equality checks.
|
||||
*
|
||||
* @param T the type of elements contained in the buffer.
|
||||
*/
|
||||
public interface Buffer<T> {
|
||||
public interface Buffer<out T> {
|
||||
/**
|
||||
* The size of this buffer.
|
||||
*/
|
||||
@ -37,49 +39,45 @@ public interface Buffer<T> {
|
||||
*/
|
||||
public operator fun iterator(): Iterator<T>
|
||||
|
||||
/**
|
||||
* Checks content equality with another buffer.
|
||||
*/
|
||||
public fun contentEquals(other: Buffer<*>): Boolean =
|
||||
asSequence().mapIndexed { index, value -> value == other[index] }.all { it }
|
||||
|
||||
public companion object {
|
||||
/**
|
||||
* Creates a [RealBuffer] with the specified [size], where each element is calculated by calling the specified
|
||||
* [initializer] function.
|
||||
* Check the element-by-element match of content of two buffers.
|
||||
*/
|
||||
public inline fun real(size: Int, initializer: (Int) -> Double): RealBuffer =
|
||||
RealBuffer(size) { initializer(it) }
|
||||
public fun <T: Any> contentEquals(first: Buffer<T>, second: Buffer<T>): Boolean{
|
||||
if (first.size != second.size) return false
|
||||
for (i in first.indices) {
|
||||
if (first[i] != second[i]) return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a [ListBuffer] of given type [T] with given [size]. Each element is calculated by calling the
|
||||
* specified [initializer] function.
|
||||
*/
|
||||
public inline fun <T> boxing(size: Int, initializer: (Int) -> T): Buffer<T> =
|
||||
ListBuffer(List(size, initializer))
|
||||
|
||||
// TODO add resolution based on Annotation or companion resolution
|
||||
List(size, initializer).asBuffer()
|
||||
|
||||
/**
|
||||
* Creates a [Buffer] of given [type]. If the type is primitive, specialized buffers are used ([IntBuffer],
|
||||
* [RealBuffer], etc.), [ListBuffer] is returned otherwise.
|
||||
* [DoubleBuffer], etc.), [ListBuffer] is returned otherwise.
|
||||
*
|
||||
* The [size] is specified, and each element is calculated by calling the specified [initializer] function.
|
||||
*/
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
public inline fun <T : Any> auto(type: KClass<T>, size: Int, initializer: (Int) -> T): Buffer<T> =
|
||||
when (type) {
|
||||
Double::class -> real(size) { initializer(it) as Double } as Buffer<T>
|
||||
Short::class -> ShortBuffer(size) { initializer(it) as Short } as Buffer<T>
|
||||
Int::class -> IntBuffer(size) { initializer(it) as Int } as Buffer<T>
|
||||
Long::class -> LongBuffer(size) { initializer(it) as Long } as Buffer<T>
|
||||
Float::class -> FloatBuffer(size) { initializer(it) as Float } as Buffer<T>
|
||||
Double::class -> MutableBuffer.double(size) { initializer(it) as Double } as Buffer<T>
|
||||
Short::class -> MutableBuffer.short(size) { initializer(it) as Short } as Buffer<T>
|
||||
Int::class -> MutableBuffer.int(size) { initializer(it) as Int } as Buffer<T>
|
||||
Long::class -> MutableBuffer.long(size) { initializer(it) as Long } as Buffer<T>
|
||||
Float::class -> MutableBuffer.float(size) { initializer(it) as Float } as Buffer<T>
|
||||
else -> boxing(size, initializer)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a [Buffer] of given type [T]. If the type is primitive, specialized buffers are used ([IntBuffer],
|
||||
* [RealBuffer], etc.), [ListBuffer] is returned otherwise.
|
||||
* [DoubleBuffer], etc.), [ListBuffer] is returned otherwise.
|
||||
*
|
||||
* The [size] is specified, and each element is calculated by calling the specified [initializer] function.
|
||||
*/
|
||||
@ -89,21 +87,6 @@ public interface Buffer<T> {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a sequence that returns all elements from this [Buffer].
|
||||
*/
|
||||
public fun <T> Buffer<T>.asSequence(): Sequence<T> = Sequence(::iterator)
|
||||
|
||||
/**
|
||||
* Creates an iterable that returns all elements from this [Buffer].
|
||||
*/
|
||||
public fun <T> Buffer<T>.asIterable(): Iterable<T> = Iterable(::iterator)
|
||||
|
||||
/**
|
||||
* Converts this [Buffer] to a new [List]
|
||||
*/
|
||||
public fun <T> Buffer<T>.toList(): List<T> = asSequence().toList()
|
||||
|
||||
/**
|
||||
* Returns an [IntRange] of the valid indices for this [Buffer].
|
||||
*/
|
||||
@ -126,6 +109,43 @@ public interface MutableBuffer<T> : Buffer<T> {
|
||||
public fun copy(): MutableBuffer<T>
|
||||
|
||||
public companion object {
|
||||
/**
|
||||
* Creates a [DoubleBuffer] with the specified [size], where each element is calculated by calling the specified
|
||||
* [initializer] function.
|
||||
*/
|
||||
public inline fun double(size: Int, initializer: (Int) -> Double): DoubleBuffer =
|
||||
DoubleBuffer(size, initializer)
|
||||
|
||||
/**
|
||||
* Creates a [ShortBuffer] with the specified [size], where each element is calculated by calling the specified
|
||||
* [initializer] function.
|
||||
*/
|
||||
public inline fun short(size: Int, initializer: (Int) -> Short): ShortBuffer =
|
||||
ShortBuffer(size, initializer)
|
||||
|
||||
/**
|
||||
* Creates a [IntBuffer] with the specified [size], where each element is calculated by calling the specified
|
||||
* [initializer] function.
|
||||
*/
|
||||
public inline fun int(size: Int, initializer: (Int) -> Int): IntBuffer =
|
||||
IntBuffer(size, initializer)
|
||||
|
||||
/**
|
||||
* Creates a [LongBuffer] with the specified [size], where each element is calculated by calling the specified
|
||||
* [initializer] function.
|
||||
*/
|
||||
public inline fun long(size: Int, initializer: (Int) -> Long): LongBuffer =
|
||||
LongBuffer(size, initializer)
|
||||
|
||||
|
||||
/**
|
||||
* Creates a [FloatBuffer] with the specified [size], where each element is calculated by calling the specified
|
||||
* [initializer] function.
|
||||
*/
|
||||
public inline fun float(size: Int, initializer: (Int) -> Float): FloatBuffer =
|
||||
FloatBuffer(size, initializer)
|
||||
|
||||
|
||||
/**
|
||||
* Create a boxing mutable buffer of given type
|
||||
*/
|
||||
@ -134,37 +154,30 @@ public interface MutableBuffer<T> : Buffer<T> {
|
||||
|
||||
/**
|
||||
* Creates a [MutableBuffer] of given [type]. If the type is primitive, specialized buffers are used
|
||||
* ([IntBuffer], [RealBuffer], etc.), [ListBuffer] is returned otherwise.
|
||||
* ([IntBuffer], [DoubleBuffer], etc.), [ListBuffer] is returned otherwise.
|
||||
*
|
||||
* The [size] is specified, and each element is calculated by calling the specified [initializer] function.
|
||||
*/
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
public inline fun <T : Any> auto(type: KClass<out T>, size: Int, initializer: (Int) -> T): MutableBuffer<T> =
|
||||
when (type) {
|
||||
Double::class -> RealBuffer(size) { initializer(it) as Double } as MutableBuffer<T>
|
||||
Short::class -> ShortBuffer(size) { initializer(it) as Short } as MutableBuffer<T>
|
||||
Int::class -> IntBuffer(size) { initializer(it) as Int } as MutableBuffer<T>
|
||||
Float::class -> FloatBuffer(size) { initializer(it) as Float } as MutableBuffer<T>
|
||||
Long::class -> LongBuffer(size) { initializer(it) as Long } as MutableBuffer<T>
|
||||
Double::class -> double(size) { initializer(it) as Double } as MutableBuffer<T>
|
||||
Short::class -> short(size) { initializer(it) as Short } as MutableBuffer<T>
|
||||
Int::class -> int(size) { initializer(it) as Int } as MutableBuffer<T>
|
||||
Float::class -> float(size) { initializer(it) as Float } as MutableBuffer<T>
|
||||
Long::class -> long(size) { initializer(it) as Long } as MutableBuffer<T>
|
||||
else -> boxing(size, initializer)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a [MutableBuffer] of given type [T]. If the type is primitive, specialized buffers are used
|
||||
* ([IntBuffer], [RealBuffer], etc.), [ListBuffer] is returned otherwise.
|
||||
* ([IntBuffer], [DoubleBuffer], etc.), [ListBuffer] is returned otherwise.
|
||||
*
|
||||
* The [size] is specified, and each element is calculated by calling the specified [initializer] function.
|
||||
*/
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
public inline fun <reified T : Any> auto(size: Int, initializer: (Int) -> T): MutableBuffer<T> =
|
||||
auto(T::class, size, initializer)
|
||||
|
||||
/**
|
||||
* Creates a [RealBuffer] with the specified [size], where each element is calculated by calling the specified
|
||||
* [initializer] function.
|
||||
*/
|
||||
public inline fun real(size: Int, initializer: (Int) -> Double): RealBuffer =
|
||||
RealBuffer(size) { initializer(it) }
|
||||
}
|
||||
}
|
||||
|
||||
@ -187,15 +200,6 @@ public inline class ListBuffer<T>(public val list: List<T>) : Buffer<T> {
|
||||
*/
|
||||
public fun <T> List<T>.asBuffer(): ListBuffer<T> = ListBuffer(this)
|
||||
|
||||
/**
|
||||
* Creates a new [ListBuffer] with the specified [size], where each element is calculated by calling the specified
|
||||
* [init] function.
|
||||
*
|
||||
* The function [init] is called for each array element sequentially starting from the first one.
|
||||
* It should return the value for an array element given its index.
|
||||
*/
|
||||
public inline fun <T> ListBuffer(size: Int, init: (Int) -> T): ListBuffer<T> = List(size, init).asBuffer()
|
||||
|
||||
/**
|
||||
* [MutableBuffer] implementation over [MutableList].
|
||||
*
|
||||
@ -216,16 +220,20 @@ public inline class MutableListBuffer<T>(public val list: MutableList<T>) : Muta
|
||||
override fun copy(): MutableBuffer<T> = MutableListBuffer(ArrayList(list))
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an [ListBuffer] that wraps the original list.
|
||||
*/
|
||||
public fun <T> MutableList<T>.asMutableBuffer(): MutableListBuffer<T> = MutableListBuffer(this)
|
||||
|
||||
/**
|
||||
* [MutableBuffer] implementation over [Array].
|
||||
*
|
||||
* @param T the type of elements contained in the buffer.
|
||||
* @property array The underlying array.
|
||||
*/
|
||||
public class ArrayBuffer<T>(private val array: Array<T>) : MutableBuffer<T> {
|
||||
public class ArrayBuffer<T>(internal val array: Array<T>) : MutableBuffer<T> {
|
||||
// Can't inline because array is invariant
|
||||
override val size: Int
|
||||
get() = array.size
|
||||
override val size: Int get() = array.size
|
||||
|
||||
override operator fun get(index: Int): T = array[index]
|
||||
|
||||
@ -237,6 +245,7 @@ public class ArrayBuffer<T>(private val array: Array<T>) : MutableBuffer<T> {
|
||||
override fun copy(): MutableBuffer<T> = ArrayBuffer(array.copyOf())
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns an [ArrayBuffer] that wraps the original array.
|
||||
*/
|
||||
@ -269,27 +278,9 @@ public class VirtualBuffer<T>(override val size: Int, private val generator: (In
|
||||
}
|
||||
|
||||
override operator fun iterator(): Iterator<T> = (0 until size).asSequence().map(generator).iterator()
|
||||
|
||||
override fun contentEquals(other: Buffer<*>): Boolean {
|
||||
return if (other is VirtualBuffer) {
|
||||
this.size == other.size && this.generator == other.generator
|
||||
} else {
|
||||
super.contentEquals(other)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert this buffer to read-only buffer.
|
||||
*/
|
||||
public fun <T> Buffer<T>.asReadOnly(): Buffer<T> = if (this is MutableBuffer) ReadOnlyBuffer(this) else this
|
||||
|
||||
/**
|
||||
* Typealias for buffer transformations.
|
||||
*/
|
||||
public typealias BufferTransform<T, R> = (Buffer<T>) -> Buffer<R>
|
||||
|
||||
/**
|
||||
* Typealias for buffer transformations with suspend function.
|
||||
*/
|
||||
public typealias SuspendBufferTransform<T, R> = suspend (Buffer<T>) -> Buffer<R>
|
||||
public fun <T> Buffer<T>.asReadOnly(): Buffer<T> = if (this is MutableBuffer) ReadOnlyBuffer(this) else this
|
@ -1,9 +0,0 @@
|
||||
package kscience.kmath.chains
|
||||
|
||||
/**
|
||||
* Performance optimized chain for real values
|
||||
*/
|
||||
public interface BlockingRealChain : Chain<Double> {
|
||||
public override suspend fun next(): Double
|
||||
public suspend fun nextBlock(size: Int): DoubleArray = DoubleArray(size) { next() }
|
||||
}
|
@ -1,12 +1,13 @@
|
||||
package space.kscience.kmath.chains
|
||||
|
||||
/**
|
||||
* Performance optimized chain for real values
|
||||
* Chunked, specialized chain for real values.
|
||||
*/
|
||||
public abstract class BlockingDoubleChain : Chain<Double> {
|
||||
public abstract fun nextDouble(): Double
|
||||
public interface BlockingDoubleChain : Chain<Double> {
|
||||
public override suspend fun next(): Double
|
||||
|
||||
override suspend fun next(): Double = nextDouble()
|
||||
|
||||
public open fun nextBlock(size: Int): DoubleArray = DoubleArray(size) { nextDouble() }
|
||||
/**
|
||||
* Returns an [DoubleArray] chunk of [size] values of [next].
|
||||
*/
|
||||
public suspend fun nextBlock(size: Int): DoubleArray = DoubleArray(size) { next() }
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
package kscience.dimensions
|
||||
package space.kscience.dimensions
|
||||
|
||||
import space.kscience.kmath.dimensions.D2
|
||||
import space.kscience.kmath.dimensions.D3
|
||||
|
@ -1,34 +0,0 @@
|
||||
package kscience.kmath.stat
|
||||
|
||||
import kscience.kmath.chains.Chain
|
||||
import kscience.kmath.chains.ConstantChain
|
||||
import kscience.kmath.chains.map
|
||||
import kscience.kmath.chains.zip
|
||||
import kscience.kmath.operations.Space
|
||||
import kscience.kmath.operations.invoke
|
||||
|
||||
/**
|
||||
* Implements [Sampler] by sampling only certain [value].
|
||||
*
|
||||
* @property value the value to sample.
|
||||
*/
|
||||
public class ConstantSampler<T : Any>(public val value: T) : Sampler<T> {
|
||||
public override fun sample(generator: RandomGenerator): Chain<T> = ConstantChain(value)
|
||||
}
|
||||
|
||||
/**
|
||||
* A space of samplers. Allows to perform simple operations on distributions.
|
||||
*
|
||||
* @property space the space to provide addition and scalar multiplication for [T].
|
||||
*/
|
||||
public class SamplerSpace<T : Any>(public val space: Space<T>) : Space<Sampler<T>> {
|
||||
public override val zero: Sampler<T> = ConstantSampler(space.zero)
|
||||
|
||||
public override fun add(a: Sampler<T>, b: Sampler<T>): Sampler<T> = Sampler { generator ->
|
||||
a.sample(generator).zip(b.sample(generator)) { aValue, bValue -> space { aValue + bValue } }
|
||||
}
|
||||
|
||||
public override fun multiply(a: Sampler<T>, k: Number): Sampler<T> = Sampler { generator ->
|
||||
a.sample(generator).map { space { it * k.toDouble() } }
|
||||
}
|
||||
}
|
@ -1,11 +1,12 @@
|
||||
package kscience.kmath.stat
|
||||
package space.kscience.kmath.stat
|
||||
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kscience.kmath.chains.Chain
|
||||
import kscience.kmath.chains.collect
|
||||
import kscience.kmath.structures.Buffer
|
||||
import kscience.kmath.structures.BufferFactory
|
||||
import kscience.kmath.structures.IntBuffer
|
||||
import space.kscience.kmath.chains.Chain
|
||||
import space.kscience.kmath.chains.collect
|
||||
import space.kscience.kmath.structures.Buffer
|
||||
import space.kscience.kmath.structures.BufferFactory
|
||||
import space.kscience.kmath.structures.IntBuffer
|
||||
import space.kscience.kmath.structures.MutableBuffer
|
||||
import kotlin.jvm.JvmName
|
||||
|
||||
/**
|
||||
@ -22,7 +23,7 @@ public fun interface Sampler<T : Any> {
|
||||
}
|
||||
|
||||
/**
|
||||
* A distribution of typed objects
|
||||
* A distribution of typed objects.
|
||||
*/
|
||||
public interface Distribution<T : Any> : Sampler<T> {
|
||||
/**
|
||||
@ -60,7 +61,7 @@ public fun <T : Comparable<T>> UnivariateDistribution<T>.integral(from: T, to: T
|
||||
public fun <T : Any> Sampler<T>.sampleBuffer(
|
||||
generator: RandomGenerator,
|
||||
size: Int,
|
||||
bufferFactory: BufferFactory<T> = Buffer.Companion::boxing
|
||||
bufferFactory: BufferFactory<T> = Buffer.Companion::boxing,
|
||||
): Chain<Buffer<T>> {
|
||||
require(size > 1)
|
||||
//creating temporary storage once
|
||||
@ -86,7 +87,7 @@ public suspend fun <T : Any> Sampler<T>.next(generator: RandomGenerator): T = sa
|
||||
*/
|
||||
@JvmName("sampleRealBuffer")
|
||||
public fun Sampler<Double>.sampleBuffer(generator: RandomGenerator, size: Int): Chain<Buffer<Double>> =
|
||||
sampleBuffer(generator, size, Buffer.Companion::real)
|
||||
sampleBuffer(generator, size, MutableBuffer.Companion::double)
|
||||
|
||||
/**
|
||||
* Generates [size] integer samples and chunks them into some buffers.
|
||||
|
@ -1,8 +1,8 @@
|
||||
package kscience.kmath.stat
|
||||
package space.kscience.kmath.stat
|
||||
|
||||
import kscience.kmath.chains.BlockingIntChain
|
||||
import kscience.kmath.chains.BlockingRealChain
|
||||
import kscience.kmath.chains.Chain
|
||||
import space.kscience.kmath.chains.BlockingDoubleChain
|
||||
import space.kscience.kmath.chains.BlockingIntChain
|
||||
import space.kscience.kmath.chains.Chain
|
||||
|
||||
/**
|
||||
* A possibly stateful chain producing random values.
|
||||
@ -18,5 +18,5 @@ public class RandomChain<out R>(
|
||||
}
|
||||
|
||||
public fun <R> RandomGenerator.chain(gen: suspend RandomGenerator.() -> R): RandomChain<R> = RandomChain(this, gen)
|
||||
public fun Chain<Double>.blocking(): BlockingRealChain = object : Chain<Double> by this, BlockingRealChain {}
|
||||
public fun Chain<Double>.blocking(): BlockingDoubleChain = object : Chain<Double> by this, BlockingDoubleChain {}
|
||||
public fun Chain<Int>.blocking(): BlockingIntChain = object : Chain<Int> by this, BlockingIntChain {}
|
||||
|
@ -8,16 +8,28 @@ import space.kscience.kmath.operations.Group
|
||||
import space.kscience.kmath.operations.ScaleOperations
|
||||
import space.kscience.kmath.operations.invoke
|
||||
|
||||
public class BasicSampler<T : Any>(public val chainBuilder: (RandomGenerator) -> Chain<T>) : Sampler<T> {
|
||||
public override fun sample(generator: RandomGenerator): Chain<T> = chainBuilder(generator)
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements [Sampler] by sampling only certain [value].
|
||||
*
|
||||
* @property value the value to sample.
|
||||
*/
|
||||
public class ConstantSampler<T : Any>(public val value: T) : Sampler<T> {
|
||||
public override fun sample(generator: RandomGenerator): Chain<T> = ConstantChain(value)
|
||||
}
|
||||
|
||||
/**
|
||||
* A space for samplers. Allows to perform simple operations on distributions
|
||||
* Implements [Sampler] by delegating sampling to value of [chainBuilder].
|
||||
*
|
||||
* @property chainBuilder the provider of [Chain].
|
||||
*/
|
||||
public class BasicSampler<T : Any>(public val chainBuilder: (RandomGenerator) -> Chain<T>) : Sampler<T> {
|
||||
public override fun sample(generator: RandomGenerator): Chain<T> = chainBuilder(generator)
|
||||
}
|
||||
|
||||
/**
|
||||
* A space of samplers. Allows to perform simple operations on distributions.
|
||||
*
|
||||
* @property algebra the space to provide addition and scalar multiplication for [T].
|
||||
*/
|
||||
public class SamplerSpace<T : Any, S>(public val algebra: S) : Group<Sampler<T>>,
|
||||
ScaleOperations<Sampler<T>> where S : Group<T>, S : ScaleOperations<T> {
|
||||
@ -29,8 +41,10 @@ public class SamplerSpace<T : Any, S>(public val algebra: S) : Group<Sampler<T>>
|
||||
}
|
||||
|
||||
public override fun scale(a: Sampler<T>, value: Double): Sampler<T> = BasicSampler { generator ->
|
||||
a.sample(generator).map { algebra { it * value } }
|
||||
a.sample(generator).map { a ->
|
||||
algebra { a * value }
|
||||
}
|
||||
}
|
||||
|
||||
override fun Sampler<T>.unaryMinus(): Sampler<T> = scale(this, -1.0)
|
||||
public override fun Sampler<T>.unaryMinus(): Sampler<T> = scale(this, -1.0)
|
||||
}
|
||||
|
@ -1,12 +1,12 @@
|
||||
package kscience.kmath.stat.distributions
|
||||
package space.kscience.kmath.stat.distributions
|
||||
|
||||
import kscience.kmath.chains.Chain
|
||||
import kscience.kmath.stat.RandomGenerator
|
||||
import kscience.kmath.stat.UnivariateDistribution
|
||||
import kscience.kmath.stat.internal.InternalErf
|
||||
import kscience.kmath.stat.samplers.GaussianSampler
|
||||
import kscience.kmath.stat.samplers.NormalizedGaussianSampler
|
||||
import kscience.kmath.stat.samplers.ZigguratNormalizedGaussianSampler
|
||||
import space.kscience.kmath.chains.Chain
|
||||
import space.kscience.kmath.stat.RandomGenerator
|
||||
import space.kscience.kmath.stat.UnivariateDistribution
|
||||
import space.kscience.kmath.stat.internal.InternalErf
|
||||
import space.kscience.kmath.stat.samplers.GaussianSampler
|
||||
import space.kscience.kmath.stat.samplers.NormalizedGaussianSampler
|
||||
import space.kscience.kmath.stat.samplers.ZigguratNormalizedGaussianSampler
|
||||
import kotlin.math.*
|
||||
|
||||
/**
|
@ -1,4 +1,4 @@
|
||||
package kscience.kmath.stat.internal
|
||||
package space.kscience.kmath.stat.internal
|
||||
|
||||
import kotlin.math.abs
|
||||
|
@ -1,4 +1,4 @@
|
||||
package kscience.kmath.stat.internal
|
||||
package space.kscience.kmath.stat.internal
|
||||
|
||||
import kotlin.math.*
|
||||
|
@ -1,4 +1,4 @@
|
||||
package kscience.kmath.stat.internal
|
||||
package space.kscience.kmath.stat.internal
|
||||
|
||||
import kotlin.math.ln
|
||||
import kotlin.math.min
|
@ -1,10 +1,10 @@
|
||||
package kscience.kmath.stat.samplers
|
||||
package space.kscience.kmath.stat.samplers
|
||||
|
||||
import kscience.kmath.chains.Chain
|
||||
import kscience.kmath.stat.RandomGenerator
|
||||
import kscience.kmath.stat.Sampler
|
||||
import kscience.kmath.stat.chain
|
||||
import kscience.kmath.stat.internal.InternalUtils
|
||||
import space.kscience.kmath.chains.Chain
|
||||
import space.kscience.kmath.stat.RandomGenerator
|
||||
import space.kscience.kmath.stat.Sampler
|
||||
import space.kscience.kmath.stat.chain
|
||||
import space.kscience.kmath.stat.internal.InternalUtils
|
||||
import kotlin.math.ln
|
||||
import kotlin.math.pow
|
||||
|
@ -1,10 +1,10 @@
|
||||
package kscience.kmath.stat.samplers
|
||||
package space.kscience.kmath.stat.samplers
|
||||
|
||||
import kscience.kmath.chains.Chain
|
||||
import kscience.kmath.stat.RandomGenerator
|
||||
import kscience.kmath.stat.Sampler
|
||||
import kscience.kmath.stat.chain
|
||||
import kscience.kmath.stat.next
|
||||
import space.kscience.kmath.chains.Chain
|
||||
import space.kscience.kmath.stat.RandomGenerator
|
||||
import space.kscience.kmath.stat.Sampler
|
||||
import space.kscience.kmath.stat.chain
|
||||
import space.kscience.kmath.stat.next
|
||||
import kotlin.math.*
|
||||
|
||||
/**
|
@ -1,10 +1,10 @@
|
||||
package kscience.kmath.stat.samplers
|
||||
package space.kscience.kmath.stat.samplers
|
||||
|
||||
import kscience.kmath.chains.Chain
|
||||
import kscience.kmath.stat.RandomGenerator
|
||||
import kscience.kmath.stat.Sampler
|
||||
import kscience.kmath.stat.chain
|
||||
import kscience.kmath.stat.internal.InternalUtils
|
||||
import space.kscience.kmath.chains.Chain
|
||||
import space.kscience.kmath.stat.RandomGenerator
|
||||
import space.kscience.kmath.stat.Sampler
|
||||
import space.kscience.kmath.stat.chain
|
||||
import space.kscience.kmath.stat.internal.InternalUtils
|
||||
import kotlin.math.ceil
|
||||
import kotlin.math.max
|
||||
import kotlin.math.min
|
@ -1,9 +1,9 @@
|
||||
package kscience.kmath.stat.samplers
|
||||
package space.kscience.kmath.stat.samplers
|
||||
|
||||
import kscience.kmath.chains.Chain
|
||||
import kscience.kmath.stat.RandomGenerator
|
||||
import kscience.kmath.stat.Sampler
|
||||
import kscience.kmath.stat.chain
|
||||
import space.kscience.kmath.chains.Chain
|
||||
import space.kscience.kmath.stat.RandomGenerator
|
||||
import space.kscience.kmath.stat.Sampler
|
||||
import space.kscience.kmath.stat.chain
|
||||
import kotlin.math.*
|
||||
|
||||
/**
|
@ -1,9 +1,9 @@
|
||||
package kscience.kmath.stat.samplers
|
||||
package space.kscience.kmath.stat.samplers
|
||||
|
||||
import kscience.kmath.chains.Chain
|
||||
import kscience.kmath.chains.map
|
||||
import kscience.kmath.stat.RandomGenerator
|
||||
import kscience.kmath.stat.Sampler
|
||||
import space.kscience.kmath.chains.Chain
|
||||
import space.kscience.kmath.chains.map
|
||||
import space.kscience.kmath.stat.RandomGenerator
|
||||
import space.kscience.kmath.stat.Sampler
|
||||
|
||||
/**
|
||||
* Sampling from a Gaussian distribution with given mean and standard deviation.
|
@ -1,9 +1,9 @@
|
||||
package kscience.kmath.stat.samplers
|
||||
package space.kscience.kmath.stat.samplers
|
||||
|
||||
import kscience.kmath.chains.Chain
|
||||
import kscience.kmath.stat.RandomGenerator
|
||||
import kscience.kmath.stat.Sampler
|
||||
import kscience.kmath.stat.chain
|
||||
import space.kscience.kmath.chains.Chain
|
||||
import space.kscience.kmath.stat.RandomGenerator
|
||||
import space.kscience.kmath.stat.Sampler
|
||||
import space.kscience.kmath.stat.chain
|
||||
import kotlin.math.exp
|
||||
|
||||
/**
|
@ -1,12 +1,12 @@
|
||||
package kscience.kmath.stat.samplers
|
||||
package space.kscience.kmath.stat.samplers
|
||||
|
||||
import kscience.kmath.chains.Chain
|
||||
import kscience.kmath.chains.ConstantChain
|
||||
import kscience.kmath.stat.RandomGenerator
|
||||
import kscience.kmath.stat.Sampler
|
||||
import kscience.kmath.stat.chain
|
||||
import kscience.kmath.stat.internal.InternalUtils
|
||||
import kscience.kmath.stat.next
|
||||
import space.kscience.kmath.chains.Chain
|
||||
import space.kscience.kmath.chains.ConstantChain
|
||||
import space.kscience.kmath.stat.RandomGenerator
|
||||
import space.kscience.kmath.stat.Sampler
|
||||
import space.kscience.kmath.stat.chain
|
||||
import space.kscience.kmath.stat.internal.InternalUtils
|
||||
import space.kscience.kmath.stat.next
|
||||
import kotlin.math.*
|
||||
|
||||
/**
|
@ -1,9 +1,9 @@
|
||||
package kscience.kmath.stat.samplers
|
||||
package space.kscience.kmath.stat.samplers
|
||||
|
||||
import kscience.kmath.chains.Chain
|
||||
import kscience.kmath.stat.RandomGenerator
|
||||
import kscience.kmath.stat.Sampler
|
||||
import kscience.kmath.stat.chain
|
||||
import space.kscience.kmath.chains.Chain
|
||||
import space.kscience.kmath.stat.RandomGenerator
|
||||
import space.kscience.kmath.stat.Sampler
|
||||
import space.kscience.kmath.stat.chain
|
||||
import kotlin.math.ln
|
||||
import kotlin.math.sqrt
|
||||
|
@ -1,6 +1,6 @@
|
||||
package kscience.kmath.stat.samplers
|
||||
package space.kscience.kmath.stat.samplers
|
||||
|
||||
import kscience.kmath.stat.Sampler
|
||||
import space.kscience.kmath.stat.Sampler
|
||||
|
||||
/**
|
||||
* Marker interface for a sampler that generates values from an N(0,1)
|
@ -1,8 +1,8 @@
|
||||
package kscience.kmath.stat.samplers
|
||||
package space.kscience.kmath.stat.samplers
|
||||
|
||||
import kscience.kmath.chains.Chain
|
||||
import kscience.kmath.stat.RandomGenerator
|
||||
import kscience.kmath.stat.Sampler
|
||||
import space.kscience.kmath.chains.Chain
|
||||
import space.kscience.kmath.stat.RandomGenerator
|
||||
import space.kscience.kmath.stat.Sampler
|
||||
|
||||
/**
|
||||
* Sampler for the Poisson distribution.
|
@ -1,9 +1,9 @@
|
||||
package kscience.kmath.stat.samplers
|
||||
package space.kscience.kmath.stat.samplers
|
||||
|
||||
import kscience.kmath.chains.Chain
|
||||
import kscience.kmath.stat.RandomGenerator
|
||||
import kscience.kmath.stat.Sampler
|
||||
import kscience.kmath.stat.chain
|
||||
import space.kscience.kmath.chains.Chain
|
||||
import space.kscience.kmath.stat.RandomGenerator
|
||||
import space.kscience.kmath.stat.Sampler
|
||||
import space.kscience.kmath.stat.chain
|
||||
import kotlin.math.ceil
|
||||
import kotlin.math.exp
|
||||
|
@ -1,9 +1,9 @@
|
||||
package kscience.kmath.stat.samplers
|
||||
package space.kscience.kmath.stat.samplers
|
||||
|
||||
import kscience.kmath.chains.Chain
|
||||
import kscience.kmath.stat.RandomGenerator
|
||||
import kscience.kmath.stat.Sampler
|
||||
import kscience.kmath.stat.chain
|
||||
import space.kscience.kmath.chains.Chain
|
||||
import space.kscience.kmath.stat.RandomGenerator
|
||||
import space.kscience.kmath.stat.Sampler
|
||||
import space.kscience.kmath.stat.chain
|
||||
import kotlin.math.*
|
||||
|
||||
/**
|
@ -3,9 +3,9 @@ package space.kscience.kmath.stat
|
||||
import kotlinx.coroutines.flow.take
|
||||
import kotlinx.coroutines.flow.toList
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kscience.kmath.stat.samplers.GaussianSampler
|
||||
import org.junit.jupiter.api.Assertions
|
||||
import org.junit.jupiter.api.Test
|
||||
import space.kscience.kmath.stat.samplers.GaussianSampler
|
||||
|
||||
internal class CommonsDistributionsTest {
|
||||
@Test
|
||||
|
Loading…
Reference in New Issue
Block a user