0.3.1-dev-11 #510
@ -15,11 +15,24 @@ import space.kscience.kmath.complex.complex
|
|||||||
import space.kscience.kmath.operations.invoke
|
import space.kscience.kmath.operations.invoke
|
||||||
import space.kscience.kmath.structures.Buffer
|
import space.kscience.kmath.structures.Buffer
|
||||||
import space.kscience.kmath.structures.DoubleBuffer
|
import space.kscience.kmath.structures.DoubleBuffer
|
||||||
|
import space.kscience.kmath.structures.getDouble
|
||||||
|
import space.kscience.kmath.structures.permute
|
||||||
|
|
||||||
@State(Scope.Benchmark)
|
@State(Scope.Benchmark)
|
||||||
internal class BufferBenchmark {
|
internal class BufferBenchmark {
|
||||||
|
|
||||||
@Benchmark
|
@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() }
|
val buffer = DoubleBuffer(size) { it.toDouble() }
|
||||||
var res = 0.0
|
var res = 0.0
|
||||||
(0 until size).forEach {
|
(0 until size).forEach {
|
||||||
@ -28,6 +41,26 @@ internal class BufferBenchmark {
|
|||||||
blackhole.consume(res)
|
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
|
@Benchmark
|
||||||
fun complexBufferReadWrite(blackhole: Blackhole) = ComplexField {
|
fun complexBufferReadWrite(blackhole: Blackhole) = ComplexField {
|
||||||
val buffer = Buffer.complex(size / 2) { Complex(it.toDouble(), -it.toDouble()) }
|
val buffer = Buffer.complex(size / 2) { Complex(it.toDouble(), -it.toDouble()) }
|
||||||
@ -42,5 +75,6 @@ internal class BufferBenchmark {
|
|||||||
|
|
||||||
private companion object {
|
private companion object {
|
||||||
private const val size = 100
|
private const val size = 100
|
||||||
|
private val reversedIndices = IntArray(size){it}.apply { reverse() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ import kotlinx.html.FlowContent
|
|||||||
import kotlinx.html.h1
|
import kotlinx.html.h1
|
||||||
import space.kscience.kmath.operations.algebra
|
import space.kscience.kmath.operations.algebra
|
||||||
import space.kscience.kmath.operations.bufferAlgebra
|
import space.kscience.kmath.operations.bufferAlgebra
|
||||||
|
import space.kscience.kmath.stat.ksComparisonStatistic
|
||||||
import space.kscience.kmath.structures.Buffer
|
import space.kscience.kmath.structures.Buffer
|
||||||
import space.kscience.kmath.structures.slice
|
import space.kscience.kmath.structures.slice
|
||||||
import space.kscience.kmath.structures.toList
|
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 s3: Buffer<Double> = s1.zip(s2) { l, r -> l + r } //s1 + s2
|
||||||
val s4 = ln(s3)
|
val s4 = ln(s3)
|
||||||
|
|
||||||
|
val kmTest = ksComparisonStatistic(s1, s2)
|
||||||
|
|
||||||
Plotly.page {
|
Plotly.page {
|
||||||
h1 { +"This is my plot" }
|
h1 { +"This is my plot" }
|
||||||
plotSeries(s1)
|
plotSeries(s1)
|
||||||
|
@ -79,11 +79,19 @@ public class BufferExpanded<T>(
|
|||||||
/**
|
/**
|
||||||
* Zero-copy select a slice inside the original buffer
|
* 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) {
|
||||||
this,
|
BufferSlice(
|
||||||
range.first,
|
origin,
|
||||||
(range.last - range.first).toInt() + 1
|
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].
|
* Resize original buffer to a given range using given [range], filling additional segments with [defaultValue].
|
||||||
|
@ -5,7 +5,8 @@ import space.kscience.kmath.misc.UnstableKMathAPI
|
|||||||
/**
|
/**
|
||||||
* Non-boxing access to primitive [Double]
|
* Non-boxing access to primitive [Double]
|
||||||
*/
|
*/
|
||||||
@OptIn(UnstableKMathAPI::class)
|
|
||||||
|
@UnstableKMathAPI
|
||||||
public fun Buffer<Double>.getDouble(index: Int): Double = if (this is BufferView) {
|
public fun Buffer<Double>.getDouble(index: Int): Double = if (this is BufferView) {
|
||||||
val originIndex = originIndex(index)
|
val originIndex = originIndex(index)
|
||||||
if( originIndex>=0) {
|
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]
|
* Non-boxing access to primitive [Int]
|
||||||
*/
|
*/
|
||||||
@OptIn(UnstableKMathAPI::class)
|
@UnstableKMathAPI
|
||||||
public fun Buffer<Int>.getInt(index: Int): Int = if (this is BufferView) {
|
public fun Buffer<Int>.getInt(index: Int): Int = if (this is BufferView) {
|
||||||
val originIndex = originIndex(index)
|
val originIndex = originIndex(index)
|
||||||
if( originIndex>=0) {
|
if( originIndex>=0) {
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package space.kscience.kmath.stat
|
package space.kscience.kmath.stat
|
||||||
|
|
||||||
|
import space.kscience.kmath.misc.UnstableKMathAPI
|
||||||
import space.kscience.kmath.operations.*
|
import space.kscience.kmath.operations.*
|
||||||
import space.kscience.kmath.structures.Buffer
|
import space.kscience.kmath.structures.Buffer
|
||||||
import space.kscience.kmath.structures.BufferFactory
|
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
|
* 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>,
|
x: Buffer<T>,
|
||||||
y: 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
|
// Copy and sort the sample arrays
|
||||||
val sx = x.sorted()
|
val sx = x.sorted()
|
||||||
val sy = y.sorted()
|
val sy = y.sorted()
|
||||||
@ -41,19 +50,19 @@ public fun <T : Comparable<T>, A, BA : BufferAlgebra<T, A>> StatisticalAlgebra<T
|
|||||||
do {
|
do {
|
||||||
val z = if (sx[rankX] <= sy[rankY]) sx[rankX] else sy[rankY]
|
val z = if (sx[rankX] <= sy[rankY]) sx[rankX] else sy[rankY]
|
||||||
while (rankX < n && sx[rankX].compareTo(z) == 0) {
|
while (rankX < n && sx[rankX].compareTo(z) == 0) {
|
||||||
rankX += 1;
|
rankX += 1
|
||||||
curD += number(m);
|
curD += number(m)
|
||||||
}
|
}
|
||||||
|
|
||||||
while (rankY < m && sy[rankY].compareTo(z) == 0) {
|
while (rankY < m && sy[rankY].compareTo(z) == 0) {
|
||||||
rankY += 1;
|
rankY += 1
|
||||||
curD -= number(n);
|
curD -= number(n)
|
||||||
}
|
}
|
||||||
|
|
||||||
when {
|
when {
|
||||||
curD > supD -> supD = curD
|
curD > supD -> supD = curD
|
||||||
-curD > supD -> supD = -curD
|
-curD > supD -> supD = -curD
|
||||||
}
|
}
|
||||||
} while (rankX < n && rankY < m);
|
} while (rankX < n && rankY < m)
|
||||||
return supD;
|
return KMComparisonResult(n, m, supD)
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user