forked from kscience/kmath
Merge remote-tracking branch 'origin/dev' into adv-expr
This commit is contained in:
commit
27605aee82
@ -2,7 +2,7 @@
|
|||||||
Buffer is one of main building blocks of kmath. It is a basic interface allowing random-access read and write (with `MutableBuffer`).
|
Buffer is one of main building blocks of kmath. It is a basic interface allowing random-access read and write (with `MutableBuffer`).
|
||||||
There are different types of buffers:
|
There are different types of buffers:
|
||||||
|
|
||||||
* Primitive buffers wrapping like `DoubleBuffer` which are wrapping primitive arrays.
|
* Primitive buffers wrapping like `RealBuffer` which are wrapping primitive arrays.
|
||||||
* Boxing `ListBuffer` wrapping a list
|
* Boxing `ListBuffer` wrapping a list
|
||||||
* Functionally defined `VirtualBuffer` which does not hold a state itself, but provides a function to calculate value
|
* Functionally defined `VirtualBuffer` which does not hold a state itself, but provides a function to calculate value
|
||||||
* `MemoryBuffer` allows direct allocation of objects in continuous memory block.
|
* `MemoryBuffer` allows direct allocation of objects in continuous memory block.
|
||||||
|
@ -10,8 +10,8 @@ import scientifik.kmath.operations.complex
|
|||||||
class BufferBenchmark {
|
class BufferBenchmark {
|
||||||
|
|
||||||
@Benchmark
|
@Benchmark
|
||||||
fun genericDoubleBufferReadWrite() {
|
fun genericRealBufferReadWrite() {
|
||||||
val buffer = DoubleBuffer(size){it.toDouble()}
|
val buffer = RealBuffer(size){it.toDouble()}
|
||||||
|
|
||||||
(0 until size).forEach {
|
(0 until size).forEach {
|
||||||
buffer[it]
|
buffer[it]
|
||||||
|
@ -6,7 +6,7 @@ fun main(args: Array<String>) {
|
|||||||
val n = 6000
|
val n = 6000
|
||||||
|
|
||||||
val array = DoubleArray(n * n) { 1.0 }
|
val array = DoubleArray(n * n) { 1.0 }
|
||||||
val buffer = DoubleBuffer(array)
|
val buffer = RealBuffer(array)
|
||||||
val strides = DefaultStrides(intArrayOf(n, n))
|
val strides = DefaultStrides(intArrayOf(n, n))
|
||||||
|
|
||||||
val structure = BufferNDStructure(strides, buffer)
|
val structure = BufferNDStructure(strides, buffer)
|
||||||
|
@ -26,10 +26,10 @@ fun main(args: Array<String>) {
|
|||||||
}
|
}
|
||||||
println("Array mapping finished in $time2 millis")
|
println("Array mapping finished in $time2 millis")
|
||||||
|
|
||||||
val buffer = DoubleBuffer(DoubleArray(n * n) { 1.0 })
|
val buffer = RealBuffer(DoubleArray(n * n) { 1.0 })
|
||||||
|
|
||||||
val time3 = measureTimeMillis {
|
val time3 = measureTimeMillis {
|
||||||
val target = DoubleBuffer(DoubleArray(n * n))
|
val target = RealBuffer(DoubleArray(n * n))
|
||||||
val res = array.forEachIndexed { index, value ->
|
val res = array.forEachIndexed { index, value ->
|
||||||
target[index] = value + 1
|
target[index] = value + 1
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@ object Transformations {
|
|||||||
private fun Buffer<Complex>.toArray(): Array<org.apache.commons.math3.complex.Complex> =
|
private fun Buffer<Complex>.toArray(): Array<org.apache.commons.math3.complex.Complex> =
|
||||||
Array(size) { org.apache.commons.math3.complex.Complex(get(it).re, get(it).im) }
|
Array(size) { org.apache.commons.math3.complex.Complex(get(it).re, get(it).im) }
|
||||||
|
|
||||||
private fun Buffer<Double>.asArray() = if (this is DoubleBuffer) {
|
private fun Buffer<Double>.asArray() = if (this is RealBuffer) {
|
||||||
array
|
array
|
||||||
} else {
|
} else {
|
||||||
DoubleArray(size) { i -> get(i) }
|
DoubleArray(size) { i -> get(i) }
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
package scientifik.kmath.domains
|
package scientifik.kmath.domains
|
||||||
|
|
||||||
import scientifik.kmath.linear.Point
|
import scientifik.kmath.linear.Point
|
||||||
import scientifik.kmath.structures.DoubleBuffer
|
import scientifik.kmath.structures.RealBuffer
|
||||||
import scientifik.kmath.structures.indices
|
import scientifik.kmath.structures.indices
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -25,7 +25,7 @@ import scientifik.kmath.structures.indices
|
|||||||
*
|
*
|
||||||
* @author Alexander Nozik
|
* @author Alexander Nozik
|
||||||
*/
|
*/
|
||||||
class HyperSquareDomain(private val lower: DoubleBuffer, private val upper: DoubleBuffer) : RealDomain {
|
class HyperSquareDomain(private val lower: RealBuffer, private val upper: RealBuffer) : RealDomain {
|
||||||
|
|
||||||
override operator fun contains(point: Point<Double>): Boolean = point.indices.all { i ->
|
override operator fun contains(point: Point<Double>): Boolean = point.indices.all { i ->
|
||||||
point[i] in lower[i]..upper[i]
|
point[i] in lower[i]..upper[i]
|
||||||
@ -49,7 +49,7 @@ class HyperSquareDomain(private val lower: DoubleBuffer, private val upper: Doub
|
|||||||
else -> point[i]
|
else -> point[i]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return DoubleBuffer(*res)
|
return RealBuffer(*res)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun volume(): Double {
|
override fun volume(): Double {
|
||||||
|
@ -30,11 +30,11 @@ object RealMatrixContext : GenericMatrixContext<Double, RealField> {
|
|||||||
override val elementContext get() = RealField
|
override val elementContext get() = RealField
|
||||||
|
|
||||||
override inline fun produce(rows: Int, columns: Int, initializer: (i: Int, j: Int) -> Double): Matrix<Double> {
|
override inline fun produce(rows: Int, columns: Int, initializer: (i: Int, j: Int) -> Double): Matrix<Double> {
|
||||||
val buffer = DoubleBuffer(rows * columns) { offset -> initializer(offset / columns, offset % columns) }
|
val buffer = RealBuffer(rows * columns) { offset -> initializer(offset / columns, offset % columns) }
|
||||||
return BufferMatrix(rows, columns, buffer)
|
return BufferMatrix(rows, columns, buffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
override inline fun point(size: Int, initializer: (Int) -> Double): Point<Double> = DoubleBuffer(size,initializer)
|
override inline fun point(size: Int, initializer: (Int) -> Double): Point<Double> = RealBuffer(size,initializer)
|
||||||
}
|
}
|
||||||
|
|
||||||
class BufferMatrix<T : Any>(
|
class BufferMatrix<T : Any>(
|
||||||
@ -102,7 +102,7 @@ infix fun BufferMatrix<Double>.dot(other: BufferMatrix<Double>): BufferMatrix<Do
|
|||||||
val array = DoubleArray(this.rowNum * other.colNum)
|
val array = DoubleArray(this.rowNum * other.colNum)
|
||||||
|
|
||||||
//convert to array to insure there is not memory indirection
|
//convert to array to insure there is not memory indirection
|
||||||
fun Buffer<out Double>.unsafeArray(): DoubleArray = if (this is DoubleBuffer) {
|
fun Buffer<out Double>.unsafeArray(): DoubleArray = if (this is RealBuffer) {
|
||||||
array
|
array
|
||||||
} else {
|
} else {
|
||||||
DoubleArray(size) { get(it) }
|
DoubleArray(size) { get(it) }
|
||||||
@ -119,6 +119,6 @@ infix fun BufferMatrix<Double>.dot(other: BufferMatrix<Double>): BufferMatrix<Do
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val buffer = DoubleBuffer(array)
|
val buffer = RealBuffer(array)
|
||||||
return BufferMatrix(rowNum, other.colNum, buffer)
|
return BufferMatrix(rowNum, other.colNum, buffer)
|
||||||
}
|
}
|
@ -37,9 +37,9 @@ interface Buffer<T> {
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
inline fun real(size: Int, initializer: (Int) -> Double): DoubleBuffer {
|
inline fun real(size: Int, initializer: (Int) -> Double): RealBuffer {
|
||||||
val array = DoubleArray(size) { initializer(it) }
|
val array = DoubleArray(size) { initializer(it) }
|
||||||
return DoubleBuffer(array)
|
return RealBuffer(array)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -51,7 +51,7 @@ interface Buffer<T> {
|
|||||||
inline fun <T : Any> auto(type: KClass<T>, size: Int, crossinline initializer: (Int) -> T): Buffer<T> {
|
inline fun <T : Any> auto(type: KClass<T>, size: Int, crossinline initializer: (Int) -> T): Buffer<T> {
|
||||||
//TODO add resolution based on Annotation or companion resolution
|
//TODO add resolution based on Annotation or companion resolution
|
||||||
return when (type) {
|
return when (type) {
|
||||||
Double::class -> DoubleBuffer(DoubleArray(size) { initializer(it) as Double }) as Buffer<T>
|
Double::class -> RealBuffer(DoubleArray(size) { initializer(it) as Double }) as Buffer<T>
|
||||||
Short::class -> ShortBuffer(ShortArray(size) { initializer(it) as Short }) as Buffer<T>
|
Short::class -> ShortBuffer(ShortArray(size) { initializer(it) as Short }) as Buffer<T>
|
||||||
Int::class -> IntBuffer(IntArray(size) { initializer(it) as Int }) as Buffer<T>
|
Int::class -> IntBuffer(IntArray(size) { initializer(it) as Int }) as Buffer<T>
|
||||||
Long::class -> LongBuffer(LongArray(size) { initializer(it) as Long }) as Buffer<T>
|
Long::class -> LongBuffer(LongArray(size) { initializer(it) as Long }) as Buffer<T>
|
||||||
@ -93,7 +93,7 @@ interface MutableBuffer<T> : Buffer<T> {
|
|||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
inline fun <T : Any> auto(type: KClass<out T>, size: Int, initializer: (Int) -> T): MutableBuffer<T> {
|
inline fun <T : Any> auto(type: KClass<out T>, size: Int, initializer: (Int) -> T): MutableBuffer<T> {
|
||||||
return when (type) {
|
return when (type) {
|
||||||
Double::class -> DoubleBuffer(DoubleArray(size) { initializer(it) as Double }) as MutableBuffer<T>
|
Double::class -> RealBuffer(DoubleArray(size) { initializer(it) as Double }) as MutableBuffer<T>
|
||||||
Short::class -> ShortBuffer(ShortArray(size) { initializer(it) as Short }) as MutableBuffer<T>
|
Short::class -> ShortBuffer(ShortArray(size) { initializer(it) as Short }) as MutableBuffer<T>
|
||||||
Int::class -> IntBuffer(IntArray(size) { initializer(it) as Int }) as MutableBuffer<T>
|
Int::class -> IntBuffer(IntArray(size) { initializer(it) as Int }) as MutableBuffer<T>
|
||||||
Long::class -> LongBuffer(LongArray(size) { initializer(it) as Long }) as MutableBuffer<T>
|
Long::class -> LongBuffer(LongArray(size) { initializer(it) as Long }) as MutableBuffer<T>
|
||||||
@ -109,12 +109,11 @@ interface MutableBuffer<T> : Buffer<T> {
|
|||||||
auto(T::class, size, initializer)
|
auto(T::class, size, initializer)
|
||||||
|
|
||||||
val real: MutableBufferFactory<Double> = { size: Int, initializer: (Int) -> Double ->
|
val real: MutableBufferFactory<Double> = { size: Int, initializer: (Int) -> Double ->
|
||||||
DoubleBuffer(DoubleArray(size) { initializer(it) })
|
RealBuffer(DoubleArray(size) { initializer(it) })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline class ListBuffer<T>(val list: List<T>) : Buffer<T> {
|
inline class ListBuffer<T>(val list: List<T>) : Buffer<T> {
|
||||||
|
|
||||||
override val size: Int
|
override val size: Int
|
||||||
@ -163,57 +162,6 @@ class ArrayBuffer<T>(private val array: Array<T>) : MutableBuffer<T> {
|
|||||||
|
|
||||||
fun <T> Array<T>.asBuffer(): ArrayBuffer<T> = ArrayBuffer(this)
|
fun <T> Array<T>.asBuffer(): ArrayBuffer<T> = ArrayBuffer(this)
|
||||||
|
|
||||||
inline class ShortBuffer(val array: ShortArray) : MutableBuffer<Short> {
|
|
||||||
override val size: Int get() = array.size
|
|
||||||
|
|
||||||
override fun get(index: Int): Short = array[index]
|
|
||||||
|
|
||||||
override fun set(index: Int, value: Short) {
|
|
||||||
array[index] = value
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun iterator() = array.iterator()
|
|
||||||
|
|
||||||
override fun copy(): MutableBuffer<Short> = ShortBuffer(array.copyOf())
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
fun ShortArray.asBuffer() = ShortBuffer(this)
|
|
||||||
|
|
||||||
inline class IntBuffer(val array: IntArray) : MutableBuffer<Int> {
|
|
||||||
override val size: Int get() = array.size
|
|
||||||
|
|
||||||
override fun get(index: Int): Int = array[index]
|
|
||||||
|
|
||||||
override fun set(index: Int, value: Int) {
|
|
||||||
array[index] = value
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun iterator() = array.iterator()
|
|
||||||
|
|
||||||
override fun copy(): MutableBuffer<Int> = IntBuffer(array.copyOf())
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
fun IntArray.asBuffer() = IntBuffer(this)
|
|
||||||
|
|
||||||
inline class LongBuffer(val array: LongArray) : MutableBuffer<Long> {
|
|
||||||
override val size: Int get() = array.size
|
|
||||||
|
|
||||||
override fun get(index: Int): Long = array[index]
|
|
||||||
|
|
||||||
override fun set(index: Int, value: Long) {
|
|
||||||
array[index] = value
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun iterator() = array.iterator()
|
|
||||||
|
|
||||||
override fun copy(): MutableBuffer<Long> = LongBuffer(array.copyOf())
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
fun LongArray.asBuffer() = LongBuffer(this)
|
|
||||||
|
|
||||||
inline class ReadOnlyBuffer<T>(val buffer: MutableBuffer<T>) : Buffer<T> {
|
inline class ReadOnlyBuffer<T>(val buffer: MutableBuffer<T>) : Buffer<T> {
|
||||||
override val size: Int get() = buffer.size
|
override val size: Int get() = buffer.size
|
||||||
|
|
||||||
|
@ -0,0 +1,53 @@
|
|||||||
|
package scientifik.kmath.structures
|
||||||
|
|
||||||
|
import kotlin.experimental.and
|
||||||
|
|
||||||
|
enum class ValueFlag(val mask: Byte) {
|
||||||
|
NAN(0b0000_0001),
|
||||||
|
MISSING(0b0000_0010),
|
||||||
|
NEGATIVE_INFINITY(0b0000_0100),
|
||||||
|
POSITIVE_INFINITY(0b0000_1000)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A buffer with flagged values
|
||||||
|
*/
|
||||||
|
interface FlaggedBuffer<T> : Buffer<T> {
|
||||||
|
fun getFlag(index: Int): Byte
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The value is valid if all flags are down
|
||||||
|
*/
|
||||||
|
fun FlaggedBuffer<*>.isValid(index: Int) = getFlag(index) != 0.toByte()
|
||||||
|
|
||||||
|
fun FlaggedBuffer<*>.hasFlag(index: Int, flag: ValueFlag) = (getFlag(index) and flag.mask) != 0.toByte()
|
||||||
|
|
||||||
|
fun FlaggedBuffer<*>.isMissing(index: Int) = hasFlag(index, ValueFlag.MISSING)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A real buffer which supports flags for each value like NaN or Missing
|
||||||
|
*/
|
||||||
|
class FlaggedRealBuffer(val values: DoubleArray, val flags: ByteArray) : FlaggedBuffer<Double?>, Buffer<Double?> {
|
||||||
|
init {
|
||||||
|
require(values.size == flags.size) { "Values and flags must have the same dimensions" }
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getFlag(index: Int): Byte = flags[index]
|
||||||
|
|
||||||
|
override val size: Int get() = values.size
|
||||||
|
|
||||||
|
override fun get(index: Int): Double? = if (isValid(index)) values[index] else null
|
||||||
|
|
||||||
|
override fun iterator(): Iterator<Double?> = values.indices.asSequence().map {
|
||||||
|
if (isValid(it)) values[it] else null
|
||||||
|
}.iterator()
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun FlaggedRealBuffer.forEachValid(block: (Double) -> Unit) {
|
||||||
|
for(i in indices){
|
||||||
|
if(isValid(i)){
|
||||||
|
block(values[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
package scientifik.kmath.structures
|
||||||
|
|
||||||
|
inline class IntBuffer(val array: IntArray) : MutableBuffer<Int> {
|
||||||
|
override val size: Int get() = array.size
|
||||||
|
|
||||||
|
override fun get(index: Int): Int = array[index]
|
||||||
|
|
||||||
|
override fun set(index: Int, value: Int) {
|
||||||
|
array[index] = value
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun iterator() = array.iterator()
|
||||||
|
|
||||||
|
override fun copy(): MutableBuffer<Int> =
|
||||||
|
IntBuffer(array.copyOf())
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun IntArray.asBuffer() = IntBuffer(this)
|
@ -0,0 +1,19 @@
|
|||||||
|
package scientifik.kmath.structures
|
||||||
|
|
||||||
|
inline class LongBuffer(val array: LongArray) : MutableBuffer<Long> {
|
||||||
|
override val size: Int get() = array.size
|
||||||
|
|
||||||
|
override fun get(index: Int): Long = array[index]
|
||||||
|
|
||||||
|
override fun set(index: Int, value: Long) {
|
||||||
|
array[index] = value
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun iterator() = array.iterator()
|
||||||
|
|
||||||
|
override fun copy(): MutableBuffer<Long> =
|
||||||
|
LongBuffer(array.copyOf())
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fun LongArray.asBuffer() = LongBuffer(this)
|
@ -1,6 +1,6 @@
|
|||||||
package scientifik.kmath.structures
|
package scientifik.kmath.structures
|
||||||
|
|
||||||
inline class DoubleBuffer(val array: DoubleArray) : MutableBuffer<Double> {
|
inline class RealBuffer(val array: DoubleArray) : MutableBuffer<Double> {
|
||||||
override val size: Int get() = array.size
|
override val size: Int get() = array.size
|
||||||
|
|
||||||
override fun get(index: Int): Double = array[index]
|
override fun get(index: Int): Double = array[index]
|
||||||
@ -12,23 +12,23 @@ inline class DoubleBuffer(val array: DoubleArray) : MutableBuffer<Double> {
|
|||||||
override fun iterator() = array.iterator()
|
override fun iterator() = array.iterator()
|
||||||
|
|
||||||
override fun copy(): MutableBuffer<Double> =
|
override fun copy(): MutableBuffer<Double> =
|
||||||
DoubleBuffer(array.copyOf())
|
RealBuffer(array.copyOf())
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("FunctionName")
|
@Suppress("FunctionName")
|
||||||
inline fun DoubleBuffer(size: Int, init: (Int) -> Double): DoubleBuffer = DoubleBuffer(DoubleArray(size) { init(it) })
|
inline fun RealBuffer(size: Int, init: (Int) -> Double): RealBuffer = RealBuffer(DoubleArray(size) { init(it) })
|
||||||
|
|
||||||
@Suppress("FunctionName")
|
@Suppress("FunctionName")
|
||||||
fun DoubleBuffer(vararg doubles: Double): DoubleBuffer = DoubleBuffer(doubles)
|
fun RealBuffer(vararg doubles: Double): RealBuffer = RealBuffer(doubles)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Transform buffer of doubles into array for high performance operations
|
* Transform buffer of doubles into array for high performance operations
|
||||||
*/
|
*/
|
||||||
val MutableBuffer<out Double>.array: DoubleArray
|
val MutableBuffer<out Double>.array: DoubleArray
|
||||||
get() = if (this is DoubleBuffer) {
|
get() = if (this is RealBuffer) {
|
||||||
array
|
array
|
||||||
} else {
|
} else {
|
||||||
DoubleArray(size) { get(it) }
|
DoubleArray(size) { get(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun DoubleArray.asBuffer() = DoubleBuffer(this)
|
fun DoubleArray.asBuffer() = RealBuffer(this)
|
@ -9,143 +9,143 @@ import kotlin.math.*
|
|||||||
* A simple field over linear buffers of [Double]
|
* A simple field over linear buffers of [Double]
|
||||||
*/
|
*/
|
||||||
object RealBufferFieldOperations : ExtendedFieldOperations<Buffer<Double>> {
|
object RealBufferFieldOperations : ExtendedFieldOperations<Buffer<Double>> {
|
||||||
override fun add(a: Buffer<Double>, b: Buffer<Double>): DoubleBuffer {
|
override fun add(a: Buffer<Double>, b: Buffer<Double>): RealBuffer {
|
||||||
require(b.size == a.size) { "The size of the first buffer ${a.size} should be the same as for second one: ${b.size} " }
|
require(b.size == a.size) { "The size of the first buffer ${a.size} should be the same as for second one: ${b.size} " }
|
||||||
return if (a is DoubleBuffer && b is DoubleBuffer) {
|
return if (a is RealBuffer && b is RealBuffer) {
|
||||||
val aArray = a.array
|
val aArray = a.array
|
||||||
val bArray = b.array
|
val bArray = b.array
|
||||||
DoubleBuffer(DoubleArray(a.size) { aArray[it] + bArray[it] })
|
RealBuffer(DoubleArray(a.size) { aArray[it] + bArray[it] })
|
||||||
} else {
|
} else {
|
||||||
DoubleBuffer(DoubleArray(a.size) { a[it] + b[it] })
|
RealBuffer(DoubleArray(a.size) { a[it] + b[it] })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun multiply(a: Buffer<Double>, k: Number): DoubleBuffer {
|
override fun multiply(a: Buffer<Double>, k: Number): RealBuffer {
|
||||||
val kValue = k.toDouble()
|
val kValue = k.toDouble()
|
||||||
return if (a is DoubleBuffer) {
|
return if (a is RealBuffer) {
|
||||||
val aArray = a.array
|
val aArray = a.array
|
||||||
DoubleBuffer(DoubleArray(a.size) { aArray[it] * kValue })
|
RealBuffer(DoubleArray(a.size) { aArray[it] * kValue })
|
||||||
} else {
|
} else {
|
||||||
DoubleBuffer(DoubleArray(a.size) { a[it] * kValue })
|
RealBuffer(DoubleArray(a.size) { a[it] * kValue })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun multiply(a: Buffer<Double>, b: Buffer<Double>): DoubleBuffer {
|
override fun multiply(a: Buffer<Double>, b: Buffer<Double>): RealBuffer {
|
||||||
require(b.size == a.size) { "The size of the first buffer ${a.size} should be the same as for second one: ${b.size} " }
|
require(b.size == a.size) { "The size of the first buffer ${a.size} should be the same as for second one: ${b.size} " }
|
||||||
return if (a is DoubleBuffer && b is DoubleBuffer) {
|
return if (a is RealBuffer && b is RealBuffer) {
|
||||||
val aArray = a.array
|
val aArray = a.array
|
||||||
val bArray = b.array
|
val bArray = b.array
|
||||||
DoubleBuffer(DoubleArray(a.size) { aArray[it] * bArray[it] })
|
RealBuffer(DoubleArray(a.size) { aArray[it] * bArray[it] })
|
||||||
} else {
|
} else {
|
||||||
DoubleBuffer(DoubleArray(a.size) { a[it] * b[it] })
|
RealBuffer(DoubleArray(a.size) { a[it] * b[it] })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun divide(a: Buffer<Double>, b: Buffer<Double>): DoubleBuffer {
|
override fun divide(a: Buffer<Double>, b: Buffer<Double>): RealBuffer {
|
||||||
require(b.size == a.size) { "The size of the first buffer ${a.size} should be the same as for second one: ${b.size} " }
|
require(b.size == a.size) { "The size of the first buffer ${a.size} should be the same as for second one: ${b.size} " }
|
||||||
return if (a is DoubleBuffer && b is DoubleBuffer) {
|
return if (a is RealBuffer && b is RealBuffer) {
|
||||||
val aArray = a.array
|
val aArray = a.array
|
||||||
val bArray = b.array
|
val bArray = b.array
|
||||||
DoubleBuffer(DoubleArray(a.size) { aArray[it] / bArray[it] })
|
RealBuffer(DoubleArray(a.size) { aArray[it] / bArray[it] })
|
||||||
} else {
|
} else {
|
||||||
DoubleBuffer(DoubleArray(a.size) { a[it] / b[it] })
|
RealBuffer(DoubleArray(a.size) { a[it] / b[it] })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun sin(arg: Buffer<Double>): DoubleBuffer {
|
override fun sin(arg: Buffer<Double>): RealBuffer {
|
||||||
return if (arg is DoubleBuffer) {
|
return if (arg is RealBuffer) {
|
||||||
val array = arg.array
|
val array = arg.array
|
||||||
DoubleBuffer(DoubleArray(arg.size) { sin(array[it]) })
|
RealBuffer(DoubleArray(arg.size) { sin(array[it]) })
|
||||||
} else {
|
} else {
|
||||||
DoubleBuffer(DoubleArray(arg.size) { sin(arg[it]) })
|
RealBuffer(DoubleArray(arg.size) { sin(arg[it]) })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun cos(arg: Buffer<Double>): DoubleBuffer {
|
override fun cos(arg: Buffer<Double>): RealBuffer {
|
||||||
return if (arg is DoubleBuffer) {
|
return if (arg is RealBuffer) {
|
||||||
val array = arg.array
|
val array = arg.array
|
||||||
DoubleBuffer(DoubleArray(arg.size) { cos(array[it]) })
|
RealBuffer(DoubleArray(arg.size) { cos(array[it]) })
|
||||||
} else {
|
} else {
|
||||||
DoubleBuffer(DoubleArray(arg.size) { cos(arg[it]) })
|
RealBuffer(DoubleArray(arg.size) { cos(arg[it]) })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun power(arg: Buffer<Double>, pow: Number): DoubleBuffer {
|
override fun power(arg: Buffer<Double>, pow: Number): RealBuffer {
|
||||||
return if (arg is DoubleBuffer) {
|
return if (arg is RealBuffer) {
|
||||||
val array = arg.array
|
val array = arg.array
|
||||||
DoubleBuffer(DoubleArray(arg.size) { array[it].pow(pow.toDouble()) })
|
RealBuffer(DoubleArray(arg.size) { array[it].pow(pow.toDouble()) })
|
||||||
} else {
|
} else {
|
||||||
DoubleBuffer(DoubleArray(arg.size) { arg[it].pow(pow.toDouble()) })
|
RealBuffer(DoubleArray(arg.size) { arg[it].pow(pow.toDouble()) })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun exp(arg: Buffer<Double>): DoubleBuffer {
|
override fun exp(arg: Buffer<Double>): RealBuffer {
|
||||||
return if (arg is DoubleBuffer) {
|
return if (arg is RealBuffer) {
|
||||||
val array = arg.array
|
val array = arg.array
|
||||||
DoubleBuffer(DoubleArray(arg.size) { exp(array[it]) })
|
RealBuffer(DoubleArray(arg.size) { exp(array[it]) })
|
||||||
} else {
|
} else {
|
||||||
DoubleBuffer(DoubleArray(arg.size) { exp(arg[it]) })
|
RealBuffer(DoubleArray(arg.size) { exp(arg[it]) })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun ln(arg: Buffer<Double>): DoubleBuffer {
|
override fun ln(arg: Buffer<Double>): RealBuffer {
|
||||||
return if (arg is DoubleBuffer) {
|
return if (arg is RealBuffer) {
|
||||||
val array = arg.array
|
val array = arg.array
|
||||||
DoubleBuffer(DoubleArray(arg.size) { ln(array[it]) })
|
RealBuffer(DoubleArray(arg.size) { ln(array[it]) })
|
||||||
} else {
|
} else {
|
||||||
DoubleBuffer(DoubleArray(arg.size) { ln(arg[it]) })
|
RealBuffer(DoubleArray(arg.size) { ln(arg[it]) })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class RealBufferField(val size: Int) : ExtendedField<Buffer<Double>> {
|
class RealBufferField(val size: Int) : ExtendedField<Buffer<Double>> {
|
||||||
|
|
||||||
override val zero: Buffer<Double> by lazy { DoubleBuffer(size) { 0.0 } }
|
override val zero: Buffer<Double> by lazy { RealBuffer(size) { 0.0 } }
|
||||||
|
|
||||||
override val one: Buffer<Double> by lazy { DoubleBuffer(size) { 1.0 } }
|
override val one: Buffer<Double> by lazy { RealBuffer(size) { 1.0 } }
|
||||||
|
|
||||||
override fun add(a: Buffer<Double>, b: Buffer<Double>): DoubleBuffer {
|
override fun add(a: Buffer<Double>, b: Buffer<Double>): RealBuffer {
|
||||||
require(a.size == size) { "The buffer size ${a.size} does not match context size $size" }
|
require(a.size == size) { "The buffer size ${a.size} does not match context size $size" }
|
||||||
return RealBufferFieldOperations.add(a, b)
|
return RealBufferFieldOperations.add(a, b)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun multiply(a: Buffer<Double>, k: Number): DoubleBuffer {
|
override fun multiply(a: Buffer<Double>, k: Number): RealBuffer {
|
||||||
require(a.size == size) { "The buffer size ${a.size} does not match context size $size" }
|
require(a.size == size) { "The buffer size ${a.size} does not match context size $size" }
|
||||||
return RealBufferFieldOperations.multiply(a, k)
|
return RealBufferFieldOperations.multiply(a, k)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun multiply(a: Buffer<Double>, b: Buffer<Double>): DoubleBuffer {
|
override fun multiply(a: Buffer<Double>, b: Buffer<Double>): RealBuffer {
|
||||||
require(a.size == size) { "The buffer size ${a.size} does not match context size $size" }
|
require(a.size == size) { "The buffer size ${a.size} does not match context size $size" }
|
||||||
return RealBufferFieldOperations.multiply(a, b)
|
return RealBufferFieldOperations.multiply(a, b)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
override fun divide(a: Buffer<Double>, b: Buffer<Double>): DoubleBuffer {
|
override fun divide(a: Buffer<Double>, b: Buffer<Double>): RealBuffer {
|
||||||
require(a.size == size) { "The buffer size ${a.size} does not match context size $size" }
|
require(a.size == size) { "The buffer size ${a.size} does not match context size $size" }
|
||||||
return RealBufferFieldOperations.divide(a, b)
|
return RealBufferFieldOperations.divide(a, b)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun sin(arg: Buffer<Double>): DoubleBuffer {
|
override fun sin(arg: Buffer<Double>): RealBuffer {
|
||||||
require(arg.size == size) { "The buffer size ${arg.size} does not match context size $size" }
|
require(arg.size == size) { "The buffer size ${arg.size} does not match context size $size" }
|
||||||
return RealBufferFieldOperations.sin(arg)
|
return RealBufferFieldOperations.sin(arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun cos(arg: Buffer<Double>): DoubleBuffer {
|
override fun cos(arg: Buffer<Double>): RealBuffer {
|
||||||
require(arg.size == size) { "The buffer size ${arg.size} does not match context size $size" }
|
require(arg.size == size) { "The buffer size ${arg.size} does not match context size $size" }
|
||||||
return RealBufferFieldOperations.cos(arg)
|
return RealBufferFieldOperations.cos(arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun power(arg: Buffer<Double>, pow: Number): DoubleBuffer {
|
override fun power(arg: Buffer<Double>, pow: Number): RealBuffer {
|
||||||
require(arg.size == size) { "The buffer size ${arg.size} does not match context size $size" }
|
require(arg.size == size) { "The buffer size ${arg.size} does not match context size $size" }
|
||||||
return RealBufferFieldOperations.power(arg, pow)
|
return RealBufferFieldOperations.power(arg, pow)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun exp(arg: Buffer<Double>): DoubleBuffer {
|
override fun exp(arg: Buffer<Double>): RealBuffer {
|
||||||
require(arg.size == size) { "The buffer size ${arg.size} does not match context size $size" }
|
require(arg.size == size) { "The buffer size ${arg.size} does not match context size $size" }
|
||||||
return RealBufferFieldOperations.exp(arg)
|
return RealBufferFieldOperations.exp(arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun ln(arg: Buffer<Double>): DoubleBuffer {
|
override fun ln(arg: Buffer<Double>): RealBuffer {
|
||||||
require(arg.size == size) { "The buffer size ${arg.size} does not match context size $size" }
|
require(arg.size == size) { "The buffer size ${arg.size} does not match context size $size" }
|
||||||
return RealBufferFieldOperations.ln(arg)
|
return RealBufferFieldOperations.ln(arg)
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ class RealNDField(override val shape: IntArray) :
|
|||||||
override val one by lazy { produce { one } }
|
override val one by lazy { produce { one } }
|
||||||
|
|
||||||
inline fun buildBuffer(size: Int, crossinline initializer: (Int) -> Double): Buffer<Double> =
|
inline fun buildBuffer(size: Int, crossinline initializer: (Int) -> Double): Buffer<Double> =
|
||||||
DoubleBuffer(DoubleArray(size) { initializer(it) })
|
RealBuffer(DoubleArray(size) { initializer(it) })
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inline transform an NDStructure to
|
* Inline transform an NDStructure to
|
||||||
@ -82,7 +82,7 @@ class RealNDField(override val shape: IntArray) :
|
|||||||
*/
|
*/
|
||||||
inline fun BufferedNDField<Double, RealField>.produceInline(crossinline initializer: RealField.(Int) -> Double): RealNDElement {
|
inline fun BufferedNDField<Double, RealField>.produceInline(crossinline initializer: RealField.(Int) -> Double): RealNDElement {
|
||||||
val array = DoubleArray(strides.linearSize) { offset -> RealField.initializer(offset) }
|
val array = DoubleArray(strides.linearSize) { offset -> RealField.initializer(offset) }
|
||||||
return BufferedNDFieldElement(this, DoubleBuffer(array))
|
return BufferedNDFieldElement(this, RealBuffer(array))
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -96,7 +96,7 @@ inline fun RealNDElement.mapIndexed(crossinline transform: RealField.(index: Int
|
|||||||
*/
|
*/
|
||||||
inline fun RealNDElement.map(crossinline transform: RealField.(Double) -> Double): RealNDElement {
|
inline fun RealNDElement.map(crossinline transform: RealField.(Double) -> Double): RealNDElement {
|
||||||
val array = DoubleArray(strides.linearSize) { offset -> RealField.transform(buffer[offset]) }
|
val array = DoubleArray(strides.linearSize) { offset -> RealField.transform(buffer[offset]) }
|
||||||
return BufferedNDFieldElement(context, DoubleBuffer(array))
|
return BufferedNDFieldElement(context, RealBuffer(array))
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -0,0 +1,20 @@
|
|||||||
|
package scientifik.kmath.structures
|
||||||
|
|
||||||
|
inline class ShortBuffer(val array: ShortArray) : MutableBuffer<Short> {
|
||||||
|
override val size: Int get() = array.size
|
||||||
|
|
||||||
|
override fun get(index: Int): Short = array[index]
|
||||||
|
|
||||||
|
override fun set(index: Int, value: Short) {
|
||||||
|
array[index] = value
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun iterator() = array.iterator()
|
||||||
|
|
||||||
|
override fun copy(): MutableBuffer<Short> =
|
||||||
|
ShortBuffer(array.copyOf())
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun ShortArray.asBuffer() = ShortBuffer(this)
|
@ -5,7 +5,7 @@ import kotlinx.coroutines.flow.*
|
|||||||
import scientifik.kmath.chains.BlockingRealChain
|
import scientifik.kmath.chains.BlockingRealChain
|
||||||
import scientifik.kmath.structures.Buffer
|
import scientifik.kmath.structures.Buffer
|
||||||
import scientifik.kmath.structures.BufferFactory
|
import scientifik.kmath.structures.BufferFactory
|
||||||
import scientifik.kmath.structures.DoubleBuffer
|
import scientifik.kmath.structures.RealBuffer
|
||||||
import scientifik.kmath.structures.asBuffer
|
import scientifik.kmath.structures.asBuffer
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -45,7 +45,7 @@ fun <T> Flow<T>.chunked(bufferSize: Int, bufferFactory: BufferFactory<T>): Flow<
|
|||||||
/**
|
/**
|
||||||
* Specialized flow chunker for real buffer
|
* Specialized flow chunker for real buffer
|
||||||
*/
|
*/
|
||||||
fun Flow<Double>.chunked(bufferSize: Int): Flow<DoubleBuffer> = flow {
|
fun Flow<Double>.chunked(bufferSize: Int): Flow<RealBuffer> = flow {
|
||||||
require(bufferSize > 0) { "Resulting chunk size must be more than zero" }
|
require(bufferSize > 0) { "Resulting chunk size must be more than zero" }
|
||||||
|
|
||||||
if (this@chunked is BlockingRealChain) {
|
if (this@chunked is BlockingRealChain) {
|
||||||
@ -61,13 +61,13 @@ fun Flow<Double>.chunked(bufferSize: Int): Flow<DoubleBuffer> = flow {
|
|||||||
array[counter] = element
|
array[counter] = element
|
||||||
counter++
|
counter++
|
||||||
if (counter == bufferSize) {
|
if (counter == bufferSize) {
|
||||||
val buffer = DoubleBuffer(array)
|
val buffer = RealBuffer(array)
|
||||||
emit(buffer)
|
emit(buffer)
|
||||||
counter = 0
|
counter = 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (counter > 0) {
|
if (counter > 0) {
|
||||||
emit(DoubleBuffer(counter) { array[it] })
|
emit(RealBuffer(counter) { array[it] })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@ import scientifik.kmath.operations.Norm
|
|||||||
import scientifik.kmath.operations.RealField
|
import scientifik.kmath.operations.RealField
|
||||||
import scientifik.kmath.operations.SpaceElement
|
import scientifik.kmath.operations.SpaceElement
|
||||||
import scientifik.kmath.structures.Buffer
|
import scientifik.kmath.structures.Buffer
|
||||||
import scientifik.kmath.structures.DoubleBuffer
|
import scientifik.kmath.structures.RealBuffer
|
||||||
import scientifik.kmath.structures.asBuffer
|
import scientifik.kmath.structures.asBuffer
|
||||||
import scientifik.kmath.structures.asIterable
|
import scientifik.kmath.structures.asIterable
|
||||||
import kotlin.math.sqrt
|
import kotlin.math.sqrt
|
||||||
@ -41,7 +41,7 @@ inline class RealVector(private val point: Point<Double>) :
|
|||||||
private val spaceCache = HashMap<Int, BufferVectorSpace<Double, RealField>>()
|
private val spaceCache = HashMap<Int, BufferVectorSpace<Double, RealField>>()
|
||||||
|
|
||||||
inline operator fun invoke(dim: Int, initializer: (Int) -> Double) =
|
inline operator fun invoke(dim: Int, initializer: (Int) -> Double) =
|
||||||
RealVector(DoubleBuffer(dim, initializer))
|
RealVector(RealBuffer(dim, initializer))
|
||||||
|
|
||||||
operator fun invoke(vararg values: Double): RealVector = values.asVector()
|
operator fun invoke(vararg values: Double): RealVector = values.asVector()
|
||||||
|
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package scientifik.kmath.real
|
package scientifik.kmath.real
|
||||||
|
|
||||||
import scientifik.kmath.structures.DoubleBuffer
|
import scientifik.kmath.structures.RealBuffer
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simplified [DoubleBuffer] to array comparison
|
* Simplified [RealBuffer] to array comparison
|
||||||
*/
|
*/
|
||||||
fun DoubleBuffer.contentEquals(vararg doubles: Double) = array.contentEquals(doubles)
|
fun RealBuffer.contentEquals(vararg doubles: Double) = array.contentEquals(doubles)
|
@ -5,8 +5,8 @@ import scientifik.kmath.linear.RealMatrixContext.elementContext
|
|||||||
import scientifik.kmath.linear.VirtualMatrix
|
import scientifik.kmath.linear.VirtualMatrix
|
||||||
import scientifik.kmath.operations.sum
|
import scientifik.kmath.operations.sum
|
||||||
import scientifik.kmath.structures.Buffer
|
import scientifik.kmath.structures.Buffer
|
||||||
import scientifik.kmath.structures.DoubleBuffer
|
|
||||||
import scientifik.kmath.structures.Matrix
|
import scientifik.kmath.structures.Matrix
|
||||||
|
import scientifik.kmath.structures.RealBuffer
|
||||||
import scientifik.kmath.structures.asIterable
|
import scientifik.kmath.structures.asIterable
|
||||||
import kotlin.math.pow
|
import kotlin.math.pow
|
||||||
|
|
||||||
@ -133,22 +133,22 @@ fun Matrix<Double>.extractColumns(columnRange: IntRange): RealMatrix =
|
|||||||
fun Matrix<Double>.extractColumn(columnIndex: Int): RealMatrix =
|
fun Matrix<Double>.extractColumn(columnIndex: Int): RealMatrix =
|
||||||
extractColumns(columnIndex..columnIndex)
|
extractColumns(columnIndex..columnIndex)
|
||||||
|
|
||||||
fun Matrix<Double>.sumByColumn(): DoubleBuffer = DoubleBuffer(colNum) { j ->
|
fun Matrix<Double>.sumByColumn(): RealBuffer = RealBuffer(colNum) { j ->
|
||||||
val column = columns[j]
|
val column = columns[j]
|
||||||
with(elementContext) {
|
with(elementContext) {
|
||||||
sum(column.asIterable())
|
sum(column.asIterable())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Matrix<Double>.minByColumn(): DoubleBuffer = DoubleBuffer(colNum) { j ->
|
fun Matrix<Double>.minByColumn(): RealBuffer = RealBuffer(colNum) { j ->
|
||||||
columns[j].asIterable().min() ?: throw Exception("Cannot produce min on empty column")
|
columns[j].asIterable().min() ?: throw Exception("Cannot produce min on empty column")
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Matrix<Double>.maxByColumn(): DoubleBuffer = DoubleBuffer(colNum) { j ->
|
fun Matrix<Double>.maxByColumn(): RealBuffer = RealBuffer(colNum) { j ->
|
||||||
columns[j].asIterable().max() ?: throw Exception("Cannot produce min on empty column")
|
columns[j].asIterable().max() ?: throw Exception("Cannot produce min on empty column")
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Matrix<Double>.averageByColumn(): DoubleBuffer = DoubleBuffer(colNum) { j ->
|
fun Matrix<Double>.averageByColumn(): RealBuffer = RealBuffer(colNum) { j ->
|
||||||
columns[j].asIterable().average()
|
columns[j].asIterable().average()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ package scientifik.kmath.histogram
|
|||||||
import scientifik.kmath.domains.Domain
|
import scientifik.kmath.domains.Domain
|
||||||
import scientifik.kmath.linear.Point
|
import scientifik.kmath.linear.Point
|
||||||
import scientifik.kmath.structures.ArrayBuffer
|
import scientifik.kmath.structures.ArrayBuffer
|
||||||
import scientifik.kmath.structures.DoubleBuffer
|
import scientifik.kmath.structures.RealBuffer
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The bin in the histogram. The histogram is by definition always done in the real space
|
* The bin in the histogram. The histogram is by definition always done in the real space
|
||||||
@ -43,9 +43,9 @@ interface MutableHistogram<T : Any, out B : Bin<T>> : Histogram<T, B> {
|
|||||||
fun <T : Any> MutableHistogram<T, *>.put(vararg point: T) = put(ArrayBuffer(point))
|
fun <T : Any> MutableHistogram<T, *>.put(vararg point: T) = put(ArrayBuffer(point))
|
||||||
|
|
||||||
fun MutableHistogram<Double, *>.put(vararg point: Number) =
|
fun MutableHistogram<Double, *>.put(vararg point: Number) =
|
||||||
put(DoubleBuffer(point.map { it.toDouble() }.toDoubleArray()))
|
put(RealBuffer(point.map { it.toDouble() }.toDoubleArray()))
|
||||||
|
|
||||||
fun MutableHistogram<Double, *>.put(vararg point: Double) = put(DoubleBuffer(point))
|
fun MutableHistogram<Double, *>.put(vararg point: Double) = put(RealBuffer(point))
|
||||||
|
|
||||||
fun <T : Any> MutableHistogram<T, *>.fill(sequence: Iterable<Point<T>>) = sequence.forEach { put(it) }
|
fun <T : Any> MutableHistogram<T, *>.fill(sequence: Iterable<Point<T>>) = sequence.forEach { put(it) }
|
||||||
|
|
||||||
|
@ -50,7 +50,7 @@ class RealHistogram(
|
|||||||
override val dimension: Int get() = lower.size
|
override val dimension: Int get() = lower.size
|
||||||
|
|
||||||
|
|
||||||
private val binSize = DoubleBuffer(dimension) { (upper[it] - lower[it]) / binNums[it] }
|
private val binSize = RealBuffer(dimension) { (upper[it] - lower[it]) / binNums[it] }
|
||||||
|
|
||||||
init {
|
init {
|
||||||
// argument checks
|
// argument checks
|
||||||
|
Loading…
Reference in New Issue
Block a user