
commonMain.space.kscience.kmath.structures.FlaggedBuffer.kt Maven / Gradle / Ivy
package space.kscience.kmath.structures
import kotlin.experimental.and
/**
* Represents flags to supply additional info about values of buffer.
*
* @property mask bit mask value of this flag.
*/
public enum class ValueFlag(public val mask: Byte) {
/**
* Reports the value is NaN.
*/
NAN(0b0000_0001),
/**
* Reports the value doesn't present in the buffer (when the type of value doesn't support `null`).
*/
MISSING(0b0000_0010),
/**
* Reports the value is negative infinity.
*/
NEGATIVE_INFINITY(0b0000_0100),
/**
* Reports the value is positive infinity
*/
POSITIVE_INFINITY(0b0000_1000)
}
/**
* A buffer with flagged values.
*/
public interface FlaggedBuffer : Buffer {
public fun getFlag(index: Int): Byte
}
/**
* The value is valid if all flags are down
*/
public fun FlaggedBuffer<*>.isValid(index: Int): Boolean = getFlag(index) != 0.toByte()
public fun FlaggedBuffer<*>.hasFlag(index: Int, flag: ValueFlag): Boolean = (getFlag(index) and flag.mask) != 0.toByte()
public fun FlaggedBuffer<*>.isMissing(index: Int): Boolean = hasFlag(index, ValueFlag.MISSING)
/**
* A real buffer which supports flags for each value like NaN or Missing
*/
public class FlaggedRealBuffer(public val values: DoubleArray, public val flags: ByteArray) : FlaggedBuffer,
Buffer {
init {
require(values.size == flags.size) { "Values and flags must have the same dimensions" }
}
override fun getFlag(index: Int): Byte = flags[index]
override val size: Int get() = values.size
override operator fun get(index: Int): Double? = if (isValid(index)) values[index] else null
override operator fun iterator(): Iterator = values.indices.asSequence().map {
if (isValid(it)) values[it] else null
}.iterator()
}
public inline fun FlaggedRealBuffer.forEachValid(block: (Double) -> Unit) {
indices
.asSequence()
.filter(::isValid)
.forEach { block(values[it]) }
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy