Added limited polimorphism to Histogram

This commit is contained in:
Alexander Nozik 2018-10-28 21:41:58 +03:00
parent 34374e1006
commit 6a0ef6a235
3 changed files with 20 additions and 20 deletions

View File

@ -6,13 +6,13 @@ import scientifik.kmath.structures.NDStructure
import scientifik.kmath.structures.ndStructure
import kotlin.math.floor
class MultivariateBin(override val center: RealVector, val sizes: RealVector, val counter: LongCounter = LongCounter()) : Bin {
class MultivariateBin(override val center: RealVector, val sizes: RealVector, val counter: LongCounter = LongCounter()) : Bin<Double> {
init {
if (center.size != sizes.size) error("Dimension mismatch in bin creation. Expected ${center.size}, but found ${sizes.size}")
}
override fun contains(vector: RealVector): Boolean {
if(vector.size != center.size) error("Dimension mismatch for input vector. Expected ${center.size}, but found ${vector.size}")
if (vector.size != center.size) error("Dimension mismatch for input vector. Expected ${center.size}, but found ${vector.size}")
return vector.asSequence().mapIndexed { i, value -> value in (center[i] - sizes[i] / 2)..(center[i] + sizes[i] / 2) }.all { it }
}
@ -28,8 +28,8 @@ class MultivariateBin(override val center: RealVector, val sizes: RealVector, va
class FastHistogram(
private val lower: RealVector,
private val upper: RealVector,
private val binNums: IntArray = IntArray(lower.size) { 100 }
) : Histogram<MultivariateBin> {
private val binNums: IntArray = IntArray(lower.size) { 20 }
) : Histogram<Double, MultivariateBin> {
init {
// argument checks
@ -105,7 +105,7 @@ class FastHistogram(
*)
*```
*/
fun fromRanges(vararg ranges: Pair<ClosedFloatingPointRange<Double>,Int>): FastHistogram {
fun fromRanges(vararg ranges: Pair<ClosedFloatingPointRange<Double>, Int>): FastHistogram {
return FastHistogram(
ranges.map { it.first.start }.toVector(),
ranges.map { it.first.endInclusive }.toVector(),

View File

@ -1,6 +1,6 @@
package scientifik.kmath.histogram
import scientifik.kmath.linear.RealVector
import scientifik.kmath.linear.Vector
import scientifik.kmath.linear.toVector
import scientifik.kmath.operations.Space
@ -8,28 +8,28 @@ import scientifik.kmath.operations.Space
* A simple geometric domain
* TODO move to geometry module
*/
interface Domain {
operator fun contains(vector: RealVector): Boolean
interface Domain<T: Any> {
operator fun contains(vector: Vector<T>): Boolean
val dimension: Int
}
/**
* The bin in the histogram. The histogram is by definition always done in the real space
*/
interface Bin : Domain {
interface Bin<T: Any> : Domain<T> {
/**
* The value of this bin
*/
val value: Number
val center: RealVector
val center: Vector<T>
}
interface Histogram<out B : Bin> : Iterable<B> {
interface Histogram<T: Any, out B : Bin<T>> : Iterable<B> {
/**
* Find existing bin, corresponding to given coordinates
*/
operator fun get(point: RealVector): B?
operator fun get(point: Vector<T>): B?
/**
* Dimension of the histogram
@ -39,24 +39,24 @@ interface Histogram<out B : Bin> : Iterable<B> {
/**
* Increment appropriate bin
*/
fun put(point: RealVector)
fun put(point: Vector<T>)
}
fun Histogram<*>.put(vararg point: Double) = put(point.toVector())
fun Histogram<Double,*>.put(vararg point: Double) = put(point.toVector())
fun Histogram<*>.fill(sequence: Iterable<RealVector>) = sequence.forEach { put(it) }
fun <T: Any> Histogram<T,*>.fill(sequence: Iterable<Vector<T>>) = sequence.forEach { put(it) }
/**
* Pass a sequence builder into histogram
*/
fun Histogram<*>.fill(buider: suspend SequenceScope<RealVector>.() -> Unit) = fill(sequence(buider).asIterable())
fun <T: Any> Histogram<T, *>.fill(buider: suspend SequenceScope<Vector<T>>.() -> Unit) = fill(sequence(buider).asIterable())
/**
* A space to perform arithmetic operations on histograms
*/
interface HistogramSpace<B : Bin, H : Histogram<B>> : Space<H> {
interface HistogramSpace<T: Any, B : Bin<T>, H : Histogram<T,B>> : Space<H> {
/**
* Rules for performing operations on bins
*/
val binSpace: Space<Bin>
val binSpace: Space<Bin<T>>
}

View File

@ -7,7 +7,7 @@ import kotlin.math.floor
//TODO move to common
class UnivariateBin(val position: Double, val size: Double, val counter: LongCounter = LongCounter()) : Bin {
class UnivariateBin(val position: Double, val size: Double, val counter: LongCounter = LongCounter()) : Bin<Double> {
//TODO add weighting
override val value: Number get() = counter.sum()
@ -25,7 +25,7 @@ class UnivariateBin(val position: Double, val size: Double, val counter: LongCou
/**
* Univariate histogram with log(n) bin search speed
*/
class UnivariateHistogram private constructor(private val factory: (Double) -> UnivariateBin) : Histogram<UnivariateBin> {
class UnivariateHistogram private constructor(private val factory: (Double) -> UnivariateBin) : Histogram<Double,UnivariateBin> {
private val bins: TreeMap<Double, UnivariateBin> = TreeMap()