From 3eef778f6036baa375d40be4f71f697ca707c5ea Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Sat, 16 Jul 2022 16:27:11 +0300 Subject: [PATCH] Add mandatory MutableBufferFactory to Algebra #477 --- CHANGELOG.md | 1 + .../kscience/kmath/benchmarks/DotBenchmark.kt | 3 +- .../kmath/benchmarks/NDFieldBenchmark.kt | 10 +--- .../kmath/benchmarks/ViktorBenchmark.kt | 21 +++---- .../kmath/benchmarks/ViktorLogBenchmark.kt | 7 +-- .../kscience/kmath/operations/complexDemo.kt | 5 +- .../kscience/kmath/structures/NDField.kt | 21 ++----- .../space/kscience/kmath/complex/Complex.kt | 8 +-- .../kscience/kmath/complex/ComplexFieldND.kt | 5 -- .../kscience/kmath/expressions/DSAlgebra.kt | 42 +++++++------- .../kmath/linear/BufferedLinearSpace.kt | 7 +-- .../kscience/kmath/linear/LinearSpace.kt | 16 +----- .../kscience/kmath/nd/BufferAlgebraND.kt | 10 ++-- .../space/kscience/kmath/nd/StructureND.kt | 4 +- .../kscience/kmath/operations/Algebra.kt | 13 +++-- .../space/kscience/kmath/operations/BigInt.kt | 13 +---- .../kmath/operations/BufferAlgebra.kt | 47 +++++++-------- .../kmath/operations/DoubleBufferOps.kt | 4 +- .../kmath/operations/bufferOperation.kt | 4 +- .../kscience/kmath/operations/numbers.kt | 33 +++++------ .../space/kscience/kmath/structures/Buffer.kt | 18 +++++- .../kscience/kmath/structures/ByteBuffer.kt | 57 +++++++++++++++++++ .../kscience/kmath/expressions/DSTest.kt | 2 +- .../histogram/UniformHistogramGroupND.kt | 14 ++--- .../space/kscience/kmath/stat/Sampler.kt | 2 +- 25 files changed, 187 insertions(+), 180 deletions(-) create mode 100644 kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/ByteBuffer.kt diff --git a/CHANGELOG.md b/CHANGELOG.md index ec993fb36..4852f474a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## [Unreleased] ### Added - Autodiff for generic algebra elements in core! +- Algebra now has an obligatory `bufferFactory` (#477). ### Changed - Kotlin 1.7 diff --git a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/DotBenchmark.kt b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/DotBenchmark.kt index 7d5ae310b..7ceecb5ab 100644 --- a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/DotBenchmark.kt +++ b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/DotBenchmark.kt @@ -16,7 +16,6 @@ import space.kscience.kmath.linear.linearSpace import space.kscience.kmath.multik.multikAlgebra import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.invoke -import space.kscience.kmath.structures.Buffer import space.kscience.kmath.tensorflow.produceWithTF import space.kscience.kmath.tensors.core.DoubleTensorAlgebra import space.kscience.kmath.tensors.core.tensorAlgebra @@ -84,7 +83,7 @@ internal class DotBenchmark { } @Benchmark - fun bufferedDot(blackhole: Blackhole) = with(DoubleField.linearSpace(Buffer.Companion::auto)) { + fun bufferedDot(blackhole: Blackhole) = with(DoubleField.linearSpace) { blackhole.consume(matrix1 dot matrix2) } diff --git a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/NDFieldBenchmark.kt b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/NDFieldBenchmark.kt index e3b3dde05..89673acd4 100644 --- a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/NDFieldBenchmark.kt +++ b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/NDFieldBenchmark.kt @@ -20,7 +20,6 @@ import space.kscience.kmath.nd.ndAlgebra import space.kscience.kmath.nd.one import space.kscience.kmath.nd4j.nd4j import space.kscience.kmath.operations.DoubleField -import space.kscience.kmath.structures.Buffer import space.kscience.kmath.tensors.core.DoubleTensor import space.kscience.kmath.tensors.core.one import space.kscience.kmath.tensors.core.tensorAlgebra @@ -28,12 +27,6 @@ import space.kscience.kmath.viktor.viktorAlgebra @State(Scope.Benchmark) internal class NDFieldBenchmark { - @Benchmark - fun autoFieldAdd(blackhole: Blackhole) = with(autoField) { - var res: StructureND = one(shape) - repeat(n) { res += 1.0 } - blackhole.consume(res) - } @Benchmark fun specializedFieldAdd(blackhole: Blackhole) = with(specializedField) { @@ -95,9 +88,8 @@ internal class NDFieldBenchmark { private const val dim = 1000 private const val n = 100 private val shape = intArrayOf(dim, dim) - private val autoField = BufferedFieldOpsND(DoubleField, Buffer.Companion::auto) private val specializedField = DoubleField.ndAlgebra - private val genericField = BufferedFieldOpsND(DoubleField, Buffer.Companion::boxing) + private val genericField = BufferedFieldOpsND(DoubleField) private val nd4jField = DoubleField.nd4j private val multikField = DoubleField.multikAlgebra private val viktorField = DoubleField.viktorAlgebra diff --git a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/ViktorBenchmark.kt b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/ViktorBenchmark.kt index de301678c..0e92a703e 100644 --- a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/ViktorBenchmark.kt +++ b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/ViktorBenchmark.kt @@ -10,25 +10,19 @@ import kotlinx.benchmark.Blackhole import kotlinx.benchmark.Scope import kotlinx.benchmark.State import org.jetbrains.bio.viktor.F64Array -import space.kscience.kmath.nd.* +import space.kscience.kmath.nd.Shape +import space.kscience.kmath.nd.StructureND +import space.kscience.kmath.nd.ndAlgebra +import space.kscience.kmath.nd.one import space.kscience.kmath.operations.DoubleField -import space.kscience.kmath.structures.Buffer import space.kscience.kmath.viktor.ViktorFieldND @State(Scope.Benchmark) internal class ViktorBenchmark { - @Benchmark - fun automaticFieldAddition(blackhole: Blackhole) { - with(autoField) { - var res: StructureND = one(shape) - repeat(n) { res += 1.0 } - blackhole.consume(res) - } - } @Benchmark - fun realFieldAddition(blackhole: Blackhole) { - with(realField) { + fun doubleFieldAddition(blackhole: Blackhole) { + with(doubleField) { var res: StructureND = one(shape) repeat(n) { res += 1.0 } blackhole.consume(res) @@ -58,8 +52,7 @@ internal class ViktorBenchmark { private val shape = Shape(dim, dim) // automatically build context most suited for given type. - private val autoField = BufferedFieldOpsND(DoubleField, Buffer.Companion::auto) - private val realField = DoubleField.ndAlgebra + private val doubleField = DoubleField.ndAlgebra private val viktorField = ViktorFieldND(dim, dim) } } diff --git a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/ViktorLogBenchmark.kt b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/ViktorLogBenchmark.kt index dfdd89d74..7bb0b876e 100644 --- a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/ViktorLogBenchmark.kt +++ b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/ViktorLogBenchmark.kt @@ -10,19 +10,17 @@ import kotlinx.benchmark.Blackhole import kotlinx.benchmark.Scope import kotlinx.benchmark.State import org.jetbrains.bio.viktor.F64Array -import space.kscience.kmath.nd.BufferedFieldOpsND import space.kscience.kmath.nd.Shape import space.kscience.kmath.nd.ndAlgebra import space.kscience.kmath.nd.one import space.kscience.kmath.operations.DoubleField -import space.kscience.kmath.structures.Buffer import space.kscience.kmath.viktor.ViktorFieldND @State(Scope.Benchmark) internal class ViktorLogBenchmark { @Benchmark fun realFieldLog(blackhole: Blackhole) { - with(realField) { + with(doubleField) { val fortyTwo = structureND(shape) { 42.0 } var res = one(shape) repeat(n) { res = ln(fortyTwo) } @@ -54,8 +52,7 @@ internal class ViktorLogBenchmark { private val shape = Shape(dim, dim) // automatically build context most suited for given type. - private val autoField = BufferedFieldOpsND(DoubleField, Buffer.Companion::auto) - private val realField = DoubleField.ndAlgebra + private val doubleField = DoubleField.ndAlgebra private val viktorField = ViktorFieldND(dim, dim) } } diff --git a/examples/src/main/kotlin/space/kscience/kmath/operations/complexDemo.kt b/examples/src/main/kotlin/space/kscience/kmath/operations/complexDemo.kt index 2e1801cc2..285b8d000 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/operations/complexDemo.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/operations/complexDemo.kt @@ -7,7 +7,6 @@ package space.kscience.kmath.operations import space.kscience.kmath.complex.Complex import space.kscience.kmath.complex.algebra -import space.kscience.kmath.complex.bufferAlgebra import space.kscience.kmath.complex.ndAlgebra import space.kscience.kmath.nd.BufferND import space.kscience.kmath.nd.StructureND @@ -18,7 +17,7 @@ fun main() = Complex.algebra { println(complex * 8 - 5 * i) //flat buffer - val buffer = with(bufferAlgebra){ + val buffer = with(bufferAlgebra) { buffer(8) { Complex(it, -it) }.map { Complex(it.im, it.re) } } println(buffer) @@ -30,7 +29,7 @@ fun main() = Complex.algebra { println(element) // 1d element operation - val result: StructureND = ndAlgebra{ + val result: StructureND = ndAlgebra { val a = structureND(8) { (it) -> i * it - it.toDouble() } val b = 3 val c = Complex(1.0, 1.0) diff --git a/examples/src/main/kotlin/space/kscience/kmath/structures/NDField.kt b/examples/src/main/kotlin/space/kscience/kmath/structures/NDField.kt index b680e267d..d6ff1dceb 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/structures/NDField.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/structures/NDField.kt @@ -32,12 +32,10 @@ fun main() { val shape = Shape(dim, dim) - // automatically build context most suited for given type. - val autoField = BufferedFieldOpsND(DoubleField, Buffer.Companion::auto) // specialized nd-field for Double. It works as generic Double field as well. - val realField = DoubleField.ndAlgebra - //A generic boxing field. It should be used for objects, not primitives. - val boxingField = BufferedFieldOpsND(DoubleField, Buffer.Companion::boxing) + val doubleField = DoubleField.ndAlgebra + //A generic field. It should be used for objects, not primitives. + val genericField = BufferedFieldOpsND(DoubleField) // Nd4j specialized field. val nd4jField = DoubleField.nd4j //viktor field @@ -46,14 +44,14 @@ fun main() { val parallelField = DoubleField.ndStreaming(dim, dim) measureAndPrint("Boxing addition") { - boxingField { + genericField { var res: StructureND = one(shape) repeat(n) { res += 1.0 } } } measureAndPrint("Specialized addition") { - realField { + doubleField { var res: StructureND = one(shape) repeat(n) { res += 1.0 } } @@ -80,15 +78,8 @@ fun main() { } } - measureAndPrint("Automatic field addition") { - autoField { - var res: StructureND = one(shape) - repeat(n) { res += 1.0 } - } - } - measureAndPrint("Lazy addition") { - val res = realField.one(shape).mapAsync(GlobalScope) { + val res = doubleField.one(shape).mapAsync(GlobalScope) { var c = 0.0 repeat(n) { c += 1.0 diff --git a/kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/Complex.kt b/kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/Complex.kt index 77fe782a9..f56fb0f6e 100644 --- a/kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/Complex.kt +++ b/kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/Complex.kt @@ -10,10 +10,7 @@ import space.kscience.kmath.memory.MemorySpec import space.kscience.kmath.memory.MemoryWriter import space.kscience.kmath.misc.UnstableKMathAPI import space.kscience.kmath.operations.* -import space.kscience.kmath.structures.Buffer -import space.kscience.kmath.structures.MemoryBuffer -import space.kscience.kmath.structures.MutableBuffer -import space.kscience.kmath.structures.MutableMemoryBuffer +import space.kscience.kmath.structures.* import kotlin.math.* /** @@ -54,6 +51,9 @@ public object ComplexField : Norm, NumbersAddOps, ScaleOperations { + override val bufferFactory: MutableBufferFactory = MutableBufferFactory { size, init -> + MutableMemoryBuffer.create(Complex, size, init) + } override val zero: Complex = 0.0.toComplex() override val one: Complex = 1.0.toComplex() diff --git a/kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/ComplexFieldND.kt b/kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/ComplexFieldND.kt index 46d4b7c5c..65943f421 100644 --- a/kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/ComplexFieldND.kt +++ b/kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/ComplexFieldND.kt @@ -56,11 +56,6 @@ public sealed class ComplexFieldOpsND : BufferedFieldOpsND - get() = bufferAlgebra(Buffer.Companion::complex) - - @OptIn(UnstableKMathAPI::class) public class ComplexFieldND(override val shape: Shape) : ComplexFieldOpsND(), FieldND, diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/DSAlgebra.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/DSAlgebra.kt index 59e6f4f6f..c55e41bb2 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/DSAlgebra.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/DSAlgebra.kt @@ -78,9 +78,9 @@ public val > DS.value: T get() = data[0] @UnstableKMathAPI public abstract class DSAlgebra>( public val algebra: A, - public val bufferFactory: MutableBufferFactory, public val order: Int, bindings: Map, + public val valueBufferFactory: MutableBufferFactory = algebra.bufferFactory, ) : ExpressionAlgebra>, SymbolIndexer { /** @@ -90,6 +90,7 @@ public abstract class DSAlgebra>( */ @PublishedApi internal val compiler: DSCompiler by lazy { + val numberOfVariables = bindings.size // get the cached compilers val cache: Array?>>? = null @@ -115,7 +116,7 @@ public abstract class DSAlgebra>( newCache[p][o] = DSCompiler( algebra, - bufferFactory, + valueBufferFactory, p, o, valueCompiler, @@ -139,16 +140,13 @@ public abstract class DSAlgebra>( } override val symbols: List = bindings.map { it.key } - public val numberOfVariables: Int get() = symbols.size - - private fun bufferForVariable(index: Int, value: T): Buffer { - val buffer = bufferFactory(compiler.size) { algebra.zero } + val buffer = valueBufferFactory(compiler.size) { algebra.zero } buffer[0] = value if (compiler.order > 0) { // the derivative of the variable with respect to itself is 1. - val indexOfDerivative = compiler.getPartialDerivativeIndex(*IntArray(numberOfVariables).apply { + val indexOfDerivative = compiler.getPartialDerivativeIndex(*IntArray(symbols.size).apply { set(index, 1) }) @@ -209,7 +207,7 @@ public abstract class DSAlgebra>( } public override fun const(value: T): DS { - val buffer = bufferFactory(compiler.size) { algebra.zero } + val buffer = valueBufferFactory(compiler.size) { algebra.zero } buffer[0] = value return DS(buffer) @@ -245,10 +243,10 @@ public abstract class DSAlgebra>( @UnstableKMathAPI public open class DSRing( algebra: A, - bufferFactory: MutableBufferFactory, order: Int, bindings: Map, -) : DSAlgebra(algebra, bufferFactory, order, bindings), + valueBufferFactory: MutableBufferFactory, +) : DSAlgebra(algebra, order, bindings, valueBufferFactory), Ring>, ScaleOperations>, NumericAlgebra>, NumbersAddOps> where A : Ring, A : NumericAlgebra, A : ScaleOperations { @@ -263,14 +261,14 @@ public open class DSRing( */ protected inline fun DS.transformDataBuffer(block: A.(MutableBuffer) -> Unit): DS { require(derivativeAlgebra == this@DSRing) { "All derivative operations should be done in the same algebra" } - val newData = bufferFactory(compiler.size) { data[it] } + val newData = valueBufferFactory(compiler.size) { data[it] } algebra.block(newData) return DS(newData) } protected fun DS.mapData(block: A.(T) -> T): DS { require(derivativeAlgebra == this@DSRing) { "All derivative operations should be done in the same algebra" } - val newData: Buffer = data.map(bufferFactory) { + val newData: Buffer = data.map(valueBufferFactory) { algebra.block(it) } return DS(newData) @@ -278,7 +276,7 @@ public open class DSRing( protected fun DS.mapDataIndexed(block: (Int, T) -> T): DS { require(derivativeAlgebra == this@DSRing) { "All derivative operations should be done in the same algebra" } - val newData: Buffer = data.mapIndexed(bufferFactory, block) + val newData: Buffer = data.mapIndexed(valueBufferFactory, block) return DS(newData) } @@ -327,19 +325,19 @@ public open class DSRing( @UnstableKMathAPI public class DerivativeStructureRingExpression( public val algebra: A, - public val bufferFactory: MutableBufferFactory, + public val elementBufferFactory: MutableBufferFactory = algebra.bufferFactory, public val function: DSRing.() -> DS, ) : DifferentiableExpression where A : Ring, A : ScaleOperations, A : NumericAlgebra { override operator fun invoke(arguments: Map): T = - DSRing(algebra, bufferFactory, 0, arguments).function().value + DSRing(algebra, 0, arguments, elementBufferFactory).function().value override fun derivativeOrNull(symbols: List): Expression = Expression { arguments -> with( DSRing( algebra, - bufferFactory, symbols.size, - arguments + arguments, + elementBufferFactory ) ) { function().derivative(symbols) } } @@ -354,10 +352,10 @@ public class DerivativeStructureRingExpression( @UnstableKMathAPI public class DSField>( algebra: A, - bufferFactory: MutableBufferFactory, order: Int, bindings: Map, -) : DSRing(algebra, bufferFactory, order, bindings), ExtendedField> { + valueBufferFactory: MutableBufferFactory, +) : DSRing(algebra, order, bindings, valueBufferFactory), ExtendedField> { override fun number(value: Number): DS = const(algebra.number(value)) override fun divide(left: DS, right: DS): DS = left.transformDataBuffer { result -> @@ -441,18 +439,18 @@ public class DSField>( @UnstableKMathAPI public class DSFieldExpression>( public val algebra: A, - public val bufferFactory: MutableBufferFactory, + private val valueBufferFactory: MutableBufferFactory = algebra.bufferFactory, public val function: DSField.() -> DS, ) : DifferentiableExpression { override operator fun invoke(arguments: Map): T = - DSField(algebra, bufferFactory, 0, arguments).function().value + DSField(algebra, 0, arguments, valueBufferFactory).function().value override fun derivativeOrNull(symbols: List): Expression = Expression { arguments -> DSField( algebra, - bufferFactory, symbols.size, arguments, + valueBufferFactory, ).run { function().derivative(symbols) } } } diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/BufferedLinearSpace.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/BufferedLinearSpace.kt index 36cbd9064..8f7569699 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/BufferedLinearSpace.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/BufferedLinearSpace.kt @@ -11,13 +11,12 @@ import space.kscience.kmath.nd.as2D import space.kscience.kmath.nd.asND import space.kscience.kmath.operations.* import space.kscience.kmath.structures.Buffer -import space.kscience.kmath.structures.BufferFactory import space.kscience.kmath.structures.VirtualBuffer import space.kscience.kmath.structures.indices public class BufferedLinearSpace>( - private val bufferAlgebra: BufferAlgebra + private val bufferAlgebra: BufferAlgebra, ) : LinearSpace { override val elementAlgebra: A get() = bufferAlgebra.elementAlgebra @@ -91,5 +90,5 @@ public class BufferedLinearSpace>( } -public fun > A.linearSpace(bufferFactory: BufferFactory): BufferedLinearSpace = - BufferedLinearSpace(BufferRingOps(this, bufferFactory)) +public val > A.linearSpace: BufferedLinearSpace + get() = BufferedLinearSpace(BufferRingOps(this)) diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LinearSpace.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LinearSpace.kt index 10438dd02..d437070c9 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LinearSpace.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LinearSpace.kt @@ -11,12 +11,9 @@ import space.kscience.kmath.nd.Structure2D import space.kscience.kmath.nd.StructureFeature import space.kscience.kmath.nd.as1D import space.kscience.kmath.operations.BufferRingOps -import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.Ring import space.kscience.kmath.operations.invoke import space.kscience.kmath.structures.Buffer -import space.kscience.kmath.structures.BufferFactory -import space.kscience.kmath.structures.DoubleBuffer import kotlin.reflect.KClass /** @@ -187,18 +184,9 @@ public interface LinearSpace> { * A structured matrix with custom buffer */ public fun > buffered( - algebra: A, - bufferFactory: BufferFactory = BufferFactory(Buffer.Companion::boxing), - ): LinearSpace = BufferedLinearSpace(BufferRingOps(algebra, bufferFactory)) + algebra: A + ): LinearSpace = BufferedLinearSpace(BufferRingOps(algebra)) - @Deprecated("use DoubleField.linearSpace") - public val double: LinearSpace = buffered(DoubleField, ::DoubleBuffer) - - /** - * Automatic buffered matrix, unboxed if it is possible - */ - public inline fun > auto(ring: A): LinearSpace = - buffered(ring, Buffer.Companion::auto) } } diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/BufferAlgebraND.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/BufferAlgebraND.kt index 68e8ebe90..8c5eef3d0 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/BufferAlgebraND.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/BufferAlgebraND.kt @@ -10,7 +10,6 @@ package space.kscience.kmath.nd import space.kscience.kmath.misc.PerformancePitfall import space.kscience.kmath.misc.UnstableKMathAPI import space.kscience.kmath.operations.* -import space.kscience.kmath.structures.BufferFactory public interface BufferAlgebraND> : AlgebraND { public val indexerBuilder: (IntArray) -> ShapeIndexer @@ -60,7 +59,7 @@ public inline fun > BufferAlgebraND.mapInline( return BufferND( indexes, bufferAlgebra.run { - bufferFactory(buffer.size) { elementAlgebra.transform(buffer[it]) } + elementBufferFactory(buffer.size) { elementAlgebra.transform(buffer[it]) } } ) } @@ -74,7 +73,7 @@ internal inline fun > BufferAlgebraND.mapIndexedInline( return BufferND( indexes, bufferAlgebra.run { - bufferFactory(buffer.size) { elementAlgebra.transform(indexes.index(it), buffer[it]) } + elementBufferFactory(buffer.size) { elementAlgebra.transform(indexes.index(it), buffer[it]) } } ) } @@ -91,7 +90,7 @@ internal inline fun > BufferAlgebraND.zipInline( return BufferND( indexes, bufferAlgebra.run { - bufferFactory(lbuffer.size) { elementAlgebra.block(lbuffer[it], rbuffer[it]) } + elementBufferFactory(lbuffer.size) { elementAlgebra.block(lbuffer[it], rbuffer[it]) } } ) } @@ -116,9 +115,8 @@ public open class BufferedFieldOpsND>( public constructor( elementAlgebra: A, - bufferFactory: BufferFactory, indexerBuilder: (IntArray) -> ShapeIndexer = BufferAlgebraND.defaultIndexerBuilder, - ) : this(BufferFieldOps(elementAlgebra, bufferFactory), indexerBuilder) + ) : this(BufferFieldOps(elementAlgebra), indexerBuilder) @OptIn(PerformancePitfall::class) override fun scale(a: StructureND, value: Double): StructureND = a.map { it * value } diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/StructureND.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/StructureND.kt index 6e54e1b9d..e14b8bf9d 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/StructureND.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/StructureND.kt @@ -120,7 +120,7 @@ public interface StructureND : Featured, WithShape { */ public fun buffered( strides: Strides, - bufferFactory: BufferFactory = BufferFactory(Buffer.Companion::boxing), + bufferFactory: BufferFactory = BufferFactory.boxing(), initializer: (IntArray) -> T, ): BufferND = BufferND(strides, bufferFactory(strides.linearSize) { i -> initializer(strides.index(i)) }) @@ -140,7 +140,7 @@ public interface StructureND : Featured, WithShape { public fun buffered( shape: IntArray, - bufferFactory: BufferFactory = BufferFactory(Buffer.Companion::boxing), + bufferFactory: BufferFactory = BufferFactory.boxing(), initializer: (IntArray) -> T, ): BufferND = buffered(DefaultStrides(shape), bufferFactory, initializer) diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/Algebra.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/Algebra.kt index 45ba32c13..a93b4365e 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/Algebra.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/Algebra.kt @@ -8,12 +8,7 @@ package space.kscience.kmath.operations import space.kscience.kmath.expressions.Symbol import space.kscience.kmath.misc.UnstableKMathAPI import space.kscience.kmath.operations.Ring.Companion.optimizedPower - -/** - * Stub for DSL the [Algebra] is. - */ -@DslMarker -public annotation class KMathContext +import space.kscience.kmath.structures.MutableBufferFactory /** * Represents an algebraic structure. @@ -21,6 +16,12 @@ public annotation class KMathContext * @param T the type of element of this structure. */ public interface Algebra { + + /** + * Provide a factory for buffers, associated with this [Algebra] + */ + public val bufferFactory: MutableBufferFactory get() = MutableBufferFactory.boxing() + /** * Wraps a raw string to [T] object. This method is designed for three purposes: * diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/BigInt.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/BigInt.kt index 99268348b..9b6911f73 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/BigInt.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/BigInt.kt @@ -10,7 +10,6 @@ import space.kscience.kmath.nd.BufferedRingOpsND import space.kscience.kmath.operations.BigInt.Companion.BASE import space.kscience.kmath.operations.BigInt.Companion.BASE_SIZE import space.kscience.kmath.structures.Buffer -import space.kscience.kmath.structures.MutableBuffer import kotlin.math.log2 import kotlin.math.max import kotlin.math.min @@ -528,19 +527,11 @@ public fun String.parseBigInteger(): BigInt? { public val BigInt.algebra: BigIntField get() = BigIntField -@Deprecated("Use BigInt::buffer") -public inline fun Buffer.Companion.bigInt(size: Int, initializer: (Int) -> BigInt): Buffer = - boxing(size, initializer) - public inline fun BigInt.Companion.buffer(size: Int, initializer: (Int) -> BigInt): Buffer = Buffer.boxing(size, initializer) -@Deprecated("Use BigInt::mutableBuffer") -public inline fun MutableBuffer.Companion.bigInt(size: Int, initializer: (Int) -> BigInt): MutableBuffer = - boxing(size, initializer) - -public inline fun BigInt.mutableBuffer(size: Int, initializer: (Int) -> BigInt): Buffer = +public inline fun BigInt.Companion.mutableBuffer(size: Int, initializer: (Int) -> BigInt): Buffer = Buffer.boxing(size, initializer) public val BigIntField.nd: BufferedRingOpsND - get() = BufferedRingOpsND(BufferRingOps(BigIntField, BigInt::buffer)) + get() = BufferedRingOpsND(BufferRingOps(BigIntField)) diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/BufferAlgebra.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/BufferAlgebra.kt index 51fff8b69..a256fe7d1 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/BufferAlgebra.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/BufferAlgebra.kt @@ -7,8 +7,6 @@ package space.kscience.kmath.operations import space.kscience.kmath.structures.Buffer import space.kscience.kmath.structures.BufferFactory -import space.kscience.kmath.structures.DoubleBuffer -import space.kscience.kmath.structures.ShortBuffer public interface WithSize { public val size: Int @@ -19,11 +17,11 @@ public interface WithSize { */ public interface BufferAlgebra> : Algebra> { public val elementAlgebra: A - public val bufferFactory: BufferFactory + public val elementBufferFactory: BufferFactory get() = elementAlgebra.bufferFactory public fun buffer(size: Int, vararg elements: T): Buffer { require(elements.size == size) { "Expected $size elements but found ${elements.size}" } - return bufferFactory(size) { elements[it] } + return elementBufferFactory(size) { elements[it] } } //TODO move to multi-receiver inline extension @@ -36,13 +34,13 @@ public interface BufferAlgebra> : Algebra> { override fun unaryOperationFunction(operation: String): (arg: Buffer) -> Buffer { val operationFunction = elementAlgebra.unaryOperationFunction(operation) - return { arg -> bufferFactory(arg.size) { operationFunction(arg[it]) } } + return { arg -> elementBufferFactory(arg.size) { operationFunction(arg[it]) } } } override fun binaryOperationFunction(operation: String): (left: Buffer, right: Buffer) -> Buffer { val operationFunction = elementAlgebra.binaryOperationFunction(operation) return { left, right -> - bufferFactory(left.size) { operationFunction(left[it], right[it]) } + elementBufferFactory(left.size) { operationFunction(left[it], right[it]) } } } } @@ -53,7 +51,7 @@ public interface BufferAlgebra> : Algebra> { private inline fun > BufferAlgebra.mapInline( buffer: Buffer, crossinline block: A.(T) -> T, -): Buffer = bufferFactory(buffer.size) { elementAlgebra.block(buffer[it]) } +): Buffer = elementBufferFactory(buffer.size) { elementAlgebra.block(buffer[it]) } /** * Inline map @@ -61,7 +59,7 @@ private inline fun > BufferAlgebra.mapInline( private inline fun > BufferAlgebra.mapIndexedInline( buffer: Buffer, crossinline block: A.(index: Int, arg: T) -> T, -): Buffer = bufferFactory(buffer.size) { elementAlgebra.block(it, buffer[it]) } +): Buffer = elementBufferFactory(buffer.size) { elementAlgebra.block(it, buffer[it]) } /** * Inline zip @@ -72,15 +70,15 @@ private inline fun > BufferAlgebra.zipInline( crossinline block: A.(l: T, r: T) -> T, ): Buffer { require(l.size == r.size) { "Incompatible buffer sizes. left: ${l.size}, right: ${r.size}" } - return bufferFactory(l.size) { elementAlgebra.block(l[it], r[it]) } + return elementBufferFactory(l.size) { elementAlgebra.block(l[it], r[it]) } } public fun BufferAlgebra.buffer(size: Int, initializer: (Int) -> T): Buffer { - return bufferFactory(size, initializer) + return elementBufferFactory(size, initializer) } public fun A.buffer(initializer: (Int) -> T): Buffer where A : BufferAlgebra, A : WithSize { - return bufferFactory(size, initializer) + return elementBufferFactory(size, initializer) } public fun > BufferAlgebra.sin(arg: Buffer): Buffer = @@ -131,7 +129,6 @@ public fun > BufferAlgebra.pow(arg: Buffer, p public open class BufferRingOps>( override val elementAlgebra: A, - override val bufferFactory: BufferFactory, ) : BufferAlgebra, RingOps> { override fun add(left: Buffer, right: Buffer): Buffer = zipInline(left, right) { l, r -> l + r } @@ -146,15 +143,13 @@ public open class BufferRingOps>( } public val ShortRing.bufferAlgebra: BufferRingOps - get() = BufferRingOps(ShortRing, ::ShortBuffer) + get() = BufferRingOps(ShortRing) public open class BufferFieldOps>( elementAlgebra: A, - bufferFactory: BufferFactory, -) : BufferRingOps(elementAlgebra, bufferFactory), BufferAlgebra, FieldOps>, - ScaleOperations> { +) : BufferRingOps(elementAlgebra), BufferAlgebra, FieldOps>, ScaleOperations> { -// override fun add(left: Buffer, right: Buffer): Buffer = zipInline(left, right) { l, r -> l + r } + // override fun add(left: Buffer, right: Buffer): Buffer = zipInline(left, right) { l, r -> l + r } // override fun multiply(left: Buffer, right: Buffer): Buffer = zipInline(left, right) { l, r -> l * r } override fun divide(left: Buffer, right: Buffer): Buffer = zipInline(left, right) { l, r -> l / r } @@ -167,30 +162,26 @@ public open class BufferFieldOps>( public class BufferField>( elementAlgebra: A, - bufferFactory: BufferFactory, override val size: Int, -) : BufferFieldOps(elementAlgebra, bufferFactory), Field>, WithSize { +) : BufferFieldOps(elementAlgebra), Field>, WithSize { - override val zero: Buffer = bufferFactory(size) { elementAlgebra.zero } - override val one: Buffer = bufferFactory(size) { elementAlgebra.one } + override val zero: Buffer = elementAlgebra.bufferFactory(size) { elementAlgebra.zero } + override val one: Buffer = elementAlgebra.bufferFactory(size) { elementAlgebra.one } } /** * Generate full buffer field from given buffer operations */ public fun > BufferFieldOps.withSize(size: Int): BufferField = - BufferField(elementAlgebra, bufferFactory, size) + BufferField(elementAlgebra, size) //Double buffer specialization public fun BufferField.buffer(vararg elements: Number): Buffer { require(elements.size == size) { "Expected $size elements but found ${elements.size}" } - return bufferFactory(size) { elements[it].toDouble() } + return elementBufferFactory(size) { elements[it].toDouble() } } -public fun > A.bufferAlgebra(bufferFactory: BufferFactory): BufferFieldOps = - BufferFieldOps(this, bufferFactory) - -public val DoubleField.bufferAlgebra: BufferFieldOps - get() = BufferFieldOps(DoubleField, ::DoubleBuffer) +public val > A.bufferAlgebra: BufferFieldOps + get() = BufferFieldOps(this) diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/DoubleBufferOps.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/DoubleBufferOps.kt index 083892105..669c0a390 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/DoubleBufferOps.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/DoubleBufferOps.kt @@ -7,8 +7,8 @@ package space.kscience.kmath.operations import space.kscience.kmath.linear.Point import space.kscience.kmath.structures.Buffer -import space.kscience.kmath.structures.BufferFactory import space.kscience.kmath.structures.DoubleBuffer +import space.kscience.kmath.structures.MutableBufferFactory import space.kscience.kmath.structures.asBuffer import kotlin.math.* @@ -19,7 +19,7 @@ public abstract class DoubleBufferOps : BufferAlgebra, Exte Norm, Double> { override val elementAlgebra: DoubleField get() = DoubleField - override val bufferFactory: BufferFactory get() = BufferFactory(::DoubleBuffer) + override val elementBufferFactory: MutableBufferFactory get() = elementAlgebra.bufferFactory override fun Buffer.map(block: DoubleField.(Double) -> Double): DoubleBuffer = mapInline { DoubleField.block(it) } diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/bufferOperation.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/bufferOperation.kt index 652472fcf..0beda11a5 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/bufferOperation.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/bufferOperation.kt @@ -88,7 +88,7 @@ public inline fun Buffer.mapIndexed( */ public inline fun Buffer.mapIndexed( crossinline block: (index: Int, value: T) -> R, -): Buffer = BufferFactory(Buffer.Companion::auto).invoke(size) { block(it, get(it)) } +): Buffer = Buffer.auto(size) { block(it, get(it)) } /** * Fold given buffer according to [operation] @@ -105,7 +105,7 @@ public inline fun Buffer.fold(initial: R, operation: (acc: R, T) -> R) @UnstableKMathAPI public inline fun Buffer.zip( other: Buffer, - bufferFactory: BufferFactory = BufferFactory(Buffer.Companion::auto), + bufferFactory: BufferFactory = BufferFactory.auto(), crossinline transform: (T1, T2) -> R, ): Buffer { require(size == other.size) { "Buffer size mismatch in zip: expected $size but found ${other.size}" } diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/numbers.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/numbers.kt index 07a137415..c108aa729 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/numbers.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/numbers.kt @@ -5,6 +5,7 @@ package space.kscience.kmath.operations +import space.kscience.kmath.structures.* import kotlin.math.pow as kpow /** @@ -65,6 +66,8 @@ public interface ExtendedField : ExtendedFieldOps, Field, PowerOperatio */ @Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE") public object DoubleField : ExtendedField, Norm, ScaleOperations { + override val bufferFactory: MutableBufferFactory = MutableBufferFactory(::DoubleBuffer) + override inline val zero: Double get() = 0.0 override inline val one: Double get() = 1.0 @@ -123,6 +126,8 @@ public val Double.Companion.algebra: DoubleField get() = DoubleField */ @Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE") public object FloatField : ExtendedField, Norm { + override val bufferFactory: MutableBufferFactory = MutableBufferFactory(::FloatBuffer) + override inline val zero: Float get() = 0.0f override inline val one: Float get() = 1.0f @@ -177,11 +182,10 @@ public val Float.Companion.algebra: FloatField get() = FloatField */ @Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE") public object IntRing : Ring, Norm, NumericAlgebra { - override inline val zero: Int - get() = 0 + override val bufferFactory: MutableBufferFactory = MutableBufferFactory(::IntBuffer) - override inline val one: Int - get() = 1 + override inline val zero: Int get() = 0 + override inline val one: Int get() = 1 override fun number(value: Number): Int = value.toInt() override inline fun add(left: Int, right: Int): Int = left + right @@ -201,11 +205,10 @@ public val Int.Companion.algebra: IntRing get() = IntRing */ @Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE") public object ShortRing : Ring, Norm, NumericAlgebra { - override inline val zero: Short - get() = 0 + override val bufferFactory: MutableBufferFactory = MutableBufferFactory(::ShortBuffer) - override inline val one: Short - get() = 1 + override inline val zero: Short get() = 0 + override inline val one: Short get() = 1 override fun number(value: Number): Short = value.toShort() override inline fun add(left: Short, right: Short): Short = (left + right).toShort() @@ -225,11 +228,10 @@ public val Short.Companion.algebra: ShortRing get() = ShortRing */ @Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE") public object ByteRing : Ring, Norm, NumericAlgebra { - override inline val zero: Byte - get() = 0 + override val bufferFactory: MutableBufferFactory = MutableBufferFactory(::ByteBuffer) - override inline val one: Byte - get() = 1 + override inline val zero: Byte get() = 0 + override inline val one: Byte get() = 1 override fun number(value: Number): Byte = value.toByte() override inline fun add(left: Byte, right: Byte): Byte = (left + right).toByte() @@ -249,11 +251,10 @@ public val Byte.Companion.algebra: ByteRing get() = ByteRing */ @Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE") public object LongRing : Ring, Norm, NumericAlgebra { - override inline val zero: Long - get() = 0L + override val bufferFactory: MutableBufferFactory = MutableBufferFactory(::LongBuffer) - override inline val one: Long - get() = 1L + override inline val zero: Long get() = 0L + override inline val one: Long get() = 1L override fun number(value: Number): Long = value.toLong() override inline fun add(left: Long, right: Long): Long = left + right diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Buffer.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Buffer.kt index 1c79c257a..5757848fe 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Buffer.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Buffer.kt @@ -16,6 +16,14 @@ import kotlin.reflect.KClass */ public fun interface BufferFactory { public operator fun invoke(size: Int, builder: (Int) -> T): Buffer + + public companion object{ + public inline fun auto(): BufferFactory = + BufferFactory(Buffer.Companion::auto) + + public fun boxing(): BufferFactory = + BufferFactory(Buffer.Companion::boxing) + } } /** @@ -23,8 +31,16 @@ public fun interface BufferFactory { * * @param T the type of buffer. */ -public fun interface MutableBufferFactory: BufferFactory{ +public fun interface MutableBufferFactory : BufferFactory { override fun invoke(size: Int, builder: (Int) -> T): MutableBuffer + + public companion object { + public inline fun auto(): MutableBufferFactory = + MutableBufferFactory(MutableBuffer.Companion::auto) + + public fun boxing(): MutableBufferFactory = + MutableBufferFactory(MutableBuffer.Companion::boxing) + } } /** diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/ByteBuffer.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/ByteBuffer.kt new file mode 100644 index 000000000..e7bf2b47c --- /dev/null +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/ByteBuffer.kt @@ -0,0 +1,57 @@ +/* + * Copyright 2018-2021 KMath contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package space.kscience.kmath.structures + +import kotlin.jvm.JvmInline + +/** + * Specialized [MutableBuffer] implementation over [ByteArray]. + * + * @property array the underlying array. + */ +@JvmInline +public value class ByteBuffer(public val array: ByteArray) : MutableBuffer { + override val size: Int get() = array.size + + override operator fun get(index: Int): Byte = array[index] + + override operator fun set(index: Int, value: Byte) { + array[index] = value + } + + override operator fun iterator(): ByteIterator = array.iterator() + override fun copy(): MutableBuffer = ByteBuffer(array.copyOf()) +} + +/** + * Creates a new [ByteBuffer] with the specified [size], where each element is calculated by calling the specified + * [init] function. + * + * The function [init] is called for each array element sequentially starting from the first one. + * It should return the value for a buffer element given its index. + */ +public inline fun ByteBuffer(size: Int, init: (Int) -> Byte): ByteBuffer = ByteBuffer(ByteArray(size) { init(it) }) + +/** + * Returns a new [ByteBuffer] of given elements. + */ +public fun ByteBuffer(vararg bytes: Byte): ByteBuffer = ByteBuffer(bytes) + +/** + * Returns a new [ByteArray] containing all the elements of this [Buffer]. + */ +public fun Buffer.toByteArray(): ByteArray = when (this) { + is ByteBuffer -> array.copyOf() + else -> ByteArray(size, ::get) +} + +/** + * Returns [ByteBuffer] over this array. + * + * @receiver the array. + * @return the new buffer. + */ +public fun ByteArray.asBuffer(): ByteBuffer = ByteBuffer(this) diff --git a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/expressions/DSTest.kt b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/expressions/DSTest.kt index 727a918ec..b6581e503 100644 --- a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/expressions/DSTest.kt +++ b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/expressions/DSTest.kt @@ -22,7 +22,7 @@ internal inline fun diff( block: DSField.() -> Unit, ) { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } - DSField(DoubleField, ::DoubleBuffer, order, mapOf(*parameters)).block() + DSField(DoubleField, order, mapOf(*parameters), ::DoubleBuffer).block() } internal class DSTest { diff --git a/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/UniformHistogramGroupND.kt b/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/UniformHistogramGroupND.kt index eafd55513..1ead049e6 100644 --- a/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/UniformHistogramGroupND.kt +++ b/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/UniformHistogramGroupND.kt @@ -21,14 +21,14 @@ public typealias HyperSquareBin = DomainBin /** * Multivariate histogram space for hyper-square real-field bins. - * @param bufferFactory is an optional parameter used to optimize buffer production. + * @param valueBufferFactory is an optional parameter used to optimize buffer production. */ public class UniformHistogramGroupND>( override val valueAlgebraND: FieldOpsND, private val lower: Buffer, private val upper: Buffer, private val binNums: IntArray = IntArray(lower.size) { 20 }, - private val bufferFactory: BufferFactory = BufferFactory(Buffer.Companion::boxing), + private val valueBufferFactory: BufferFactory = valueAlgebraND.elementAlgebra.bufferFactory, ) : HistogramGroupND { init { @@ -94,7 +94,7 @@ public class UniformHistogramGroupND>( } } hBuilder.apply(builder) - val values: BufferND = ndCounter.mapToBuffer(bufferFactory) { it.value } + val values: BufferND = ndCounter.mapToBuffer(valueBufferFactory) { it.value } return HistogramND(this, values) } @@ -114,12 +114,12 @@ public class UniformHistogramGroupND>( public fun > Histogram.Companion.uniformNDFromRanges( valueAlgebraND: FieldOpsND, vararg ranges: ClosedFloatingPointRange, - bufferFactory: BufferFactory = BufferFactory(Buffer.Companion::boxing), + bufferFactory: BufferFactory = valueAlgebraND.elementAlgebra.bufferFactory, ): UniformHistogramGroupND = UniformHistogramGroupND( valueAlgebraND, ranges.map(ClosedFloatingPointRange::start).asBuffer(), ranges.map(ClosedFloatingPointRange::endInclusive).asBuffer(), - bufferFactory = bufferFactory + valueBufferFactory = bufferFactory ) public fun Histogram.Companion.uniformDoubleNDFromRanges( @@ -140,7 +140,7 @@ public fun Histogram.Companion.uniformDoubleNDFromRanges( public fun > Histogram.Companion.uniformNDFromRanges( valueAlgebraND: FieldOpsND, vararg ranges: Pair, Int>, - bufferFactory: BufferFactory = BufferFactory(Buffer.Companion::boxing), + bufferFactory: BufferFactory = valueAlgebraND.elementAlgebra.bufferFactory, ): UniformHistogramGroupND = UniformHistogramGroupND( valueAlgebraND, ListBuffer( @@ -154,7 +154,7 @@ public fun > Histogram.Companion.uniformNDFromRanges( .map(ClosedFloatingPointRange::endInclusive) ), ranges.map(Pair, Int>::second).toIntArray(), - bufferFactory = bufferFactory + valueBufferFactory = bufferFactory ) public fun Histogram.Companion.uniformDoubleNDFromRanges( diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/Sampler.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/Sampler.kt index 890318e31..1c88922ac 100644 --- a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/Sampler.kt +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/Sampler.kt @@ -35,7 +35,7 @@ public fun interface Sampler { public fun Sampler.sampleBuffer( generator: RandomGenerator, size: Int, - bufferFactory: BufferFactory = BufferFactory(Buffer.Companion::boxing), + bufferFactory: BufferFactory = BufferFactory.boxing(), ): Chain> { require(size > 1) //creating temporary storage once