All Downloads are FREE. Search and download functionalities are using the official Maven repository.

commonMain.jetbrains.datalore.plot.base.DiscreteTransform.kt Maven / Gradle / Ivy

There is a newer version: 4.5.3-alpha1
Show newest version
/*
 * Copyright (c) 2021. JetBrains s.r.o.
 * Use of this source code is governed by the MIT license that can be found in the LICENSE file.
 */

package jetbrains.datalore.plot.base

import kotlin.math.roundToInt

final class DiscreteTransform(
    private val domainValues: Collection,
    private val domainLimits: List
) : Transform {

    private val indexByDomainValue: Map

    val effectiveDomain: List
    val effectiveDomainTransformed: List

    init {
        effectiveDomain = if (domainLimits.isEmpty()) {
            domainValues.distinct()
        } else {
            domainLimits.distinct()
        }

        indexByDomainValue = effectiveDomain.mapIndexed { index, value -> value to index }.toMap()
        effectiveDomainTransformed = effectiveDomain.map { indexByDomainValue.getValue(it).toDouble() }
    }

    override fun hasDomainLimits(): Boolean {
        return domainLimits.isNotEmpty()
    }

    override fun isInDomain(v: Any?): Boolean {
        return indexByDomainValue.containsKey(v)
    }

    fun indexOf(v: Any): Int {
        return indexByDomainValue.getValue(v)
    }

    override fun apply(l: List<*>): List {
        return l.map { asNumber(it) }
    }

    override fun applyInverse(v: Double?): Any? {
        return fromNumber(v)
    }

    private fun asNumber(input: Any?): Double? {
        if (input == null) {
            return null
        }
        if (indexByDomainValue.containsKey(input)) {
            return indexByDomainValue.getValue(input).toDouble()
        }

        throw IllegalStateException(
            "value $input is not in the domain: ${effectiveDomain}"
        )
    }

    private fun fromNumber(v: Double?): Any? {
        if (v == null || !v.isFinite()) {
            return null
        }

        val i = v.roundToInt()
        return if (i >= 0 && i < effectiveDomain.size) {
            effectiveDomain[i]
        } else {
            null
        }
    }

    companion object {
        fun join(l: List): DiscreteTransform {
            val domainValues = LinkedHashSet()
            val domainLimits = LinkedHashSet()
            for (transform in l) {
                domainValues.addAll(transform.domainValues)
                domainLimits.addAll(transform.domainLimits)
            }
            return DiscreteTransform(domainValues.toList(), domainLimits.toList())
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy