diff --git a/build.gradle b/build.gradle index bce9c1492..1d08c5527 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,5 @@ buildscript { - ext.kotlin_version = '1.2.60' + ext.kotlin_version = '1.2.61' repositories { mavenCentral() diff --git a/kmath-common/src/main/kotlin/scientifik/kmath/misc/Cumulative.kt b/kmath-common/src/main/kotlin/scientifik/kmath/misc/Cumulative.kt new file mode 100644 index 000000000..4d4f8ced6 --- /dev/null +++ b/kmath-common/src/main/kotlin/scientifik/kmath/misc/Cumulative.kt @@ -0,0 +1,59 @@ +package scientifik.kmath.misc + +import kotlin.jvm.JvmName + + +/** + * Generic cumulative operation on iterator + * @param T type of initial iterable + * @param R type of resulting iterable + * @param initial lazy evaluated + */ +fun Iterator.cumulative(initial: R, operation: (T, R) -> R): Iterator = object : Iterator { + var state: R = initial + override fun hasNext(): Boolean = this@cumulative.hasNext() + + override fun next(): R { + state = operation.invoke(this@cumulative.next(), state) + return state + } +} + +fun Iterable.cumulative(initial: R, operation: (T, R) -> R): Iterable = object : Iterable { + override fun iterator(): Iterator = this@cumulative.iterator().cumulative(initial, operation) +} + +fun Sequence.cumulative(initial: R, operation: (T, R) -> R): Sequence = object : Sequence { + override fun iterator(): Iterator = this@cumulative.iterator().cumulative(initial, operation) +} + +fun List.cumulative(initial: R, operation: (T, R) -> R): List = this.iterator().cumulative(initial, operation).asSequence().toList() + +//Cumulative sum + +@JvmName("cumulativeSumOfDouble") +fun Iterable.cumulativeSum() = this.cumulative(0.0){ element, sum -> sum + element} + +@JvmName("cumulativeSumOfInt") +fun Iterable.cumulativeSum() = this.cumulative(0){ element, sum -> sum + element} + +@JvmName("cumulativeSumOfLong") +fun Iterable.cumulativeSum() = this.cumulative(0L){ element, sum -> sum + element} + +@JvmName("cumulativeSumOfDouble") +fun Sequence.cumulativeSum() = this.cumulative(0.0){ element, sum -> sum + element} + +@JvmName("cumulativeSumOfInt") +fun Sequence.cumulativeSum() = this.cumulative(0){ element, sum -> sum + element} + +@JvmName("cumulativeSumOfLong") +fun Sequence.cumulativeSum() = this.cumulative(0L){ element, sum -> sum + element} + +@JvmName("cumulativeSumOfDouble") +fun List.cumulativeSum() = this.cumulative(0.0){ element, sum -> sum + element} + +@JvmName("cumulativeSumOfInt") +fun List.cumulativeSum() = this.cumulative(0){ element, sum -> sum + element} + +@JvmName("cumulativeSumOfLong") +fun List.cumulativeSum() = this.cumulative(0L){ element, sum -> sum + element} \ No newline at end of file diff --git a/kmath-common/src/test/kotlin/scientifik.kmath.misc/CumulativeKtTest.kt b/kmath-common/src/test/kotlin/scientifik.kmath.misc/CumulativeKtTest.kt new file mode 100644 index 000000000..e7c99e7d0 --- /dev/null +++ b/kmath-common/src/test/kotlin/scientifik.kmath.misc/CumulativeKtTest.kt @@ -0,0 +1,13 @@ +package scientifik.kmath.misc + +import kotlin.test.Test +import kotlin.test.assertEquals + +class CumulativeKtTest { + @Test + fun testCumulativeSum() { + val initial = listOf(-1.0, 2.0, 1.0, 1.0) + val cumulative = initial.cumulativeSum() + assertEquals(listOf(-1.0, 1.0, 2.0, 3.0), cumulative) + } +} \ No newline at end of file