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

org.nield.kotlinstatistics.BigDecimalStatistics.kt Maven / Gradle / Ivy

There is a newer version: 1.2.1
Show newest version
package org.nield.kotlinstatistics

import java.math.BigDecimal
import java.util.concurrent.atomic.AtomicBoolean

fun Sequence.sum() = fold(BigDecimal.ZERO) { x,y -> x + y }!!
fun Iterable.sum() = fold(BigDecimal.ZERO) { x,y -> x + y }!!

fun Sequence.average() = toList().let { list ->
    list.sum() / BigDecimal.valueOf(list.count().toDouble())
}
fun Iterable.average() = asSequence().average()




// AGGREGATION OPERATORS


inline fun  Sequence.sumBy(crossinline keySelector: (T) -> K, crossinline bigDecimalSelector: (T) -> BigDecimal) =
        groupApply(keySelector, bigDecimalSelector) { it.sum() }

inline fun  Iterable.sumBy(crossinline keySelector: (T) -> K, crossinline bigDecimalSelector: (T) -> BigDecimal) =
        asSequence().sumBy(keySelector, bigDecimalSelector)

fun  Sequence>.sumBy() =
        groupApply({it.first}, {it.second}) { it.sum() }

fun  Iterable>.sumBy() = asSequence().sumBy()




inline fun  Sequence.averageBy(crossinline keySelector: (T) -> K, crossinline bigDecimalSelector: (T) -> BigDecimal) =
        groupApply(keySelector, bigDecimalSelector) { it.average() }

inline fun  Iterable.averageBy(crossinline keySelector: (T) -> K, crossinline bigDecimalSelector: (T) -> BigDecimal) =
        asSequence().averageBy(keySelector, bigDecimalSelector)

fun  Sequence>.averageBy() =
        groupApply({it.first}, {it.second}) { it.average() }

fun  Iterable>.averageBy() = asSequence().averageBy()




// bin operators


inline fun  Sequence.binByBigDecimal(binSize: BigDecimal,
                                           gapSize: BigDecimal,
                                           crossinline valueSelector: (T) -> BigDecimal,
                                           rangeStart: BigDecimal? = null
) = toList().binByBigDecimal(binSize, gapSize, valueSelector, { it }, rangeStart)

inline fun  Sequence.binByBigDecimal(binSize: BigDecimal,
                                              gapSize: BigDecimal,
                                              crossinline valueSelector: (T) -> BigDecimal,
                                              crossinline groupOp: (List) -> G,
                                              rangeStart: BigDecimal? = null
) = toList().binByBigDecimal(binSize, gapSize, valueSelector, groupOp, rangeStart)

inline fun  Iterable.binByBigDecimal(binSize: BigDecimal,
                                       gapSize: BigDecimal,
                                       crossinline valueSelector: (T) -> BigDecimal,
                                       rangeStart: BigDecimal? = null
) = toList().binByBigDecimal(binSize, gapSize, valueSelector, { it }, rangeStart)

inline fun  Iterable.binByBigDecimal(binSize: BigDecimal,
                                          gapSize: BigDecimal,
                                          crossinline valueSelector: (T) -> BigDecimal,
                                          crossinline groupOp: (List) -> G,
                                          rangeStart: BigDecimal? = null
) = toList().binByBigDecimal(binSize, gapSize, valueSelector, groupOp, rangeStart)

inline fun  List.binByBigDecimal(binSize: BigDecimal,
                                       gapSize: BigDecimal,
                                       crossinline valueSelector: (T) -> BigDecimal,
                                       rangeStart: BigDecimal? = null
): BinModel, BigDecimal> = binByBigDecimal(binSize, gapSize, valueSelector, { it }, rangeStart)

inline fun  List.binByBigDecimal(binSize: BigDecimal,
                                          gapSize: BigDecimal,
                                          crossinline valueSelector: (T) -> BigDecimal,
                                          crossinline groupOp: (List) -> G,
                                          rangeStart: BigDecimal? = null
): BinModel {

    val groupedByC = asSequence().groupBy(valueSelector)
    val minC = rangeStart?:groupedByC.keys.min()!!
    val maxC = groupedByC.keys.max()!!

    val bins = mutableListOf>().apply {
        var currentRangeStart = minC
        var currentRangeEnd = minC
        val isFirst = AtomicBoolean(true)
        while  (currentRangeEnd < maxC) {
            currentRangeEnd = currentRangeStart + binSize - if (isFirst.getAndSet(false)) BigDecimal.ZERO else gapSize
            add(currentRangeStart..currentRangeEnd)
            currentRangeStart = currentRangeEnd + gapSize
        }
    }

    return bins.asSequence()
            .map { it to mutableListOf() }
            .map { binWithList ->
                groupedByC.entries.asSequence()
                        .filter { it.key in binWithList.first }
                        .forEach { binWithList.second.addAll(it.value) }
                binWithList
            }.map { Bin(it.first, groupOp(it.second)) }
            .toList()
            .let(::BinModel)
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy