forked from kscience/kmath
Histograms refactor
This commit is contained in:
parent
ce18e85a0a
commit
d1b4d1ac11
@ -8,7 +8,7 @@ import java.util.*
|
|||||||
import kotlin.math.abs
|
import kotlin.math.abs
|
||||||
import kotlin.math.sqrt
|
import kotlin.math.sqrt
|
||||||
|
|
||||||
internal fun <B: ClosedFloatingPointRange<Double>> TreeMap<Double, B>.getBin(value: Double): B? {
|
private fun <B : ClosedFloatingPointRange<Double>> TreeMap<Double, B>.getBin(value: Double): B? {
|
||||||
// check ceiling entry and return it if it is what needed
|
// check ceiling entry and return it if it is what needed
|
||||||
val ceil = ceilingEntry(value)?.value
|
val ceil = ceilingEntry(value)?.value
|
||||||
if (ceil != null && value in ceil) return ceil
|
if (ceil != null && value in ceil) return ceil
|
||||||
@ -29,12 +29,9 @@ public class TreeHistogram(
|
|||||||
override val bins: Collection<UnivariateBin> get() = binMap.values
|
override val bins: Collection<UnivariateBin> get() = binMap.values
|
||||||
}
|
}
|
||||||
|
|
||||||
private class UnivariateBinValue(
|
/**
|
||||||
override val domain: UnivariateDomain,
|
* A space for univariate histograms with variable bin borders based on a tree map
|
||||||
override val value: Double,
|
*/
|
||||||
override val standardDeviation: Double,
|
|
||||||
) : UnivariateBin, ClosedFloatingPointRange<Double> by domain.range
|
|
||||||
|
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
public class TreeHistogramSpace(
|
public class TreeHistogramSpace(
|
||||||
public val binFactory: (Double) -> UnivariateDomain,
|
public val binFactory: (Double) -> UnivariateDomain,
|
||||||
@ -73,7 +70,7 @@ public class TreeHistogramSpace(
|
|||||||
val resBins = TreeMap<Double, UnivariateBin>()
|
val resBins = TreeMap<Double, UnivariateBin>()
|
||||||
bins.forEach { key, binCounter ->
|
bins.forEach { key, binCounter ->
|
||||||
val count = binCounter.counter.value
|
val count = binCounter.counter.value
|
||||||
resBins[key] = UnivariateBinValue(binCounter.domain, count, sqrt(count))
|
resBins[key] = UnivariateBin(binCounter.domain, count, sqrt(count))
|
||||||
}
|
}
|
||||||
return TreeHistogram(this, resBins)
|
return TreeHistogram(this, resBins)
|
||||||
}
|
}
|
||||||
@ -86,12 +83,14 @@ public class TreeHistogramSpace(
|
|||||||
require(b.context == this) { "Histogram $b does not belong to this context" }
|
require(b.context == this) { "Histogram $b does not belong to this context" }
|
||||||
val bins = TreeMap<Double, UnivariateBin>().apply {
|
val bins = TreeMap<Double, UnivariateBin>().apply {
|
||||||
(a.bins.map { it.domain } union b.bins.map { it.domain }).forEach { def ->
|
(a.bins.map { it.domain } union b.bins.map { it.domain }).forEach { def ->
|
||||||
val newBin = UnivariateBinValue(
|
put(def.center,
|
||||||
|
UnivariateBin(
|
||||||
def,
|
def,
|
||||||
value = (a[def.center]?.value ?: 0.0) + (b[def.center]?.value ?: 0.0),
|
value = (a[def.center]?.value ?: 0.0) + (b[def.center]?.value ?: 0.0),
|
||||||
standardDeviation = (a[def.center]?.standardDeviation
|
standardDeviation = (a[def.center]?.standardDeviation
|
||||||
?: 0.0) + (b[def.center]?.standardDeviation ?: 0.0)
|
?: 0.0) + (b[def.center]?.standardDeviation ?: 0.0)
|
||||||
)
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return TreeHistogram(this, bins)
|
return TreeHistogram(this, bins)
|
||||||
@ -101,7 +100,7 @@ public class TreeHistogramSpace(
|
|||||||
val bins = TreeMap<Double, UnivariateBin>().apply {
|
val bins = TreeMap<Double, UnivariateBin>().apply {
|
||||||
a.bins.forEach { bin ->
|
a.bins.forEach { bin ->
|
||||||
put(bin.domain.center,
|
put(bin.domain.center,
|
||||||
UnivariateBinValue(
|
UnivariateBin(
|
||||||
bin.domain,
|
bin.domain,
|
||||||
value = bin.value * k.toDouble(),
|
value = bin.value * k.toDouble(),
|
||||||
standardDeviation = abs(bin.standardDeviation * k.toDouble())
|
standardDeviation = abs(bin.standardDeviation * k.toDouble())
|
||||||
|
@ -10,26 +10,23 @@ import kscience.kmath.structures.asSequence
|
|||||||
|
|
||||||
public val UnivariateDomain.center: Double get() = (range.endInclusive - range.start) / 2
|
public val UnivariateDomain.center: Double get() = (range.endInclusive - range.start) / 2
|
||||||
|
|
||||||
public interface UnivariateBin : Bin<Double>, ClosedFloatingPointRange<Double> {
|
|
||||||
public val domain: UnivariateDomain
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The value of histogram including weighting
|
* A univariate bin based an a range
|
||||||
|
* @param value The value of histogram including weighting
|
||||||
|
* @param standardDeviation Standard deviation of the bin value. Zero or negative if not applicable
|
||||||
*/
|
*/
|
||||||
public override val value: Double
|
public class UnivariateBin(
|
||||||
|
public val domain: UnivariateDomain,
|
||||||
/**
|
override val value: Double,
|
||||||
* Standard deviation of the bin value. Zero if not applicable
|
public val standardDeviation: Double,
|
||||||
*/
|
) : Bin<Double>, ClosedFloatingPointRange<Double> by domain.range {
|
||||||
public val standardDeviation: Double
|
|
||||||
|
|
||||||
public override val dimension: Int get() = 1
|
public override val dimension: Int get() = 1
|
||||||
|
|
||||||
public override fun contains(point: Buffer<Double>): Boolean = point.size == 1 && contains(point[0])
|
public override fun contains(point: Buffer<Double>): Boolean = point.size == 1 && contains(point[0])
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@UnstableKMathAPI
|
@OptIn(UnstableKMathAPI::class)
|
||||||
public interface UnivariateHistogram : Histogram<Double, UnivariateBin>,
|
public interface UnivariateHistogram : Histogram<Double, UnivariateBin>,
|
||||||
SpaceElement<UnivariateHistogram, Space<UnivariateHistogram>> {
|
SpaceElement<UnivariateHistogram, Space<UnivariateHistogram>> {
|
||||||
public operator fun get(value: Double): UnivariateBin?
|
public operator fun get(value: Double): UnivariateBin?
|
||||||
|
Loading…
Reference in New Issue
Block a user