[final] Generalize UniformHistogram1D

This commit is contained in:
Alexander Nozik 2022-04-10 09:48:55 +03:00
parent 3de8976ea5
commit eba3a2526e
No known key found for this signature in database
GPG Key ID: F7FCF2DD25C71357
2 changed files with 43 additions and 20 deletions

View File

@ -6,6 +6,7 @@
package space.kscience.kmath.histogram package space.kscience.kmath.histogram
import space.kscience.kmath.domains.Domain1D import space.kscience.kmath.domains.Domain1D
import space.kscience.kmath.domains.center
import space.kscience.kmath.linear.Point import space.kscience.kmath.linear.Point
import space.kscience.kmath.misc.UnstableKMathAPI import space.kscience.kmath.misc.UnstableKMathAPI
import space.kscience.kmath.operations.asSequence import space.kscience.kmath.operations.asSequence
@ -16,7 +17,6 @@ import space.kscience.kmath.structures.Buffer
* A univariate bin based on a range * A univariate bin based on a range
* *
* @property binValue The value of histogram including weighting * @property binValue The value of histogram including weighting
* @property standardDeviation Standard deviation of the bin value. Zero or negative if not applicable
*/ */
@UnstableKMathAPI @UnstableKMathAPI
public data class Bin1D<T : Comparable<T>, out V>( public data class Bin1D<T : Comparable<T>, out V>(
@ -56,5 +56,8 @@ public fun Histogram1DBuilder<Double, *>.fill(array: DoubleArray): Unit =
array.forEach(this::putValue) array.forEach(this::putValue)
@UnstableKMathAPI @UnstableKMathAPI
public fun <T: Any> Histogram1DBuilder<T, *>.fill(buffer: Buffer<T>): Unit = public fun <T : Any> Histogram1DBuilder<T, *>.fill(buffer: Buffer<T>): Unit =
buffer.asSequence().forEach(this::putValue) buffer.asSequence().forEach(this::putValue)
@OptIn(UnstableKMathAPI::class)
public val Bin1D<Double, *>.center: Double get() = domain.center

View File

@ -17,7 +17,7 @@ import kotlin.math.floor
@OptIn(UnstableKMathAPI::class) @OptIn(UnstableKMathAPI::class)
public class UniformHistogram1D<V : Any>( public class UniformHistogram1D<V : Any>(
public val group: UniformHistogram1DGroup<V, *>, public val group: UniformHistogram1DGroup<V, *>,
public val values: Map<Int, V>, internal val values: Map<Int, V>,
) : Histogram1D<Double, V> { ) : Histogram1D<Double, V> {
private val startPoint get() = group.startPoint private val startPoint get() = group.startPoint
@ -82,7 +82,7 @@ public class UniformHistogram1DGroup<V : Any, A>(
) )
/** /**
* * Fill histogram.
*/ */
public inline fun produce(block: Histogram1DBuilder<Double, V>.() -> Unit): UniformHistogram1D<V> { public inline fun produce(block: Histogram1DBuilder<Double, V>.() -> Unit): UniformHistogram1D<V> {
val map = HashMap<Int, V>() val map = HashMap<Int, V>()
@ -104,23 +104,25 @@ public class UniformHistogram1DGroup<V : Any, A>(
* (conserving the norming). * (conserving the norming).
*/ */
@OptIn(UnstableKMathAPI::class) @OptIn(UnstableKMathAPI::class)
public fun produceFrom(histogram: Histogram1D<Double, V>): UniformHistogram1D<V> = public fun produceFrom(
if ((histogram as? UniformHistogram1D)?.group == this) histogram histogram: Histogram1D<Double, V>,
else { ): UniformHistogram1D<V> = if ((histogram as? UniformHistogram1D)?.group == this) {
val map = HashMap<Int, V>() histogram
histogram.bins.forEach { bin -> } else {
val range = bin.domain.range val map = HashMap<Int, V>()
val indexOfLeft = getIndex(range.start) histogram.bins.forEach { bin ->
val indexOfRight = getIndex(range.endInclusive) val range = bin.domain.range
val numBins = indexOfRight - indexOfLeft + 1 val indexOfLeft = getIndex(range.start)
for (i in indexOfLeft..indexOfRight) { val indexOfRight = getIndex(range.endInclusive)
map[indexOfLeft] = with(valueAlgebra) { val numBins = indexOfRight - indexOfLeft + 1
(map[indexOfLeft] ?: zero) + bin.binValue / numBins for (i in indexOfLeft..indexOfRight) {
} map[indexOfLeft] = with(valueAlgebra) {
(map[indexOfLeft] ?: zero) + bin.binValue / numBins
} }
} }
UniformHistogram1D(this, map)
} }
UniformHistogram1D(this, map)
}
} }
public fun <V : Any, A> Histogram.Companion.uniform1D( public fun <V : Any, A> Histogram.Companion.uniform1D(
@ -134,3 +136,21 @@ public fun <V : Any, A> Histogram.Companion.uniform1D(
public fun <V : Any> UniformHistogram1DGroup<V, *>.produce( public fun <V : Any> UniformHistogram1DGroup<V, *>.produce(
buffer: Buffer<Double>, buffer: Buffer<Double>,
): UniformHistogram1D<V> = produce { fill(buffer) } ): UniformHistogram1D<V> = produce { fill(buffer) }
/**
* Map of bin centers to bin values
*/
@OptIn(UnstableKMathAPI::class)
public val <V : Any> UniformHistogram1D<V>.binValues: Map<Double, V>
get() = bins.associate { it.center to it.binValue }
//TODO add normalized values inside Field-based histogram spaces with context receivers
///**
// * Map of bin centers to normalized bin values (bin size as normalization)
// */
//@OptIn(UnstableKMathAPI::class)
//public val <V : Any> UniformHistogram1D<V>.binValuesNormalized: Map<Double, V>
// get() = group.valueAlgebra {
// bins.associate { it.center to it.binValue / group.binSize }
// }