Minor refactoring

This commit is contained in:
Alexander Nozik 2021-11-09 17:56:53 +03:00
parent d62bc66d4a
commit fa9ff4c978
5 changed files with 71 additions and 16 deletions

View File

@ -15,11 +15,24 @@ import space.kscience.kmath.complex.complex
import space.kscience.kmath.operations.invoke
import space.kscience.kmath.structures.Buffer
import space.kscience.kmath.structures.DoubleBuffer
import space.kscience.kmath.structures.getDouble
import space.kscience.kmath.structures.permute
@State(Scope.Benchmark)
internal class BufferBenchmark {
@Benchmark
fun genericDoubleBufferReadWrite(blackhole: Blackhole) {
fun doubleArrayReadWrite(blackhole: Blackhole) {
val buffer = DoubleArray(size) { it.toDouble() }
var res = 0.0
(0 until size).forEach {
res += buffer[it]
}
blackhole.consume(res)
}
@Benchmark
fun doubleBufferReadWrite(blackhole: Blackhole) {
val buffer = DoubleBuffer(size) { it.toDouble() }
var res = 0.0
(0 until size).forEach {
@ -28,6 +41,26 @@ internal class BufferBenchmark {
blackhole.consume(res)
}
@Benchmark
fun bufferViewReadWrite(blackhole: Blackhole) {
val buffer = DoubleBuffer(size) { it.toDouble() }.permute(reversedIndices)
var res = 0.0
(0 until size).forEach {
res += buffer[it]
}
blackhole.consume(res)
}
@Benchmark
fun bufferViewReadWriteSpecialized(blackhole: Blackhole) {
val buffer = DoubleBuffer(size) { it.toDouble() }.permute(reversedIndices)
var res = 0.0
(0 until size).forEach {
res += buffer.getDouble(it)
}
blackhole.consume(res)
}
@Benchmark
fun complexBufferReadWrite(blackhole: Blackhole) = ComplexField {
val buffer = Buffer.complex(size / 2) { Complex(it.toDouble(), -it.toDouble()) }
@ -42,5 +75,6 @@ internal class BufferBenchmark {
private companion object {
private const val size = 100
private val reversedIndices = IntArray(size){it}.apply { reverse() }
}
}

View File

@ -5,6 +5,7 @@ import kotlinx.html.FlowContent
import kotlinx.html.h1
import space.kscience.kmath.operations.algebra
import space.kscience.kmath.operations.bufferAlgebra
import space.kscience.kmath.stat.ksComparisonStatistic
import space.kscience.kmath.structures.Buffer
import space.kscience.kmath.structures.slice
import space.kscience.kmath.structures.toList
@ -34,6 +35,8 @@ fun main() = with(Double.algebra.bufferAlgebra.seriesAlgebra()) {
val s3: Buffer<Double> = s1.zip(s2) { l, r -> l + r } //s1 + s2
val s4 = ln(s3)
val kmTest = ksComparisonStatistic(s1, s2)
Plotly.page {
h1 { +"This is my plot" }
plotSeries(s1)

View File

@ -79,11 +79,19 @@ public class BufferExpanded<T>(
/**
* Zero-copy select a slice inside the original buffer
*/
public fun <T> Buffer<T>.slice(range: UIntRange): BufferView<T> = BufferSlice(
public fun <T> Buffer<T>.slice(range: UIntRange): BufferView<T> = if (this is BufferSlice) {
BufferSlice(
origin,
this.offset + range.first,
(range.last - range.first).toInt() + 1
)
} else {
BufferSlice(
this,
range.first,
(range.last - range.first).toInt() + 1
)
}
/**
* Resize original buffer to a given range using given [range], filling additional segments with [defaultValue].

View File

@ -5,7 +5,8 @@ import space.kscience.kmath.misc.UnstableKMathAPI
/**
* Non-boxing access to primitive [Double]
*/
@OptIn(UnstableKMathAPI::class)
@UnstableKMathAPI
public fun Buffer<Double>.getDouble(index: Int): Double = if (this is BufferView) {
val originIndex = originIndex(index)
if( originIndex>=0) {
@ -22,7 +23,7 @@ public fun Buffer<Double>.getDouble(index: Int): Double = if (this is BufferView
/**
* Non-boxing access to primitive [Int]
*/
@OptIn(UnstableKMathAPI::class)
@UnstableKMathAPI
public fun Buffer<Int>.getInt(index: Int): Int = if (this is BufferView) {
val originIndex = originIndex(index)
if( originIndex>=0) {

View File

@ -1,5 +1,6 @@
package space.kscience.kmath.stat
import space.kscience.kmath.misc.UnstableKMathAPI
import space.kscience.kmath.operations.*
import space.kscience.kmath.structures.Buffer
import space.kscience.kmath.structures.BufferFactory
@ -20,12 +21,20 @@ public fun <T : Comparable<T>> StatisticalAlgebra<T, *, *>.ecdf(buffer: Buffer<T
}
/**
* Resulting value of kolmogorov-smirnov two-sample statistic
*/
@UnstableKMathAPI
public data class KMComparisonResult<T : Comparable<T>>(val n: Int, val m: Int, val value: T)
/**
* Kolmogorov-Smirnov sample comparison test
* Implementation copied from https://commons.apache.org/proper/commons-math/javadocs/api-3.6.1/index.html?org/apache/commons/math3/stat/inference/KolmogorovSmirnovTest.html
*/
public fun <T : Comparable<T>, A, BA : BufferAlgebra<T, A>> StatisticalAlgebra<T, A, BA>.kolmogorovSmirnovTest(
@UnstableKMathAPI
public fun <T : Comparable<T>, A, BA : BufferAlgebra<T, A>> StatisticalAlgebra<T, A, BA>.ksComparisonStatistic(
x: Buffer<T>,
y: Buffer<T>,
): T where A : Group<T>, A : NumericAlgebra<T> = elementAlgebra.invoke {
): KMComparisonResult<T> where A : Group<T>, A : NumericAlgebra<T> = elementAlgebra.invoke {
// Copy and sort the sample arrays
val sx = x.sorted()
val sy = y.sorted()
@ -41,19 +50,19 @@ public fun <T : Comparable<T>, A, BA : BufferAlgebra<T, A>> StatisticalAlgebra<T
do {
val z = if (sx[rankX] <= sy[rankY]) sx[rankX] else sy[rankY]
while (rankX < n && sx[rankX].compareTo(z) == 0) {
rankX += 1;
curD += number(m);
rankX += 1
curD += number(m)
}
while (rankY < m && sy[rankY].compareTo(z) == 0) {
rankY += 1;
curD -= number(n);
rankY += 1
curD -= number(n)
}
when {
curD > supD -> supD = curD
-curD > supD -> supD = -curD
}
} while (rankX < n && rankY < m);
return supD;
} while (rankX < n && rankY < m)
return KMComparisonResult(n, m, supD)
}