From 12b599fff23afafe97be27ceaa51461d0dd7f86c Mon Sep 17 00:00:00 2001 From: Iaroslav Date: Wed, 23 Sep 2020 21:15:54 +0700 Subject: [PATCH 1/7] Fix some packaging issues, add some KDoc comments, minor refactor --- build.gradle.kts | 6 ++-- .../kmath/structures/ArrayBenchmark.kt | 21 ++++++------ .../kmath/structures/BufferBenchmark.kt | 6 ++-- .../kmath/structures/NDFieldBenchmark.kt | 11 +++--- .../kmath/structures/ViktorBenchmark.kt | 4 +-- .../ast/ExpressionsInterpretersBenchmark.kt | 2 +- .../commons/prob/DistributionBenchmark.kt | 7 ++-- .../structures/StructureReadBenchmark.kt | 8 ++--- .../kscience/kmath/asm/internal/AsmBuilder.kt | 2 +- .../commons/expressions/DiffExpression.kt | 2 +- .../FunctionalExpressionAlgebra.kt | 33 ++++++++++++------ .../kscience/kmath/linear/FeaturedMatrix.kt | 6 +++- .../kotlin/kscience/kmath/misc/AutoDiff.kt | 34 +++++++++++++++---- .../kscience/kmath/operations/BigInt.kt | 4 +-- .../kscience/kmath/operations/Complex.kt | 2 +- .../kmath/structures/FlaggedBuffer.kt | 3 +- .../kscience/kmath/structures/Structure1D.kt | 2 +- .../kmath/coroutines/coroutinesExtra.kt | 3 +- .../kscience/kmath/geometry/GeometrySpace.kt | 2 +- .../histogram/MultivariateHistogramTest.kt | 7 ++-- .../{scientifik => kscience}/memory/Memory.kt | 0 .../memory/MemorySpec.kt | 3 +- .../memory/DataViewMemory.kt | 0 .../memory/ByteBufferMemory.kt | 3 +- .../kscience/kmath/prob/Distribution.kt | 2 +- .../kotlin/kscience/kmath/prob/SamplerTest.kt | 2 +- 26 files changed, 103 insertions(+), 72 deletions(-) rename kmath-memory/src/commonMain/kotlin/{scientifik => kscience}/memory/Memory.kt (100%) rename kmath-memory/src/commonMain/kotlin/{scientifik => kscience}/memory/MemorySpec.kt (95%) rename kmath-memory/src/jsMain/kotlin/{scientifik => kscience}/memory/DataViewMemory.kt (100%) rename kmath-memory/src/jvmMain/kotlin/{scientifik => kscience}/memory/ByteBufferMemory.kt (98%) diff --git a/build.gradle.kts b/build.gradle.kts index 838a05771..8f22b309d 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -3,9 +3,9 @@ plugins { id("org.jetbrains.changelog") version "0.4.0" } -val kmathVersion by extra("0.2.0-dev-1") -val bintrayRepo by extra("kscience") -val githubProject by extra("kmath") +val kmathVersion: String by extra("0.2.0-dev-1") +val bintrayRepo: String by extra("kscience") +val githubProject: String by extra("kmath") allprojects { repositories { diff --git a/examples/src/benchmarks/kotlin/kscience/kmath/structures/ArrayBenchmark.kt b/examples/src/benchmarks/kotlin/kscience/kmath/structures/ArrayBenchmark.kt index 2673552f5..7772facb0 100644 --- a/examples/src/benchmarks/kotlin/kscience/kmath/structures/ArrayBenchmark.kt +++ b/examples/src/benchmarks/kotlin/kscience/kmath/structures/ArrayBenchmark.kt @@ -10,30 +10,29 @@ class ArrayBenchmark { @Benchmark fun benchmarkArrayRead() { var res = 0 - for (i in 1.._root_ide_package_.kscience.kmath.structures.ArrayBenchmark.Companion.size) res += _root_ide_package_.kscience.kmath.structures.ArrayBenchmark.Companion.array[_root_ide_package_.kscience.kmath.structures.ArrayBenchmark.Companion.size - i] + for (i in 1..size) res += array[size - i] } @Benchmark fun benchmarkBufferRead() { var res = 0 - for (i in 1.._root_ide_package_.kscience.kmath.structures.ArrayBenchmark.Companion.size) res += _root_ide_package_.kscience.kmath.structures.ArrayBenchmark.Companion.arrayBuffer.get( - _root_ide_package_.kscience.kmath.structures.ArrayBenchmark.Companion.size - i) + for (i in 1..size) res += arrayBuffer.get( + size - i + ) } @Benchmark fun nativeBufferRead() { var res = 0 - for (i in 1.._root_ide_package_.kscience.kmath.structures.ArrayBenchmark.Companion.size) res += _root_ide_package_.kscience.kmath.structures.ArrayBenchmark.Companion.nativeBuffer.get( - _root_ide_package_.kscience.kmath.structures.ArrayBenchmark.Companion.size - i) + for (i in 1..size) res += nativeBuffer.get( + size - i + ) } companion object { const val size: Int = 1000 - val array: IntArray = IntArray(_root_ide_package_.kscience.kmath.structures.ArrayBenchmark.Companion.size) { it } - val arrayBuffer: IntBuffer = IntBuffer.wrap(_root_ide_package_.kscience.kmath.structures.ArrayBenchmark.Companion.array) - - val nativeBuffer: IntBuffer = IntBuffer.allocate(_root_ide_package_.kscience.kmath.structures.ArrayBenchmark.Companion.size).also { - for (i in 0 until _root_ide_package_.kscience.kmath.structures.ArrayBenchmark.Companion.size) it.put(i, i) - } + val array: IntArray = IntArray(size) { it } + val arrayBuffer: IntBuffer = IntBuffer.wrap(array) + val nativeBuffer: IntBuffer = IntBuffer.allocate(size).also { for (i in 0 until size) it.put(i, i) } } } diff --git a/examples/src/benchmarks/kotlin/kscience/kmath/structures/BufferBenchmark.kt b/examples/src/benchmarks/kotlin/kscience/kmath/structures/BufferBenchmark.kt index 009d51001..40ba49a34 100644 --- a/examples/src/benchmarks/kotlin/kscience/kmath/structures/BufferBenchmark.kt +++ b/examples/src/benchmarks/kotlin/kscience/kmath/structures/BufferBenchmark.kt @@ -11,7 +11,7 @@ class BufferBenchmark { @Benchmark fun genericRealBufferReadWrite() { - val buffer = RealBuffer(size){it.toDouble()} + val buffer = RealBuffer(size) { it.toDouble() } (0 until size).forEach { buffer[it] @@ -20,7 +20,7 @@ class BufferBenchmark { @Benchmark fun complexBufferReadWrite() { - val buffer = MutableBuffer.complex(size / 2){Complex(it.toDouble(), -it.toDouble())} + val buffer = MutableBuffer.complex(size / 2) { Complex(it.toDouble(), -it.toDouble()) } (0 until size / 2).forEach { buffer[it] @@ -28,6 +28,6 @@ class BufferBenchmark { } companion object { - const val size = 100 + const val size: Int = 100 } } \ No newline at end of file diff --git a/examples/src/benchmarks/kotlin/kscience/kmath/structures/NDFieldBenchmark.kt b/examples/src/benchmarks/kotlin/kscience/kmath/structures/NDFieldBenchmark.kt index 64f279c39..8f37feda4 100644 --- a/examples/src/benchmarks/kotlin/kscience/kmath/structures/NDFieldBenchmark.kt +++ b/examples/src/benchmarks/kotlin/kscience/kmath/structures/NDFieldBenchmark.kt @@ -40,11 +40,10 @@ class NDFieldBenchmark { } companion object { - val dim = 1000 - val n = 100 - - val bufferedField = NDField.auto(RealField, dim, dim) - val specializedField = NDField.real(dim, dim) - val genericField = NDField.boxing(RealField, dim, dim) + const val dim: Int = 1000 + const val n: Int = 100 + val bufferedField: BufferedNDField = NDField.auto(RealField, dim, dim) + val specializedField: RealNDField = NDField.real(dim, dim) + val genericField: BoxingNDField = NDField.boxing(RealField, dim, dim) } } \ No newline at end of file diff --git a/examples/src/benchmarks/kotlin/kscience/kmath/structures/ViktorBenchmark.kt b/examples/src/benchmarks/kotlin/kscience/kmath/structures/ViktorBenchmark.kt index a4b831f7c..7f55c0560 100644 --- a/examples/src/benchmarks/kotlin/kscience/kmath/structures/ViktorBenchmark.kt +++ b/examples/src/benchmarks/kotlin/kscience/kmath/structures/ViktorBenchmark.kt @@ -10,8 +10,8 @@ import org.openjdk.jmh.annotations.State @State(Scope.Benchmark) class ViktorBenchmark { - final val dim = 1000 - final val n = 100 + final val dim: Int = 1000 + final val n: Int = 100 // automatically build context most suited for given type. final val autoField: BufferedNDField = NDField.auto(RealField, dim, dim) diff --git a/examples/src/main/kotlin/kscience/kmath/ast/ExpressionsInterpretersBenchmark.kt b/examples/src/main/kotlin/kscience/kmath/ast/ExpressionsInterpretersBenchmark.kt index a5768f1f5..f0a32e5bd 100644 --- a/examples/src/main/kotlin/kscience/kmath/ast/ExpressionsInterpretersBenchmark.kt +++ b/examples/src/main/kotlin/kscience/kmath/ast/ExpressionsInterpretersBenchmark.kt @@ -1,4 +1,4 @@ -//package kscience.kmath.ast +package kscience.kmath.ast // //import kscience.kmath.asm.compile //import kscience.kmath.expressions.Expression diff --git a/examples/src/main/kotlin/kscience/kmath/commons/prob/DistributionBenchmark.kt b/examples/src/main/kotlin/kscience/kmath/commons/prob/DistributionBenchmark.kt index 57a9c55c5..a2d7a0291 100644 --- a/examples/src/main/kotlin/kscience/kmath/commons/prob/DistributionBenchmark.kt +++ b/examples/src/main/kotlin/kscience/kmath/commons/prob/DistributionBenchmark.kt @@ -10,10 +10,8 @@ import org.apache.commons.rng.simple.RandomSource import java.time.Duration import java.time.Instant - -private suspend fun runChain(): Duration { +private fun runChain(): Duration { val generator = RandomGenerator.fromSource(RandomSource.MT, 123L) - val normal = Distribution.normal(NormalSamplerMethod.Ziggurat) val chain = normal.sample(generator) as BlockingRealChain @@ -67,5 +65,4 @@ fun main() { println("Chain: ${chainJob.await()}") println("Direct: ${directJob.await()}") } - -} \ No newline at end of file +} diff --git a/examples/src/main/kotlin/kscience/kmath/structures/StructureReadBenchmark.kt b/examples/src/main/kotlin/kscience/kmath/structures/StructureReadBenchmark.kt index a2bfea2f9..00606ec08 100644 --- a/examples/src/main/kotlin/kscience/kmath/structures/StructureReadBenchmark.kt +++ b/examples/src/main/kotlin/kscience/kmath/structures/StructureReadBenchmark.kt @@ -12,24 +12,24 @@ fun main() { val structure = BufferNDStructure(strides, buffer) measureTimeMillis { - var res: Double = 0.0 + var res = 0.0 strides.indices().forEach { res = structure[it] } } // warmup val time1 = measureTimeMillis { - var res: Double = 0.0 + var res = 0.0 strides.indices().forEach { res = structure[it] } } println("Structure reading finished in $time1 millis") val time2 = measureTimeMillis { - var res: Double = 0.0 + var res = 0.0 strides.indices().forEach { res = buffer[strides.offset(it)] } } println("Buffer reading finished in $time2 millis") val time3 = measureTimeMillis { - var res: Double = 0.0 + var res = 0.0 strides.indices().forEach { res = array[strides.offset(it)] } } println("Array reading finished in $time3 millis") diff --git a/kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/internal/AsmBuilder.kt b/kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/internal/AsmBuilder.kt index ab2de97aa..c64ca1d8f 100644 --- a/kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/internal/AsmBuilder.kt +++ b/kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/internal/AsmBuilder.kt @@ -32,7 +32,7 @@ internal class AsmBuilder internal constructor( * Internal classloader of [AsmBuilder] with alias to define class from byte array. */ private class ClassLoader(parent: java.lang.ClassLoader) : java.lang.ClassLoader(parent) { - internal fun defineClass(name: String?, b: ByteArray): Class<*> = defineClass(name, b, 0, b.size) + fun defineClass(name: String?, b: ByteArray): Class<*> = defineClass(name, b, 0, b.size) } /** diff --git a/kmath-commons/src/main/kotlin/kscience/kmath/commons/expressions/DiffExpression.kt b/kmath-commons/src/main/kotlin/kscience/kmath/commons/expressions/DiffExpression.kt index 3ac908536..8a09cc793 100644 --- a/kmath-commons/src/main/kotlin/kscience/kmath/commons/expressions/DiffExpression.kt +++ b/kmath-commons/src/main/kotlin/kscience/kmath/commons/expressions/DiffExpression.kt @@ -94,7 +94,7 @@ public class DiffExpression(public val function: DerivativeStructureField.() -> * TODO make result [DiffExpression] */ public fun derivative(orders: Map): Expression = Expression { arguments -> - (DerivativeStructureField(orders.values.max() ?: 0, arguments)) { function().deriv(orders) } + (DerivativeStructureField(orders.values.maxOrNull() ?: 0, arguments)) { function().deriv(orders) } } //TODO add gradient and maybe other vector operators diff --git a/kmath-core/src/commonMain/kotlin/kscience/kmath/expressions/FunctionalExpressionAlgebra.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/expressions/FunctionalExpressionAlgebra.kt index 49844a2be..5b050dd36 100644 --- a/kmath-core/src/commonMain/kotlin/kscience/kmath/expressions/FunctionalExpressionAlgebra.kt +++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/expressions/FunctionalExpressionAlgebra.kt @@ -4,7 +4,7 @@ import kscience.kmath.operations.* internal class FunctionalUnaryOperation(val context: Algebra, val name: String, private val expr: Expression) : Expression { - public override operator fun invoke(arguments: Map): T = + override operator fun invoke(arguments: Map): T = context.unaryOperation(name, expr.invoke(arguments)) } @@ -14,17 +14,17 @@ internal class FunctionalBinaryOperation( val first: Expression, val second: Expression ) : Expression { - public override operator fun invoke(arguments: Map): T = + override operator fun invoke(arguments: Map): T = context.binaryOperation(name, first.invoke(arguments), second.invoke(arguments)) } internal class FunctionalVariableExpression(val name: String, val default: T? = null) : Expression { - public override operator fun invoke(arguments: Map): T = + override operator fun invoke(arguments: Map): T = arguments[name] ?: default ?: error("Parameter not found: $name") } internal class FunctionalConstantExpression(val value: T) : Expression { - public override operator fun invoke(arguments: Map): T = value + override operator fun invoke(arguments: Map): T = value } internal class FunctionalConstProductExpression( @@ -32,7 +32,7 @@ internal class FunctionalConstProductExpression( private val expr: Expression, val const: Number ) : Expression { - public override operator fun invoke(arguments: Map): T = context.multiply(expr.invoke(arguments), const) + override operator fun invoke(arguments: Map): T = context.multiply(expr.invoke(arguments), const) } /** @@ -139,16 +139,27 @@ public open class FunctionalExpressionField(algebra: A) : public open class FunctionalExpressionExtendedField(algebra: A) : FunctionalExpressionField(algebra), ExtendedField> where A : ExtendedField, A : NumericAlgebra { - public override fun sin(arg: Expression): Expression = unaryOperation(TrigonometricOperations.SIN_OPERATION, arg) - public override fun cos(arg: Expression): Expression = unaryOperation(TrigonometricOperations.COS_OPERATION, arg) - public override fun asin(arg: Expression): Expression = unaryOperation(TrigonometricOperations.ASIN_OPERATION, arg) - public override fun acos(arg: Expression): Expression = unaryOperation(TrigonometricOperations.ACOS_OPERATION, arg) - public override fun atan(arg: Expression): Expression = unaryOperation(TrigonometricOperations.ATAN_OPERATION, arg) + public override fun sin(arg: Expression): Expression = + unaryOperation(TrigonometricOperations.SIN_OPERATION, arg) + + public override fun cos(arg: Expression): Expression = + unaryOperation(TrigonometricOperations.COS_OPERATION, arg) + + public override fun asin(arg: Expression): Expression = + unaryOperation(TrigonometricOperations.ASIN_OPERATION, arg) + + public override fun acos(arg: Expression): Expression = + unaryOperation(TrigonometricOperations.ACOS_OPERATION, arg) + + public override fun atan(arg: Expression): Expression = + unaryOperation(TrigonometricOperations.ATAN_OPERATION, arg) public override fun power(arg: Expression, pow: Number): Expression = binaryOperation(PowerOperations.POW_OPERATION, arg, number(pow)) - public override fun exp(arg: Expression): Expression = unaryOperation(ExponentialOperations.EXP_OPERATION, arg) + public override fun exp(arg: Expression): Expression = + unaryOperation(ExponentialOperations.EXP_OPERATION, arg) + public override fun ln(arg: Expression): Expression = unaryOperation(ExponentialOperations.LN_OPERATION, arg) public override fun unaryOperation(operation: String, arg: Expression): Expression = diff --git a/kmath-core/src/commonMain/kotlin/kscience/kmath/linear/FeaturedMatrix.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/linear/FeaturedMatrix.kt index 65dc8df76..5d9af8608 100644 --- a/kmath-core/src/commonMain/kotlin/kscience/kmath/linear/FeaturedMatrix.kt +++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/linear/FeaturedMatrix.kt @@ -24,7 +24,11 @@ public interface FeaturedMatrix : Matrix { public companion object } -public inline fun Structure2D.Companion.real(rows: Int, columns: Int, initializer: (Int, Int) -> Double): Matrix = +public inline fun Structure2D.Companion.real( + rows: Int, + columns: Int, + initializer: (Int, Int) -> Double +): Matrix = MatrixContext.real.produce(rows, columns, initializer) /** diff --git a/kmath-core/src/commonMain/kotlin/kscience/kmath/misc/AutoDiff.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/misc/AutoDiff.kt index b4a610eb1..bfcd5959f 100644 --- a/kmath-core/src/commonMain/kotlin/kscience/kmath/misc/AutoDiff.kt +++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/misc/AutoDiff.kt @@ -1,10 +1,7 @@ package kscience.kmath.misc import kscience.kmath.linear.Point -import kscience.kmath.operations.ExtendedField -import kscience.kmath.operations.Field -import kscience.kmath.operations.invoke -import kscience.kmath.operations.sum +import kscience.kmath.operations.* import kscience.kmath.structures.asBuffer import kotlin.contracts.InvocationKind import kotlin.contracts.contract @@ -17,23 +14,37 @@ import kotlin.contracts.contract /** * Differentiable variable with value and derivative of differentiation ([deriv]) result * with respect to this variable. + * + * @param T the non-nullable type of value. + * @property value The value of this variable. */ public open class Variable(public val value: T) +/** + * Represents result of [deriv] call. + * + * @param T the non-nullable type of value. + * @param value the value of result. + * @property deriv The mapping of differentiated variables to their derivatives. + * @property context The field over [T]. + */ public class DerivationResult( value: T, public val deriv: Map, T>, public val context: Field ) : Variable(value) { + /** + * Returns derivative of [variable] or returns [Ring.zero] in [context]. + */ public fun deriv(variable: Variable): T = deriv[variable] ?: context.zero /** - * compute divergence + * Computes the divergence. */ public fun div(): T = context { sum(deriv.values) } /** - * Compute a gradient for variables in given order + * Computes the gradient for variables in given order. */ public fun grad(vararg variables: Variable): Point { check(variables.isNotEmpty()) { "Variable order is not provided for gradient construction" } @@ -53,6 +64,9 @@ public class DerivationResult( * assertEquals(17.0, y.x) // the value of result (y) * assertEquals(9.0, x.d) // dy/dx * ``` + * + * @param body the action in [AutoDiffField] context returning [Variable] to differentiate with respect to. + * @return the result of differentiation. */ public inline fun > F.deriv(body: AutoDiffField.() -> Variable): DerivationResult { contract { callsInPlace(body, InvocationKind.EXACTLY_ONCE) } @@ -65,12 +79,15 @@ public inline fun > F.deriv(body: AutoDiffField.() - } } +/** + * Represents field in context of which functions can be derived. + */ public abstract class AutoDiffField> : Field> { public abstract val context: F /** * A variable accessing inner state of derivatives. - * Use this function in inner builders to avoid creating additional derivative bindings + * Use this value in inner builders to avoid creating additional derivative bindings. */ public abstract var Variable.d: T @@ -87,6 +104,9 @@ public abstract class AutoDiffField> : Field> */ public abstract fun derive(value: R, block: F.(R) -> Unit): R + /** + * + */ public abstract fun variable(value: T): Variable public inline fun variable(block: F.() -> T): Variable = variable(context.block()) diff --git a/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/BigInt.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/BigInt.kt index 4590c58fc..20f289596 100644 --- a/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/BigInt.kt +++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/BigInt.kt @@ -299,7 +299,7 @@ public class BigInt internal constructor( for (i in mag.indices) { val cur: ULong = carry + mag[i].toULong() * x.toULong() - result[i] = (cur and BASE.toULong()).toUInt() + result[i] = (cur and BASE).toUInt() carry = cur shr BASE_SIZE } result[resultLength - 1] = (carry and BASE).toUInt() @@ -316,7 +316,7 @@ public class BigInt internal constructor( for (j in mag2.indices) { val cur: ULong = result[i + j].toULong() + mag1[i].toULong() * mag2[j].toULong() + carry - result[i + j] = (cur and BASE.toULong()).toUInt() + result[i + j] = (cur and BASE).toUInt() carry = cur shr BASE_SIZE } diff --git a/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/Complex.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/Complex.kt index c0faf5dc5..9aec6e178 100644 --- a/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/Complex.kt +++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/Complex.kt @@ -159,7 +159,7 @@ public object ComplexField : ExtendedField, Norm { } /** - * Represents complex number. + * Represents `double`-based complex number. * * @property re The real part. * @property im The imaginary part. diff --git a/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/FlaggedBuffer.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/FlaggedBuffer.kt index e3fda0e10..4965e37cf 100644 --- a/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/FlaggedBuffer.kt +++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/FlaggedBuffer.kt @@ -48,7 +48,8 @@ public fun FlaggedBuffer<*>.isMissing(index: Int): Boolean = hasFlag(index, Valu /** * A real buffer which supports flags for each value like NaN or Missing */ -public class FlaggedRealBuffer(public val values: DoubleArray, public val flags: ByteArray) : FlaggedBuffer, Buffer { +public class FlaggedRealBuffer(public val values: DoubleArray, public val flags: ByteArray) : FlaggedBuffer, + Buffer { init { require(values.size == flags.size) { "Values and flags must have the same dimensions" } } diff --git a/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/Structure1D.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/Structure1D.kt index af5cc9e3f..95422ac60 100644 --- a/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/Structure1D.kt +++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/Structure1D.kt @@ -17,7 +17,7 @@ public interface Structure1D : NDStructure, Buffer { /** * A 1D wrapper for nd-structure */ -private inline class Structure1DWrapper(public val structure: NDStructure) : Structure1D { +private inline class Structure1DWrapper(val structure: NDStructure) : Structure1D { override val shape: IntArray get() = structure.shape override val size: Int get() = structure.shape[0] diff --git a/kmath-coroutines/src/commonMain/kotlin/kscience/kmath/coroutines/coroutinesExtra.kt b/kmath-coroutines/src/commonMain/kotlin/kscience/kmath/coroutines/coroutinesExtra.kt index 351207111..7dcdc0d62 100644 --- a/kmath-coroutines/src/commonMain/kotlin/kscience/kmath/coroutines/coroutinesExtra.kt +++ b/kmath-coroutines/src/commonMain/kotlin/kscience/kmath/coroutines/coroutinesExtra.kt @@ -21,7 +21,8 @@ internal class LazyDeferred(val dispatcher: CoroutineDispatcher, val block: s } public class AsyncFlow internal constructor(internal val deferredFlow: Flow>) : Flow { - override suspend fun collect(collector: FlowCollector): Unit = deferredFlow.collect { collector.emit((it.await())) } + override suspend fun collect(collector: FlowCollector): Unit = + deferredFlow.collect { collector.emit((it.await())) } } public fun Flow.async( diff --git a/kmath-geometry/src/commonMain/kotlin/kscience/kmath/geometry/GeometrySpace.kt b/kmath-geometry/src/commonMain/kotlin/kscience/kmath/geometry/GeometrySpace.kt index 64badacf5..54d2510cf 100644 --- a/kmath-geometry/src/commonMain/kotlin/kscience/kmath/geometry/GeometrySpace.kt +++ b/kmath-geometry/src/commonMain/kotlin/kscience/kmath/geometry/GeometrySpace.kt @@ -4,7 +4,7 @@ import kscience.kmath.operations.Space public interface Vector -public interface GeometrySpace: Space { +public interface GeometrySpace : Space { /** * L2 distance */ diff --git a/kmath-histograms/src/commonTest/kotlin/scietifik/kmath/histogram/MultivariateHistogramTest.kt b/kmath-histograms/src/commonTest/kotlin/scietifik/kmath/histogram/MultivariateHistogramTest.kt index 87292f17e..eebb41019 100644 --- a/kmath-histograms/src/commonTest/kotlin/scietifik/kmath/histogram/MultivariateHistogramTest.kt +++ b/kmath-histograms/src/commonTest/kotlin/scietifik/kmath/histogram/MultivariateHistogramTest.kt @@ -5,10 +5,7 @@ import kscience.kmath.histogram.fill import kscience.kmath.histogram.put import kscience.kmath.real.RealVector import kotlin.random.Random -import kotlin.test.Test -import kotlin.test.assertEquals -import kotlin.test.assertFalse -import kotlin.test.assertTrue +import kotlin.test.* internal class MultivariateHistogramTest { @Test @@ -18,7 +15,7 @@ internal class MultivariateHistogramTest { (-1.0..1.0) ) histogram.put(0.55, 0.55) - val bin = histogram.find { it.value.toInt() > 0 }!! + val bin = histogram.find { it.value.toInt() > 0 } ?: fail() assertTrue { bin.contains(RealVector(0.55, 0.55)) } assertTrue { bin.contains(RealVector(0.6, 0.5)) } assertFalse { bin.contains(RealVector(-0.55, 0.55)) } diff --git a/kmath-memory/src/commonMain/kotlin/scientifik/memory/Memory.kt b/kmath-memory/src/commonMain/kotlin/kscience/memory/Memory.kt similarity index 100% rename from kmath-memory/src/commonMain/kotlin/scientifik/memory/Memory.kt rename to kmath-memory/src/commonMain/kotlin/kscience/memory/Memory.kt diff --git a/kmath-memory/src/commonMain/kotlin/scientifik/memory/MemorySpec.kt b/kmath-memory/src/commonMain/kotlin/kscience/memory/MemorySpec.kt similarity index 95% rename from kmath-memory/src/commonMain/kotlin/scientifik/memory/MemorySpec.kt rename to kmath-memory/src/commonMain/kotlin/kscience/memory/MemorySpec.kt index d2cbb32fd..5e0eb3cad 100644 --- a/kmath-memory/src/commonMain/kotlin/scientifik/memory/MemorySpec.kt +++ b/kmath-memory/src/commonMain/kotlin/kscience/memory/MemorySpec.kt @@ -32,7 +32,8 @@ public fun MemoryReader.read(spec: MemorySpec, offset: Int): T = wi /** * Writes the object [value] with [spec] starting from [offset]. */ -public fun MemoryWriter.write(spec: MemorySpec, offset: Int, value: T): Unit = with(spec) { write(offset, value) } +public fun MemoryWriter.write(spec: MemorySpec, offset: Int, value: T): Unit = + with(spec) { write(offset, value) } /** * Reads array of [size] objects mapped by [spec] at certain [offset]. diff --git a/kmath-memory/src/jsMain/kotlin/scientifik/memory/DataViewMemory.kt b/kmath-memory/src/jsMain/kotlin/kscience/memory/DataViewMemory.kt similarity index 100% rename from kmath-memory/src/jsMain/kotlin/scientifik/memory/DataViewMemory.kt rename to kmath-memory/src/jsMain/kotlin/kscience/memory/DataViewMemory.kt diff --git a/kmath-memory/src/jvmMain/kotlin/scientifik/memory/ByteBufferMemory.kt b/kmath-memory/src/jvmMain/kotlin/kscience/memory/ByteBufferMemory.kt similarity index 98% rename from kmath-memory/src/jvmMain/kotlin/scientifik/memory/ByteBufferMemory.kt rename to kmath-memory/src/jvmMain/kotlin/kscience/memory/ByteBufferMemory.kt index c912b28ff..3c37e2ffd 100644 --- a/kmath-memory/src/jvmMain/kotlin/scientifik/memory/ByteBufferMemory.kt +++ b/kmath-memory/src/jvmMain/kotlin/kscience/memory/ByteBufferMemory.kt @@ -100,7 +100,8 @@ public actual fun Memory.Companion.allocate(length: Int): Memory = * Wraps a [Memory] around existing [ByteArray]. This operation is unsafe since the array is not copied * and could be mutated independently from the resulting [Memory]. */ -public actual fun Memory.Companion.wrap(array: ByteArray): Memory = ByteBufferMemory(checkNotNull(ByteBuffer.wrap(array))) +public actual fun Memory.Companion.wrap(array: ByteArray): Memory = + ByteBufferMemory(checkNotNull(ByteBuffer.wrap(array))) /** * Wraps this [ByteBuffer] to [Memory] object. diff --git a/kmath-prob/src/commonMain/kotlin/kscience/kmath/prob/Distribution.kt b/kmath-prob/src/commonMain/kotlin/kscience/kmath/prob/Distribution.kt index d55a52f56..72660e20d 100644 --- a/kmath-prob/src/commonMain/kotlin/kscience/kmath/prob/Distribution.kt +++ b/kmath-prob/src/commonMain/kotlin/kscience/kmath/prob/Distribution.kt @@ -62,7 +62,7 @@ public fun Sampler.sampleBuffer( //clear list from previous run tmp.clear() //Fill list - repeat(size){ + repeat(size) { tmp.add(chain.next()) } //return new buffer with elements from tmp diff --git a/kmath-prob/src/jvmTest/kotlin/kscience/kmath/prob/SamplerTest.kt b/kmath-prob/src/jvmTest/kotlin/kscience/kmath/prob/SamplerTest.kt index 3d8a4f531..75db5c402 100644 --- a/kmath-prob/src/jvmTest/kotlin/kscience/kmath/prob/SamplerTest.kt +++ b/kmath-prob/src/jvmTest/kotlin/kscience/kmath/prob/SamplerTest.kt @@ -6,7 +6,7 @@ import kotlin.test.Test class SamplerTest { @Test - fun bufferSamplerTest(){ + fun bufferSamplerTest() { val sampler: Sampler = BasicSampler { it.chain { nextDouble() } } val data = sampler.sampleBuffer(RandomGenerator.default, 100) From 940fabfac2d9756f9ece8bf8b06673a7f2c6c9d1 Mon Sep 17 00:00:00 2001 From: Iaroslav Postovalov Date: Sun, 27 Sep 2020 14:50:07 +0700 Subject: [PATCH 2/7] Add more KDoc comments, fix grammar issue --- doc/linear.md | 4 +- examples/build.gradle.kts | 4 +- .../kmath/structures/ArrayBenchmark.kt | 2 +- .../kmath/structures/BufferBenchmark.kt | 3 +- .../kmath/structures/NDFieldBenchmark.kt | 2 +- .../kmath/structures/ViktorBenchmark.kt | 4 +- .../commons/prob/DistributionBenchmark.kt | 18 +- .../kmath/commons/prob/DistributionDemo.kt | 4 +- .../kscience/kmath/operations/BigIntDemo.kt | 4 +- .../structures/StructureReadBenchmark.kt | 2 - .../structures/StructureWriteBenchmark.kt | 13 +- .../kmath/structures/typeSafeDimensions.kt | 7 +- .../commons/expressions/DiffExpression.kt | 9 +- .../kscience/kmath/operations/Complex.kt | 19 +- .../kmath/structures/BoxingNDField.kt | 7 +- .../kscience/kmath/structures/BoxingNDRing.kt | 5 +- .../kmath/structures/BufferedNDAlgebra.kt | 6 +- .../kscience/kmath/structures/Buffers.kt | 72 +++++--- .../kscience/kmath/structures/MemoryBuffer.kt | 2 +- .../kscience/kmath/structures/NDAlgebra.kt | 167 +++++++++++++++--- .../kscience/kmath/structures/NDStructure.kt | 12 +- .../kscience/kmath/dimensions/Dimensions.kt | 20 ++- .../dimensions/DMatrixContextTest.kt | 0 .../kscience/kmath/histogram/Histogram.kt | 3 +- .../kscience/kmath/prob/RandomGenerator.kt | 56 +++++- 25 files changed, 323 insertions(+), 122 deletions(-) rename kmath-dimensions/src/commonTest/kotlin/{scientifik => kscience}/dimensions/DMatrixContextTest.kt (100%) diff --git a/doc/linear.md b/doc/linear.md index 883df275e..6ccc6caac 100644 --- a/doc/linear.md +++ b/doc/linear.md @@ -6,10 +6,10 @@ back-ends. The new operations added as extensions to contexts instead of being m Two major contexts used for linear algebra and hyper-geometry: -* `VectorSpace` forms a mathematical space on top of array-like structure (`Buffer` and its typealias `Point` used for geometry). +* `VectorSpace` forms a mathematical space on top of array-like structure (`Buffer` and its type alias `Point` used for geometry). * `MatrixContext` forms a space-like context for 2d-structures. It does not store matrix size and therefore does not implement -`Space` interface (it is not possible to create zero element without knowing the matrix size). +`Space` interface (it is impossible to create zero element without knowing the matrix size). ## Vector spaces diff --git a/examples/build.gradle.kts b/examples/build.gradle.kts index 3d193efce..4e752fc35 100644 --- a/examples/build.gradle.kts +++ b/examples/build.gradle.kts @@ -28,7 +28,9 @@ dependencies { implementation(project(":kmath-dimensions")) implementation("org.jetbrains.kotlinx:kotlinx-io-jvm:0.2.0-npm-dev-6") implementation("org.jetbrains.kotlinx:kotlinx.benchmark.runtime:0.2.0-dev-20") - "benchmarksCompile"(sourceSets.main.get().output + sourceSets.main.get().compileClasspath) //sourceSets.main.output + sourceSets.main.runtimeClasspath + implementation("org.slf4j:slf4j-simple:1.7.30") + "benchmarksImplementation"("org.jetbrains.kotlinx:kotlinx.benchmark.runtime-jvm:0.2.0-dev-8") + "benchmarksImplementation"(sourceSets.main.get().output + sourceSets.main.get().runtimeClasspath) } // Configure benchmark diff --git a/examples/src/benchmarks/kotlin/kscience/kmath/structures/ArrayBenchmark.kt b/examples/src/benchmarks/kotlin/kscience/kmath/structures/ArrayBenchmark.kt index 7772facb0..a91d02253 100644 --- a/examples/src/benchmarks/kotlin/kscience/kmath/structures/ArrayBenchmark.kt +++ b/examples/src/benchmarks/kotlin/kscience/kmath/structures/ArrayBenchmark.kt @@ -6,7 +6,7 @@ import org.openjdk.jmh.annotations.State import java.nio.IntBuffer @State(Scope.Benchmark) -class ArrayBenchmark { +internal class ArrayBenchmark { @Benchmark fun benchmarkArrayRead() { var res = 0 diff --git a/examples/src/benchmarks/kotlin/kscience/kmath/structures/BufferBenchmark.kt b/examples/src/benchmarks/kotlin/kscience/kmath/structures/BufferBenchmark.kt index 40ba49a34..8b6fd4a51 100644 --- a/examples/src/benchmarks/kotlin/kscience/kmath/structures/BufferBenchmark.kt +++ b/examples/src/benchmarks/kotlin/kscience/kmath/structures/BufferBenchmark.kt @@ -7,8 +7,7 @@ import org.openjdk.jmh.annotations.Scope import org.openjdk.jmh.annotations.State @State(Scope.Benchmark) -class BufferBenchmark { - +internal class BufferBenchmark { @Benchmark fun genericRealBufferReadWrite() { val buffer = RealBuffer(size) { it.toDouble() } diff --git a/examples/src/benchmarks/kotlin/kscience/kmath/structures/NDFieldBenchmark.kt b/examples/src/benchmarks/kotlin/kscience/kmath/structures/NDFieldBenchmark.kt index 8f37feda4..8ec47ae81 100644 --- a/examples/src/benchmarks/kotlin/kscience/kmath/structures/NDFieldBenchmark.kt +++ b/examples/src/benchmarks/kotlin/kscience/kmath/structures/NDFieldBenchmark.kt @@ -7,7 +7,7 @@ import org.openjdk.jmh.annotations.Scope import org.openjdk.jmh.annotations.State @State(Scope.Benchmark) -class NDFieldBenchmark { +internal class NDFieldBenchmark { @Benchmark fun autoFieldAdd() { bufferedField { diff --git a/examples/src/benchmarks/kotlin/kscience/kmath/structures/ViktorBenchmark.kt b/examples/src/benchmarks/kotlin/kscience/kmath/structures/ViktorBenchmark.kt index 7f55c0560..464925ca0 100644 --- a/examples/src/benchmarks/kotlin/kscience/kmath/structures/ViktorBenchmark.kt +++ b/examples/src/benchmarks/kotlin/kscience/kmath/structures/ViktorBenchmark.kt @@ -9,7 +9,7 @@ import org.openjdk.jmh.annotations.Scope import org.openjdk.jmh.annotations.State @State(Scope.Benchmark) -class ViktorBenchmark { +internal class ViktorBenchmark { final val dim: Int = 1000 final val n: Int = 100 @@ -42,7 +42,7 @@ class ViktorBenchmark { } @Benchmark - fun realdFieldLog() { + fun realFieldLog() { realField { val fortyTwo = produce { 42.0 } var res = one diff --git a/examples/src/main/kotlin/kscience/kmath/commons/prob/DistributionBenchmark.kt b/examples/src/main/kotlin/kscience/kmath/commons/prob/DistributionBenchmark.kt index a2d7a0291..9c0a01961 100644 --- a/examples/src/main/kotlin/kscience/kmath/commons/prob/DistributionBenchmark.kt +++ b/examples/src/main/kotlin/kscience/kmath/commons/prob/DistributionBenchmark.kt @@ -14,11 +14,10 @@ private fun runChain(): Duration { val generator = RandomGenerator.fromSource(RandomSource.MT, 123L) val normal = Distribution.normal(NormalSamplerMethod.Ziggurat) val chain = normal.sample(generator) as BlockingRealChain - val startTime = Instant.now() var sum = 0.0 - repeat(10000001) { counter -> + repeat(10000001) { counter -> sum += chain.nextDouble() if (counter % 100000 == 0) { @@ -27,6 +26,7 @@ private fun runChain(): Duration { println("Chain sampler completed $counter elements in $duration: $meanValue") } } + return Duration.between(startTime, Instant.now()) } @@ -34,10 +34,9 @@ private fun runDirect(): Duration { val provider = RandomSource.create(RandomSource.MT, 123L) val sampler = ZigguratNormalizedGaussianSampler(provider) val startTime = Instant.now() - var sum = 0.0 - repeat(10000001) { counter -> + repeat(10000001) { counter -> sum += sampler.sample() if (counter % 100000 == 0) { @@ -46,6 +45,7 @@ private fun runDirect(): Duration { println("Direct sampler completed $counter elements in $duration: $meanValue") } } + return Duration.between(startTime, Instant.now()) } @@ -54,14 +54,8 @@ private fun runDirect(): Duration { */ fun main() { runBlocking(Dispatchers.Default) { - val chainJob = async { - runChain() - } - - val directJob = async { - runDirect() - } - + val chainJob = async { runChain() } + val directJob = async { runDirect() } println("Chain: ${chainJob.await()}") println("Direct: ${directJob.await()}") } diff --git a/examples/src/main/kotlin/kscience/kmath/commons/prob/DistributionDemo.kt b/examples/src/main/kotlin/kscience/kmath/commons/prob/DistributionDemo.kt index dbb51267b..7d53e5178 100644 --- a/examples/src/main/kotlin/kscience/kmath/commons/prob/DistributionDemo.kt +++ b/examples/src/main/kotlin/kscience/kmath/commons/prob/DistributionDemo.kt @@ -7,9 +7,9 @@ import kscience.kmath.prob.Distribution import kscience.kmath.prob.RandomGenerator import kscience.kmath.prob.normal -data class AveragingChainState(var num: Int = 0, var value: Double = 0.0) +private data class AveragingChainState(var num: Int = 0, var value: Double = 0.0) -fun Chain.mean(): Chain = collectWithState(AveragingChainState(), { it.copy() }) { chain -> +private fun Chain.mean(): Chain = collectWithState(AveragingChainState(), { it.copy() }) { chain -> val next = chain.next() num++ value += next diff --git a/examples/src/main/kotlin/kscience/kmath/operations/BigIntDemo.kt b/examples/src/main/kotlin/kscience/kmath/operations/BigIntDemo.kt index 692ea6d8c..0e9811ff8 100644 --- a/examples/src/main/kotlin/kscience/kmath/operations/BigIntDemo.kt +++ b/examples/src/main/kotlin/kscience/kmath/operations/BigIntDemo.kt @@ -1,8 +1,6 @@ package kscience.kmath.operations fun main() { - val res = BigIntField { - number(1) * 2 - } + val res = BigIntField { number(1) * 2 } println("bigint:$res") } \ No newline at end of file diff --git a/examples/src/main/kotlin/kscience/kmath/structures/StructureReadBenchmark.kt b/examples/src/main/kotlin/kscience/kmath/structures/StructureReadBenchmark.kt index 00606ec08..51fd4f956 100644 --- a/examples/src/main/kotlin/kscience/kmath/structures/StructureReadBenchmark.kt +++ b/examples/src/main/kotlin/kscience/kmath/structures/StructureReadBenchmark.kt @@ -4,11 +4,9 @@ import kotlin.system.measureTimeMillis fun main() { val n = 6000 - val array = DoubleArray(n * n) { 1.0 } val buffer = RealBuffer(array) val strides = DefaultStrides(intArrayOf(n, n)) - val structure = BufferNDStructure(strides, buffer) measureTimeMillis { diff --git a/examples/src/main/kotlin/kscience/kmath/structures/StructureWriteBenchmark.kt b/examples/src/main/kotlin/kscience/kmath/structures/StructureWriteBenchmark.kt index b2975393f..db55b454f 100644 --- a/examples/src/main/kotlin/kscience/kmath/structures/StructureWriteBenchmark.kt +++ b/examples/src/main/kotlin/kscience/kmath/structures/StructureWriteBenchmark.kt @@ -4,24 +4,17 @@ import kotlin.system.measureTimeMillis fun main() { val n = 6000 - val structure = NDStructure.build(intArrayOf(n, n), Buffer.Companion::auto) { 1.0 } - structure.mapToBuffer { it + 1 } // warm-up - - val time1 = measureTimeMillis { - val res = structure.mapToBuffer { it + 1 } - } + val time1 = measureTimeMillis { val res = structure.mapToBuffer { it + 1 } } println("Structure mapping finished in $time1 millis") - val array = DoubleArray(n * n) { 1.0 } val time2 = measureTimeMillis { val target = DoubleArray(n * n) - val res = array.forEachIndexed { index, value -> - target[index] = value + 1 - } + val res = array.forEachIndexed { index, value -> target[index] = value + 1 } } + println("Array mapping finished in $time2 millis") val buffer = RealBuffer(DoubleArray(n * n) { 1.0 }) diff --git a/examples/src/main/kotlin/kscience/kmath/structures/typeSafeDimensions.kt b/examples/src/main/kotlin/kscience/kmath/structures/typeSafeDimensions.kt index bf83a9f05..987eea16f 100644 --- a/examples/src/main/kotlin/kscience/kmath/structures/typeSafeDimensions.kt +++ b/examples/src/main/kotlin/kscience/kmath/structures/typeSafeDimensions.kt @@ -6,7 +6,7 @@ import kscience.kmath.dimensions.DMatrixContext import kscience.kmath.dimensions.Dimension import kscience.kmath.operations.RealField -fun DMatrixContext.simple() { +private fun DMatrixContext.simple() { val m1 = produce { i, j -> (i + j).toDouble() } val m2 = produce { i, j -> (i + j).toDouble() } @@ -14,12 +14,11 @@ fun DMatrixContext.simple() { m1.transpose() + m2 } - -object D5 : Dimension { +private object D5 : Dimension { override val dim: UInt = 5u } -fun DMatrixContext.custom() { +private fun DMatrixContext.custom() { val m1 = produce { i, j -> (i + j).toDouble() } val m2 = produce { i, j -> (i - j).toDouble() } val m3 = produce { i, j -> (i - j).toDouble() } diff --git a/kmath-commons/src/main/kotlin/kscience/kmath/commons/expressions/DiffExpression.kt b/kmath-commons/src/main/kotlin/kscience/kmath/commons/expressions/DiffExpression.kt index 8a09cc793..c39f0d04c 100644 --- a/kmath-commons/src/main/kotlin/kscience/kmath/commons/expressions/DiffExpression.kt +++ b/kmath-commons/src/main/kotlin/kscience/kmath/commons/expressions/DiffExpression.kt @@ -9,14 +9,17 @@ import org.apache.commons.math3.analysis.differentiation.DerivativeStructure import kotlin.properties.ReadOnlyProperty /** - * A field wrapping commons-math derivative structures + * A field over commons-math [DerivativeStructure]. + * + * @property order The derivation order. + * @property parameters The map of free parameters. */ public class DerivativeStructureField( public val order: Int, public val parameters: Map ) : ExtendedField { - public override val zero: DerivativeStructure by lazy { DerivativeStructure(order, parameters.size) } - public override val one: DerivativeStructure by lazy { DerivativeStructure(order, parameters.size, 1.0) } + public override val zero: DerivativeStructure by lazy { DerivativeStructure(parameters.size, order) } + public override val one: DerivativeStructure by lazy { DerivativeStructure(parameters.size, order, 1.0) } private val variables: Map = parameters.mapValues { (key, value) -> DerivativeStructure(parameters.size, order, parameters.keys.indexOf(key), value) diff --git a/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/Complex.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/Complex.kt index 9aec6e178..d410d304a 100644 --- a/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/Complex.kt +++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/Complex.kt @@ -3,6 +3,7 @@ package kscience.kmath.operations import kscience.kmath.structures.Buffer import kscience.kmath.structures.MemoryBuffer import kscience.kmath.structures.MutableBuffer +import kscience.kmath.structures.MutableMemoryBuffer import kscience.memory.MemoryReader import kscience.memory.MemorySpec import kscience.memory.MemoryWriter @@ -177,10 +178,10 @@ public data class Complex(val re: Double, val im: Double) : FieldElement { - override val objectSize: Int = 16 + override val objectSize: Int + get() = 16 - override fun MemoryReader.read(offset: Int): Complex = - Complex(readDouble(offset), readDouble(offset + 8)) + override fun MemoryReader.read(offset: Int): Complex = Complex(readDouble(offset), readDouble(offset + 8)) override fun MemoryWriter.write(offset: Int, value: Complex) { writeDouble(offset, value.re) @@ -197,8 +198,16 @@ public data class Complex(val re: Double, val im: Double) : FieldElement Complex): Buffer = MemoryBuffer.create(Complex, size, init) -public inline fun MutableBuffer.Companion.complex(size: Int, init: (Int) -> Complex): Buffer = - MemoryBuffer.create(Complex, size, init) +/** + * Creates a new buffer of complex numbers with the specified [size], where each element is calculated by calling the + * specified [init] function. + */ +public inline fun MutableBuffer.Companion.complex(size: Int, init: (Int) -> Complex): MutableBuffer = + MutableMemoryBuffer.create(Complex, size, init) diff --git a/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/BoxingNDField.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/BoxingNDField.kt index c3c859f7a..dc65b12c4 100644 --- a/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/BoxingNDField.kt +++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/BoxingNDField.kt @@ -15,8 +15,9 @@ public class BoxingNDField>( public fun buildBuffer(size: Int, initializer: (Int) -> T): Buffer = bufferFactory(size, initializer) - public override fun check(vararg elements: NDBuffer) { - check(elements.all { it.strides == strides }) { "Element strides are not the same as context strides" } + public override fun check(vararg elements: NDBuffer): Array> { + require(elements.all { it.strides == strides }) { "Element strides are not the same as context strides" } + return elements } public override fun produce(initializer: F.(IntArray) -> T): BufferedNDFieldElement = @@ -75,6 +76,6 @@ public inline fun , R> F.nd( vararg shape: Int, action: NDField.() -> R ): R { - val ndfield: BoxingNDField = NDField.boxing(this, *shape, bufferFactory = bufferFactory) + val ndfield = NDField.boxing(this, *shape, bufferFactory = bufferFactory) return ndfield.action() } diff --git a/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/BoxingNDRing.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/BoxingNDRing.kt index 461b0387c..b6794984c 100644 --- a/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/BoxingNDRing.kt +++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/BoxingNDRing.kt @@ -14,8 +14,9 @@ public class BoxingNDRing>( public fun buildBuffer(size: Int, initializer: (Int) -> T): Buffer = bufferFactory(size, initializer) - override fun check(vararg elements: NDBuffer) { - require(elements.all { it.strides == strides }) { "Element strides are not the same as context strides" } + override fun check(vararg elements: NDBuffer): Array> { + if (!elements.all { it.strides == this.strides }) error("Element strides are not the same as context strides") + return elements } override fun produce(initializer: R.(IntArray) -> T): BufferedNDRingElement = diff --git a/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/BufferedNDAlgebra.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/BufferedNDAlgebra.kt index 66b4f19e1..3dcd0322c 100644 --- a/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/BufferedNDAlgebra.kt +++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/BufferedNDAlgebra.kt @@ -5,8 +5,10 @@ import kscience.kmath.operations.* public interface BufferedNDAlgebra : NDAlgebra> { public val strides: Strides - public override fun check(vararg elements: NDBuffer): Unit = - require(elements.all { it.strides == strides }) { ("Strides mismatch") } + public override fun check(vararg elements: NDBuffer): Array> { + require(elements.all { it.strides == strides }) { "Strides mismatch" } + return elements + } /** * Convert any [NDStructure] to buffered structure using strides from this context. diff --git a/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/Buffers.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/Buffers.kt index 53587e503..5174eb314 100644 --- a/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/Buffers.kt +++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/Buffers.kt @@ -46,35 +46,48 @@ public interface Buffer { asSequence().mapIndexed { index, value -> value == other[index] }.all { it } public companion object { - public inline fun real(size: Int, initializer: (Int) -> Double): RealBuffer { - val array = DoubleArray(size) { initializer(it) } - return RealBuffer(array) - } + /** + * Creates a [RealBuffer] with the specified [size], where each element is calculated by calling the specified + * [initializer] function. + */ + public inline fun real(size: Int, initializer: (Int) -> Double): RealBuffer = + RealBuffer(size) { initializer(it) } /** - * Create a boxing buffer of given type + * Creates a [ListBuffer] of given type [T] with given [size]. Each element is calculated by calling the + * specified [initializer] function. */ public inline fun boxing(size: Int, initializer: (Int) -> T): Buffer = ListBuffer(List(size, initializer)) + // TODO add resolution based on Annotation or companion resolution + + /** + * Creates a [Buffer] of given [type]. If the type is primitive, specialized buffers are used ([IntBuffer], + * [RealBuffer], etc.), [ListBuffer] is returned otherwise. + * + * The [size] is specified, and each element is calculated by calling the specified [initializer] function. + */ @Suppress("UNCHECKED_CAST") - public inline fun auto(type: KClass, size: Int, crossinline initializer: (Int) -> T): Buffer { - //TODO add resolution based on Annotation or companion resolution - return when (type) { - Double::class -> RealBuffer(DoubleArray(size) { initializer(it) as Double }) as Buffer - Short::class -> ShortBuffer(ShortArray(size) { initializer(it) as Short }) as Buffer - Int::class -> IntBuffer(IntArray(size) { initializer(it) as Int }) as Buffer - Long::class -> LongBuffer(LongArray(size) { initializer(it) as Long }) as Buffer + public inline fun auto(type: KClass, size: Int, initializer: (Int) -> T): Buffer = + when (type) { + Double::class -> RealBuffer(size) { initializer(it) as Double } as Buffer + Short::class -> ShortBuffer(size) { initializer(it) as Short } as Buffer + Int::class -> IntBuffer(size) { initializer(it) as Int } as Buffer + Long::class -> LongBuffer(size) { initializer(it) as Long } as Buffer + Float::class -> FloatBuffer(size) { initializer(it) as Float } as Buffer Complex::class -> complex(size) { initializer(it) as Complex } as Buffer else -> boxing(size, initializer) } - } /** - * Create most appropriate immutable buffer for given type avoiding boxing wherever possible + * Creates a [Buffer] of given type [T]. If the type is primitive, specialized buffers are used ([IntBuffer], + * [RealBuffer], etc.), [ListBuffer] is returned otherwise. + * + * The [size] is specified, and each element is calculated by calling the specified [initializer] function. */ @Suppress("UNCHECKED_CAST") - public inline fun auto(size: Int, crossinline initializer: (Int) -> T): Buffer = + public inline fun auto(size: Int, initializer: (Int) -> T): Buffer = auto(T::class, size, initializer) } } @@ -117,25 +130,40 @@ public interface MutableBuffer : Buffer { public inline fun boxing(size: Int, initializer: (Int) -> T): MutableBuffer = MutableListBuffer(MutableList(size, initializer)) + /** + * Creates a [MutableBuffer] of given [type]. If the type is primitive, specialized buffers are used + * ([IntBuffer], [RealBuffer], etc.), [ListBuffer] is returned otherwise. + * + * The [size] is specified, and each element is calculated by calling the specified [initializer] function. + */ @Suppress("UNCHECKED_CAST") public inline fun auto(type: KClass, size: Int, initializer: (Int) -> T): MutableBuffer = when (type) { - Double::class -> RealBuffer(DoubleArray(size) { initializer(it) as Double }) as MutableBuffer - Short::class -> ShortBuffer(ShortArray(size) { initializer(it) as Short }) as MutableBuffer - Int::class -> IntBuffer(IntArray(size) { initializer(it) as Int }) as MutableBuffer - Long::class -> LongBuffer(LongArray(size) { initializer(it) as Long }) as MutableBuffer + Double::class -> RealBuffer(size) { initializer(it) as Double } as MutableBuffer + Short::class -> ShortBuffer(size) { initializer(it) as Short } as MutableBuffer + Int::class -> IntBuffer(size) { initializer(it) as Int } as MutableBuffer + Float::class -> FloatBuffer(size) { initializer(it) as Float } as MutableBuffer + Long::class -> LongBuffer(size) { initializer(it) as Long } as MutableBuffer + Complex::class -> complex(size) { initializer(it) as Complex } as MutableBuffer else -> boxing(size, initializer) } /** - * Create most appropriate mutable buffer for given type avoiding boxing wherever possible + * Creates a [MutableBuffer] of given type [T]. If the type is primitive, specialized buffers are used + * ([IntBuffer], [RealBuffer], etc.), [ListBuffer] is returned otherwise. + * + * The [size] is specified, and each element is calculated by calling the specified [initializer] function. */ @Suppress("UNCHECKED_CAST") public inline fun auto(size: Int, initializer: (Int) -> T): MutableBuffer = auto(T::class, size, initializer) - public val real: MutableBufferFactory = - { size, initializer -> RealBuffer(DoubleArray(size) { initializer(it) }) } + /** + * Creates a [RealBuffer] with the specified [size], where each element is calculated by calling the specified + * [initializer] function. + */ + public inline fun real(size: Int, initializer: (Int) -> Double): RealBuffer = + RealBuffer(size) { initializer(it) } } } diff --git a/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/MemoryBuffer.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/MemoryBuffer.kt index b7e6a8218..308256992 100644 --- a/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/MemoryBuffer.kt +++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/MemoryBuffer.kt @@ -53,7 +53,7 @@ public class MutableMemoryBuffer(memory: Memory, spec: MemorySpec) : public inline fun create( spec: MemorySpec, size: Int, - crossinline initializer: (Int) -> T + initializer: (Int) -> T ): MutableMemoryBuffer = MutableMemoryBuffer(Memory.allocate(size * spec.objectSize), spec).also { buffer -> (0 until size).forEach { buffer[it] = initializer(it) } } diff --git a/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/NDAlgebra.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/NDAlgebra.kt index 28eaef2f1..4315f0423 100644 --- a/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/NDAlgebra.kt +++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/NDAlgebra.kt @@ -6,49 +6,77 @@ import kscience.kmath.operations.Ring import kscience.kmath.operations.Space /** - * An exception is thrown when the expected ans actual shape of NDArray differs + * An exception is thrown when the expected ans actual shape of NDArray differs. + * + * @property expected the expected shape. + * @property actual the actual shape. */ -public class ShapeMismatchException(public val expected: IntArray, public val actual: IntArray) : RuntimeException() +public class ShapeMismatchException(public val expected: IntArray, public val actual: IntArray) : + RuntimeException("Shape ${actual.contentToString()} doesn't fit in expected shape ${expected.contentToString()}.") /** - * The base interface for all nd-algebra implementations - * @param T the type of nd-structure element - * @param C the type of the element context - * @param N the type of the structure + * The base interface for all ND-algebra implementations. + * + * @param T the type of ND-structure element. + * @param C the type of the element context. + * @param N the type of the structure. */ public interface NDAlgebra> { + /** + * The shape of ND-structures this algebra operates on. + */ public val shape: IntArray + + /** + * The algebra over elements of ND structure. + */ public val elementContext: C /** - * Produce a new [N] structure using given initializer function + * Produces a new [N] structure using given initializer function. */ public fun produce(initializer: C.(IntArray) -> T): N /** - * Map elements from one structure to another one + * Maps elements from one structure to another one by applying [transform] to them. */ public fun map(arg: N, transform: C.(T) -> T): N /** - * Map indexed elements + * Maps elements from one structure to another one by applying [transform] to them alongside with their indices. */ public fun mapIndexed(arg: N, transform: C.(index: IntArray, T) -> T): N /** - * Combine two structures into one + * Combines two structures into one. */ public fun combine(a: N, b: N, transform: C.(T, T) -> T): N /** - * Check if given elements are consistent with this context + * Checks if given element is consistent with this context. + * + * @param element the structure to check. + * @return the valid structure. */ - public fun check(vararg elements: N): Unit = elements.forEach { - if (!shape.contentEquals(it.shape)) throw ShapeMismatchException(shape, it.shape) + public fun check(element: N): N { + if (!element.shape.contentEquals(shape)) throw ShapeMismatchException(shape, element.shape) + return element } /** - * element-by-element invoke a function working on [T] on a [NDStructure] + * Checks if given elements are consistent with this context. + * + * @param elements the structures to check. + * @return the array of valid structures. + */ + public fun check(vararg elements: N): Array = elements + .map(NDStructure::shape) + .singleOrNull { !shape.contentEquals(it) } + ?.let { throw ShapeMismatchException(shape, it) } + ?: elements + + /** + * Element-wise invocation of function working on [T] on a [NDStructure]. */ public operator fun Function1.invoke(structure: N): N = map(structure) { value -> this@invoke(value) } @@ -56,42 +84,107 @@ public interface NDAlgebra> { } /** - * An nd-space over element space + * Space of [NDStructure]. + * + * @param T the type of the element contained in ND structure. + * @param N the type of ND structure. + * @param S the type of space of structure elements. */ public interface NDSpace, N : NDStructure> : Space, NDAlgebra { /** - * Element-by-element addition + * Element-wise addition. + * + * @param a the addend. + * @param b the augend. + * @return the sum. */ - override fun add(a: N, b: N): N = combine(a, b) { aValue, bValue -> add(aValue, bValue) } + public override fun add(a: N, b: N): N = combine(a, b) { aValue, bValue -> add(aValue, bValue) } /** - * Multiply all elements by constant + * Element-wise multiplication by scalar. + * + * @param a the multiplicand. + * @param k the multiplier. + * @return the product. */ - override fun multiply(a: N, k: Number): N = map(a) { multiply(it, k) } + public override fun multiply(a: N, k: Number): N = map(a) { multiply(it, k) } - //TODO move to extensions after KEEP-176 + // TODO move to extensions after KEEP-176 + + /** + * Adds an ND structure to an element of it. + * + * @receiver the addend. + * @param arg the augend. + * @return the sum. + */ public operator fun N.plus(arg: T): N = map(this) { value -> add(arg, value) } + /** + * Subtracts an element from ND structure of it. + * + * @receiver the dividend. + * @param arg the divisor. + * @return the quotient. + */ public operator fun N.minus(arg: T): N = map(this) { value -> add(arg, -value) } + /** + * Adds an element to ND structure of it. + * + * @receiver the addend. + * @param arg the augend. + * @return the sum. + */ public operator fun T.plus(arg: N): N = map(arg) { value -> add(this@plus, value) } + + /** + * Subtracts an ND structure from an element of it. + * + * @receiver the dividend. + * @param arg the divisor. + * @return the quotient. + */ public operator fun T.minus(arg: N): N = map(arg) { value -> add(-this@minus, value) } public companion object } /** - * An nd-ring over element ring + * Ring of [NDStructure]. + * + * @param T the type of the element contained in ND structure. + * @param N the type of ND structure. + * @param R the type of ring of structure elements. */ public interface NDRing, N : NDStructure> : Ring, NDSpace { /** - * Element-by-element multiplication + * Element-wise multiplication. + * + * @param a the multiplicand. + * @param b the multiplier. + * @return the product. */ - override fun multiply(a: N, b: N): N = combine(a, b) { aValue, bValue -> multiply(aValue, bValue) } + public override fun multiply(a: N, b: N): N = combine(a, b) { aValue, bValue -> multiply(aValue, bValue) } //TODO move to extensions after KEEP-176 + + /** + * Multiplies an ND structure by an element of it. + * + * @receiver the multiplicand. + * @param arg the multiplier. + * @return the product. + */ public operator fun N.times(arg: T): N = map(this) { value -> multiply(arg, value) } + /** + * Multiplies an element by a ND structure of it. + * + * @receiver the multiplicand. + * @param arg the multiplier. + * @return the product. + */ public operator fun T.times(arg: N): N = map(arg) { value -> multiply(this@times, value) } public companion object @@ -102,29 +195,47 @@ public interface NDRing, N : NDStructure> : Ring, NDSpace, N : NDStructure> : Field, NDRing { /** - * Element-by-element division + * Element-wise division. + * + * @param a the dividend. + * @param b the divisor. + * @return the quotient. */ - override fun divide(a: N, b: N): N = combine(a, b) { aValue, bValue -> divide(aValue, bValue) } + public override fun divide(a: N, b: N): N = combine(a, b) { aValue, bValue -> divide(aValue, bValue) } //TODO move to extensions after KEEP-176 + /** + * Divides an ND structure by an element of it. + * + * @receiver the dividend. + * @param arg the divisor. + * @return the quotient. + */ public operator fun N.div(arg: T): N = map(this) { value -> divide(arg, value) } + /** + * Divides an element by an ND structure of it. + * + * @receiver the dividend. + * @param arg the divisor. + * @return the quotient. + */ public operator fun T.div(arg: N): N = map(arg) { divide(it, this@div) } public companion object { private val realNDFieldCache: MutableMap = hashMapOf() /** - * Create a nd-field for [Double] values or pull it from cache if it was created previously + * Create a nd-field for [Double] values or pull it from cache if it was created previously. */ public fun real(vararg shape: Int): RealNDField = realNDFieldCache.getOrPut(shape) { RealNDField(shape) } /** - * Create a nd-field with boxing generic buffer + * Create an ND field with boxing generic buffer. */ public fun > boxing( field: F, diff --git a/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/NDStructure.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/NDStructure.kt index 4ab49c9bc..b8c8c855b 100644 --- a/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/NDStructure.kt +++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/NDStructure.kt @@ -37,9 +37,8 @@ public interface NDStructure { */ public fun elements(): Sequence> - override fun equals(other: Any?): Boolean - - override fun hashCode(): Int + public override fun equals(other: Any?): Boolean + public override fun hashCode(): Int public companion object { /** @@ -49,13 +48,8 @@ public interface NDStructure { if (st1 === st2) return true // fast comparison of buffers if possible - if ( - st1 is NDBuffer && - st2 is NDBuffer && - st1.strides == st2.strides - ) { + if (st1 is NDBuffer && st2 is NDBuffer && st1.strides == st2.strides) return st1.buffer.contentEquals(st2.buffer) - } //element by element comparison if it could not be avoided return st1.elements().all { (index, value) -> value == st2[index] } diff --git a/kmath-dimensions/src/commonMain/kotlin/kscience/kmath/dimensions/Dimensions.kt b/kmath-dimensions/src/commonMain/kotlin/kscience/kmath/dimensions/Dimensions.kt index f49e1e0f0..9450f9174 100644 --- a/kmath-dimensions/src/commonMain/kotlin/kscience/kmath/dimensions/Dimensions.kt +++ b/kmath-dimensions/src/commonMain/kotlin/kscience/kmath/dimensions/Dimensions.kt @@ -3,8 +3,9 @@ package kscience.kmath.dimensions import kotlin.reflect.KClass /** - * An abstract class which is not used in runtime. Designates a size of some structure. - * Could be replaced later by fully inline constructs + * Represents a quantity of dimensions in certain structure. + * + * @property dim The number of dimensions. */ public interface Dimension { public val dim: UInt @@ -16,18 +17,33 @@ public fun KClass.dim(): UInt = Dimension.resolve(this).dim public expect fun Dimension.Companion.resolve(type: KClass): D +/** + * Finds or creates [Dimension] with [Dimension.dim] equal to [dim]. + */ public expect fun Dimension.Companion.of(dim: UInt): Dimension +/** + * Finds [Dimension.dim] of given type [D]. + */ public inline fun Dimension.Companion.dim(): UInt = D::class.dim() +/** + * Type representing 1 dimension. + */ public object D1 : Dimension { override val dim: UInt get() = 1U } +/** + * Type representing 2 dimensions. + */ public object D2 : Dimension { override val dim: UInt get() = 2U } +/** + * Type representing 3 dimensions. + */ public object D3 : Dimension { override val dim: UInt get() = 3U } diff --git a/kmath-dimensions/src/commonTest/kotlin/scientifik/dimensions/DMatrixContextTest.kt b/kmath-dimensions/src/commonTest/kotlin/kscience/dimensions/DMatrixContextTest.kt similarity index 100% rename from kmath-dimensions/src/commonTest/kotlin/scientifik/dimensions/DMatrixContextTest.kt rename to kmath-dimensions/src/commonTest/kotlin/kscience/dimensions/DMatrixContextTest.kt diff --git a/kmath-histograms/src/commonMain/kotlin/kscience/kmath/histogram/Histogram.kt b/kmath-histograms/src/commonMain/kotlin/kscience/kmath/histogram/Histogram.kt index 98300dada..370a01215 100644 --- a/kmath-histograms/src/commonMain/kotlin/kscience/kmath/histogram/Histogram.kt +++ b/kmath-histograms/src/commonMain/kotlin/kscience/kmath/histogram/Histogram.kt @@ -10,9 +10,10 @@ import kscience.kmath.structures.RealBuffer */ public interface Bin : Domain { /** - * The value of this bin + * The value of this bin. */ public val value: Number + public val center: Point } diff --git a/kmath-prob/src/commonMain/kotlin/kscience/kmath/prob/RandomGenerator.kt b/kmath-prob/src/commonMain/kotlin/kscience/kmath/prob/RandomGenerator.kt index 0d95d6f97..2dd4ce51e 100644 --- a/kmath-prob/src/commonMain/kotlin/kscience/kmath/prob/RandomGenerator.kt +++ b/kmath-prob/src/commonMain/kotlin/kscience/kmath/prob/RandomGenerator.kt @@ -3,16 +3,59 @@ package kscience.kmath.prob import kotlin.random.Random /** - * A basic generator + * An interface that is implemented by random number generator algorithms. */ public interface RandomGenerator { + /** + * Gets the next random [Boolean] value. + */ public fun nextBoolean(): Boolean + + /** + * Gets the next random [Double] value uniformly distributed between 0 (inclusive) and 1 (exclusive). + */ public fun nextDouble(): Double + + /** + * Gets the next random `Int` from the random number generator. + * + * Generates an `Int` random value uniformly distributed between [Int.MIN_VALUE] and [Int.MAX_VALUE] (inclusive). + */ public fun nextInt(): Int + + /** + * Gets the next random non-negative `Int` from the random number generator less than the specified [until] bound. + * + * Generates an `Int` random value uniformly distributed between `0` (inclusive) and the specified [until] bound + * (exclusive). + */ public fun nextInt(until: Int): Int + + /** + * Gets the next random `Long` from the random number generator. + * + * Generates a `Long` random value uniformly distributed between [Long.MIN_VALUE] and [Long.MAX_VALUE] (inclusive). + */ public fun nextLong(): Long + + /** + * Gets the next random non-negative `Long` from the random number generator less than the specified [until] bound. + * + * Generates a `Long` random value uniformly distributed between `0` (inclusive) and the specified [until] bound (exclusive). + */ public fun nextLong(until: Long): Long + + /** + * Fills a subrange of the specified byte [array] starting from [fromIndex] inclusive and ending [toIndex] exclusive + * with random bytes. + * + * @return [array] with the subrange filled with random bytes. + */ public fun fillBytes(array: ByteArray, fromIndex: Int = 0, toIndex: Int = array.size) + + /** + * Creates a byte array of the specified [size], filled with random bytes. + */ public fun nextBytes(size: Int): ByteArray = ByteArray(size).also { fillBytes(it) } /** @@ -25,12 +68,21 @@ public interface RandomGenerator { public fun fork(): RandomGenerator public companion object { - public val default: DefaultGenerator by lazy { DefaultGenerator() } + /** + * The [DefaultGenerator] instance. + */ + public val default: DefaultGenerator by lazy(::DefaultGenerator) + /** + * Returns [DefaultGenerator] of given [seed]. + */ public fun default(seed: Long): DefaultGenerator = DefaultGenerator(Random(seed)) } } +/** + * Implements [RandomGenerator] by delegating all operations to [Random]. + */ public inline class DefaultGenerator(public val random: Random = Random) : RandomGenerator { public override fun nextBoolean(): Boolean = random.nextBoolean() public override fun nextDouble(): Double = random.nextDouble() From 049ac896671dded53e4482b1b677b02131ef4d93 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Wed, 30 Sep 2020 12:30:06 +0300 Subject: [PATCH 3/7] More informative toString for NDBuffer and Complex --- .../kscience/kmath/operations/ComplexDemo.kt | 6 ++- .../kscience/kmath/operations/Complex.kt | 5 +++ .../kscience/kmath/structures/NDStructure.kt | 38 +++++++++++++------ 3 files changed, 37 insertions(+), 12 deletions(-) diff --git a/examples/src/main/kotlin/kscience/kmath/operations/ComplexDemo.kt b/examples/src/main/kotlin/kscience/kmath/operations/ComplexDemo.kt index 3c97940a8..34b3c9981 100644 --- a/examples/src/main/kotlin/kscience/kmath/operations/ComplexDemo.kt +++ b/examples/src/main/kotlin/kscience/kmath/operations/ComplexDemo.kt @@ -5,15 +5,19 @@ import kscience.kmath.structures.NDField import kscience.kmath.structures.complex fun main() { + // 2d element val element = NDElement.complex(2, 2) { index: IntArray -> Complex(index[0].toDouble() - index[1].toDouble(), index[0].toDouble() + index[1].toDouble()) } + println(element) - val compute = (NDField.complex(8)) { + // 1d element operation + val result = with(NDField.complex(8)) { val a = produce { (it) -> i * it - it.toDouble() } val b = 3 val c = Complex(1.0, 1.0) (a pow b) + c } + println(result) } diff --git a/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/Complex.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/Complex.kt index 24bfec054..7bd7b6085 100644 --- a/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/Complex.kt +++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/Complex.kt @@ -176,6 +176,11 @@ public data class Complex(val re: Double, val im: Double) : FieldElement { override val objectSize: Int = 16 diff --git a/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/NDStructure.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/NDStructure.kt index fd679d073..c107ef7cc 100644 --- a/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/NDStructure.kt +++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/NDStructure.kt @@ -70,7 +70,7 @@ public interface NDStructure { public fun build( strides: Strides, bufferFactory: BufferFactory = Buffer.Companion::boxing, - initializer: (IntArray) -> T + initializer: (IntArray) -> T, ): BufferNDStructure = BufferNDStructure(strides, bufferFactory(strides.linearSize) { i -> initializer(strides.index(i)) }) @@ -79,40 +79,40 @@ public interface NDStructure { */ public inline fun auto( strides: Strides, - crossinline initializer: (IntArray) -> T + crossinline initializer: (IntArray) -> T, ): BufferNDStructure = BufferNDStructure(strides, Buffer.auto(strides.linearSize) { i -> initializer(strides.index(i)) }) public inline fun auto( type: KClass, strides: Strides, - crossinline initializer: (IntArray) -> T + crossinline initializer: (IntArray) -> T, ): BufferNDStructure = BufferNDStructure(strides, Buffer.auto(type, strides.linearSize) { i -> initializer(strides.index(i)) }) public fun build( shape: IntArray, bufferFactory: BufferFactory = Buffer.Companion::boxing, - initializer: (IntArray) -> T + initializer: (IntArray) -> T, ): BufferNDStructure = build(DefaultStrides(shape), bufferFactory, initializer) public inline fun auto( shape: IntArray, - crossinline initializer: (IntArray) -> T + crossinline initializer: (IntArray) -> T, ): BufferNDStructure = auto(DefaultStrides(shape), initializer) @JvmName("autoVarArg") public inline fun auto( vararg shape: Int, - crossinline initializer: (IntArray) -> T + crossinline initializer: (IntArray) -> T, ): BufferNDStructure = auto(DefaultStrides(shape), initializer) public inline fun auto( type: KClass, vararg shape: Int, - crossinline initializer: (IntArray) -> T + crossinline initializer: (IntArray) -> T, ): BufferNDStructure = auto(type, DefaultStrides(shape), initializer) } @@ -274,6 +274,22 @@ public abstract class NDBuffer : NDStructure { result = 31 * result + buffer.hashCode() return result } + + override fun toString(): String { + val bufferRepr: String = when (shape.size) { + 1 -> buffer.asSequence().joinToString(prefix = "[", postfix = "]", separator = ", ") + 2 -> (0 until shape[0]).joinToString(prefix = "[", postfix = "]", separator = ", ") { i -> + (0 until shape[1]).joinToString(prefix = "[", postfix = "]", separator = ", ") { j -> + val offset = strides.offset(intArrayOf(i, j)) + buffer[offset].toString() + } + } + else -> "..." + } + return "NDBuffer(shape=${shape.contentToString()}, buffer=$bufferRepr)" + } + + } /** @@ -281,7 +297,7 @@ public abstract class NDBuffer : NDStructure { */ public class BufferNDStructure( override val strides: Strides, - override val buffer: Buffer + override val buffer: Buffer, ) : NDBuffer() { init { if (strides.linearSize != buffer.size) { @@ -295,7 +311,7 @@ public class BufferNDStructure( */ public inline fun NDStructure.mapToBuffer( factory: BufferFactory = Buffer.Companion::auto, - crossinline transform: (T) -> R + crossinline transform: (T) -> R, ): BufferNDStructure { return if (this is BufferNDStructure) BufferNDStructure(this.strides, factory.invoke(strides.linearSize) { transform(buffer[it]) }) @@ -310,7 +326,7 @@ public inline fun NDStructure.mapToBuffer( */ public class MutableBufferNDStructure( override val strides: Strides, - override val buffer: MutableBuffer + override val buffer: MutableBuffer, ) : NDBuffer(), MutableNDStructure { init { @@ -324,7 +340,7 @@ public class MutableBufferNDStructure( public inline fun NDStructure.combine( struct: NDStructure, - crossinline block: (T, T) -> T + crossinline block: (T, T) -> T, ): NDStructure { require(shape.contentEquals(struct.shape)) { "Shape mismatch in structure combination" } return NDStructure.auto(shape) { block(this[it], struct[it]) } From 7d60fa142d6adf1d922eba6afbce41c476e31a19 Mon Sep 17 00:00:00 2001 From: Iaroslav Postovalov Date: Wed, 30 Sep 2020 21:28:39 +0700 Subject: [PATCH 4/7] Remove kotlin-reflect dependency (-2MiB to library size), optimize type copying, optimize reflection usages, optimize lexer --- kmath-ast/build.gradle.kts | 1 - .../jvmMain/kotlin/kscience/kmath/asm/asm.kt | 18 +++-- .../kscience/kmath/asm/internal/AsmBuilder.kt | 69 +++++++++---------- .../kmath/asm/internal/codegenUtils.kt | 12 ++-- .../kotlin/kscience/kmath/ast/parser.kt | 17 ++--- 5 files changed, 63 insertions(+), 54 deletions(-) diff --git a/kmath-ast/build.gradle.kts b/kmath-ast/build.gradle.kts index df876df10..a0afcdc4f 100644 --- a/kmath-ast/build.gradle.kts +++ b/kmath-ast/build.gradle.kts @@ -14,7 +14,6 @@ kotlin.sourceSets { implementation("org.ow2.asm:asm:8.0.1") implementation("org.ow2.asm:asm-commons:8.0.1") implementation("com.github.h0tk3y.betterParse:better-parse:0.4.0") - implementation(kotlin("reflect")) } } } diff --git a/kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/asm.kt b/kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/asm.kt index 53425e7e3..00b9caf15 100644 --- a/kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/asm.kt +++ b/kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/asm.kt @@ -6,9 +6,11 @@ import kscience.kmath.asm.internal.buildAlgebraOperationCall import kscience.kmath.asm.internal.buildName import kscience.kmath.ast.MST import kscience.kmath.ast.MstExpression +import kscience.kmath.ast.mstInSpace import kscience.kmath.expressions.Expression +import kscience.kmath.expressions.invoke import kscience.kmath.operations.Algebra -import kotlin.reflect.KClass +import kscience.kmath.operations.RealField /** * Compiles given MST to an Expression using AST compiler. @@ -18,7 +20,8 @@ import kotlin.reflect.KClass * @return the compiled expression. * @author Alexander Nozik */ -public fun MST.compileWith(type: KClass, algebra: Algebra): Expression { +@PublishedApi +internal fun MST.compileWith(type: Class, algebra: Algebra): Expression { fun AsmBuilder.visit(node: MST): Unit = when (node) { is MST.Symbolic -> { val symbol = try { @@ -61,11 +64,18 @@ public fun MST.compileWith(type: KClass, algebra: Algebra): Expr * * @author Alexander Nozik. */ -public inline fun Algebra.expression(mst: MST): Expression = mst.compileWith(T::class, this) +public inline fun Algebra.expression(mst: MST): Expression = + mst.compileWith(T::class.java, this) /** * Optimizes performance of an [MstExpression] using ASM codegen. * * @author Alexander Nozik. */ -public inline fun MstExpression.compile(): Expression = mst.compileWith(T::class, algebra) +public inline fun MstExpression.compile(): Expression = mst.compileWith(T::class.java, algebra) + +public fun main() { + val x = RealField.mstInSpace { symbol("x") + number(2.0) }.compile() + println(x("x" to 1.0)) +} + diff --git a/kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/internal/AsmBuilder.kt b/kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/internal/AsmBuilder.kt index ab2de97aa..06f02a94d 100644 --- a/kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/internal/AsmBuilder.kt +++ b/kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/internal/AsmBuilder.kt @@ -10,7 +10,6 @@ import org.objectweb.asm.Opcodes.* import org.objectweb.asm.commons.InstructionAdapter import java.util.* import java.util.stream.Collectors -import kotlin.reflect.KClass /** * ASM Builder is a structure that abstracts building a class designated to unwrap [MST] to plain Java expression. @@ -23,7 +22,7 @@ import kotlin.reflect.KClass * @author Iaroslav Postovalov */ internal class AsmBuilder internal constructor( - private val classOfT: KClass<*>, + private val classOfT: Class<*>, private val algebra: Algebra, private val className: String, private val invokeLabel0Visitor: AsmBuilder.() -> Unit @@ -32,7 +31,7 @@ internal class AsmBuilder internal constructor( * Internal classloader of [AsmBuilder] with alias to define class from byte array. */ private class ClassLoader(parent: java.lang.ClassLoader) : java.lang.ClassLoader(parent) { - internal fun defineClass(name: String?, b: ByteArray): Class<*> = defineClass(name, b, 0, b.size) + fun defineClass(name: String?, b: ByteArray): Class<*> = defineClass(name, b, 0, b.size) } /** @@ -43,7 +42,7 @@ internal class AsmBuilder internal constructor( /** * ASM Type for [algebra]. */ - private val tAlgebraType: Type = algebra::class.asm + private val tAlgebraType: Type = algebra.javaClass.asm /** * ASM type for [T]. @@ -55,16 +54,6 @@ internal class AsmBuilder internal constructor( */ private val classType: Type = Type.getObjectType(className.replace(oldChar = '.', newChar = '/'))!! - /** - * Index of `this` variable in invoke method of the built subclass. - */ - private val invokeThisVar: Int = 0 - - /** - * Index of `arguments` variable in invoke method of the built subclass. - */ - private val invokeArgumentsVar: Int = 1 - /** * List of constants to provide to the subclass. */ @@ -76,22 +65,22 @@ internal class AsmBuilder internal constructor( private lateinit var invokeMethodVisitor: InstructionAdapter /** - * State if this [AsmBuilder] needs to generate constants field. + * States whether this [AsmBuilder] needs to generate constants field. */ private var hasConstants: Boolean = true /** - * State if [T] a primitive type, so [AsmBuilder] may generate direct primitive calls. + * States whether [T] a primitive type, so [AsmBuilder] may generate direct primitive calls. */ internal var primitiveMode: Boolean = false /** - * Primitive type to apple for specific primitive calls. Use [OBJECT_TYPE], if not in [primitiveMode]. + * Primitive type to apply for specific primitive calls. Use [OBJECT_TYPE], if not in [primitiveMode]. */ internal var primitiveMask: Type = OBJECT_TYPE /** - * Boxed primitive type to apple for specific primitive calls. Use [OBJECT_TYPE], if not in [primitiveMode]. + * Boxed primitive type to apply for specific primitive calls. Use [OBJECT_TYPE], if not in [primitiveMode]. */ internal var primitiveMaskBoxed: Type = OBJECT_TYPE @@ -103,7 +92,7 @@ internal class AsmBuilder internal constructor( /** * Stack of useful objects types on stack expected by algebra calls. */ - internal val expectationStack: ArrayDeque = ArrayDeque(listOf(tType)) + internal val expectationStack: ArrayDeque = ArrayDeque(1).also { it.push(tType) } /** * The cache for instance built by this builder. @@ -361,7 +350,7 @@ internal class AsmBuilder internal constructor( * from it). */ private fun loadNumberConstant(value: Number, mustBeBoxed: Boolean) { - val boxed = value::class.asm + val boxed = value.javaClass.asm val primitive = BOXED_TO_PRIMITIVES[boxed] if (primitive != null) { @@ -475,17 +464,27 @@ internal class AsmBuilder internal constructor( internal fun loadStringConstant(string: String): Unit = invokeMethodVisitor.aconst(string) internal companion object { + /** + * Index of `this` variable in invoke method of the built subclass. + */ + private const val invokeThisVar: Int = 0 + + /** + * Index of `arguments` variable in invoke method of the built subclass. + */ + private const val invokeArgumentsVar: Int = 1 + /** * Maps JVM primitive numbers boxed types to their primitive ASM types. */ - private val SIGNATURE_LETTERS: Map, Type> by lazy { + private val SIGNATURE_LETTERS: Map, Type> by lazy { hashMapOf( - java.lang.Byte::class to Type.BYTE_TYPE, - java.lang.Short::class to Type.SHORT_TYPE, - java.lang.Integer::class to Type.INT_TYPE, - java.lang.Long::class to Type.LONG_TYPE, - java.lang.Float::class to Type.FLOAT_TYPE, - java.lang.Double::class to Type.DOUBLE_TYPE + java.lang.Byte::class.java to Type.BYTE_TYPE, + java.lang.Short::class.java to Type.SHORT_TYPE, + java.lang.Integer::class.java to Type.INT_TYPE, + java.lang.Long::class.java to Type.LONG_TYPE, + java.lang.Float::class.java to Type.FLOAT_TYPE, + java.lang.Double::class.java to Type.DOUBLE_TYPE ) } @@ -523,43 +522,43 @@ internal class AsmBuilder internal constructor( /** * Provides boxed number types values of which can be stored in JVM bytecode constant pool. */ - private val INLINABLE_NUMBERS: Set> by lazy { SIGNATURE_LETTERS.keys } + private val INLINABLE_NUMBERS: Set> by lazy { SIGNATURE_LETTERS.keys } /** * ASM type for [Expression]. */ - internal val EXPRESSION_TYPE: Type by lazy { Expression::class.asm } + internal val EXPRESSION_TYPE: Type by lazy { Type.getObjectType("kscience/kmath/expressions/Expression") } /** * ASM type for [java.lang.Number]. */ - internal val NUMBER_TYPE: Type by lazy { java.lang.Number::class.asm } + internal val NUMBER_TYPE: Type by lazy { Type.getObjectType("java/lang/Number") } /** * ASM type for [java.util.Map]. */ - internal val MAP_TYPE: Type by lazy { java.util.Map::class.asm } + internal val MAP_TYPE: Type by lazy { Type.getObjectType("java/util/Map") } /** * ASM type for [java.lang.Object]. */ - internal val OBJECT_TYPE: Type by lazy { java.lang.Object::class.asm } + internal val OBJECT_TYPE: Type by lazy { Type.getObjectType("java/lang/Object") } /** * ASM type for array of [java.lang.Object]. */ @Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN", "RemoveRedundantQualifierName") - internal val OBJECT_ARRAY_TYPE: Type by lazy { Array::class.asm } + internal val OBJECT_ARRAY_TYPE: Type by lazy { Type.getType("[Ljava/lang/Object;") } /** * ASM type for [Algebra]. */ - internal val ALGEBRA_TYPE: Type by lazy { Algebra::class.asm } + internal val ALGEBRA_TYPE: Type by lazy { Type.getObjectType("kscience/kmath/operations/Algebra") } /** * ASM type for [java.lang.String]. */ - internal val STRING_TYPE: Type by lazy { java.lang.String::class.asm } + internal val STRING_TYPE: Type by lazy { Type.getObjectType("java/lang/String") } /** * ASM type for MapIntrinsics. diff --git a/kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/internal/codegenUtils.kt b/kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/internal/codegenUtils.kt index 67fce40ac..ef9751502 100644 --- a/kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/internal/codegenUtils.kt +++ b/kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/internal/codegenUtils.kt @@ -10,9 +10,9 @@ import org.objectweb.asm.* import org.objectweb.asm.Opcodes.INVOKEVIRTUAL import org.objectweb.asm.commons.InstructionAdapter import java.lang.reflect.Method +import java.util.* import kotlin.contracts.InvocationKind import kotlin.contracts.contract -import kotlin.reflect.KClass private val methodNameAdapters: Map, String> by lazy { hashMapOf( @@ -26,12 +26,12 @@ private val methodNameAdapters: Map, String> by lazy { } /** - * Returns ASM [Type] for given [KClass]. + * Returns ASM [Type] for given [Class]. * * @author Iaroslav Postovalov */ -internal val KClass<*>.asm: Type - get() = Type.getType(java) +internal inline val Class<*>.asm: Type + get() = Type.getType(this) /** * Returns singleton array with this value if the [predicate] is true, returns empty array otherwise. @@ -140,7 +140,7 @@ private fun AsmBuilder.buildExpectationStack( if (specific != null) mapTypes(specific, parameterTypes).reversed().forEach { expectationStack.push(it) } else - repeat(arity) { expectationStack.push(tType) } + expectationStack.addAll(Collections.nCopies(arity, tType)) return specific != null } @@ -169,7 +169,7 @@ private fun AsmBuilder.tryInvokeSpecific( val arity = parameterTypes.size val theName = methodNameAdapters[name to arity] ?: name val spec = findSpecific(context, theName, parameterTypes) ?: return false - val owner = context::class.asm + val owner = context.javaClass.asm invokeAlgebraOperation( owner = owner.internalName, diff --git a/kmath-ast/src/jvmMain/kotlin/kscience/kmath/ast/parser.kt b/kmath-ast/src/jvmMain/kotlin/kscience/kmath/ast/parser.kt index 15e6625db..94cd3b321 100644 --- a/kmath-ast/src/jvmMain/kotlin/kscience/kmath/ast/parser.kt +++ b/kmath-ast/src/jvmMain/kotlin/kscience/kmath/ast/parser.kt @@ -7,6 +7,7 @@ import com.github.h0tk3y.betterParse.grammar.parser import com.github.h0tk3y.betterParse.grammar.tryParseToEnd import com.github.h0tk3y.betterParse.lexer.Token import com.github.h0tk3y.betterParse.lexer.TokenMatch +import com.github.h0tk3y.betterParse.lexer.literalToken import com.github.h0tk3y.betterParse.lexer.regexToken import com.github.h0tk3y.betterParse.parser.ParseResult import com.github.h0tk3y.betterParse.parser.Parser @@ -23,14 +24,14 @@ public object ArithmeticsEvaluator : Grammar() { // TODO replace with "...".toRegex() when better-parse 0.4.1 is released private val num: Token by regexToken("[\\d.]+(?:[eE][-+]?\\d+)?") private val id: Token by regexToken("[a-z_A-Z][\\da-z_A-Z]*") - private val lpar: Token by regexToken("\\(") - private val rpar: Token by regexToken("\\)") - private val comma: Token by regexToken(",") - private val mul: Token by regexToken("\\*") - private val pow: Token by regexToken("\\^") - private val div: Token by regexToken("/") - private val minus: Token by regexToken("-") - private val plus: Token by regexToken("\\+") + private val lpar: Token by literalToken("(") + private val rpar: Token by literalToken(")") + private val comma: Token by literalToken(",") + private val mul: Token by literalToken("*") + private val pow: Token by literalToken("^") + private val div: Token by literalToken("/") + private val minus: Token by literalToken("-") + private val plus: Token by literalToken("+") private val ws: Token by regexToken("\\s+", ignore = true) private val number: Parser by num use { MST.Numeric(text.toDouble()) } From a465ab64f035def4de58ff028a912e3367a238de Mon Sep 17 00:00:00 2001 From: Iaroslav Postovalov Date: Thu, 1 Oct 2020 01:21:34 +0700 Subject: [PATCH 5/7] Remove accidentally left main method --- kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/asm.kt | 9 --------- 1 file changed, 9 deletions(-) diff --git a/kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/asm.kt b/kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/asm.kt index 00b9caf15..2b6fa6247 100644 --- a/kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/asm.kt +++ b/kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/asm.kt @@ -6,11 +6,8 @@ import kscience.kmath.asm.internal.buildAlgebraOperationCall import kscience.kmath.asm.internal.buildName import kscience.kmath.ast.MST import kscience.kmath.ast.MstExpression -import kscience.kmath.ast.mstInSpace import kscience.kmath.expressions.Expression -import kscience.kmath.expressions.invoke import kscience.kmath.operations.Algebra -import kscience.kmath.operations.RealField /** * Compiles given MST to an Expression using AST compiler. @@ -73,9 +70,3 @@ public inline fun Algebra.expression(mst: MST): Expression< * @author Alexander Nozik. */ public inline fun MstExpression.compile(): Expression = mst.compileWith(T::class.java, algebra) - -public fun main() { - val x = RealField.mstInSpace { symbol("x") + number(2.0) }.compile() - println(x("x" to 1.0)) -} - From 6e6e71543ee6578d74a9549d839501c6d10fbe9e Mon Sep 17 00:00:00 2001 From: Iaroslav Postovalov Date: Thu, 1 Oct 2020 20:32:07 +0700 Subject: [PATCH 6/7] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f3fe37b6b..5d13a360f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ - Minor exceptions refactor (throwing `IllegalArgumentException` by argument checks instead of `IllegalStateException`) - `Polynomial` secondary constructor made function. - Kotlin version: 1.3.72 -> 1.4.20-M1 +- `kmath-ast` doesn't depend on heavy `kotlin-reflect` library. ### Deprecated From 6ee0039985d8a8a491fd330c24cd601bda50488b Mon Sep 17 00:00:00 2001 From: Iaroslav Postovalov Date: Thu, 1 Oct 2020 21:49:57 +0700 Subject: [PATCH 7/7] Fix build problems --- .../commonMain/kotlin/kscience/kmath/operations/Complex.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/Complex.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/Complex.kt index 3c3b17d50..37055a5c8 100644 --- a/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/Complex.kt +++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/Complex.kt @@ -1,12 +1,12 @@ package kscience.kmath.operations +import kscience.kmath.memory.MemoryReader +import kscience.kmath.memory.MemorySpec +import kscience.kmath.memory.MemoryWriter import kscience.kmath.structures.Buffer import kscience.kmath.structures.MemoryBuffer import kscience.kmath.structures.MutableBuffer import kscience.kmath.structures.MutableMemoryBuffer -import kscience.memory.MemoryReader -import kscience.memory.MemorySpec -import kscience.memory.MemoryWriter import kotlin.math.* /**