Add non-boxing BufferView access

This commit is contained in:
Alexander Nozik 2021-11-09 12:25:17 +03:00
parent 1315a8cd34
commit f6b576071d
5 changed files with 66 additions and 22 deletions

View File

@ -0,0 +1,37 @@
package space.kscience.kmath.structures
import space.kscience.kmath.misc.UnstableKMathAPI
/**
* Non-boxing access to primitive [Double]
*/
@OptIn(UnstableKMathAPI::class)
public fun Buffer<Double>.getDouble(index: Int): Double = if (this is BufferView) {
val originIndex = originIndex(index)
if( originIndex>=0) {
origin.getDouble(originIndex)
} else {
get(index)
}
} else if (this is DoubleBuffer) {
array[index]
} else {
get(index)
}
/**
* Non-boxing access to primitive [Int]
*/
@OptIn(UnstableKMathAPI::class)
public fun Buffer<Int>.getInt(index: Int): Int = if (this is BufferView) {
val originIndex = originIndex(index)
if( originIndex>=0) {
origin.getInt(originIndex)
} else {
get(index)
}
} else if (this is IntBuffer) {
array[index]
} else {
get(index)
}

View File

@ -3,7 +3,7 @@
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
*/
package space.kscience.kmath.stat
package space.kscience.kmath.random
import kotlinx.coroutines.*
import kotlin.contracts.InvocationKind

View File

@ -3,7 +3,7 @@
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
*/
package space.kscience.kmath.stat
package space.kscience.kmath.random
import space.kscience.kmath.chains.BlockingDoubleChain
import space.kscience.kmath.chains.Chain

View File

@ -3,7 +3,7 @@
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
*/
package space.kscience.kmath.stat
package space.kscience.kmath.random
import space.kscience.kmath.structures.DoubleBuffer
import kotlin.random.Random

View File

@ -3,26 +3,33 @@ package space.kscience.kmath.stat
import space.kscience.kmath.structures.Buffer
import space.kscience.kmath.structures.asIterable
public class Rank<T: Comparable<T>>: BlockingStatistic<T, IntArray> {
override fun evaluateBlocking(data: Buffer<T>): IntArray {
// https://www.geeksforgeeks.org/rank-elements-array/
val permutations = ArrayList<Pair<T, Int>>(data.size)
data.asIterable().mapIndexedTo(permutations) { i, v -> v to i }
permutations.sortBy { it.first }
var rank = 1
var i = 0
val r = IntArray(data.size) { 0 }
while (i < data.size) {
var j = i
while (j < data.size - 1 && permutations[j].first == permutations[j + 1]) ++j
val n = j - i + 1
(0 until n).map { k ->
val idx = permutations[i + k].second
r[idx] = rank + ((n - 1) * 0.5f).toInt()
/**
* Rank statistics
*/
public class Rank<T : Comparable<T>> : BlockingStatistic<T, IntArray> {
override fun evaluateBlocking(data: Buffer<T>): IntArray = Companion.evaluate(data)
public companion object {
public fun <T : Comparable<T>> evaluate(data: Buffer<T>): IntArray {
// https://www.geeksforgeeks.org/rank-elements-array/
val permutations = ArrayList<Pair<T, Int>>(data.size)
data.asIterable().mapIndexedTo(permutations) { i, v -> v to i }
permutations.sortBy { it.first }
var rank = 1
var i = 0
val r = IntArray(data.size)
while (i < data.size) {
var j = i
while (j < data.size - 1 && permutations[j].first == permutations[j + 1]) ++j
val n = j - i + 1
(0 until n).map { k ->
val idx = permutations[i + k].second
r[idx] = rank + ((n - 1) * 0.5f).toInt()
}
rank += n
i += n
}
rank += n
i += n
return r
}
return r
}
}