From 5e4522bb06c571880d257824143313b42405216c Mon Sep 17 00:00:00 2001 From: Iaroslav Date: Tue, 8 Sep 2020 16:40:47 +0700 Subject: [PATCH] Upgrade build tools plugin to dev version; file reformat; change dependencies' versions; specify visibility explicitly at certain places (core, especially), make some interfaces `fun` --- build.gradle.kts | 17 +- examples/build.gradle.kts | 34 +-- .../structures/StructureReadBenchmark.kt | 2 +- .../structures/StructureWriteBenchmark.kt | 4 +- gradle/wrapper/gradle-wrapper.jar | Bin 58910 -> 59203 bytes gradle/wrapper/gradle-wrapper.properties | 2 +- gradlew | 2 +- gradlew.bat | 21 +- kmath-ast/build.gradle.kts | 6 +- .../kotlin/scientifik/kmath/ast/MST.kt | 18 +- .../kotlin/scientifik/kmath/ast/MstAlgebra.kt | 4 +- .../scientifik/kmath/ast/MstExpression.kt | 23 +- .../kotlin/scientifik/kmath/ast/parser.kt | 18 +- .../kotlin/scientifik/kmath/asm/asm.kt | 6 +- kmath-commons/build.gradle.kts | 4 +- .../commons/expressions/DiffExpression.kt | 39 ++- kmath-core/build.gradle.kts | 9 +- .../kotlin/scientifik/kmath/domains/Domain.kt | 6 +- .../kmath/domains/HyperSquareDomain.kt | 2 +- .../scientifik/kmath/domains/RealDomain.kt | 14 +- .../kmath/domains/UnconstrainedDomain.kt | 2 +- .../kmath/domains/UnivariateDomain.kt | 4 +- .../kmath/expressions/Expression.kt | 22 +- .../FunctionalExpressionAlgebra.kt | 35 +-- .../{Builders.kt => expressionBuilders.kt} | 8 +- .../scientifik/kmath/linear/BufferMatrix.kt | 12 +- .../scientifik/kmath/linear/FeaturedMatrix.kt | 36 ++- .../kmath/linear/LUPDecomposition.kt | 59 ++-- .../scientifik/kmath/linear/LinearAlgebra.kt | 14 +- .../scientifik/kmath/linear/MatrixBuilder.kt | 14 +- .../scientifik/kmath/linear/MatrixContext.kt | 29 +- .../scientifik/kmath/linear/MatrixFeatures.kt | 30 +- .../scientifik/kmath/linear/VectorSpace.kt | 20 +- .../scientifik/kmath/linear/VirtualMatrix.kt | 25 +- .../kotlin/scientifik/kmath/misc/AutoDiff.kt | 48 +-- .../kotlin/scientifik/kmath/misc/Grids.kt | 10 +- .../scientifik/kmath/misc/cumulative.kt | 36 ++- .../scientifik/kmath/operations/Algebra.kt | 89 +++--- .../kmath/operations/AlgebraElements.kt | 28 +- .../kmath/operations/AlgebraExtensions.kt | 20 +- .../scientifik/kmath/operations/BigInt.kt | 276 ++++++++---------- .../scientifik/kmath/operations/Complex.kt | 35 ++- .../kmath/operations/NumberAlgebra.kt | 4 +- .../kmath/operations/OptionalOperations.kt | 122 ++++---- .../kmath/structures/BoxingNDField.kt | 8 +- .../kmath/structures/BoxingNDRing.kt | 6 +- .../kmath/structures/BufferAccessor2D.kt | 17 +- .../kmath/structures/BufferedNDAlgebra.kt | 22 +- .../kmath/structures/BufferedNDElement.kt | 18 +- .../scientifik/kmath/structures/Buffers.kt | 50 ++-- .../kmath/structures/ComplexNDField.kt | 24 +- .../kmath/structures/ExtendedNDField.kt | 2 +- .../kmath/structures/FlaggedBuffer.kt | 2 +- .../scientifik/kmath/structures/IntBuffer.kt | 2 +- .../scientifik/kmath/structures/LongBuffer.kt | 10 +- .../scientifik/kmath/structures/NDAlgebra.kt | 58 ++-- .../kmath/structures/RealNDField.kt | 12 +- .../kmath/structures/ShortBuffer.kt | 10 +- .../kmath/structures/ShortNDRing.kt | 18 +- .../kmath/structures/Structure2D.kt | 26 +- .../scientifik/kmath/operations/BigNumbers.kt | 8 +- kmath-coroutines/build.gradle.kts | 16 +- .../kotlin/scientifik/kmath/chains/Chain.kt | 38 ++- kmath-dimensions/build.gradle.kts | 12 +- .../scientifik/kmath/dimensions/Dimensions.kt | 22 +- .../kotlin/scientifik/kmath/dimensions/dim.kt | 4 +- .../kotlin/scientifik/kmath/dimensions/dim.kt | 4 +- kmath-for-real/build.gradle.kts | 9 +- .../scientifik/kmath/real/realMatrix.kt | 64 ++-- kmath-functions/build.gradle.kts | 9 +- .../scientifik/kmath/functions/Piecewise.kt | 16 +- .../scientifik/kmath/functions/Polynomial.kt | 27 +- .../scientifik/kmath/functions/functions.kt | 18 +- .../kmath/interpolation/Interpolator.kt | 12 +- .../kmath/interpolation/LinearInterpolator.kt | 2 +- .../kmath/interpolation/SplineInterpolator.kt | 4 +- .../kmath/interpolation/XYPointSet.kt | 21 +- .../interpolation/LinearInterpolatorTest.kt | 3 +- kmath-geometry/build.gradle.kts | 6 +- kmath-histograms/build.gradle.kts | 6 +- kmath-koma/build.gradle.kts | 11 +- kmath-memory/build.gradle.kts | 3 +- .../kotlin/scientifik/memory/Memory.kt | 58 ++-- .../kotlin/scientifik/memory/MemorySpec.kt | 16 +- .../scientifik/memory/DataViewMemory.kt | 4 +- .../scientifik/memory/ByteBufferMemory.kt | 8 +- kmath-prob/build.gradle.kts | 11 +- .../scientifik/kmath/prob/distributions.kt | 12 +- kmath-viktor/build.gradle.kts | 6 +- settings.gradle.kts | 23 +- 90 files changed, 905 insertions(+), 1042 deletions(-) rename kmath-core/src/commonMain/kotlin/scientifik/kmath/expressions/{Builders.kt => expressionBuilders.kt} (65%) diff --git a/build.gradle.kts b/build.gradle.kts index 8a2ba3617..3a9991443 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,11 +1,8 @@ -plugins { - id("scientifik.publish") apply false -} +plugins { id("ru.mipt.npm.publish") apply false } -val kmathVersion by extra("0.1.4-dev-8") - -val bintrayRepo by extra("scientifik") -val githubProject by extra("kmath") +val kmathVersion: String by extra("0.1.4-dev-8") +val bintrayRepo: String by extra("scientifik") +val githubProject: String by extra("kmath") allprojects { repositories { @@ -18,8 +15,4 @@ allprojects { version = kmathVersion } -subprojects { - if (name.startsWith("kmath")) { - apply(plugin = "scientifik.publish") - } -} \ No newline at end of file +subprojects { if (name.startsWith("kmath")) apply(plugin = "ru.mipt.npm.publish") } diff --git a/examples/build.gradle.kts b/examples/build.gradle.kts index f5a4d5831..9fd90d08b 100644 --- a/examples/build.gradle.kts +++ b/examples/build.gradle.kts @@ -1,16 +1,13 @@ -import org.jetbrains.kotlin.allopen.gradle.AllOpenExtension import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { java kotlin("jvm") - kotlin("plugin.allopen") version "1.3.72" - id("kotlinx.benchmark") version "0.2.0-dev-8" + kotlin("plugin.allopen") version "1.4.0" + id("kotlinx.benchmark") version "0.2.0-dev-20" } -configure { - annotation("org.openjdk.jmh.annotations.State") -} +allOpen.annotation("org.openjdk.jmh.annotations.State") repositories { maven("http://dl.bintray.com/kyonifer/maven") @@ -19,9 +16,7 @@ repositories { mavenCentral() } -sourceSets { - register("benchmarks") -} +sourceSets.register("benchmarks") dependencies { implementation(project(":kmath-ast")) @@ -34,25 +29,22 @@ dependencies { implementation(project(":kmath-dimensions")) implementation("com.kyonifer:koma-core-ejml:0.12") implementation("org.jetbrains.kotlinx:kotlinx-io-jvm:0.2.0-npm-dev-6") - implementation("org.jetbrains.kotlinx:kotlinx.benchmark.runtime:0.2.0-dev-8") + 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 } // Configure benchmark benchmark { // Setup configurations - targets { + targets // This one matches sourceSet name above - register("benchmarks") - } + .register("benchmarks") - configurations { - register("fast") { - warmups = 5 // number of warmup iterations - iterations = 3 // number of iterations - iterationTime = 500 // time in seconds per iteration - iterationTimeUnit = "ms" // time unity for iterationTime, default is seconds - } + configurations.register("fast") { + warmups = 5 // number of warmup iterations + iterations = 3 // number of iterations + iterationTime = 500 // time in seconds per iteration + iterationTimeUnit = "ms" // time unity for iterationTime, default is seconds } } @@ -65,7 +57,7 @@ kotlin.sourceSets.all { tasks.withType { kotlinOptions { - jvmTarget = Scientifik.JVM_TARGET.toString() + jvmTarget = "11" freeCompilerArgs = freeCompilerArgs + "-Xopt-in=kotlin.RequiresOptIn" } } diff --git a/examples/src/main/kotlin/scientifik/kmath/structures/StructureReadBenchmark.kt b/examples/src/main/kotlin/scientifik/kmath/structures/StructureReadBenchmark.kt index a33fdb2c4..d5998cd0a 100644 --- a/examples/src/main/kotlin/scientifik/kmath/structures/StructureReadBenchmark.kt +++ b/examples/src/main/kotlin/scientifik/kmath/structures/StructureReadBenchmark.kt @@ -2,7 +2,7 @@ package scientifik.kmath.structures import kotlin.system.measureTimeMillis -fun main(args: Array) { +fun main() { val n = 6000 val array = DoubleArray(n * n) { 1.0 } diff --git a/examples/src/main/kotlin/scientifik/kmath/structures/StructureWriteBenchmark.kt b/examples/src/main/kotlin/scientifik/kmath/structures/StructureWriteBenchmark.kt index 0241f12ad..ffcecbce2 100644 --- a/examples/src/main/kotlin/scientifik/kmath/structures/StructureWriteBenchmark.kt +++ b/examples/src/main/kotlin/scientifik/kmath/structures/StructureWriteBenchmark.kt @@ -2,9 +2,7 @@ package scientifik.kmath.structures import kotlin.system.measureTimeMillis - -fun main(args: Array) { - +fun main() { val n = 6000 val structure = NDStructure.build(intArrayOf(n, n), Buffer.Companion::auto) { 1.0 } diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 62d4c053550b91381bbd28b1afc82d634bf73a8a..e708b1c023ec8b20f512888fe07c5bd3ff77bb8f 100644 GIT binary patch delta 6656 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 Yte!%o?r4GTrVtxD61Ym!|5fq-1K$0e!T1w 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 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index bb8b2fc26..12d38de6a 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.5.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-6.6.1-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index fbd7c5158..4f906e0c8 100755 --- a/gradlew +++ b/gradlew @@ -130,7 +130,7 @@ fi if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then APP_HOME=`cygpath --path --mixed "$APP_HOME"` CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - + JAVACMD=`cygpath --unix "$JAVACMD"` # We build the pattern for arguments to be converted via cygpath diff --git a/gradlew.bat b/gradlew.bat index 5093609d5..107acd32c 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -40,7 +40,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init +if "%ERRORLEVEL%" == "0" goto execute echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. @@ -54,7 +54,7 @@ goto fail set JAVA_HOME=%JAVA_HOME:"=% set JAVA_EXE=%JAVA_HOME%/bin/java.exe -if exist "%JAVA_EXE%" goto init +if exist "%JAVA_EXE%" goto execute echo. echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% @@ -64,21 +64,6 @@ echo location of your Java installation. goto fail -:init -@rem Get command-line arguments, handling Windows variants - -if not "%OS%" == "Windows_NT" goto win9xME_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* - :execute @rem Setup the command line @@ -86,7 +71,7 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* :end @rem End local scope for the variables with windows NT shell diff --git a/kmath-ast/build.gradle.kts b/kmath-ast/build.gradle.kts index 86b10bdc7..c376154b5 100644 --- a/kmath-ast/build.gradle.kts +++ b/kmath-ast/build.gradle.kts @@ -1,8 +1,6 @@ -plugins { id("scientifik.mpp") } +plugins { id("ru.mipt.npm.mpp") } kotlin.sourceSets { - all { languageSettings.useExperimentalAnnotation("kotlin.contracts.ExperimentalContracts") } - commonMain { dependencies { api(project(":kmath-core")) @@ -17,4 +15,4 @@ kotlin.sourceSets { implementation(kotlin("reflect")) } } -} \ No newline at end of file +} diff --git a/kmath-ast/src/commonMain/kotlin/scientifik/kmath/ast/MST.kt b/kmath-ast/src/commonMain/kotlin/scientifik/kmath/ast/MST.kt index 0e8151c04..798172799 100644 --- a/kmath-ast/src/commonMain/kotlin/scientifik/kmath/ast/MST.kt +++ b/kmath-ast/src/commonMain/kotlin/scientifik/kmath/ast/MST.kt @@ -7,20 +7,20 @@ import scientifik.kmath.operations.RealField /** * A Mathematical Syntax Tree node for mathematical expressions. */ -sealed class MST { +public sealed class MST { /** * A node containing raw string. * * @property value the value of this node. */ - data class Symbolic(val value: String) : MST() + public data class Symbolic(val value: String) : MST() /** * A node containing a numeric value or scalar. * * @property value the value of this number. */ - data class Numeric(val value: Number) : MST() + public data class Numeric(val value: Number) : MST() /** * A node containing an unary operation. @@ -28,9 +28,7 @@ sealed class MST { * @property operation the identifier of operation. * @property value the argument of this operation. */ - data class Unary(val operation: String, val value: MST) : MST() { - companion object - } + public data class Unary(val operation: String, val value: MST) : MST() /** * A node containing binary operation. @@ -39,9 +37,7 @@ sealed class MST { * @property left the left operand. * @property right the right operand. */ - data class Binary(val operation: String, val left: MST, val right: MST) : MST() { - companion object - } + public data class Binary(val operation: String, val left: MST, val right: MST) : MST() } // TODO add a function with named arguments @@ -53,7 +49,7 @@ sealed class MST { * @param node the node to evaluate. * @return the value of expression. */ -fun Algebra.evaluate(node: MST): T = when (node) { +public fun Algebra.evaluate(node: MST): T = when (node) { is MST.Numeric -> (this as? NumericAlgebra)?.number(node.value) ?: error("Numeric nodes are not supported by $this") is MST.Symbolic -> symbol(node.value) @@ -84,4 +80,4 @@ fun Algebra.evaluate(node: MST): T = when (node) { * @param algebra the algebra that provides operations. * @return the value of expression. */ -fun MST.interpret(algebra: Algebra): T = algebra.evaluate(this) +public fun MST.interpret(algebra: Algebra): T = algebra.evaluate(this) diff --git a/kmath-ast/src/commonMain/kotlin/scientifik/kmath/ast/MstAlgebra.kt b/kmath-ast/src/commonMain/kotlin/scientifik/kmath/ast/MstAlgebra.kt index 23deae24b..e4480e608 100644 --- a/kmath-ast/src/commonMain/kotlin/scientifik/kmath/ast/MstAlgebra.kt +++ b/kmath-ast/src/commonMain/kotlin/scientifik/kmath/ast/MstAlgebra.kt @@ -5,7 +5,7 @@ import scientifik.kmath.operations.* /** * [Algebra] over [MST] nodes. */ -object MstAlgebra : NumericAlgebra { +public object MstAlgebra : NumericAlgebra { override fun number(value: Number): MST = MST.Numeric(value) override fun symbol(value: String): MST = MST.Symbolic(value) @@ -20,7 +20,7 @@ object MstAlgebra : NumericAlgebra { /** * [Space] over [MST] nodes. */ -object MstSpace : Space, NumericAlgebra { +public object MstSpace : Space, NumericAlgebra { override val zero: MST = number(0.0) override fun number(value: Number): MST = MstAlgebra.number(value) diff --git a/kmath-ast/src/commonMain/kotlin/scientifik/kmath/ast/MstExpression.kt b/kmath-ast/src/commonMain/kotlin/scientifik/kmath/ast/MstExpression.kt index 3cee33956..9d8a6a804 100644 --- a/kmath-ast/src/commonMain/kotlin/scientifik/kmath/ast/MstExpression.kt +++ b/kmath-ast/src/commonMain/kotlin/scientifik/kmath/ast/MstExpression.kt @@ -2,7 +2,6 @@ package scientifik.kmath.ast import scientifik.kmath.expressions.* import scientifik.kmath.operations.* -import kotlin.contracts.ExperimentalContracts import kotlin.contracts.InvocationKind import kotlin.contracts.contract @@ -13,7 +12,7 @@ import kotlin.contracts.contract * @property algebra the algebra that provides operations. * @property mst the [MST] node. */ -class MstExpression(val algebra: Algebra, val mst: MST) : Expression { +public class MstExpression(public val algebra: Algebra, public val mst: MST) : Expression { private inner class InnerAlgebra(val arguments: Map) : NumericAlgebra { override fun symbol(value: String): T = arguments[value] ?: algebra.symbol(value) override fun unaryOperation(operation: String, arg: T): T = algebra.unaryOperation(operation, arg) @@ -33,7 +32,7 @@ class MstExpression(val algebra: Algebra, val mst: MST) : Expression { /** * Builds [MstExpression] over [Algebra]. */ -inline fun , E : Algebra> A.mst( +public inline fun , E : Algebra> A.mst( mstAlgebra: E, block: E.() -> MST ): MstExpression = MstExpression(this, mstAlgebra.block()) @@ -41,7 +40,7 @@ inline fun , E : Algebra> A.mst( /** * Builds [MstExpression] over [Space]. */ -inline fun Space.mstInSpace(block: MstSpace.() -> MST): MstExpression { +public inline fun Space.mstInSpace(block: MstSpace.() -> MST): MstExpression { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } return MstExpression(this, MstSpace.block()) } @@ -49,7 +48,7 @@ inline fun Space.mstInSpace(block: MstSpace.() -> MST): Mst /** * Builds [MstExpression] over [Ring]. */ -inline fun Ring.mstInRing(block: MstRing.() -> MST): MstExpression { +public inline fun Ring.mstInRing(block: MstRing.() -> MST): MstExpression { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } return MstExpression(this, MstRing.block()) } @@ -57,7 +56,7 @@ inline fun Ring.mstInRing(block: MstRing.() -> MST): MstExp /** * Builds [MstExpression] over [Field]. */ -inline fun Field.mstInField(block: MstField.() -> MST): MstExpression { +public inline fun Field.mstInField(block: MstField.() -> MST): MstExpression { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } return MstExpression(this, MstField.block()) } @@ -65,7 +64,7 @@ inline fun Field.mstInField(block: MstField.() -> MST): Mst /** * Builds [MstExpression] over [ExtendedField]. */ -inline fun Field.mstInExtendedField(block: MstExtendedField.() -> MST): MstExpression { +public inline fun Field.mstInExtendedField(block: MstExtendedField.() -> MST): MstExpression { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } return MstExpression(this, MstExtendedField.block()) } @@ -73,7 +72,7 @@ inline fun Field.mstInExtendedField(block: MstExtendedField /** * Builds [MstExpression] over [FunctionalExpressionSpace]. */ -inline fun > FunctionalExpressionSpace.mstInSpace(block: MstSpace.() -> MST): MstExpression { +public inline fun > FunctionalExpressionSpace.mstInSpace(block: MstSpace.() -> MST): MstExpression { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } return algebra.mstInSpace(block) } @@ -81,7 +80,7 @@ inline fun > FunctionalExpressionSpace.mstIn /** * Builds [MstExpression] over [FunctionalExpressionRing]. */ -inline fun > FunctionalExpressionRing.mstInRing(block: MstRing.() -> MST): MstExpression { +public inline fun > FunctionalExpressionRing.mstInRing(block: MstRing.() -> MST): MstExpression { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } return algebra.mstInRing(block) } @@ -89,7 +88,7 @@ inline fun > FunctionalExpressionRing.mstInRi /** * Builds [MstExpression] over [FunctionalExpressionField]. */ -inline fun > FunctionalExpressionField.mstInField(block: MstField.() -> MST): MstExpression { +public inline fun > FunctionalExpressionField.mstInField(block: MstField.() -> MST): MstExpression { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } return algebra.mstInField(block) } @@ -97,7 +96,9 @@ inline fun > FunctionalExpressionField.mstIn /** * Builds [MstExpression] over [FunctionalExpressionExtendedField]. */ -inline fun > FunctionalExpressionExtendedField.mstInExtendedField(block: MstExtendedField.() -> MST): MstExpression { +public inline fun > FunctionalExpressionExtendedField.mstInExtendedField( + block: MstExtendedField.() -> MST +): MstExpression { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } return algebra.mstInExtendedField(block) } diff --git a/kmath-ast/src/commonMain/kotlin/scientifik/kmath/ast/parser.kt b/kmath-ast/src/commonMain/kotlin/scientifik/kmath/ast/parser.kt index cba335a8d..5733649e4 100644 --- a/kmath-ast/src/commonMain/kotlin/scientifik/kmath/ast/parser.kt +++ b/kmath-ast/src/commonMain/kotlin/scientifik/kmath/ast/parser.kt @@ -18,7 +18,7 @@ import scientifik.kmath.operations.SpaceOperations /** * TODO move to core */ -object ArithmeticsEvaluator : Grammar() { +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]*") @@ -35,23 +35,23 @@ object ArithmeticsEvaluator : Grammar() { private val number: Parser by num use { MST.Numeric(text.toDouble()) } private val singular: Parser by id use { MST.Symbolic(text) } - private val unaryFunction: Parser by (id and skip(lpar) and parser(::subSumChain) and skip(rpar)) + private val unaryFunction: Parser by (id and -lpar and parser(::subSumChain) and -rpar) .map { (id, term) -> MST.Unary(id.text, term) } private val binaryFunction: Parser by id - .and(skip(lpar)) + .and(-lpar) .and(parser(::subSumChain)) - .and(skip(comma)) + .and(-comma) .and(parser(::subSumChain)) - .and(skip(rpar)) + .and(-rpar) .map { (id, left, right) -> MST.Binary(id.text, left, right) } private val term: Parser by number .or(binaryFunction) .or(unaryFunction) .or(singular) - .or(skip(minus) and parser(::term) map { MST.Unary(SpaceOperations.MINUS_OPERATION, it) }) - .or(skip(lpar) and parser(::subSumChain) and skip(rpar)) + .or(-minus and parser(::term) map { MST.Unary(SpaceOperations.MINUS_OPERATION, it) }) + .or(-lpar and parser(::subSumChain) and -rpar) private val powChain: Parser by leftAssociative(term = term, operator = pow) { a, _, b -> MST.Binary(PowerOperations.POW_OPERATION, a, b) @@ -86,7 +86,7 @@ object ArithmeticsEvaluator : Grammar() { * @receiver the string to parse. * @return the [MST] node. */ -fun String.tryParseMath(): ParseResult = ArithmeticsEvaluator.tryParseToEnd(this) +public fun String.tryParseMath(): ParseResult = ArithmeticsEvaluator.tryParseToEnd(this) /** * Parses the string into [MST]. @@ -94,4 +94,4 @@ fun String.tryParseMath(): ParseResult = ArithmeticsEvaluator.tryParseToEnd * @receiver the string to parse. * @return the [MST] node. */ -fun String.parseMath(): MST = ArithmeticsEvaluator.parseToEnd(this) +public fun String.parseMath(): MST = ArithmeticsEvaluator.parseToEnd(this) diff --git a/kmath-ast/src/jvmMain/kotlin/scientifik/kmath/asm/asm.kt b/kmath-ast/src/jvmMain/kotlin/scientifik/kmath/asm/asm.kt index ee0ea15ff..5d563aceb 100644 --- a/kmath-ast/src/jvmMain/kotlin/scientifik/kmath/asm/asm.kt +++ b/kmath-ast/src/jvmMain/kotlin/scientifik/kmath/asm/asm.kt @@ -13,7 +13,7 @@ import kotlin.reflect.KClass /** * Compile given MST to an Expression using AST compiler */ -fun MST.compileWith(type: KClass, algebra: Algebra): Expression { +public fun MST.compileWith(type: KClass, algebra: Algebra): Expression { fun AsmBuilder.visit(node: MST) { when (node) { is MST.Symbolic -> { @@ -56,9 +56,9 @@ fun MST.compileWith(type: KClass, algebra: Algebra): Expression< /** * Compile an [MST] to ASM using given algebra */ -inline fun Algebra.expression(mst: MST): Expression = mst.compileWith(T::class, this) +public inline fun Algebra.expression(mst: MST): Expression = mst.compileWith(T::class, this) /** * Optimize performance of an [MstExpression] using ASM codegen */ -inline fun MstExpression.compile(): Expression = mst.compileWith(T::class, algebra) +public inline fun MstExpression.compile(): Expression = mst.compileWith(T::class, algebra) diff --git a/kmath-commons/build.gradle.kts b/kmath-commons/build.gradle.kts index 63c832b7c..45eee7765 100644 --- a/kmath-commons/build.gradle.kts +++ b/kmath-commons/build.gradle.kts @@ -1,4 +1,4 @@ -plugins { id("scientifik.jvm") } +plugins { id("ru.mipt.npm.jvm") } description = "Commons math binding for kmath" dependencies { @@ -8,5 +8,3 @@ dependencies { api(project(":kmath-functions")) api("org.apache.commons:commons-math3:3.6.1") } - -kotlin.sourceSets.all { languageSettings.useExperimentalAnnotation("kotlin.contracts.ExperimentalContracts") } diff --git a/kmath-commons/src/main/kotlin/scientifik/kmath/commons/expressions/DiffExpression.kt b/kmath-commons/src/main/kotlin/scientifik/kmath/commons/expressions/DiffExpression.kt index 9119991e5..a6f905471 100644 --- a/kmath-commons/src/main/kotlin/scientifik/kmath/commons/expressions/DiffExpression.kt +++ b/kmath-commons/src/main/kotlin/scientifik/kmath/commons/expressions/DiffExpression.kt @@ -7,14 +7,13 @@ import scientifik.kmath.operations.ExtendedField import scientifik.kmath.operations.Field import scientifik.kmath.operations.invoke import kotlin.properties.ReadOnlyProperty -import kotlin.reflect.KProperty /** * A field wrapping commons-math derivative structures */ -class DerivativeStructureField( - val order: Int, - val parameters: Map +public class DerivativeStructureField( + public val order: Int, + public val parameters: Map ) : ExtendedField { override val zero: DerivativeStructure by lazy { DerivativeStructure(order, parameters.size) } override val one: DerivativeStructure by lazy { DerivativeStructure(order, parameters.size, 1.0) } @@ -23,25 +22,24 @@ class DerivativeStructureField( DerivativeStructure(parameters.size, order, parameters.keys.indexOf(key), value) } - val variable: ReadOnlyProperty = object : ReadOnlyProperty { - override fun getValue(thisRef: Any?, property: KProperty<*>): DerivativeStructure = - variables[property.name] ?: error("A variable with name ${property.name} does not exist") + public val variable: ReadOnlyProperty = ReadOnlyProperty { _, property -> + variables[property.name] ?: error("A variable with name ${property.name} does not exist") } - fun variable(name: String, default: DerivativeStructure? = null): DerivativeStructure = + public fun variable(name: String, default: DerivativeStructure? = null): DerivativeStructure = variables[name] ?: default ?: error("A variable with name $name does not exist") - fun Number.const(): DerivativeStructure = DerivativeStructure(order, parameters.size, toDouble()) + public fun Number.const(): DerivativeStructure = DerivativeStructure(order, parameters.size, toDouble()) - fun DerivativeStructure.deriv(parName: String, order: Int = 1): Double { + public fun DerivativeStructure.deriv(parName: String, order: Int = 1): Double { return deriv(mapOf(parName to order)) } - fun DerivativeStructure.deriv(orders: Map): Double { + public fun DerivativeStructure.deriv(orders: Map): Double { return getPartialDerivative(*parameters.keys.map { orders[it] ?: 0 }.toIntArray()) } - fun DerivativeStructure.deriv(vararg orders: Pair): Double = deriv(mapOf(*orders)) + public fun DerivativeStructure.deriv(vararg orders: Pair): Double = deriv(mapOf(*orders)) override fun add(a: DerivativeStructure, b: DerivativeStructure): DerivativeStructure = a.add(b) @@ -61,7 +59,6 @@ class DerivativeStructureField( override fun asin(arg: DerivativeStructure): DerivativeStructure = arg.asin() override fun acos(arg: DerivativeStructure): DerivativeStructure = arg.acos() override fun atan(arg: DerivativeStructure): DerivativeStructure = arg.atan() - override fun sinh(arg: DerivativeStructure): DerivativeStructure = arg.sinh() override fun cosh(arg: DerivativeStructure): DerivativeStructure = arg.cosh() override fun tanh(arg: DerivativeStructure): DerivativeStructure = arg.tanh() @@ -75,7 +72,7 @@ class DerivativeStructureField( else -> arg.pow(pow.toDouble()) } - fun power(arg: DerivativeStructure, pow: DerivativeStructure): DerivativeStructure = arg.pow(pow) + public fun power(arg: DerivativeStructure, pow: DerivativeStructure): DerivativeStructure = arg.pow(pow) override fun exp(arg: DerivativeStructure): DerivativeStructure = arg.exp() override fun ln(arg: DerivativeStructure): DerivativeStructure = arg.log() @@ -88,7 +85,8 @@ class DerivativeStructureField( /** * A constructs that creates a derivative structure with required order on-demand */ -class DiffExpression(val function: DerivativeStructureField.() -> DerivativeStructure) : Expression { +public class DiffExpression(public val function: DerivativeStructureField.() -> DerivativeStructure) : + Expression { override operator fun invoke(arguments: Map): Double = DerivativeStructureField( 0, arguments @@ -98,21 +96,20 @@ class DiffExpression(val function: DerivativeStructureField.() -> DerivativeStru * Get the derivative expression with given orders * TODO make result [DiffExpression] */ - fun derivative(orders: Map): Expression = object : Expression { - override operator fun invoke(arguments: Map): Double = - (DerivativeStructureField(orders.values.max() ?: 0, arguments)) { function().deriv(orders) } + public fun derivative(orders: Map): Expression = Expression { arguments -> + (DerivativeStructureField(orders.values.max() ?: 0, arguments)) { function().deriv(orders) } } //TODO add gradient and maybe other vector operators } -fun DiffExpression.derivative(vararg orders: Pair): Expression = derivative(mapOf(*orders)) -fun DiffExpression.derivative(name: String): Expression = derivative(name to 1) +public fun DiffExpression.derivative(vararg orders: Pair): Expression = derivative(mapOf(*orders)) +public fun DiffExpression.derivative(name: String): Expression = derivative(name to 1) /** * A context for [DiffExpression] (not to be confused with [DerivativeStructure]) */ -object DiffExpressionAlgebra : ExpressionAlgebra, Field { +public object DiffExpressionAlgebra : ExpressionAlgebra, Field { override fun variable(name: String, default: Double?): DiffExpression = DiffExpression { variable(name, default?.const()) } diff --git a/kmath-core/build.gradle.kts b/kmath-core/build.gradle.kts index 7f9922de4..e315e1640 100644 --- a/kmath-core/build.gradle.kts +++ b/kmath-core/build.gradle.kts @@ -1,6 +1,7 @@ -plugins { id("scientifik.mpp") } +plugins { id("ru.mipt.npm.mpp") } -kotlin.sourceSets { - all { languageSettings.useExperimentalAnnotation("kotlin.contracts.ExperimentalContracts") } - commonMain { dependencies { api(project(":kmath-memory")) } } +kotlin.sourceSets.commonMain { + dependencies { + api(project(":kmath-memory")) + } } diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/domains/Domain.kt b/kmath-core/src/commonMain/kotlin/scientifik/kmath/domains/Domain.kt index 341383bfb..c4c823bf2 100644 --- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/domains/Domain.kt +++ b/kmath-core/src/commonMain/kotlin/scientifik/kmath/domains/Domain.kt @@ -7,14 +7,14 @@ import scientifik.kmath.linear.Point * * @param T the type of element of this domain. */ -interface Domain { +public interface Domain { /** * Checks if the specified point is contained in this domain. */ - operator fun contains(point: Point): Boolean + public operator fun contains(point: Point): Boolean /** * Number of hyperspace dimensions. */ - val dimension: Int + public val dimension: Int } diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/domains/HyperSquareDomain.kt b/kmath-core/src/commonMain/kotlin/scientifik/kmath/domains/HyperSquareDomain.kt index 66798c42f..e118282bf 100644 --- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/domains/HyperSquareDomain.kt +++ b/kmath-core/src/commonMain/kotlin/scientifik/kmath/domains/HyperSquareDomain.kt @@ -25,7 +25,7 @@ import scientifik.kmath.structures.indices * * @author Alexander Nozik */ -class HyperSquareDomain(private val lower: RealBuffer, private val upper: RealBuffer) : RealDomain { +public class HyperSquareDomain(private val lower: RealBuffer, private val upper: RealBuffer) : RealDomain { override operator fun contains(point: Point): Boolean = point.indices.all { i -> point[i] in lower[i]..upper[i] diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/domains/RealDomain.kt b/kmath-core/src/commonMain/kotlin/scientifik/kmath/domains/RealDomain.kt index 7507ccd59..b1da63519 100644 --- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/domains/RealDomain.kt +++ b/kmath-core/src/commonMain/kotlin/scientifik/kmath/domains/RealDomain.kt @@ -22,8 +22,8 @@ import scientifik.kmath.linear.Point * * @author Alexander Nozik */ -interface RealDomain : Domain { - fun nearestInDomain(point: Point): Point +public interface RealDomain : Domain { + public fun nearestInDomain(point: Point): Point /** * The lower edge for the domain going down from point @@ -31,7 +31,7 @@ interface RealDomain : Domain { * @param point * @return */ - fun getLowerBound(num: Int, point: Point): Double? + public fun getLowerBound(num: Int, point: Point): Double? /** * The upper edge of the domain going up from point @@ -39,25 +39,25 @@ interface RealDomain : Domain { * @param point * @return */ - fun getUpperBound(num: Int, point: Point): Double? + public fun getUpperBound(num: Int, point: Point): Double? /** * Global lower edge * @param num * @return */ - fun getLowerBound(num: Int): Double? + public fun getLowerBound(num: Int): Double? /** * Global upper edge * @param num * @return */ - fun getUpperBound(num: Int): Double? + public fun getUpperBound(num: Int): Double? /** * Hyper volume * @return */ - fun volume(): Double + public fun volume(): Double } diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/domains/UnconstrainedDomain.kt b/kmath-core/src/commonMain/kotlin/scientifik/kmath/domains/UnconstrainedDomain.kt index 595a3dbe7..5c9170663 100644 --- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/domains/UnconstrainedDomain.kt +++ b/kmath-core/src/commonMain/kotlin/scientifik/kmath/domains/UnconstrainedDomain.kt @@ -17,7 +17,7 @@ package scientifik.kmath.domains import scientifik.kmath.linear.Point -class UnconstrainedDomain(override val dimension: Int) : RealDomain { +public class UnconstrainedDomain(override val dimension: Int) : RealDomain { override operator fun contains(point: Point): Boolean = true override fun getLowerBound(num: Int, point: Point): Double? = Double.NEGATIVE_INFINITY diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/domains/UnivariateDomain.kt b/kmath-core/src/commonMain/kotlin/scientifik/kmath/domains/UnivariateDomain.kt index 280dc7d66..5b47476d8 100644 --- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/domains/UnivariateDomain.kt +++ b/kmath-core/src/commonMain/kotlin/scientifik/kmath/domains/UnivariateDomain.kt @@ -3,8 +3,8 @@ package scientifik.kmath.domains import scientifik.kmath.linear.Point import scientifik.kmath.structures.asBuffer -inline class UnivariateDomain(val range: ClosedFloatingPointRange) : RealDomain { - operator fun contains(d: Double): Boolean = range.contains(d) +public inline class UnivariateDomain(public val range: ClosedFloatingPointRange) : RealDomain { + public operator fun contains(d: Double): Boolean = range.contains(d) override operator fun contains(point: Point): Boolean { require(point.size == 0) diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/expressions/Expression.kt b/kmath-core/src/commonMain/kotlin/scientifik/kmath/expressions/Expression.kt index fd11c246d..a21735f27 100644 --- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/expressions/Expression.kt +++ b/kmath-core/src/commonMain/kotlin/scientifik/kmath/expressions/Expression.kt @@ -5,45 +5,37 @@ import scientifik.kmath.operations.Algebra /** * An elementary function that could be invoked on a map of arguments */ -interface Expression { +public fun interface Expression { /** * Calls this expression from arguments. * * @param arguments the map of arguments. * @return the value. */ - operator fun invoke(arguments: Map): T + public operator fun invoke(arguments: Map): T - companion object + public companion object } -/** - * Create simple lazily evaluated expression inside given algebra - */ -fun Algebra.expression(block: Algebra.(arguments: Map) -> T): Expression = - object : Expression { - override operator fun invoke(arguments: Map): T = block(arguments) - } - /** * Calls this expression from arguments. * * @param pairs the pair of arguments' names to values. * @return the value. */ -operator fun Expression.invoke(vararg pairs: Pair): T = invoke(mapOf(*pairs)) +public operator fun Expression.invoke(vararg pairs: Pair): T = invoke(mapOf(*pairs)) /** * A context for expression construction */ -interface ExpressionAlgebra : Algebra { +public interface ExpressionAlgebra : Algebra { /** * Introduce a variable into expression context */ - fun variable(name: String, default: T? = null): E + public fun variable(name: String, default: T? = null): E /** * A constant expression which does not depend on arguments */ - fun const(value: T): E + public fun const(value: T): E } diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/expressions/FunctionalExpressionAlgebra.kt b/kmath-core/src/commonMain/kotlin/scientifik/kmath/expressions/FunctionalExpressionAlgebra.kt index d36c31a0d..58f874671 100644 --- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/expressions/FunctionalExpressionAlgebra.kt +++ b/kmath-core/src/commonMain/kotlin/scientifik/kmath/expressions/FunctionalExpressionAlgebra.kt @@ -39,7 +39,8 @@ internal class FunctionalConstProductExpression( * * @param algebra The algebra to provide for Expressions built. */ -abstract class FunctionalExpressionAlgebra>(val algebra: A) : ExpressionAlgebra> { +public abstract class FunctionalExpressionAlgebra>(public val algebra: A) : + ExpressionAlgebra> { /** * Builds an Expression of constant expression which does not depend on arguments. */ @@ -66,7 +67,7 @@ abstract class FunctionalExpressionAlgebra>(val algebra: A) : /** * A context class for [Expression] construction for [Space] algebras. */ -open class FunctionalExpressionSpace>(algebra: A) : +public open class FunctionalExpressionSpace>(algebra: A) : FunctionalExpressionAlgebra(algebra), Space> { override val zero: Expression get() = const(algebra.zero) @@ -82,10 +83,10 @@ open class FunctionalExpressionSpace>(algebra: A) : override fun multiply(a: Expression, k: Number): Expression = FunctionalConstProductExpression(algebra, a, k) - operator fun Expression.plus(arg: T): Expression = this + const(arg) - operator fun Expression.minus(arg: T): Expression = this - const(arg) - operator fun T.plus(arg: Expression): Expression = arg + this - operator fun T.minus(arg: Expression): Expression = arg - this + public operator fun Expression.plus(arg: T): Expression = this + const(arg) + public operator fun Expression.minus(arg: T): Expression = this - const(arg) + public operator fun T.plus(arg: Expression): Expression = arg + this + public operator fun T.minus(arg: Expression): Expression = arg - this override fun unaryOperation(operation: String, arg: Expression): Expression = super.unaryOperation(operation, arg) @@ -94,7 +95,7 @@ open class FunctionalExpressionSpace>(algebra: A) : super.binaryOperation(operation, left, right) } -open class FunctionalExpressionRing(algebra: A) : FunctionalExpressionSpace(algebra), +public open class FunctionalExpressionRing(algebra: A) : FunctionalExpressionSpace(algebra), Ring> where A : Ring, A : NumericAlgebra { override val one: Expression get() = const(algebra.one) @@ -105,8 +106,8 @@ open class FunctionalExpressionRing(algebra: A) : FunctionalExpressionSpac override fun multiply(a: Expression, b: Expression): Expression = binaryOperation(RingOperations.TIMES_OPERATION, a, b) - operator fun Expression.times(arg: T): Expression = this * const(arg) - operator fun T.times(arg: Expression): Expression = arg * this + public operator fun Expression.times(arg: T): Expression = this * const(arg) + public operator fun T.times(arg: Expression): Expression = arg * this override fun unaryOperation(operation: String, arg: Expression): Expression = super.unaryOperation(operation, arg) @@ -115,7 +116,7 @@ open class FunctionalExpressionRing(algebra: A) : FunctionalExpressionSpac super.binaryOperation(operation, left, right) } -open class FunctionalExpressionField(algebra: A) : +public open class FunctionalExpressionField(algebra: A) : FunctionalExpressionRing(algebra), Field> where A : Field, A : NumericAlgebra { /** @@ -124,8 +125,8 @@ open class FunctionalExpressionField(algebra: A) : override fun divide(a: Expression, b: Expression): Expression = binaryOperation(FieldOperations.DIV_OPERATION, a, b) - operator fun Expression.div(arg: T): Expression = this / const(arg) - operator fun T.div(arg: Expression): Expression = arg / this + public operator fun Expression.div(arg: T): Expression = this / const(arg) + public operator fun T.div(arg: Expression): Expression = arg / this override fun unaryOperation(operation: String, arg: Expression): Expression = super.unaryOperation(operation, arg) @@ -134,7 +135,7 @@ open class FunctionalExpressionField(algebra: A) : super.binaryOperation(operation, left, right) } -open class FunctionalExpressionExtendedField(algebra: A) : +public open class FunctionalExpressionExtendedField(algebra: A) : FunctionalExpressionField(algebra), ExtendedField> where A : ExtendedField, A : NumericAlgebra { override fun sin(arg: Expression): Expression = unaryOperation(TrigonometricOperations.SIN_OPERATION, arg) @@ -156,14 +157,14 @@ open class FunctionalExpressionExtendedField(algebra: A) : super.binaryOperation(operation, left, right) } -inline fun > A.expressionInSpace(block: FunctionalExpressionSpace.() -> Expression): Expression = +public inline fun > A.expressionInSpace(block: FunctionalExpressionSpace.() -> Expression): Expression = FunctionalExpressionSpace(this).block() -inline fun > A.expressionInRing(block: FunctionalExpressionRing.() -> Expression): Expression = +public inline fun > A.expressionInRing(block: FunctionalExpressionRing.() -> Expression): Expression = FunctionalExpressionRing(this).block() -inline fun > A.expressionInField(block: FunctionalExpressionField.() -> Expression): Expression = +public inline fun > A.expressionInField(block: FunctionalExpressionField.() -> Expression): Expression = FunctionalExpressionField(this).block() -inline fun > A.expressionInExtendedField(block: FunctionalExpressionExtendedField.() -> Expression): Expression = +public inline fun > A.expressionInExtendedField(block: FunctionalExpressionExtendedField.() -> Expression): Expression = FunctionalExpressionExtendedField(this).block() diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/expressions/Builders.kt b/kmath-core/src/commonMain/kotlin/scientifik/kmath/expressions/expressionBuilders.kt similarity index 65% rename from kmath-core/src/commonMain/kotlin/scientifik/kmath/expressions/Builders.kt rename to kmath-core/src/commonMain/kotlin/scientifik/kmath/expressions/expressionBuilders.kt index 8d0b82a89..737f94b38 100644 --- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/expressions/Builders.kt +++ b/kmath-core/src/commonMain/kotlin/scientifik/kmath/expressions/expressionBuilders.kt @@ -11,7 +11,7 @@ import kotlin.contracts.contract /** * Creates a functional expression with this [Space]. */ -inline fun Space.spaceExpression(block: FunctionalExpressionSpace>.() -> Expression): Expression { +public inline fun Space.spaceExpression(block: FunctionalExpressionSpace>.() -> Expression): Expression { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } return FunctionalExpressionSpace(this).block() } @@ -19,7 +19,7 @@ inline fun Space.spaceExpression(block: FunctionalExpressionSpace Ring.ringExpression(block: FunctionalExpressionRing>.() -> Expression): Expression { +public inline fun Ring.ringExpression(block: FunctionalExpressionRing>.() -> Expression): Expression { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } return FunctionalExpressionRing(this).block() } @@ -27,7 +27,7 @@ inline fun Ring.ringExpression(block: FunctionalExpressionRing /** * Creates a functional expression with this [Field]. */ -inline fun Field.fieldExpression(block: FunctionalExpressionField>.() -> Expression): Expression { +public inline fun Field.fieldExpression(block: FunctionalExpressionField>.() -> Expression): Expression { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } return FunctionalExpressionField(this).block() } @@ -35,7 +35,7 @@ inline fun Field.fieldExpression(block: FunctionalExpressionField ExtendedField.extendedFieldExpression(block: FunctionalExpressionExtendedField>.() -> Expression): Expression { +public inline fun ExtendedField.extendedFieldExpression(block: FunctionalExpressionExtendedField>.() -> Expression): Expression { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } return FunctionalExpressionExtendedField(this).block() } diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/linear/BufferMatrix.kt b/kmath-core/src/commonMain/kotlin/scientifik/kmath/linear/BufferMatrix.kt index 343b8287e..c28cc5ab7 100644 --- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/linear/BufferMatrix.kt +++ b/kmath-core/src/commonMain/kotlin/scientifik/kmath/linear/BufferMatrix.kt @@ -7,7 +7,7 @@ import scientifik.kmath.structures.* /** * Basic implementation of Matrix space based on [NDStructure] */ -class BufferMatrixContext>( +public class BufferMatrixContext>( override val elementContext: R, private val bufferFactory: BufferFactory ) : GenericMatrixContext { @@ -19,11 +19,11 @@ class BufferMatrixContext>( override fun point(size: Int, initializer: (Int) -> T): Point = bufferFactory(size, initializer) - companion object + public companion object } @Suppress("OVERRIDE_BY_INLINE") -object RealMatrixContext : GenericMatrixContext { +public object RealMatrixContext : GenericMatrixContext { override val elementContext: RealField get() = RealField @@ -35,10 +35,10 @@ object RealMatrixContext : GenericMatrixContext { override inline fun point(size: Int, initializer: (Int) -> Double): Point = RealBuffer(size, initializer) } -class BufferMatrix( +public class BufferMatrix( override val rowNum: Int, override val colNum: Int, - val buffer: Buffer, + public val buffer: Buffer, override val features: Set = emptySet() ) : FeaturedMatrix { @@ -90,7 +90,7 @@ class BufferMatrix( /** * Optimized dot product for real matrices */ -infix fun BufferMatrix.dot(other: BufferMatrix): BufferMatrix { +public infix fun BufferMatrix.dot(other: BufferMatrix): BufferMatrix { require(colNum == other.rowNum) { "Matrix dot operation dimension mismatch: ($rowNum, $colNum) x (${other.rowNum}, ${other.colNum})" } val array = DoubleArray(this.rowNum * other.colNum) diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/linear/FeaturedMatrix.kt b/kmath-core/src/commonMain/kotlin/scientifik/kmath/linear/FeaturedMatrix.kt index 9b60bf719..3e5116435 100644 --- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/linear/FeaturedMatrix.kt +++ b/kmath-core/src/commonMain/kotlin/scientifik/kmath/linear/FeaturedMatrix.kt @@ -11,11 +11,9 @@ import kotlin.math.sqrt /** * A 2d structure plus optional matrix-specific features */ -interface FeaturedMatrix : Matrix { - +public interface FeaturedMatrix : Matrix { override val shape: IntArray get() = intArrayOf(rowNum, colNum) - - val features: Set + public val features: Set /** * Suggest new feature for this matrix. The result is the new matrix that may or may not reuse existing data structure. @@ -23,12 +21,12 @@ interface FeaturedMatrix : Matrix { * The implementation does not guarantee to check that matrix actually have the feature, so one should be careful to * add only those features that are valid. */ - fun suggestFeature(vararg features: MatrixFeature): FeaturedMatrix + public fun suggestFeature(vararg features: MatrixFeature): FeaturedMatrix - companion object + public companion object } -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 { contract { callsInPlace(initializer) } return MatrixContext.real.produce(rows, columns, initializer) } @@ -36,31 +34,31 @@ inline fun Structure2D.Companion.real(rows: Int, columns: Int, initializer: (Int /** * Build a square matrix from given elements. */ -fun Structure2D.Companion.square(vararg elements: T): FeaturedMatrix { +public fun Structure2D.Companion.square(vararg elements: T): FeaturedMatrix { val size: Int = sqrt(elements.size.toDouble()).toInt() require(size * size == elements.size) { "The number of elements ${elements.size} is not a full square" } val buffer = elements.asBuffer() return BufferMatrix(size, size, buffer) } -val Matrix<*>.features: Set get() = (this as? FeaturedMatrix)?.features ?: emptySet() +public val Matrix<*>.features: Set get() = (this as? FeaturedMatrix)?.features ?: emptySet() /** * Check if matrix has the given feature class */ -inline fun Matrix<*>.hasFeature(): Boolean = +public inline fun Matrix<*>.hasFeature(): Boolean = features.find { it is T } != null /** * Get the first feature matching given class. Does not guarantee that matrix has only one feature matching the criteria */ -inline fun Matrix<*>.getFeature(): T? = +public inline fun Matrix<*>.getFeature(): T? = features.filterIsInstance().firstOrNull() /** * Diagonal matrix of ones. The matrix is virtual no actual matrix is created */ -fun > GenericMatrixContext.one(rows: Int, columns: Int): FeaturedMatrix = +public fun > GenericMatrixContext.one(rows: Int, columns: Int): FeaturedMatrix = VirtualMatrix(rows, columns, DiagonalFeature) { i, j -> if (i == j) elementContext.one else elementContext.zero } @@ -69,20 +67,20 @@ fun > GenericMatrixContext.one(rows: Int, columns: In /** * A virtual matrix of zeroes */ -fun > GenericMatrixContext.zero(rows: Int, columns: Int): FeaturedMatrix = +public fun > GenericMatrixContext.zero(rows: Int, columns: Int): FeaturedMatrix = VirtualMatrix(rows, columns) { _, _ -> elementContext.zero } -class TransposedFeature(val original: Matrix) : MatrixFeature +public class TransposedFeature(public val original: Matrix) : MatrixFeature /** * Create a virtual transposed matrix without copying anything. `A.transpose().transpose() === A` */ -fun Matrix.transpose(): Matrix { - return this.getFeature>()?.original ?: VirtualMatrix( - this.colNum, - this.rowNum, +public fun Matrix.transpose(): Matrix { + return getFeature>()?.original ?: VirtualMatrix( + colNum, + rowNum, setOf(TransposedFeature(this)) ) { i, j -> get(j, i) } } -infix fun Matrix.dot(other: Matrix): Matrix = with(MatrixContext.real) { dot(other) } +public infix fun Matrix.dot(other: Matrix): Matrix = with(MatrixContext.real) { dot(other) } diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/linear/LUPDecomposition.kt b/kmath-core/src/commonMain/kotlin/scientifik/kmath/linear/LUPDecomposition.kt index f3e4f648f..2bad1aa46 100644 --- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/linear/LUPDecomposition.kt +++ b/kmath-core/src/commonMain/kotlin/scientifik/kmath/linear/LUPDecomposition.kt @@ -7,19 +7,20 @@ import scientifik.kmath.operations.invoke import scientifik.kmath.structures.BufferAccessor2D import scientifik.kmath.structures.Matrix import scientifik.kmath.structures.Structure2D +import kotlin.contracts.contract import kotlin.reflect.KClass /** * Common implementation of [LUPDecompositionFeature] */ -class LUPDecomposition( - val context: GenericMatrixContext>, - val lu: Structure2D, - val pivot: IntArray, +public class LUPDecomposition( + public val context: GenericMatrixContext>, + public val lu: Structure2D, + public val pivot: IntArray, private val even: Boolean ) : LUPDecompositionFeature, DeterminantFeature { - - val elementContext: Field get() = context.elementContext + public val elementContext: Field + get() = context.elementContext /** * Returns the matrix L of the decomposition. @@ -44,7 +45,6 @@ class LUPDecomposition( if (j >= i) lu[i, j] else elementContext.zero } - /** * Returns the P rows permutation matrix. * @@ -55,7 +55,6 @@ class LUPDecomposition( if (j == pivot[i]) elementContext.one else elementContext.zero } - /** * Return the determinant of the matrix * @return determinant of the matrix @@ -66,22 +65,19 @@ class LUPDecomposition( } -fun , F : Field> GenericMatrixContext.abs(value: T): T = +public fun , F : Field> GenericMatrixContext.abs(value: T): T = if (value > elementContext.zero) value else elementContext { -value } - /** * Create a lup decomposition of generic matrix */ -fun , F : Field> GenericMatrixContext.lup( +public inline fun , F : Field> GenericMatrixContext.lup( type: KClass, matrix: Matrix, checkSingular: (T) -> Boolean ): LUPDecomposition { - if (matrix.rowNum != matrix.colNum) { - error("LU decomposition supports only square matrices") - } - + contract { callsInPlace(checkSingular) } + require(matrix.rowNum == matrix.colNum) { "LU decomposition supports only square matrices" } val m = matrix.colNum val pivot = IntArray(matrix.rowNum) @@ -154,15 +150,18 @@ fun , F : Field> GenericMatrixContext.lup( } } -inline fun , F : Field> GenericMatrixContext.lup( +public inline fun , F : Field> GenericMatrixContext.lup( matrix: Matrix, - noinline checkSingular: (T) -> Boolean -): LUPDecomposition = lup(T::class, matrix, checkSingular) + checkSingular: (T) -> Boolean +): LUPDecomposition { + contract { callsInPlace(checkSingular) } + return lup(T::class, matrix, checkSingular) +} -fun GenericMatrixContext.lup(matrix: Matrix): LUPDecomposition = +public fun GenericMatrixContext.lup(matrix: Matrix): LUPDecomposition = lup(Double::class, matrix) { it < 1e-11 } -fun LUPDecomposition.solve(type: KClass, matrix: Matrix): Matrix { +public fun LUPDecomposition.solve(type: KClass, matrix: Matrix): Matrix { require(matrix.rowNum == pivot.size) { "Matrix dimension mismatch. Expected ${pivot.size}, but got ${matrix.colNum}" } BufferAccessor2D(type, matrix.rowNum, matrix.colNum).run { @@ -207,27 +206,31 @@ fun LUPDecomposition.solve(type: KClass, matrix: Matrix): Mat } } -inline fun LUPDecomposition.solve(matrix: Matrix): Matrix = solve(T::class, matrix) +public inline fun LUPDecomposition.solve(matrix: Matrix): Matrix = solve(T::class, matrix) /** * Solve a linear equation **a*x = b** */ -inline fun , F : Field> GenericMatrixContext.solve( +public inline fun , F : Field> GenericMatrixContext.solve( a: Matrix, b: Matrix, - noinline checkSingular: (T) -> Boolean + checkSingular: (T) -> Boolean ): Matrix { + contract { callsInPlace(checkSingular) } // Use existing decomposition if it is provided by matrix val decomposition = a.getFeature() ?: lup(T::class, a, checkSingular) return decomposition.solve(T::class, b) } -fun RealMatrixContext.solve(a: Matrix, b: Matrix): Matrix = solve(a, b) { it < 1e-11 } +public fun RealMatrixContext.solve(a: Matrix, b: Matrix): Matrix = solve(a, b) { it < 1e-11 } -inline fun , F : Field> GenericMatrixContext.inverse( +public inline fun , F : Field> GenericMatrixContext.inverse( matrix: Matrix, - noinline checkSingular: (T) -> Boolean -): Matrix = solve(matrix, one(matrix.rowNum, matrix.colNum), checkSingular) + checkSingular: (T) -> Boolean +): Matrix { + contract { callsInPlace(checkSingular) } + return solve(matrix, one(matrix.rowNum, matrix.colNum), checkSingular) +} -fun RealMatrixContext.inverse(matrix: Matrix): Matrix = +public fun RealMatrixContext.inverse(matrix: Matrix): Matrix = solve(matrix, one(matrix.rowNum, matrix.colNum)) { it < 1e-11 } diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/linear/LinearAlgebra.kt b/kmath-core/src/commonMain/kotlin/scientifik/kmath/linear/LinearAlgebra.kt index fb49d18ed..4daa03e5d 100644 --- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/linear/LinearAlgebra.kt +++ b/kmath-core/src/commonMain/kotlin/scientifik/kmath/linear/LinearAlgebra.kt @@ -4,25 +4,25 @@ import scientifik.kmath.structures.Buffer import scientifik.kmath.structures.Matrix import scientifik.kmath.structures.VirtualBuffer -typealias Point = Buffer +public typealias Point = Buffer /** * A group of methods to resolve equation A dot X = B, where A and B are matrices or vectors */ -interface LinearSolver { - fun solve(a: Matrix, b: Matrix): Matrix - fun solve(a: Matrix, b: Point): Point = solve(a, b.asMatrix()).asPoint() - fun inverse(a: Matrix): Matrix +public interface LinearSolver { + public fun solve(a: Matrix, b: Matrix): Matrix + public fun solve(a: Matrix, b: Point): Point = solve(a, b.asMatrix()).asPoint() + public fun inverse(a: Matrix): Matrix } /** * Convert matrix to vector if it is possible */ -fun Matrix.asPoint(): Point = +public fun Matrix.asPoint(): Point = if (this.colNum == 1) { VirtualBuffer(rowNum) { get(it, 0) } } else { error("Can't convert matrix with more than one column to vector") } -fun Point.asMatrix(): VirtualMatrix = VirtualMatrix(size, 1) { i, _ -> get(i) } +public fun Point.asMatrix(): VirtualMatrix = VirtualMatrix(size, 1) { i, _ -> get(i) } diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/linear/MatrixBuilder.kt b/kmath-core/src/commonMain/kotlin/scientifik/kmath/linear/MatrixBuilder.kt index 390362f8c..5efa53bc2 100644 --- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/linear/MatrixBuilder.kt +++ b/kmath-core/src/commonMain/kotlin/scientifik/kmath/linear/MatrixBuilder.kt @@ -5,8 +5,8 @@ import scientifik.kmath.structures.BufferFactory import scientifik.kmath.structures.Structure2D import scientifik.kmath.structures.asBuffer -class MatrixBuilder(val rows: Int, val columns: Int) { - operator fun invoke(vararg elements: T): FeaturedMatrix { +public class MatrixBuilder(public val rows: Int, public val columns: Int) { + public operator fun invoke(vararg elements: T): FeaturedMatrix { require(rows * columns == elements.size) { "The number of elements ${elements.size} is not equal $rows * $columns" } val buffer = elements.asBuffer() return BufferMatrix(rows, columns, buffer) @@ -15,14 +15,14 @@ class MatrixBuilder(val rows: Int, val columns: Int) { //TODO add specific matrix builder functions like diagonal, etc } -fun Structure2D.Companion.build(rows: Int, columns: Int): MatrixBuilder = MatrixBuilder(rows, columns) +public fun Structure2D.Companion.build(rows: Int, columns: Int): MatrixBuilder = MatrixBuilder(rows, columns) -fun Structure2D.Companion.row(vararg values: T): FeaturedMatrix { +public fun Structure2D.Companion.row(vararg values: T): FeaturedMatrix { val buffer = values.asBuffer() return BufferMatrix(1, values.size, buffer) } -inline fun Structure2D.Companion.row( +public inline fun Structure2D.Companion.row( size: Int, factory: BufferFactory = Buffer.Companion::auto, noinline builder: (Int) -> T @@ -31,12 +31,12 @@ inline fun Structure2D.Companion.row( return BufferMatrix(1, size, buffer) } -fun Structure2D.Companion.column(vararg values: T): FeaturedMatrix { +public fun Structure2D.Companion.column(vararg values: T): FeaturedMatrix { val buffer = values.asBuffer() return BufferMatrix(values.size, 1, buffer) } -inline fun Structure2D.Companion.column( +public inline fun Structure2D.Companion.column( size: Int, factory: BufferFactory = Buffer.Companion::auto, noinline builder: (Int) -> T diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/linear/MatrixContext.kt b/kmath-core/src/commonMain/kotlin/scientifik/kmath/linear/MatrixContext.kt index 763bb1615..13d4e68b9 100644 --- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/linear/MatrixContext.kt +++ b/kmath-core/src/commonMain/kotlin/scientifik/kmath/linear/MatrixContext.kt @@ -12,30 +12,31 @@ import scientifik.kmath.structures.asSequence /** * Basic operations on matrices. Operates on [Matrix] */ -interface MatrixContext : SpaceOperations> { +public interface MatrixContext : SpaceOperations> { /** * Produce a matrix with this context and given dimensions */ - fun produce(rows: Int, columns: Int, initializer: (i: Int, j: Int) -> T): Matrix + public fun produce(rows: Int, columns: Int, initializer: (i: Int, j: Int) -> T): Matrix - infix fun Matrix.dot(other: Matrix): Matrix + public infix fun Matrix.dot(other: Matrix): Matrix - infix fun Matrix.dot(vector: Point): Point + public infix fun Matrix.dot(vector: Point): Point - operator fun Matrix.times(value: T): Matrix + public operator fun Matrix.times(value: T): Matrix - operator fun T.times(m: Matrix): Matrix = m * this + public operator fun T.times(m: Matrix): Matrix = m * this - companion object { + public companion object { /** * Non-boxing double matrix */ - val real: RealMatrixContext = RealMatrixContext + public val real: RealMatrixContext + get() = RealMatrixContext /** * A structured matrix with custom buffer */ - fun > buffered( + public fun > buffered( ring: R, bufferFactory: BufferFactory = Buffer.Companion::boxing ): GenericMatrixContext = BufferMatrixContext(ring, bufferFactory) @@ -43,21 +44,21 @@ interface MatrixContext : SpaceOperations> { /** * Automatic buffered matrix, unboxed if it is possible */ - inline fun > auto(ring: R): GenericMatrixContext = + public inline fun > auto(ring: R): GenericMatrixContext = buffered(ring, Buffer.Companion::auto) } } -interface GenericMatrixContext> : MatrixContext { +public interface GenericMatrixContext> : MatrixContext { /** * The ring context for matrix elements */ - val elementContext: R + public val elementContext: R /** * Produce a point compatible with matrix space */ - fun point(size: Int, initializer: (Int) -> T): Point + public fun point(size: Int, initializer: (Int) -> T): Point override infix fun Matrix.dot(other: Matrix): Matrix { //TODO add typed error @@ -102,7 +103,7 @@ interface GenericMatrixContext> : MatrixContext { override fun multiply(a: Matrix, k: Number): Matrix = produce(a.rowNum, a.colNum) { i, j -> elementContext { a[i, j] * k } } - operator fun Number.times(matrix: FeaturedMatrix): Matrix = matrix * this + public operator fun Number.times(matrix: FeaturedMatrix): Matrix = matrix * this override operator fun Matrix.times(value: T): Matrix = produce(rowNum, colNum) { i, j -> elementContext { get(i, j) * value } } diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/linear/MatrixFeatures.kt b/kmath-core/src/commonMain/kotlin/scientifik/kmath/linear/MatrixFeatures.kt index 87cfe21b0..3448a2e7c 100644 --- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/linear/MatrixFeatures.kt +++ b/kmath-core/src/commonMain/kotlin/scientifik/kmath/linear/MatrixFeatures.kt @@ -4,59 +4,59 @@ package scientifik.kmath.linear * A marker interface representing some matrix feature like diagonal, sparse, zero, etc. Features used to optimize matrix * operations performance in some cases. */ -interface MatrixFeature +public interface MatrixFeature /** * The matrix with this feature is considered to have only diagonal non-null elements */ -object DiagonalFeature : MatrixFeature +public object DiagonalFeature : MatrixFeature /** * Matrix with this feature has all zero elements */ -object ZeroFeature : MatrixFeature +public object ZeroFeature : MatrixFeature /** * Matrix with this feature have unit elements on diagonal and zero elements in all other places */ -object UnitFeature : MatrixFeature +public object UnitFeature : MatrixFeature /** * Inverted matrix feature */ -interface InverseMatrixFeature : MatrixFeature { - val inverse: FeaturedMatrix +public interface InverseMatrixFeature : MatrixFeature { + public val inverse: FeaturedMatrix } /** * A determinant container */ -interface DeterminantFeature : MatrixFeature { - val determinant: T +public interface DeterminantFeature : MatrixFeature { + public val determinant: T } @Suppress("FunctionName") -fun DeterminantFeature(determinant: T): DeterminantFeature = object : DeterminantFeature { +public fun DeterminantFeature(determinant: T): DeterminantFeature = object : DeterminantFeature { override val determinant: T = determinant } /** * Lower triangular matrix */ -object LFeature : MatrixFeature +public object LFeature : MatrixFeature /** * Upper triangular feature */ -object UFeature : MatrixFeature +public object UFeature : MatrixFeature /** * TODO add documentation */ -interface LUPDecompositionFeature : MatrixFeature { - val l: FeaturedMatrix - val u: FeaturedMatrix - val p: FeaturedMatrix +public interface LUPDecompositionFeature : MatrixFeature { + public val l: FeaturedMatrix + public val u: FeaturedMatrix + public val p: FeaturedMatrix } //TODO add sparse matrix feature diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/linear/VectorSpace.kt b/kmath-core/src/commonMain/kotlin/scientifik/kmath/linear/VectorSpace.kt index 82e5c7ef6..a75523f7c 100644 --- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/linear/VectorSpace.kt +++ b/kmath-core/src/commonMain/kotlin/scientifik/kmath/linear/VectorSpace.kt @@ -10,12 +10,12 @@ import scientifik.kmath.structures.BufferFactory * A linear space for vectors. * Could be used on any point-like structure */ -interface VectorSpace> : Space> { - val size: Int - val space: S +public interface VectorSpace> : Space> { + public val size: Int + public val space: S override val zero: Point get() = produce { space.zero } - fun produce(initializer: (Int) -> T): Point + public fun produce(initializer: (Int) -> T): Point /** * Produce a space-element of this vector space for expressions @@ -28,13 +28,13 @@ interface VectorSpace> : Space> { //TODO add basis - companion object { + public companion object { private val realSpaceCache: MutableMap> = hashMapOf() /** * Non-boxing double vector space */ - fun real(size: Int): BufferVectorSpace = realSpaceCache.getOrPut(size) { + public fun real(size: Int): BufferVectorSpace = realSpaceCache.getOrPut(size) { BufferVectorSpace( size, RealField, @@ -45,7 +45,7 @@ interface VectorSpace> : Space> { /** * A structured vector space with custom buffer */ - fun > buffered( + public fun > buffered( size: Int, space: S, bufferFactory: BufferFactory = Buffer.Companion::boxing @@ -54,16 +54,16 @@ interface VectorSpace> : Space> { /** * Automatic buffered vector, unboxed if it is possible */ - inline fun > auto(size: Int, space: S): VectorSpace = + public inline fun > auto(size: Int, space: S): VectorSpace = buffered(size, space, Buffer.Companion::auto) } } -class BufferVectorSpace>( +public class BufferVectorSpace>( override val size: Int, override val space: S, - val bufferFactory: BufferFactory + public val bufferFactory: BufferFactory ) : VectorSpace { override fun produce(initializer: (Int) -> T): Buffer = bufferFactory(size, initializer) //override fun produceElement(initializer: (Int) -> T): Vector = BufferVector(this, produce(initializer)) diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/linear/VirtualMatrix.kt b/kmath-core/src/commonMain/kotlin/scientifik/kmath/linear/VirtualMatrix.kt index 5266dc884..f6794ce01 100644 --- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/linear/VirtualMatrix.kt +++ b/kmath-core/src/commonMain/kotlin/scientifik/kmath/linear/VirtualMatrix.kt @@ -2,14 +2,18 @@ package scientifik.kmath.linear import scientifik.kmath.structures.Matrix -class VirtualMatrix( +public class VirtualMatrix( override val rowNum: Int, override val colNum: Int, override val features: Set = emptySet(), - val generator: (i: Int, j: Int) -> T + public val generator: (i: Int, j: Int) -> T ) : FeaturedMatrix { - - constructor(rowNum: Int, colNum: Int, vararg features: MatrixFeature, generator: (i: Int, j: Int) -> T) : this( + public constructor( + rowNum: Int, + colNum: Int, + vararg features: MatrixFeature, + generator: (i: Int, j: Int) -> T + ) : this( rowNum, colNum, setOf(*features), @@ -42,18 +46,15 @@ class VirtualMatrix( } - companion object { + public companion object { /** * Wrap a matrix adding additional features to it */ - fun wrap(matrix: Matrix, vararg features: MatrixFeature): FeaturedMatrix { - return if (matrix is VirtualMatrix) { + public fun wrap(matrix: Matrix, vararg features: MatrixFeature): FeaturedMatrix { + return if (matrix is VirtualMatrix) VirtualMatrix(matrix.rowNum, matrix.colNum, matrix.features + features, matrix.generator) - } else { - VirtualMatrix(matrix.rowNum, matrix.colNum, matrix.features + features) { i, j -> - matrix[i, j] - } - } + else + VirtualMatrix(matrix.rowNum, matrix.colNum, matrix.features + features) { i, j -> matrix[i, j] } } } } diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/misc/AutoDiff.kt b/kmath-core/src/commonMain/kotlin/scientifik/kmath/misc/AutoDiff.kt index be222783e..6bed19456 100644 --- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/misc/AutoDiff.kt +++ b/kmath-core/src/commonMain/kotlin/scientifik/kmath/misc/AutoDiff.kt @@ -19,24 +19,24 @@ import kotlin.contracts.contract * Differentiable variable with value and derivative of differentiation ([deriv]) result * with respect to this variable. */ -open class Variable(val value: T) +public open class Variable(public val value: T) -class DerivationResult( +public class DerivationResult( value: T, - val deriv: Map, T>, - val context: Field + public val deriv: Map, T>, + public val context: Field ) : Variable(value) { - fun deriv(variable: Variable): T = deriv[variable] ?: context.zero + public fun deriv(variable: Variable): T = deriv[variable] ?: context.zero /** * compute divergence */ - fun div(): T = context { sum(deriv.values) } + public fun div(): T = context { sum(deriv.values) } /** * Compute a gradient for variables in given order */ - fun grad(vararg variables: Variable): Point { + public fun grad(vararg variables: Variable): Point { check(variables.isNotEmpty()) { "Variable order is not provided for gradient construction" } return variables.map(::deriv).asBuffer() } @@ -55,7 +55,7 @@ class DerivationResult( * assertEquals(9.0, x.d) // dy/dx * ``` */ -inline fun > F.deriv(body: AutoDiffField.() -> Variable): DerivationResult { +public inline fun > F.deriv(body: AutoDiffField.() -> Variable): DerivationResult { contract { callsInPlace(body, InvocationKind.EXACTLY_ONCE) } return (AutoDiffContext(this)) { @@ -67,14 +67,14 @@ inline fun > F.deriv(body: AutoDiffField.() -> Varia } -abstract class AutoDiffField> : Field> { - abstract val context: F +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 */ - abstract var Variable.d: T + public abstract var Variable.d: T /** * Performs update of derivative after the rest of the formula in the back-pass. @@ -87,11 +87,11 @@ abstract class AutoDiffField> : Field> { * } * ``` */ - abstract fun derive(value: R, block: F.(R) -> Unit): R + public abstract fun derive(value: R, block: F.(R) -> Unit): R - abstract fun variable(value: T): Variable + public abstract fun variable(value: T): Variable - inline fun variable(block: F.() -> T): Variable = variable(context.block()) + public inline fun variable(block: F.() -> T): Variable = variable(context.block()) // Overloads for Double constants @@ -153,7 +153,6 @@ internal class AutoDiffContext>(override val context: F) : // Basic math (+, -, *, /) - override fun add(a: Variable, b: Variable): Variable = derive(variable { a.value + b.value }) { z -> a.d += z.d b.d += z.d @@ -177,35 +176,36 @@ internal class AutoDiffContext>(override val context: F) : // Extensions for differentiation of various basic mathematical functions // x ^ 2 -fun > AutoDiffField.sqr(x: Variable): Variable = +public fun > AutoDiffField.sqr(x: Variable): Variable = derive(variable { x.value * x.value }) { z -> x.d += z.d * 2 * x.value } // x ^ 1/2 -fun > AutoDiffField.sqrt(x: Variable): Variable = +public fun > AutoDiffField.sqrt(x: Variable): Variable = derive(variable { sqrt(x.value) }) { z -> x.d += z.d * 0.5 / z.value } // x ^ y (const) -fun > AutoDiffField.pow(x: Variable, y: Double): Variable = +public fun > AutoDiffField.pow(x: Variable, y: Double): Variable = derive(variable { power(x.value, y) }) { z -> x.d += z.d * y * power(x.value, y - 1) } -fun > AutoDiffField.pow(x: Variable, y: Int): Variable = pow(x, y.toDouble()) +public fun > AutoDiffField.pow(x: Variable, y: Int): Variable = + pow(x, y.toDouble()) // exp(x) -fun > AutoDiffField.exp(x: Variable): Variable = +public fun > AutoDiffField.exp(x: Variable): Variable = derive(variable { exp(x.value) }) { z -> x.d += z.d * z.value } // ln(x) -fun > AutoDiffField.ln(x: Variable): Variable = +public fun > AutoDiffField.ln(x: Variable): Variable = derive(variable { ln(x.value) }) { z -> x.d += z.d / x.value } // x ^ y (any) -fun > AutoDiffField.pow(x: Variable, y: Variable): Variable = +public fun > AutoDiffField.pow(x: Variable, y: Variable): Variable = exp(y * ln(x)) // sin(x) -fun > AutoDiffField.sin(x: Variable): Variable = +public fun > AutoDiffField.sin(x: Variable): Variable = derive(variable { sin(x.value) }) { z -> x.d += z.d * cos(x.value) } // cos(x) -fun > AutoDiffField.cos(x: Variable): Variable = +public fun > AutoDiffField.cos(x: Variable): Variable = derive(variable { cos(x.value) }) { z -> x.d -= z.d * sin(x.value) } diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/misc/Grids.kt b/kmath-core/src/commonMain/kotlin/scientifik/kmath/misc/Grids.kt index 1272ddd1c..cf3e93895 100644 --- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/misc/Grids.kt +++ b/kmath-core/src/commonMain/kotlin/scientifik/kmath/misc/Grids.kt @@ -10,17 +10,21 @@ import kotlin.math.abs * * If step is negative, the same goes from upper boundary downwards */ -fun ClosedFloatingPointRange.toSequenceWithStep(step: Double): Sequence = when { +public fun ClosedFloatingPointRange.toSequenceWithStep(step: Double): Sequence = when { step == 0.0 -> error("Zero step in double progression") + step > 0 -> sequence { var current = start + while (current <= endInclusive) { yield(current) current += step } } + else -> sequence { var current = endInclusive + while (current >= start) { yield(current) current += step @@ -31,7 +35,7 @@ fun ClosedFloatingPointRange.toSequenceWithStep(step: Double): Sequence< /** * Convert double range to sequence with the fixed number of points */ -fun ClosedFloatingPointRange.toSequenceWithPoints(numPoints: Int): Sequence { +public fun ClosedFloatingPointRange.toSequenceWithPoints(numPoints: Int): Sequence { require(numPoints > 1) { "The number of points should be more than 2" } return toSequenceWithStep(abs(endInclusive - start) / (numPoints - 1)) } @@ -40,7 +44,7 @@ fun ClosedFloatingPointRange.toSequenceWithPoints(numPoints: Int): Seque * Convert double range to array of evenly spaced doubles, where the size of array equals [numPoints] */ @Deprecated("Replace by 'toSequenceWithPoints'") -fun ClosedFloatingPointRange.toGrid(numPoints: Int): DoubleArray { +public fun ClosedFloatingPointRange.toGrid(numPoints: Int): DoubleArray { require(numPoints >= 2) { "Can't create generic grid with less than two points" } return DoubleArray(numPoints) { i -> start + (endInclusive - start) / (numPoints - 1) * i } } diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/misc/cumulative.kt b/kmath-core/src/commonMain/kotlin/scientifik/kmath/misc/cumulative.kt index e11adc135..f7dfcd781 100644 --- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/misc/cumulative.kt +++ b/kmath-core/src/commonMain/kotlin/scientifik/kmath/misc/cumulative.kt @@ -2,7 +2,6 @@ package scientifik.kmath.misc import scientifik.kmath.operations.Space import scientifik.kmath.operations.invoke -import kotlin.contracts.ExperimentalContracts import kotlin.contracts.contract import kotlin.jvm.JvmName @@ -13,7 +12,7 @@ import kotlin.jvm.JvmName * @param R the type of resulting iterable. * @param initial lazy evaluated. */ -inline fun Iterator.cumulative(initial: R, crossinline operation: (R, T) -> R): Iterator { +public inline fun Iterator.cumulative(initial: R, crossinline operation: (R, T) -> R): Iterator { contract { callsInPlace(operation) } return object : Iterator { @@ -28,14 +27,13 @@ inline fun Iterator.cumulative(initial: R, crossinline operation: (R, } } -inline fun Iterable.cumulative(initial: R, crossinline operation: (R, T) -> R): Iterable = +public inline fun Iterable.cumulative(initial: R, crossinline operation: (R, T) -> R): Iterable = Iterable { this@cumulative.iterator().cumulative(initial, operation) } -inline fun Sequence.cumulative(initial: R, crossinline operation: (R, T) -> R): Sequence = Sequence { - this@cumulative.iterator().cumulative(initial, operation) -} +public inline fun Sequence.cumulative(initial: R, crossinline operation: (R, T) -> R): Sequence = + Sequence { this@cumulative.iterator().cumulative(initial, operation) } -fun List.cumulative(initial: R, operation: (R, T) -> R): List = +public fun List.cumulative(initial: R, operation: (R, T) -> R): List = iterator().cumulative(initial, operation).asSequence().toList() //Cumulative sum @@ -43,38 +41,38 @@ fun List.cumulative(initial: R, operation: (R, T) -> R): List = /** * Cumulative sum with custom space */ -fun Iterable.cumulativeSum(space: Space): Iterable = +public fun Iterable.cumulativeSum(space: Space): Iterable = space { cumulative(zero) { element: T, sum: T -> sum + element } } @JvmName("cumulativeSumOfDouble") -fun Iterable.cumulativeSum(): Iterable = cumulative(0.0) { element, sum -> sum + element } +public fun Iterable.cumulativeSum(): Iterable = cumulative(0.0) { element, sum -> sum + element } @JvmName("cumulativeSumOfInt") -fun Iterable.cumulativeSum(): Iterable = cumulative(0) { element, sum -> sum + element } +public fun Iterable.cumulativeSum(): Iterable = cumulative(0) { element, sum -> sum + element } @JvmName("cumulativeSumOfLong") -fun Iterable.cumulativeSum(): Iterable = cumulative(0L) { element, sum -> sum + element } +public fun Iterable.cumulativeSum(): Iterable = cumulative(0L) { element, sum -> sum + element } -fun Sequence.cumulativeSum(space: Space): Sequence = +public fun Sequence.cumulativeSum(space: Space): Sequence = space { cumulative(zero) { element: T, sum: T -> sum + element } } @JvmName("cumulativeSumOfDouble") -fun Sequence.cumulativeSum(): Sequence = cumulative(0.0) { element, sum -> sum + element } +public fun Sequence.cumulativeSum(): Sequence = cumulative(0.0) { element, sum -> sum + element } @JvmName("cumulativeSumOfInt") -fun Sequence.cumulativeSum(): Sequence = cumulative(0) { element, sum -> sum + element } +public fun Sequence.cumulativeSum(): Sequence = cumulative(0) { element, sum -> sum + element } @JvmName("cumulativeSumOfLong") -fun Sequence.cumulativeSum(): Sequence = cumulative(0L) { element, sum -> sum + element } +public fun Sequence.cumulativeSum(): Sequence = cumulative(0L) { element, sum -> sum + element } -fun List.cumulativeSum(space: Space): List = +public fun List.cumulativeSum(space: Space): List = space { cumulative(zero) { element: T, sum: T -> sum + element } } @JvmName("cumulativeSumOfDouble") -fun List.cumulativeSum(): List = cumulative(0.0) { element, sum -> sum + element } +public fun List.cumulativeSum(): List = cumulative(0.0) { element, sum -> sum + element } @JvmName("cumulativeSumOfInt") -fun List.cumulativeSum(): List = cumulative(0) { element, sum -> sum + element } +public fun List.cumulativeSum(): List = cumulative(0) { element, sum -> sum + element } @JvmName("cumulativeSumOfLong") -fun List.cumulativeSum(): List = cumulative(0L) { element, sum -> sum + element } +public fun List.cumulativeSum(): List = cumulative(0L) { element, sum -> sum + element } diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/operations/Algebra.kt b/kmath-core/src/commonMain/kotlin/scientifik/kmath/operations/Algebra.kt index f18bde597..40f974096 100644 --- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/operations/Algebra.kt +++ b/kmath-core/src/commonMain/kotlin/scientifik/kmath/operations/Algebra.kt @@ -4,28 +4,28 @@ package scientifik.kmath.operations * Stub for DSL the [Algebra] is. */ @DslMarker -annotation class KMathContext +public annotation class KMathContext /** * Represents an algebraic structure. * * @param T the type of element of this structure. */ -interface Algebra { +public interface Algebra { /** * Wrap raw string or variable */ - fun symbol(value: String): T = error("Wrapping of '$value' is not supported in $this") + public fun symbol(value: String): T = error("Wrapping of '$value' is not supported in $this") /** * Dynamic call of unary operation with name [operation] on [arg] */ - fun unaryOperation(operation: String, arg: T): T + public fun unaryOperation(operation: String, arg: T): T /** * Dynamic call of binary operation [operation] on [left] and [right] */ - fun binaryOperation(operation: String, left: T, right: T): T + public fun binaryOperation(operation: String, left: T, right: T): T } /** @@ -33,29 +33,30 @@ interface Algebra { * * @param T the type of element of this structure. */ -interface NumericAlgebra : Algebra { +public interface NumericAlgebra : Algebra { /** * Wraps a number. */ - fun number(value: Number): T + public fun number(value: Number): T /** * Dynamic call of binary operation [operation] on [left] and [right] where left element is [Number]. */ - fun leftSideNumberOperation(operation: String, left: Number, right: T): T = + public fun leftSideNumberOperation(operation: String, left: Number, right: T): T = binaryOperation(operation, number(left), right) /** * Dynamic call of binary operation [operation] on [left] and [right] where right element is [Number]. */ - fun rightSideNumberOperation(operation: String, left: T, right: Number): T = + public fun rightSideNumberOperation(operation: String, left: T, right: Number): T = leftSideNumberOperation(operation, right, left) } /** * Call a block with an [Algebra] as receiver. */ -inline operator fun , R> A.invoke(block: A.() -> R): R = run(block) +// TODO add contract when KT-32313 is fixed +public inline operator fun , R> A.invoke(block: A.() -> R): R = block() /** * Represents "semispace", i.e. algebraic structure with associative binary operation called "addition" as well as @@ -63,7 +64,7 @@ inline operator fun , R> A.invoke(block: A.() -> R): R = run(bloc * * @param T the type of element of this semispace. */ -interface SpaceOperations : Algebra { +public interface SpaceOperations : Algebra { /** * Addition of two elements. * @@ -71,7 +72,7 @@ interface SpaceOperations : Algebra { * @param b the augend. * @return the sum. */ - fun add(a: T, b: T): T + public fun add(a: T, b: T): T /** * Multiplication of element by scalar. @@ -80,7 +81,7 @@ interface SpaceOperations : Algebra { * @param k the multiplicand. * @return the produce. */ - fun multiply(a: T, k: Number): T + public fun multiply(a: T, k: Number): T // Operations to be performed in this context. Could be moved to extensions in case of KEEP-176 @@ -90,7 +91,7 @@ interface SpaceOperations : Algebra { * @receiver this value. * @return the additive inverse of this value. */ - operator fun T.unaryMinus(): T = multiply(this, -1.0) + public operator fun T.unaryMinus(): T = multiply(this, -1.0) /** * Returns this value. @@ -98,7 +99,7 @@ interface SpaceOperations : Algebra { * @receiver this value. * @return this value. */ - operator fun T.unaryPlus(): T = this + public operator fun T.unaryPlus(): T = this /** * Addition of two elements. @@ -107,7 +108,7 @@ interface SpaceOperations : Algebra { * @param b the augend. * @return the sum. */ - operator fun T.plus(b: T): T = add(this, b) + public operator fun T.plus(b: T): T = add(this, b) /** * Subtraction of two elements. @@ -116,7 +117,7 @@ interface SpaceOperations : Algebra { * @param b the subtrahend. * @return the difference. */ - operator fun T.minus(b: T): T = add(this, -b) + public operator fun T.minus(b: T): T = add(this, -b) /** * Multiplication of this element by a scalar. @@ -125,7 +126,7 @@ interface SpaceOperations : Algebra { * @param k the multiplicand. * @return the product. */ - operator fun T.times(k: Number): T = multiply(this, k.toDouble()) + public operator fun T.times(k: Number): T = multiply(this, k.toDouble()) /** * Division of this element by scalar. @@ -134,7 +135,7 @@ interface SpaceOperations : Algebra { * @param k the divisor. * @return the quotient. */ - operator fun T.div(k: Number): T = multiply(this, 1.0 / k.toDouble()) + public operator fun T.div(k: Number): T = multiply(this, 1.0 / k.toDouble()) /** * Multiplication of this number by element. @@ -143,7 +144,7 @@ interface SpaceOperations : Algebra { * @param b the multiplicand. * @return the product. */ - operator fun Number.times(b: T): T = b * this + public operator fun Number.times(b: T): T = b * this override fun unaryOperation(operation: String, arg: T): T = when (operation) { PLUS_OPERATION -> arg @@ -157,18 +158,16 @@ interface SpaceOperations : Algebra { else -> error("Binary operation $operation not defined in $this") } - companion object { + public companion object { /** * The identifier of addition. */ - const val PLUS_OPERATION: String = "+" + public const val PLUS_OPERATION: String = "+" /** * The identifier of subtraction (and negation). */ - const val MINUS_OPERATION: String = "-" - - const val NOT_OPERATION: String = "!" + public const val MINUS_OPERATION: String = "-" } } @@ -178,11 +177,11 @@ interface SpaceOperations : Algebra { * * @param T the type of element of this group. */ -interface Space : SpaceOperations { +public interface Space : SpaceOperations { /** * The neutral element of addition. */ - val zero: T + public val zero: T } /** @@ -191,14 +190,14 @@ interface Space : SpaceOperations { * * @param T the type of element of this semiring. */ -interface RingOperations : SpaceOperations { +public interface RingOperations : SpaceOperations { /** * Multiplies two elements. * * @param a the multiplier. * @param b the multiplicand. */ - fun multiply(a: T, b: T): T + public fun multiply(a: T, b: T): T /** * Multiplies this element by scalar. @@ -206,18 +205,18 @@ interface RingOperations : SpaceOperations { * @receiver the multiplier. * @param b the multiplicand. */ - operator fun T.times(b: T): T = multiply(this, b) + public operator fun T.times(b: T): T = multiply(this, b) override fun binaryOperation(operation: String, left: T, right: T): T = when (operation) { TIMES_OPERATION -> multiply(left, right) else -> super.binaryOperation(operation, left, right) } - companion object { + public companion object { /** * The identifier of multiplication. */ - const val TIMES_OPERATION: String = "*" + public const val TIMES_OPERATION: String = "*" } } @@ -227,11 +226,11 @@ interface RingOperations : SpaceOperations { * * @param T the type of element of this ring. */ -interface Ring : Space, RingOperations, NumericAlgebra { +public interface Ring : Space, RingOperations, NumericAlgebra { /** * neutral operation for multiplication */ - val one: T + public val one: T override fun number(value: Number): T = one * value.toDouble() @@ -255,7 +254,7 @@ interface Ring : Space, RingOperations, NumericAlgebra { * @receiver the addend. * @param b the augend. */ - operator fun T.plus(b: Number): T = this + number(b) + public operator fun T.plus(b: Number): T = this + number(b) /** * Addition of scalar and element. @@ -263,7 +262,7 @@ interface Ring : Space, RingOperations, NumericAlgebra { * @receiver the addend. * @param b the augend. */ - operator fun Number.plus(b: T): T = b + this + public operator fun Number.plus(b: T): T = b + this /** * Subtraction of element from number. @@ -272,7 +271,7 @@ interface Ring : Space, RingOperations, NumericAlgebra { * @param b the subtrahend. * @receiver the difference. */ - operator fun T.minus(b: Number): T = this - number(b) + public operator fun T.minus(b: Number): T = this - number(b) /** * Subtraction of number from element. @@ -281,7 +280,7 @@ interface Ring : Space, RingOperations, NumericAlgebra { * @param b the subtrahend. * @receiver the difference. */ - operator fun Number.minus(b: T): T = -b + this + public operator fun Number.minus(b: T): T = -b + this } /** @@ -290,7 +289,7 @@ interface Ring : Space, RingOperations, NumericAlgebra { * * @param T the type of element of this semifield. */ -interface FieldOperations : RingOperations { +public interface FieldOperations : RingOperations { /** * Division of two elements. * @@ -298,7 +297,7 @@ interface FieldOperations : RingOperations { * @param b the divisor. * @return the quotient. */ - fun divide(a: T, b: T): T + public fun divide(a: T, b: T): T /** * Division of two elements. @@ -307,18 +306,18 @@ interface FieldOperations : RingOperations { * @param b the divisor. * @return the quotient. */ - operator fun T.div(b: T): T = divide(this, b) + public operator fun T.div(b: T): T = divide(this, b) override fun binaryOperation(operation: String, left: T, right: T): T = when (operation) { DIV_OPERATION -> divide(left, right) else -> super.binaryOperation(operation, left, right) } - companion object { + public companion object { /** * The identifier of division. */ - const val DIV_OPERATION: String = "/" + public const val DIV_OPERATION: String = "/" } } @@ -328,7 +327,7 @@ interface FieldOperations : RingOperations { * * @param T the type of element of this semifield. */ -interface Field : Ring, FieldOperations { +public interface Field : Ring, FieldOperations { /** * Division of element by scalar. * @@ -336,5 +335,5 @@ interface Field : Ring, FieldOperations { * @param b the divisor. * @return the quotient. */ - operator fun Number.div(b: T): T = this * divide(one, b) + public operator fun Number.div(b: T): T = this * divide(one, b) } diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/operations/AlgebraElements.kt b/kmath-core/src/commonMain/kotlin/scientifik/kmath/operations/AlgebraElements.kt index 197897c14..4ed1be0ee 100644 --- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/operations/AlgebraElements.kt +++ b/kmath-core/src/commonMain/kotlin/scientifik/kmath/operations/AlgebraElements.kt @@ -5,11 +5,11 @@ package scientifik.kmath.operations * * @param C the type of mathematical context for this element. */ -interface MathElement { +public interface MathElement { /** * The context this element belongs to. */ - val context: C + public val context: C } /** @@ -18,16 +18,16 @@ interface MathElement { * @param T the type wrapped by this wrapper. * @param I the type of this wrapper. */ -interface MathWrapper { +public interface MathWrapper { /** * Unwraps [I] to [T]. */ - fun unwrap(): T + public fun unwrap(): T /** * Wraps [T] to [I]. */ - fun T.wrap(): I + public fun T.wrap(): I } /** @@ -37,14 +37,14 @@ interface MathWrapper { * @param I self type of the element. Needed for static type checking. * @param S the type of space. */ -interface SpaceElement, S : Space> : MathElement, MathWrapper { +public interface SpaceElement, S : Space> : MathElement, MathWrapper { /** * Adds element to this one. * * @param b the augend. * @return the sum. */ - operator fun plus(b: T): I = context.add(unwrap(), b).wrap() + public operator fun plus(b: T): I = context.add(unwrap(), b).wrap() /** * Subtracts element from this one. @@ -52,7 +52,7 @@ interface SpaceElement, S : Space> : MathElement * @param b the subtrahend. * @return the difference. */ - operator fun minus(b: T): I = context.add(unwrap(), context.multiply(b, -1.0)).wrap() + public operator fun minus(b: T): I = context.add(unwrap(), context.multiply(b, -1.0)).wrap() /** * Multiplies this element by number. @@ -60,7 +60,7 @@ interface SpaceElement, S : Space> : MathElement * @param k the multiplicand. * @return the product. */ - operator fun times(k: Number): I = context.multiply(unwrap(), k.toDouble()).wrap() + public operator fun times(k: Number): I = context.multiply(unwrap(), k.toDouble()).wrap() /** * Divides this element by number. @@ -68,7 +68,7 @@ interface SpaceElement, S : Space> : MathElement * @param k the divisor. * @return the quotient. */ - operator fun div(k: Number): I = context.multiply(unwrap(), 1.0 / k.toDouble()).wrap() + public operator fun div(k: Number): I = context.multiply(unwrap(), 1.0 / k.toDouble()).wrap() } /** @@ -78,14 +78,14 @@ interface SpaceElement, S : Space> : MathElement * @param I self type of the element. Needed for static type checking. * @param R the type of space. */ -interface RingElement, R : Ring> : SpaceElement { +public interface RingElement, R : Ring> : SpaceElement { /** * Multiplies this element by another one. * * @param b the multiplicand. * @return the product. */ - operator fun times(b: T): I = context.multiply(unwrap(), b).wrap() + public operator fun times(b: T): I = context.multiply(unwrap(), b).wrap() } /** @@ -95,7 +95,7 @@ interface RingElement, R : Ring> : SpaceElement, F : Field> : RingElement { +public interface FieldElement, F : Field> : RingElement { override val context: F /** @@ -104,5 +104,5 @@ interface FieldElement, F : Field> : RingElement * @param b the divisor. * @return the quotient. */ - operator fun div(b: T): I = context.divide(unwrap(), b).wrap() + public operator fun div(b: T): I = context.divide(unwrap(), b).wrap() } diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/operations/AlgebraExtensions.kt b/kmath-core/src/commonMain/kotlin/scientifik/kmath/operations/AlgebraExtensions.kt index 00b16dc98..b80e7582d 100644 --- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/operations/AlgebraExtensions.kt +++ b/kmath-core/src/commonMain/kotlin/scientifik/kmath/operations/AlgebraExtensions.kt @@ -7,7 +7,7 @@ package scientifik.kmath.operations * @param data the iterable to sum up. * @return the sum. */ -fun Space.sum(data: Iterable): T = data.fold(zero) { left, right -> add(left, right) } +public fun Space.sum(data: Iterable): T = data.fold(zero) { left, right -> add(left, right) } /** * Returns the sum of all elements in the sequence in this [Space]. @@ -16,7 +16,7 @@ fun Space.sum(data: Iterable): T = data.fold(zero) { left, right -> ad * @param data the sequence to sum up. * @return the sum. */ -fun Space.sum(data: Sequence): T = data.fold(zero) { left, right -> add(left, right) } +public fun Space.sum(data: Sequence): T = data.fold(zero) { left, right -> add(left, right) } /** * Returns an average value of elements in the iterable in this [Space]. @@ -25,7 +25,7 @@ fun Space.sum(data: Sequence): T = data.fold(zero) { left, right -> ad * @param data the iterable to find average. * @return the average value. */ -fun Space.average(data: Iterable): T = sum(data) / data.count() +public fun Space.average(data: Iterable): T = sum(data) / data.count() /** * Returns an average value of elements in the sequence in this [Space]. @@ -34,7 +34,7 @@ fun Space.average(data: Iterable): T = sum(data) / data.count() * @param data the sequence to find average. * @return the average value. */ -fun Space.average(data: Sequence): T = sum(data) / data.count() +public fun Space.average(data: Sequence): T = sum(data) / data.count() /** * Returns the sum of all elements in the iterable in provided space. @@ -43,7 +43,7 @@ fun Space.average(data: Sequence): T = sum(data) / data.count() * @param space the algebra that provides addition. * @return the sum. */ -fun Iterable.sumWith(space: Space): T = space.sum(this) +public fun Iterable.sumWith(space: Space): T = space.sum(this) /** * Returns the sum of all elements in the sequence in provided space. @@ -52,7 +52,7 @@ fun Iterable.sumWith(space: Space): T = space.sum(this) * @param space the algebra that provides addition. * @return the sum. */ -fun Sequence.sumWith(space: Space): T = space.sum(this) +public fun Sequence.sumWith(space: Space): T = space.sum(this) /** * Returns an average value of elements in the iterable in this [Space]. @@ -61,7 +61,7 @@ fun Sequence.sumWith(space: Space): T = space.sum(this) * @param space the algebra that provides addition and division. * @return the average value. */ -fun Iterable.averageWith(space: Space): T = space.average(this) +public fun Iterable.averageWith(space: Space): T = space.average(this) /** * Returns an average value of elements in the sequence in this [Space]. @@ -70,7 +70,7 @@ fun Iterable.averageWith(space: Space): T = space.average(this) * @param space the algebra that provides addition and division. * @return the average value. */ -fun Sequence.averageWith(space: Space): T = space.average(this) +public fun Sequence.averageWith(space: Space): T = space.average(this) //TODO optimized power operation @@ -82,7 +82,7 @@ fun Sequence.averageWith(space: Space): T = space.average(this) * @param power the exponent. * @return the base raised to the power. */ -fun Ring.power(arg: T, power: Int): T { +public fun Ring.power(arg: T, power: Int): T { require(power >= 0) { "The power can't be negative." } require(power != 0 || arg != zero) { "The $zero raised to $power is not defined." } if (power == 0) return one @@ -99,7 +99,7 @@ fun Ring.power(arg: T, power: Int): T { * @param power the exponent. * @return the base raised to the power. */ -fun Field.power(arg: T, power: Int): T { +public fun Field.power(arg: T, power: Int): T { require(power != 0 || arg != zero) { "The $zero raised to $power is not defined." } if (power == 0) return one if (power < 0) return one / (this as Ring).power(arg, -power) diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/operations/BigInt.kt b/kmath-core/src/commonMain/kotlin/scientifik/kmath/operations/BigInt.kt index 0eed7132e..56ec84f0b 100644 --- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/operations/BigInt.kt +++ b/kmath-core/src/commonMain/kotlin/scientifik/kmath/operations/BigInt.kt @@ -3,22 +3,21 @@ package scientifik.kmath.operations import scientifik.kmath.operations.BigInt.Companion.BASE import scientifik.kmath.operations.BigInt.Companion.BASE_SIZE import scientifik.kmath.structures.* -import kotlin.contracts.ExperimentalContracts import kotlin.contracts.contract import kotlin.math.log2 import kotlin.math.max import kotlin.math.min import kotlin.math.sign -typealias Magnitude = UIntArray -typealias TBase = ULong +public typealias Magnitude = UIntArray +public typealias TBase = ULong /** * Kotlin Multiplatform implementation of Big Integer numbers (KBigInteger). * * @author Robert Drynkin (https://github.com/robdrynkin) and Peter Klimai (https://github.com/pklimai) */ -object BigIntField : Field { +public object BigIntField : Field { override val zero: BigInt = BigInt.ZERO override val one: BigInt = BigInt.ONE @@ -29,113 +28,93 @@ object BigIntField : Field { override fun multiply(a: BigInt, b: BigInt): BigInt = a.times(b) - operator fun String.unaryPlus(): BigInt = this.parseBigInteger() ?: error("Can't parse $this as big integer") + public operator fun String.unaryPlus(): BigInt = this.parseBigInteger() ?: error("Can't parse $this as big integer") - operator fun String.unaryMinus(): BigInt = + public operator fun String.unaryMinus(): BigInt = -(this.parseBigInteger() ?: error("Can't parse $this as big integer")) override fun divide(a: BigInt, b: BigInt): BigInt = a.div(b) } -class BigInt internal constructor( +public class BigInt internal constructor( private val sign: Byte, private val magnitude: Magnitude ) : Comparable { - override fun compareTo(other: BigInt): Int { - return when { - (this.sign == 0.toByte()) and (other.sign == 0.toByte()) -> 0 - this.sign < other.sign -> -1 - this.sign > other.sign -> 1 - else -> this.sign * compareMagnitudes(this.magnitude, other.magnitude) + override fun compareTo(other: BigInt): Int = when { + (this.sign == 0.toByte()) and (other.sign == 0.toByte()) -> 0 + this.sign < other.sign -> -1 + this.sign > other.sign -> 1 + else -> this.sign * compareMagnitudes(this.magnitude, other.magnitude) + } + + override fun equals(other: Any?): Boolean = + if (other is BigInt) compareTo(other) == 0 else error("Can't compare KBigInteger to a different type") + + override fun hashCode(): Int = magnitude.hashCode() + sign + + public fun abs(): BigInt = if (sign == 0.toByte()) this else BigInt(1, magnitude) + + public operator fun unaryMinus(): BigInt = + if (this.sign == 0.toByte()) this else BigInt((-this.sign).toByte(), this.magnitude) + + public operator fun plus(b: BigInt): BigInt = when { + b.sign == 0.toByte() -> this + sign == 0.toByte() -> b + this == -b -> ZERO + sign == b.sign -> BigInt(sign, addMagnitudes(magnitude, b.magnitude)) + + else -> { + val comp = compareMagnitudes(magnitude, b.magnitude) + + if (comp == 1) + BigInt(sign, subtractMagnitudes(magnitude, b.magnitude)) + else + BigInt((-sign).toByte(), subtractMagnitudes(b.magnitude, magnitude)) } } - override fun equals(other: Any?): Boolean { - if (other is BigInt) { - return this.compareTo(other) == 0 - } else error("Can't compare KBigInteger to a different type") - } + public operator fun minus(b: BigInt): BigInt = this + (-b) - override fun hashCode(): Int { - return magnitude.hashCode() + this.sign - } - - fun abs(): BigInt = if (sign == 0.toByte()) this else BigInt(1, magnitude) - - operator fun unaryMinus(): BigInt { - return if (this.sign == 0.toByte()) this else BigInt((-this.sign).toByte(), this.magnitude) - } - - operator fun plus(b: BigInt): BigInt { - return when { - b.sign == 0.toByte() -> this - this.sign == 0.toByte() -> b - this == -b -> ZERO - this.sign == b.sign -> BigInt(this.sign, addMagnitudes(this.magnitude, b.magnitude)) - else -> { - val comp: Int = compareMagnitudes(this.magnitude, b.magnitude) - - if (comp == 1) { - BigInt(this.sign, subtractMagnitudes(this.magnitude, b.magnitude)) - } else { - BigInt((-this.sign).toByte(), subtractMagnitudes(b.magnitude, this.magnitude)) - } - } - } - } - - operator fun minus(b: BigInt): BigInt { - return this + (-b) - } - - operator fun times(b: BigInt): BigInt { - return when { - this.sign == 0.toByte() -> ZERO - b.sign == 0.toByte() -> ZERO + public operator fun times(b: BigInt): BigInt = when { + this.sign == 0.toByte() -> ZERO + b.sign == 0.toByte() -> ZERO // TODO: Karatsuba - else -> BigInt((this.sign * b.sign).toByte(), multiplyMagnitudes(this.magnitude, b.magnitude)) - } + else -> BigInt((this.sign * b.sign).toByte(), multiplyMagnitudes(this.magnitude, b.magnitude)) } - operator fun times(other: UInt): BigInt { - return when { - this.sign == 0.toByte() -> ZERO - other == 0U -> ZERO - else -> BigInt(this.sign, multiplyMagnitudeByUInt(this.magnitude, other)) - } + public operator fun times(other: UInt): BigInt = when { + sign == 0.toByte() -> ZERO + other == 0U -> ZERO + else -> BigInt(sign, multiplyMagnitudeByUInt(magnitude, other)) } - operator fun times(other: Int): BigInt { - return if (other > 0) - this * kotlin.math.abs(other).toUInt() - else - -this * kotlin.math.abs(other).toUInt() - } + public operator fun times(other: Int): BigInt = if (other > 0) + this * kotlin.math.abs(other).toUInt() + else + -this * kotlin.math.abs(other).toUInt() - operator fun div(other: UInt): BigInt { - return BigInt(this.sign, divideMagnitudeByUInt(this.magnitude, other)) - } + public operator fun div(other: UInt): BigInt = BigInt(this.sign, divideMagnitudeByUInt(this.magnitude, other)) - operator fun div(other: Int): BigInt { - return BigInt( - (this.sign * other.sign).toByte(), - divideMagnitudeByUInt(this.magnitude, kotlin.math.abs(other).toUInt()) - ) - } + public operator fun div(other: Int): BigInt = BigInt( + (this.sign * other.sign).toByte(), + divideMagnitudeByUInt(this.magnitude, kotlin.math.abs(other).toUInt()) + ) private fun division(other: BigInt): Pair { // Long division algorithm: // https://en.wikipedia.org/wiki/Division_algorithm#Integer_division_(unsigned)_with_remainder // TODO: Implement more effective algorithm - var q: BigInt = ZERO - var r: BigInt = ZERO + var q = ZERO + var r = ZERO val bitSize = (BASE_SIZE * (this.magnitude.size - 1) + log2(this.magnitude.lastOrNull()?.toFloat() ?: 0f + 1)).toInt() + for (i in bitSize downTo 0) { r = r shl 1 r = r or ((abs(this) shr i) and ONE) + if (r >= abs(other)) { r -= abs(other) q += (ONE shl i) @@ -145,99 +124,84 @@ class BigInt internal constructor( return Pair(BigInt((this.sign * other.sign).toByte(), q.magnitude), r) } - operator fun div(other: BigInt): BigInt { - return this.division(other).first - } + public operator fun div(other: BigInt): BigInt = this.division(other).first - infix fun shl(i: Int): BigInt { + public infix fun shl(i: Int): BigInt { if (this == ZERO) return ZERO if (i == 0) return this - val fullShifts = i / BASE_SIZE + 1 val relShift = i % BASE_SIZE val shiftLeft = { x: UInt -> if (relShift >= 32) 0U else x shl relShift } val shiftRight = { x: UInt -> if (BASE_SIZE - relShift >= 32) 0U else x shr (BASE_SIZE - relShift) } - - val newMagnitude: Magnitude = Magnitude(this.magnitude.size + fullShifts) + val newMagnitude = Magnitude(this.magnitude.size + fullShifts) for (j in this.magnitude.indices) { newMagnitude[j + fullShifts - 1] = shiftLeft(this.magnitude[j]) - if (j != 0) { + + if (j != 0) newMagnitude[j + fullShifts - 1] = newMagnitude[j + fullShifts - 1] or shiftRight(this.magnitude[j - 1]) - } } newMagnitude[this.magnitude.size + fullShifts - 1] = shiftRight(this.magnitude.last()) - return BigInt(this.sign, stripLeadingZeros(newMagnitude)) } - infix fun shr(i: Int): BigInt { + public infix fun shr(i: Int): BigInt { if (this == ZERO) return ZERO if (i == 0) return this - val fullShifts = i / BASE_SIZE val relShift = i % BASE_SIZE val shiftRight = { x: UInt -> if (relShift >= 32) 0U else x shr relShift } val shiftLeft = { x: UInt -> if (BASE_SIZE - relShift >= 32) 0U else x shl (BASE_SIZE - relShift) } - if (this.magnitude.size - fullShifts <= 0) { - return ZERO - } + if (this.magnitude.size - fullShifts <= 0) return ZERO val newMagnitude: Magnitude = Magnitude(this.magnitude.size - fullShifts) for (j in fullShifts until this.magnitude.size) { newMagnitude[j - fullShifts] = shiftRight(this.magnitude[j]) - if (j != this.magnitude.size - 1) { + + if (j != this.magnitude.size - 1) newMagnitude[j - fullShifts] = newMagnitude[j - fullShifts] or shiftLeft(this.magnitude[j + 1]) - } } return BigInt(this.sign, stripLeadingZeros(newMagnitude)) } - infix fun or(other: BigInt): BigInt { + public infix fun or(other: BigInt): BigInt { if (this == ZERO) return other if (other == ZERO) return this val resSize = max(this.magnitude.size, other.magnitude.size) val newMagnitude: Magnitude = Magnitude(resSize) + for (i in 0 until resSize) { - if (i < this.magnitude.size) { - newMagnitude[i] = newMagnitude[i] or this.magnitude[i] - } - if (i < other.magnitude.size) { - newMagnitude[i] = newMagnitude[i] or other.magnitude[i] - } + if (i < this.magnitude.size) newMagnitude[i] = newMagnitude[i] or this.magnitude[i] + if (i < other.magnitude.size) newMagnitude[i] = newMagnitude[i] or other.magnitude[i] } + return BigInt(1, stripLeadingZeros(newMagnitude)) } - infix fun and(other: BigInt): BigInt { + public infix fun and(other: BigInt): BigInt { if ((this == ZERO) or (other == ZERO)) return ZERO val resSize = min(this.magnitude.size, other.magnitude.size) val newMagnitude: Magnitude = Magnitude(resSize) - for (i in 0 until resSize) { - newMagnitude[i] = this.magnitude[i] and other.magnitude[i] - } + for (i in 0 until resSize) newMagnitude[i] = this.magnitude[i] and other.magnitude[i] return BigInt(1, stripLeadingZeros(newMagnitude)) } - operator fun rem(other: Int): Int { + public operator fun rem(other: Int): Int { val res = this - (this / other) * other return if (res == ZERO) 0 else res.sign * res.magnitude[0].toInt() } - operator fun rem(other: BigInt): BigInt { - return this - (this / other) * other - } + public operator fun rem(other: BigInt): BigInt = this - (this / other) * other - fun modPow(exponent: BigInt, m: BigInt): BigInt { - return when { - exponent == ZERO -> ONE - exponent % 2 == 1 -> (this * modPow(exponent - ONE, m)) % m - else -> { - val sqRoot = modPow(exponent / 2, m) - (sqRoot * sqRoot) % m - } + public fun modPow(exponent: BigInt, m: BigInt): BigInt = when { + exponent == ZERO -> ONE + exponent % 2 == 1 -> (this * modPow(exponent - ONE, m)) % m + + else -> { + val sqRoot = modPow(exponent / 2, m) + (sqRoot * sqRoot) % m } } @@ -261,11 +225,11 @@ class BigInt internal constructor( return res } - companion object { - const val BASE: ULong = 0xffffffffUL - const val BASE_SIZE: Int = 32 - val ZERO: BigInt = BigInt(0, uintArrayOf()) - val ONE: BigInt = BigInt(1, uintArrayOf(1u)) + public companion object { + public const val BASE: ULong = 0xffffffffUL + public const val BASE_SIZE: Int = 32 + public val ZERO: BigInt = BigInt(0, uintArrayOf()) + public val ONE: BigInt = BigInt(1, uintArrayOf(1u)) private val hexMapping: HashMap = hashMapOf( 0U to "0", 1U to "1", 2U to "2", 3U to "3", @@ -349,11 +313,13 @@ class BigInt internal constructor( for (i in mag1.indices) { var carry: ULong = 0UL + 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() carry = cur shr BASE_SIZE } + result[i + mag2.size] = (carry and BASE).toUInt() } @@ -361,15 +327,16 @@ class BigInt internal constructor( } private fun divideMagnitudeByUInt(mag: Magnitude, x: UInt): Magnitude { - val resultLength: Int = mag.size + val resultLength = mag.size val result = Magnitude(resultLength) - var carry: ULong = 0UL + var carry = 0uL for (i in mag.size - 1 downTo 0) { val cur: ULong = mag[i].toULong() + (carry shl BASE_SIZE) result[i] = (cur / x).toUInt() carry = cur % x } + return stripLeadingZeros(result) } @@ -377,31 +344,29 @@ class BigInt internal constructor( } - private fun stripLeadingZeros(mag: Magnitude): Magnitude { - if (mag.isEmpty() || mag.last() != 0U) { - return mag - } - var resSize: Int = mag.size - 1 + if (mag.isEmpty() || mag.last() != 0U) return mag + var resSize = mag.size - 1 + while (mag[resSize] == 0U) { - if (resSize == 0) - break + if (resSize == 0) break resSize -= 1 } + return mag.sliceArray(IntRange(0, resSize)) } -fun abs(x: BigInt): BigInt = x.abs() +public fun abs(x: BigInt): BigInt = x.abs() /** * Convert this [Int] to [BigInt] */ -fun Int.toBigInt(): BigInt = BigInt(sign.toByte(), uintArrayOf(kotlin.math.abs(this).toUInt())) +public fun Int.toBigInt(): BigInt = BigInt(sign.toByte(), uintArrayOf(kotlin.math.abs(this).toUInt())) /** * Convert this [Long] to [BigInt] */ -fun Long.toBigInt(): BigInt = BigInt( +public fun Long.toBigInt(): BigInt = BigInt( sign.toByte(), stripLeadingZeros( uintArrayOf( (kotlin.math.abs(this).toULong() and BASE).toUInt(), @@ -413,13 +378,14 @@ fun Long.toBigInt(): BigInt = BigInt( /** * Convert UInt to [BigInt] */ -fun UInt.toBigInt(): BigInt = BigInt(1, uintArrayOf(this)) +public fun UInt.toBigInt(): BigInt = BigInt(1, uintArrayOf(this)) /** * Convert ULong to [BigInt] */ -fun ULong.toBigInt(): BigInt = BigInt( +public fun ULong.toBigInt(): BigInt = BigInt( 1, + stripLeadingZeros( uintArrayOf( (this and BASE).toUInt(), @@ -431,12 +397,12 @@ fun ULong.toBigInt(): BigInt = BigInt( /** * Create a [BigInt] with this array of magnitudes with protective copy */ -fun UIntArray.toBigInt(sign: Byte): BigInt { +public fun UIntArray.toBigInt(sign: Byte): BigInt { require(sign != 0.toByte() || !isNotEmpty()) return BigInt(sign, copyOf()) } -val hexChToInt: MutableMap = hashMapOf( +private val hexChToInt: MutableMap = hashMapOf( '0' to 0, '1' to 1, '2' to 2, '3' to 3, '4' to 4, '5' to 5, '6' to 6, '7' to 7, '8' to 8, '9' to 9, 'A' to 10, 'B' to 11, @@ -446,9 +412,10 @@ val hexChToInt: MutableMap = hashMapOf( /** * Returns null if a valid number can not be read from a string */ -fun String.parseBigInteger(): BigInt? { +public fun String.parseBigInteger(): BigInt? { val sign: Int val sPositive: String + when { this[0] == '+' -> { sign = +1 @@ -463,43 +430,46 @@ fun String.parseBigInteger(): BigInt? { sign = +1 } } + var res = BigInt.ZERO var digitValue = BigInt.ONE val sPositiveUpper = sPositive.toUpperCase() + if (sPositiveUpper.startsWith("0X")) { // hex representation val sHex = sPositiveUpper.substring(2) + for (ch in sHex.reversed()) { if (ch == '_') continue res += digitValue * (hexChToInt[ch] ?: return null) digitValue *= 16.toBigInt() } - } else { // decimal representation - for (ch in sPositiveUpper.reversed()) { - if (ch == '_') continue - if (ch !in '0'..'9') { - return null - } - res += digitValue * (ch.toInt() - '0'.toInt()) - digitValue *= 10.toBigInt() + } else for (ch in sPositiveUpper.reversed()) { + // decimal representation + if (ch == '_') continue + if (ch !in '0'..'9') { + return null } + res += digitValue * (ch.toInt() - '0'.toInt()) + digitValue *= 10.toBigInt() } + return res * sign } -inline fun Buffer.Companion.bigInt(size: Int, initializer: (Int) -> BigInt): Buffer { +public inline fun Buffer.Companion.bigInt(size: Int, initializer: (Int) -> BigInt): Buffer { contract { callsInPlace(initializer) } return boxing(size, initializer) } -inline fun MutableBuffer.Companion.bigInt(size: Int, initializer: (Int) -> BigInt): MutableBuffer { +public inline fun MutableBuffer.Companion.bigInt(size: Int, initializer: (Int) -> BigInt): MutableBuffer { contract { callsInPlace(initializer) } return boxing(size, initializer) } -fun NDAlgebra.Companion.bigInt(vararg shape: Int): BoxingNDRing = +public fun NDAlgebra.Companion.bigInt(vararg shape: Int): BoxingNDRing = BoxingNDRing(shape, BigIntField, Buffer.Companion::bigInt) -fun NDElement.Companion.bigInt( +public fun NDElement.Companion.bigInt( vararg shape: Int, initializer: BigIntField.(IntArray) -> BigInt ): BufferedNDRingElement = NDAlgebra.bigInt(*shape).produce(initializer) diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/operations/Complex.kt b/kmath-core/src/commonMain/kotlin/scientifik/kmath/operations/Complex.kt index dcfd97d1a..facc2ad26 100644 --- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/operations/Complex.kt +++ b/kmath-core/src/commonMain/kotlin/scientifik/kmath/operations/Complex.kt @@ -6,20 +6,19 @@ import scientifik.kmath.structures.MutableBuffer import scientifik.memory.MemoryReader import scientifik.memory.MemorySpec import scientifik.memory.MemoryWriter -import kotlin.contracts.ExperimentalContracts import kotlin.contracts.contract import kotlin.math.* /** * This complex's conjugate. */ -val Complex.conjugate: Complex +public val Complex.conjugate: Complex get() = Complex(re, -im) /** * This complex's reciprocal. */ -val Complex.reciprocal: Complex +public val Complex.reciprocal: Complex get() { val scale = re * re + im * im return Complex(re / scale, -im / scale) @@ -28,13 +27,13 @@ val Complex.reciprocal: Complex /** * Absolute value of complex number. */ -val Complex.r: Double +public val Complex.r: Double get() = sqrt(re * re + im * im) /** * An angle between vector represented by complex number and X axis. */ -val Complex.theta: Double +public val Complex.theta: Double get() = atan(im / re) private val PI_DIV_2 = Complex(PI / 2, 0) @@ -42,14 +41,14 @@ private val PI_DIV_2 = Complex(PI / 2, 0) /** * A field of [Complex]. */ -object ComplexField : ExtendedField, Norm { +public object ComplexField : ExtendedField, Norm { override val zero: Complex = 0.0.toComplex() override val one: Complex = 1.0.toComplex() /** * The imaginary unit. */ - val i: Complex = Complex(0.0, 1.0) + public val i: Complex = Complex(0.0, 1.0) override fun add(a: Complex, b: Complex): Complex = Complex(a.re + b.re, a.im + b.im) @@ -117,7 +116,7 @@ object ComplexField : ExtendedField, Norm { * @param c the augend. * @return the sum. */ - operator fun Double.plus(c: Complex): Complex = add(this.toComplex(), c) + public operator fun Double.plus(c: Complex): Complex = add(this.toComplex(), c) /** * Subtracts complex number from real one. @@ -126,7 +125,7 @@ object ComplexField : ExtendedField, Norm { * @param c the subtrahend. * @return the difference. */ - operator fun Double.minus(c: Complex): Complex = add(this.toComplex(), -c) + public operator fun Double.minus(c: Complex): Complex = add(this.toComplex(), -c) /** * Adds real number to complex one. @@ -135,7 +134,7 @@ object ComplexField : ExtendedField, Norm { * @param d the augend. * @return the sum. */ - operator fun Complex.plus(d: Double): Complex = d + this + public operator fun Complex.plus(d: Double): Complex = d + this /** * Subtracts real number from complex one. @@ -144,7 +143,7 @@ object ComplexField : ExtendedField, Norm { * @param d the subtrahend. * @return the difference. */ - operator fun Complex.minus(d: Double): Complex = add(this, -d.toComplex()) + public operator fun Complex.minus(d: Double): Complex = add(this, -d.toComplex()) /** * Multiplies real number by complex one. @@ -153,7 +152,7 @@ object ComplexField : ExtendedField, Norm { * @param c the multiplicand. * @receiver the product. */ - operator fun Double.times(c: Complex): Complex = Complex(c.re * this, c.im * this) + public operator fun Double.times(c: Complex): Complex = Complex(c.re * this, c.im * this) override fun norm(arg: Complex): Complex = sqrt(arg.conjugate * arg) @@ -166,8 +165,8 @@ object ComplexField : ExtendedField, Norm { * @property re The real part. * @property im The imaginary part. */ -data class Complex(val re: Double, val im: Double) : FieldElement, Comparable { - constructor(re: Number, im: Number) : this(re.toDouble(), im.toDouble()) +public data class Complex(val re: Double, val im: Double) : FieldElement, Comparable { + public constructor(re: Number, im: Number) : this(re.toDouble(), im.toDouble()) override val context: ComplexField get() = ComplexField @@ -177,7 +176,7 @@ data class Complex(val re: Double, val im: Double) : FieldElement { + public companion object : MemorySpec { override val objectSize: Int = 16 override fun MemoryReader.read(offset: Int): Complex = @@ -196,14 +195,14 @@ data class Complex(val re: Double, val im: Double) : FieldElement Complex): Buffer { +public inline fun Buffer.Companion.complex(size: Int, crossinline init: (Int) -> Complex): Buffer { contract { callsInPlace(init) } return MemoryBuffer.create(Complex, size, init) } -inline fun MutableBuffer.Companion.complex(size: Int, crossinline init: (Int) -> Complex): Buffer { +public inline fun MutableBuffer.Companion.complex(size: Int, crossinline init: (Int) -> Complex): Buffer { contract { callsInPlace(init) } return MemoryBuffer.create(Complex, size, init) } diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/operations/NumberAlgebra.kt b/kmath-core/src/commonMain/kotlin/scientifik/kmath/operations/NumberAlgebra.kt index 0735a96da..54460a0da 100644 --- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/operations/NumberAlgebra.kt +++ b/kmath-core/src/commonMain/kotlin/scientifik/kmath/operations/NumberAlgebra.kt @@ -7,7 +7,7 @@ import kotlin.math.pow as kpow /** * Advanced Number-like semifield that implements basic operations. */ -interface ExtendedFieldOperations : +public interface ExtendedFieldOperations : FieldOperations, TrigonometricOperations, HyperbolicOperations, @@ -41,7 +41,7 @@ interface ExtendedFieldOperations : /** * Advanced Number-like field that implements basic operations. */ -interface ExtendedField : ExtendedFieldOperations, Field { +public interface ExtendedField : ExtendedFieldOperations, Field { override fun sinh(arg: T): T = (exp(arg) - exp(-arg)) / 2 override fun cosh(arg: T): T = (exp(arg) + exp(-arg)) / 2 override fun tanh(arg: T): T = (exp(arg) - exp(-arg)) / (exp(-arg) + exp(arg)) diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/operations/OptionalOperations.kt b/kmath-core/src/commonMain/kotlin/scientifik/kmath/operations/OptionalOperations.kt index 1dac649aa..101f62293 100644 --- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/operations/OptionalOperations.kt +++ b/kmath-core/src/commonMain/kotlin/scientifik/kmath/operations/OptionalOperations.kt @@ -5,230 +5,230 @@ package scientifik.kmath.operations * * @param T the type of element of this structure. */ -interface TrigonometricOperations : Algebra { +public interface TrigonometricOperations : Algebra { /** * Computes the sine of [arg]. */ - fun sin(arg: T): T + public fun sin(arg: T): T /** * Computes the cosine of [arg]. */ - fun cos(arg: T): T + public fun cos(arg: T): T /** * Computes the tangent of [arg]. */ - fun tan(arg: T): T + public fun tan(arg: T): T /** * Computes the inverse sine of [arg]. */ - fun asin(arg: T): T + public fun asin(arg: T): T /** * Computes the inverse cosine of [arg]. */ - fun acos(arg: T): T + public fun acos(arg: T): T /** * Computes the inverse tangent of [arg]. */ - fun atan(arg: T): T + public fun atan(arg: T): T - companion object { + public companion object { /** * The identifier of sine. */ - const val SIN_OPERATION: String = "sin" + public const val SIN_OPERATION: String = "sin" /** * The identifier of cosine. */ - const val COS_OPERATION: String = "cos" + public const val COS_OPERATION: String = "cos" /** * The identifier of tangent. */ - const val TAN_OPERATION: String = "tan" + public const val TAN_OPERATION: String = "tan" /** * The identifier of inverse sine. */ - const val ASIN_OPERATION: String = "asin" + public const val ASIN_OPERATION: String = "asin" /** * The identifier of inverse cosine. */ - const val ACOS_OPERATION: String = "acos" + public const val ACOS_OPERATION: String = "acos" /** * The identifier of inverse tangent. */ - const val ATAN_OPERATION: String = "atan" + public const val ATAN_OPERATION: String = "atan" } } /** * Computes the sine of [arg]. */ -fun >> sin(arg: T): T = arg.context.sin(arg) +public fun >> sin(arg: T): T = arg.context.sin(arg) /** * Computes the cosine of [arg]. */ -fun >> cos(arg: T): T = arg.context.cos(arg) +public fun >> cos(arg: T): T = arg.context.cos(arg) /** * Computes the tangent of [arg]. */ -fun >> tan(arg: T): T = arg.context.tan(arg) +public fun >> tan(arg: T): T = arg.context.tan(arg) /** * Computes the inverse sine of [arg]. */ -fun >> asin(arg: T): T = arg.context.asin(arg) +public fun >> asin(arg: T): T = arg.context.asin(arg) /** * Computes the inverse cosine of [arg]. */ -fun >> acos(arg: T): T = arg.context.acos(arg) +public fun >> acos(arg: T): T = arg.context.acos(arg) /** * Computes the inverse tangent of [arg]. */ -fun >> atan(arg: T): T = arg.context.atan(arg) +public fun >> atan(arg: T): T = arg.context.atan(arg) /** * A container for hyperbolic trigonometric operations for specific type. * * @param T the type of element of this structure. */ -interface HyperbolicOperations : Algebra { +public interface HyperbolicOperations : Algebra { /** * Computes the hyperbolic sine of [arg]. */ - fun sinh(arg: T): T + public fun sinh(arg: T): T /** * Computes the hyperbolic cosine of [arg]. */ - fun cosh(arg: T): T + public fun cosh(arg: T): T /** * Computes the hyperbolic tangent of [arg]. */ - fun tanh(arg: T): T + public fun tanh(arg: T): T /** * Computes the inverse hyperbolic sine of [arg]. */ - fun asinh(arg: T): T + public fun asinh(arg: T): T /** * Computes the inverse hyperbolic cosine of [arg]. */ - fun acosh(arg: T): T + public fun acosh(arg: T): T /** * Computes the inverse hyperbolic tangent of [arg]. */ - fun atanh(arg: T): T + public fun atanh(arg: T): T - companion object { + public companion object { /** * The identifier of hyperbolic sine. */ - const val SINH_OPERATION: String = "sinh" + public const val SINH_OPERATION: String = "sinh" /** * The identifier of hyperbolic cosine. */ - const val COSH_OPERATION: String = "cosh" + public const val COSH_OPERATION: String = "cosh" /** * The identifier of hyperbolic tangent. */ - const val TANH_OPERATION: String = "tanh" + public const val TANH_OPERATION: String = "tanh" /** * The identifier of inverse hyperbolic sine. */ - const val ASINH_OPERATION: String = "asinh" + public const val ASINH_OPERATION: String = "asinh" /** * The identifier of inverse hyperbolic cosine. */ - const val ACOSH_OPERATION: String = "acosh" + public const val ACOSH_OPERATION: String = "acosh" /** * The identifier of inverse hyperbolic tangent. */ - const val ATANH_OPERATION: String = "atanh" + public const val ATANH_OPERATION: String = "atanh" } } /** * Computes the hyperbolic sine of [arg]. */ -fun >> sinh(arg: T): T = arg.context.sinh(arg) +public fun >> sinh(arg: T): T = arg.context.sinh(arg) /** * Computes the hyperbolic cosine of [arg]. */ -fun >> cosh(arg: T): T = arg.context.cosh(arg) +public fun >> cosh(arg: T): T = arg.context.cosh(arg) /** * Computes the hyperbolic tangent of [arg]. */ -fun >> tanh(arg: T): T = arg.context.tanh(arg) +public fun >> tanh(arg: T): T = arg.context.tanh(arg) /** * Computes the inverse hyperbolic sine of [arg]. */ -fun >> asinh(arg: T): T = arg.context.asinh(arg) +public fun >> asinh(arg: T): T = arg.context.asinh(arg) /** * Computes the inverse hyperbolic cosine of [arg]. */ -fun >> acosh(arg: T): T = arg.context.acosh(arg) +public fun >> acosh(arg: T): T = arg.context.acosh(arg) /** * Computes the inverse hyperbolic tangent of [arg]. */ -fun >> atanh(arg: T): T = arg.context.atanh(arg) +public fun >> atanh(arg: T): T = arg.context.atanh(arg) /** * A context extension to include power operations based on exponentiation. * * @param T the type of element of this structure. */ -interface PowerOperations : Algebra { +public interface PowerOperations : Algebra { /** * Raises [arg] to the power [pow]. */ - fun power(arg: T, pow: Number): T + public fun power(arg: T, pow: Number): T /** * Computes the square root of the value [arg]. */ - fun sqrt(arg: T): T = power(arg, 0.5) + public fun sqrt(arg: T): T = power(arg, 0.5) /** * Raises this value to the power [pow]. */ - infix fun T.pow(pow: Number): T = power(this, pow) + public infix fun T.pow(pow: Number): T = power(this, pow) - companion object { + public companion object { /** * The identifier of exponentiation. */ - const val POW_OPERATION: String = "pow" + public const val POW_OPERATION: String = "pow" /** * The identifier of square root. */ - const val SQRT_OPERATION: String = "sqrt" + public const val SQRT_OPERATION: String = "sqrt" } } @@ -239,56 +239,56 @@ interface PowerOperations : Algebra { * @param power the exponent. * @return the base raised to the power. */ -infix fun >> T.pow(power: Double): T = context.power(this, power) +public infix fun >> T.pow(power: Double): T = context.power(this, power) /** * Computes the square root of the value [arg]. */ -fun >> sqrt(arg: T): T = arg pow 0.5 +public fun >> sqrt(arg: T): T = arg pow 0.5 /** * Computes the square of the value [arg]. */ -fun >> sqr(arg: T): T = arg pow 2.0 +public fun >> sqr(arg: T): T = arg pow 2.0 /** * A container for operations related to `exp` and `ln` functions. * * @param T the type of element of this structure. */ -interface ExponentialOperations : Algebra { +public interface ExponentialOperations : Algebra { /** * Computes Euler's number `e` raised to the power of the value [arg]. */ - fun exp(arg: T): T + public fun exp(arg: T): T /** * Computes the natural logarithm (base `e`) of the value [arg]. */ - fun ln(arg: T): T + public fun ln(arg: T): T - companion object { + public companion object { /** * The identifier of exponential function. */ - const val EXP_OPERATION: String = "exp" + public const val EXP_OPERATION: String = "exp" /** * The identifier of natural logarithm. */ - const val LN_OPERATION: String = "ln" + public const val LN_OPERATION: String = "ln" } } /** * The identifier of exponential function. */ -fun >> exp(arg: T): T = arg.context.exp(arg) +public fun >> exp(arg: T): T = arg.context.exp(arg) /** * The identifier of natural logarithm. */ -fun >> ln(arg: T): T = arg.context.ln(arg) +public fun >> ln(arg: T): T = arg.context.ln(arg) /** * A container for norm functional on element. @@ -296,14 +296,14 @@ fun >> ln(arg: T): T = arg.context. * @param T the type of element having norm defined. * @param R the type of norm. */ -interface Norm { +public interface Norm { /** * Computes the norm of [arg] (i.e. absolute value or vector length). */ - fun norm(arg: T): R + public fun norm(arg: T): R } /** * Computes the norm of [arg] (i.e. absolute value or vector length). */ -fun >, R> norm(arg: T): R = arg.context.norm(arg) +public fun >, R> norm(arg: T): R = arg.context.norm(arg) diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/BoxingNDField.kt b/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/BoxingNDField.kt index be71645d1..5950532e1 100644 --- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/BoxingNDField.kt +++ b/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/BoxingNDField.kt @@ -3,16 +3,16 @@ package scientifik.kmath.structures import scientifik.kmath.operations.Field import scientifik.kmath.operations.FieldElement -class BoxingNDField>( +public class BoxingNDField>( override val shape: IntArray, override val elementContext: F, - val bufferFactory: BufferFactory + public val bufferFactory: BufferFactory ) : BufferedNDField { override val zero: BufferedNDFieldElement by lazy { produce { zero } } override val one: BufferedNDFieldElement by lazy { produce { one } } override val strides: Strides = DefaultStrides(shape) - fun buildBuffer(size: Int, initializer: (Int) -> T): Buffer = + public fun buildBuffer(size: Int, initializer: (Int) -> T): Buffer = bufferFactory(size, initializer) override fun check(vararg elements: NDBuffer) { @@ -70,7 +70,7 @@ class BoxingNDField>( BufferedNDFieldElement(this@BoxingNDField, buffer) } -inline fun , R> F.nd( +public inline fun , R> F.nd( noinline bufferFactory: BufferFactory, vararg shape: Int, action: NDField.() -> R diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/BoxingNDRing.kt b/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/BoxingNDRing.kt index 91b945e79..9e44e38aa 100644 --- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/BoxingNDRing.kt +++ b/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/BoxingNDRing.kt @@ -3,16 +3,16 @@ package scientifik.kmath.structures import scientifik.kmath.operations.Ring import scientifik.kmath.operations.RingElement -class BoxingNDRing>( +public class BoxingNDRing>( override val shape: IntArray, override val elementContext: R, - val bufferFactory: BufferFactory + public val bufferFactory: BufferFactory ) : BufferedNDRing { override val strides: Strides = DefaultStrides(shape) override val zero: BufferedNDRingElement by lazy { produce { zero } } override val one: BufferedNDRingElement by lazy { produce { one } } - fun buildBuffer(size: Int, initializer: (Int) -> T): Buffer = bufferFactory(size, initializer) + 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" } diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/BufferAccessor2D.kt b/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/BufferAccessor2D.kt index 2c3d69094..0a02fdc8f 100644 --- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/BufferAccessor2D.kt +++ b/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/BufferAccessor2D.kt @@ -5,24 +5,23 @@ import kotlin.reflect.KClass /** * A context that allows to operate on a [MutableBuffer] as on 2d array */ -class BufferAccessor2D(val type: KClass, val rowNum: Int, val colNum: Int) { - operator fun Buffer.get(i: Int, j: Int): T = get(i + colNum * j) +public class BufferAccessor2D(public val type: KClass, public val rowNum: Int, public val colNum: Int) { + public operator fun Buffer.get(i: Int, j: Int): T = get(i + colNum * j) - operator fun MutableBuffer.set(i: Int, j: Int, value: T) { + public operator fun MutableBuffer.set(i: Int, j: Int, value: T) { set(i + colNum * j, value) } - inline fun create(init: (i: Int, j: Int) -> T): MutableBuffer = + public inline fun create(init: (i: Int, j: Int) -> T): MutableBuffer = MutableBuffer.auto(type, rowNum * colNum) { offset -> init(offset / colNum, offset % colNum) } - fun create(mat: Structure2D): MutableBuffer = create { i, j -> mat[i, j] } + public fun create(mat: Structure2D): MutableBuffer = create { i, j -> mat[i, j] } //TODO optimize wrapper - fun MutableBuffer.collect(): Structure2D = + public fun MutableBuffer.collect(): Structure2D = NDStructure.auto(type, rowNum, colNum) { (i, j) -> get(i, j) }.as2D() - - inner class Row(val buffer: MutableBuffer, val rowIndex: Int) : MutableBuffer { + public inner class Row(public val buffer: MutableBuffer, public val rowIndex: Int) : MutableBuffer { override val size: Int get() = colNum override operator fun get(index: Int): T = buffer[rowIndex, index] @@ -39,5 +38,5 @@ class BufferAccessor2D(val type: KClass, val rowNum: Int, val colNum /** * Get row */ - fun MutableBuffer.row(i: Int): Row = Row(this, i) + public fun MutableBuffer.row(i: Int): Row = Row(this, i) } diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/BufferedNDAlgebra.kt b/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/BufferedNDAlgebra.kt index 2c0c2021f..ac8ca0db4 100644 --- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/BufferedNDAlgebra.kt +++ b/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/BufferedNDAlgebra.kt @@ -2,8 +2,8 @@ package scientifik.kmath.structures import scientifik.kmath.operations.* -interface BufferedNDAlgebra : NDAlgebra> { - val strides: Strides +public interface BufferedNDAlgebra : NDAlgebra> { + public val strides: Strides override fun check(vararg elements: NDBuffer): Unit = require(elements.all { it.strides == strides }) { ("Strides mismatch") } @@ -15,29 +15,27 @@ interface BufferedNDAlgebra : NDAlgebra> { * * If the argument is [NDBuffer] with different strides structure, the new element will be produced. */ - fun NDStructure.toBuffer(): NDBuffer { - return if (this is NDBuffer && this.strides == this@BufferedNDAlgebra.strides) { + public fun NDStructure.toBuffer(): NDBuffer = + if (this is NDBuffer && this.strides == this@BufferedNDAlgebra.strides) this - } else { - produce { index -> get(index) } - } - } + else + produce { index -> this@toBuffer[index] } /** * Convert a buffer to element of this algebra */ - fun NDBuffer.toElement(): MathElement> + public fun NDBuffer.toElement(): MathElement> } -interface BufferedNDSpace> : NDSpace>, BufferedNDAlgebra { +public interface BufferedNDSpace> : NDSpace>, BufferedNDAlgebra { override fun NDBuffer.toElement(): SpaceElement, *, out BufferedNDSpace> } -interface BufferedNDRing> : NDRing>, BufferedNDSpace { +public interface BufferedNDRing> : NDRing>, BufferedNDSpace { override fun NDBuffer.toElement(): RingElement, *, out BufferedNDRing> } -interface BufferedNDField> : NDField>, BufferedNDRing { +public interface BufferedNDField> : NDField>, BufferedNDRing { override fun NDBuffer.toElement(): FieldElement, *, out BufferedNDField> } diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/BufferedNDElement.kt b/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/BufferedNDElement.kt index 20e34fadd..4de31d101 100644 --- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/BufferedNDElement.kt +++ b/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/BufferedNDElement.kt @@ -5,7 +5,7 @@ import scientifik.kmath.operations.* /** * Base class for an element with context, containing strides */ -abstract class BufferedNDElement : NDBuffer(), NDElement> { +public abstract class BufferedNDElement : NDBuffer(), NDElement> { abstract override val context: BufferedNDAlgebra override val strides: Strides get() = context.strides @@ -13,7 +13,7 @@ abstract class BufferedNDElement : NDBuffer(), NDElement>( +public class BufferedNDSpaceElement>( override val context: BufferedNDSpace, override val buffer: Buffer ) : BufferedNDElement(), SpaceElement, BufferedNDSpaceElement, BufferedNDSpace> { @@ -26,7 +26,7 @@ class BufferedNDSpaceElement>( } } -class BufferedNDRingElement>( +public class BufferedNDRingElement>( override val context: BufferedNDRing, override val buffer: Buffer ) : BufferedNDElement(), RingElement, BufferedNDRingElement, BufferedNDRing> { @@ -38,7 +38,7 @@ class BufferedNDRingElement>( } } -class BufferedNDFieldElement>( +public class BufferedNDFieldElement>( override val context: BufferedNDField, override val buffer: Buffer ) : BufferedNDElement(), FieldElement, BufferedNDFieldElement, BufferedNDField> { @@ -54,7 +54,7 @@ class BufferedNDFieldElement>( /** * Element by element application of any operation on elements to the whole array. Just like in numpy. */ -operator fun > Function1.invoke(ndElement: BufferedNDElement): MathElement> = +public operator fun > Function1.invoke(ndElement: BufferedNDElement): MathElement> = ndElement.context.run { map(ndElement) { invoke(it) }.toElement() } /* plus and minus */ @@ -62,13 +62,13 @@ operator fun > Function1.invoke(ndElement: BufferedN /** * Summation operation for [BufferedNDElement] and single element */ -operator fun > BufferedNDElement.plus(arg: T): NDElement> = +public operator fun > BufferedNDElement.plus(arg: T): NDElement> = context.map(this) { it + arg }.wrap() /** * Subtraction operation between [BufferedNDElement] and single element */ -operator fun > BufferedNDElement.minus(arg: T): NDElement> = +public operator fun > BufferedNDElement.minus(arg: T): NDElement> = context.map(this) { it - arg }.wrap() /* prod and div */ @@ -76,11 +76,11 @@ operator fun > BufferedNDElement.minus(arg: T): NDEl /** * Product operation for [BufferedNDElement] and single element */ -operator fun > BufferedNDElement.times(arg: T): NDElement> = +public operator fun > BufferedNDElement.times(arg: T): NDElement> = context.map(this) { it * arg }.wrap() /** * Division operation between [BufferedNDElement] and single element */ -operator fun > BufferedNDElement.div(arg: T): NDElement> = +public operator fun > BufferedNDElement.div(arg: T): NDElement> = context.map(this) { it / arg }.wrap() diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/Buffers.kt b/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/Buffers.kt index 4afaa63ab..48d15d50a 100644 --- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/Buffers.kt +++ b/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/Buffers.kt @@ -11,44 +11,44 @@ import kotlin.reflect.KClass * * @param T the type of buffer. */ -typealias BufferFactory = (Int, (Int) -> T) -> Buffer +public typealias BufferFactory = (Int, (Int) -> T) -> Buffer /** * Function that produces [MutableBuffer] from its size and function that supplies values. * * @param T the type of buffer. */ -typealias MutableBufferFactory = (Int, (Int) -> T) -> MutableBuffer +public typealias MutableBufferFactory = (Int, (Int) -> T) -> MutableBuffer /** * A generic immutable random-access structure for both primitives and objects. * * @param T the type of elements contained in the buffer. */ -interface Buffer { +public interface Buffer { /** * The size of this buffer. */ - val size: Int + public val size: Int /** * Gets element at given index. */ - operator fun get(index: Int): T + public operator fun get(index: Int): T /** * Iterates over all elements. */ - operator fun iterator(): Iterator + public operator fun iterator(): Iterator /** * Checks content equality with another buffer. */ - fun contentEquals(other: Buffer<*>): Boolean = + public fun contentEquals(other: Buffer<*>): Boolean = asSequence().mapIndexed { index, value -> value == other[index] }.all { it } - companion object { - inline fun real(size: Int, initializer: (Int) -> Double): RealBuffer { + public companion object { + public inline fun real(size: Int, initializer: (Int) -> Double): RealBuffer { val array = DoubleArray(size) { initializer(it) } return RealBuffer(array) } @@ -56,10 +56,10 @@ interface Buffer { /** * Create a boxing buffer of given type */ - inline fun boxing(size: Int, initializer: (Int) -> T): Buffer = ListBuffer(List(size, initializer)) + public inline fun boxing(size: Int, initializer: (Int) -> T): Buffer = ListBuffer(List(size, initializer)) @Suppress("UNCHECKED_CAST") - inline fun auto(type: KClass, size: Int, crossinline initializer: (Int) -> T): Buffer { + 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 @@ -75,7 +75,7 @@ interface Buffer { * Create most appropriate immutable buffer for given type avoiding boxing wherever possible */ @Suppress("UNCHECKED_CAST") - inline fun auto(size: Int, crossinline initializer: (Int) -> T): Buffer = + public inline fun auto(size: Int, crossinline initializer: (Int) -> T): Buffer = auto(T::class, size, initializer) } } @@ -83,35 +83,35 @@ interface Buffer { /** * Creates a sequence that returns all elements from this [Buffer]. */ -fun Buffer.asSequence(): Sequence = Sequence(::iterator) +public fun Buffer.asSequence(): Sequence = Sequence(::iterator) /** * Creates an iterable that returns all elements from this [Buffer]. */ -fun Buffer.asIterable(): Iterable = Iterable(::iterator) +public fun Buffer.asIterable(): Iterable = Iterable(::iterator) /** * Returns an [IntRange] of the valid indices for this [Buffer]. */ -val Buffer<*>.indices: IntRange get() = 0 until size +public val Buffer<*>.indices: IntRange get() = 0 until size /** * A generic mutable random-access structure for both primitives and objects. * * @param T the type of elements contained in the buffer. */ -interface MutableBuffer : Buffer { +public interface MutableBuffer : Buffer { /** * Sets the array element at the specified [index] to the specified [value]. */ - operator fun set(index: Int, value: T) + public operator fun set(index: Int, value: T) /** * Returns a shallow copy of the buffer. */ - fun copy(): MutableBuffer + public fun copy(): MutableBuffer - companion object { + public companion object { /** * Create a boxing mutable buffer of given type */ @@ -216,7 +216,7 @@ class ArrayBuffer(private val array: Array) : MutableBuffer { /** * Returns an [ArrayBuffer] that wraps the original array. */ -fun Array.asBuffer(): ArrayBuffer = ArrayBuffer(this) +public fun Array.asBuffer(): ArrayBuffer = ArrayBuffer(this) /** * Immutable wrapper for [MutableBuffer]. @@ -224,7 +224,7 @@ fun Array.asBuffer(): ArrayBuffer = ArrayBuffer(this) * @param T the type of elements contained in the buffer. * @property buffer The underlying buffer. */ -inline class ReadOnlyBuffer(val buffer: MutableBuffer) : Buffer { +public inline class ReadOnlyBuffer(public val buffer: MutableBuffer) : Buffer { override val size: Int get() = buffer.size override operator fun get(index: Int): T = buffer[index] @@ -238,7 +238,7 @@ inline class ReadOnlyBuffer(val buffer: MutableBuffer) : Buffer { * * @param T the type of elements provided by the buffer. */ -class VirtualBuffer(override val size: Int, private val generator: (Int) -> T) : Buffer { +public class VirtualBuffer(override val size: Int, private val generator: (Int) -> T) : Buffer { override operator fun get(index: Int): T { if (index < 0 || index >= size) throw IndexOutOfBoundsException("Expected index from 0 to ${size - 1}, but found $index") return generator(index) @@ -258,14 +258,14 @@ class VirtualBuffer(override val size: Int, private val generator: (Int) -> T /** * Convert this buffer to read-only buffer. */ -fun Buffer.asReadOnly(): Buffer = if (this is MutableBuffer) ReadOnlyBuffer(this) else this +public fun Buffer.asReadOnly(): Buffer = if (this is MutableBuffer) ReadOnlyBuffer(this) else this /** * Typealias for buffer transformations. */ -typealias BufferTransform = (Buffer) -> Buffer +public typealias BufferTransform = (Buffer) -> Buffer /** * Typealias for buffer transformations with suspend function. */ -typealias SuspendBufferTransform = suspend (Buffer) -> Buffer +public typealias SuspendBufferTransform = suspend (Buffer) -> Buffer diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/ComplexNDField.kt b/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/ComplexNDField.kt index 2c6e3a5c7..56fe2a5ac 100644 --- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/ComplexNDField.kt +++ b/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/ComplexNDField.kt @@ -8,12 +8,12 @@ import kotlin.contracts.ExperimentalContracts import kotlin.contracts.InvocationKind import kotlin.contracts.contract -typealias ComplexNDElement = BufferedNDFieldElement +public typealias ComplexNDElement = BufferedNDFieldElement /** * An optimized nd-field for complex numbers */ -class ComplexNDField(override val shape: IntArray) : +public class ComplexNDField(override val shape: IntArray) : BufferedNDField, ExtendedNDField> { @@ -22,7 +22,7 @@ class ComplexNDField(override val shape: IntArray) : override val zero: ComplexNDElement by lazy { produce { zero } } override val one: ComplexNDElement by lazy { produce { one } } - inline fun buildBuffer(size: Int, crossinline initializer: (Int) -> Complex): Buffer = + public inline fun buildBuffer(size: Int, crossinline initializer: (Int) -> Complex): Buffer = Buffer.complex(size) { initializer(it) } /** @@ -130,29 +130,25 @@ operator fun Function1.invoke(ndElement: ComplexNDElement): Co /** * Summation operation for [BufferedNDElement] and single element */ -operator fun ComplexNDElement.plus(arg: Complex): ComplexNDElement = map { it + arg } +public operator fun ComplexNDElement.plus(arg: Complex): ComplexNDElement = map { it + arg } /** * Subtraction operation between [BufferedNDElement] and single element */ -operator fun ComplexNDElement.minus(arg: Complex): ComplexNDElement = - map { it - arg } +public operator fun ComplexNDElement.minus(arg: Complex): ComplexNDElement = map { it - arg } -operator fun ComplexNDElement.plus(arg: Double): ComplexNDElement = - map { it + arg } +public operator fun ComplexNDElement.plus(arg: Double): ComplexNDElement = map { it + arg } +public operator fun ComplexNDElement.minus(arg: Double): ComplexNDElement = map { it - arg } -operator fun ComplexNDElement.minus(arg: Double): ComplexNDElement = - map { it - arg } +public fun NDField.Companion.complex(vararg shape: Int): ComplexNDField = ComplexNDField(shape) -fun NDField.Companion.complex(vararg shape: Int): ComplexNDField = ComplexNDField(shape) - -fun NDElement.Companion.complex(vararg shape: Int, initializer: ComplexField.(IntArray) -> Complex): ComplexNDElement = +public fun NDElement.Companion.complex(vararg shape: Int, initializer: ComplexField.(IntArray) -> Complex): ComplexNDElement = NDField.complex(*shape).produce(initializer) /** * Produce a context for n-dimensional operations inside this real field */ -inline fun ComplexField.nd(vararg shape: Int, action: ComplexNDField.() -> R): R { +public inline fun ComplexField.nd(vararg shape: Int, action: ComplexNDField.() -> R): R { contract { callsInPlace(action, InvocationKind.EXACTLY_ONCE) } return NDField.complex(*shape).action() } diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/ExtendedNDField.kt b/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/ExtendedNDField.kt index 24aa48c6b..12731ff86 100644 --- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/ExtendedNDField.kt +++ b/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/ExtendedNDField.kt @@ -9,7 +9,7 @@ import scientifik.kmath.operations.ExtendedField * @param N the type of ND structure. * @param F the extended field of structure elements. */ -interface ExtendedNDField, N : NDStructure> : NDField, ExtendedField +public interface ExtendedNDField, N : NDStructure> : NDField, ExtendedField ///** // * NDField that supports [ExtendedField] operations on its elements diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/FlaggedBuffer.kt b/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/FlaggedBuffer.kt index 9c32aa31b..314f9fd63 100644 --- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/FlaggedBuffer.kt +++ b/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/FlaggedBuffer.kt @@ -9,7 +9,7 @@ import kotlin.experimental.and * * @property mask bit mask value of this flag. */ -enum class ValueFlag(val mask: Byte) { +public enum class ValueFlag(public val mask: Byte) { /** * Reports the value is NaN. */ diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/IntBuffer.kt b/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/IntBuffer.kt index 95651c547..88a3bd39d 100644 --- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/IntBuffer.kt +++ b/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/IntBuffer.kt @@ -9,7 +9,7 @@ import kotlin.contracts.contract * * @property array the underlying array. */ -inline class IntBuffer(val array: IntArray) : MutableBuffer { +public inline class IntBuffer(public val array: IntArray) : MutableBuffer { override val size: Int get() = array.size override operator fun get(index: Int): Int = array[index] diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/LongBuffer.kt b/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/LongBuffer.kt index a44109f8a..17f161d19 100644 --- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/LongBuffer.kt +++ b/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/LongBuffer.kt @@ -8,7 +8,7 @@ import kotlin.contracts.contract * * @property array the underlying array. */ -inline class LongBuffer(val array: LongArray) : MutableBuffer { +public inline class LongBuffer(public val array: LongArray) : MutableBuffer { override val size: Int get() = array.size override operator fun get(index: Int): Long = array[index] @@ -31,7 +31,7 @@ inline class LongBuffer(val array: LongArray) : MutableBuffer { * The function [init] is called for each array element sequentially starting from the first one. * It should return the value for an buffer element given its index. */ -inline fun LongBuffer(size: Int, init: (Int) -> Long): LongBuffer { +public inline fun LongBuffer(size: Int, init: (Int) -> Long): LongBuffer { contract { callsInPlace(init) } return LongBuffer(LongArray(size) { init(it) }) } @@ -39,12 +39,12 @@ inline fun LongBuffer(size: Int, init: (Int) -> Long): LongBuffer { /** * Returns a new [LongBuffer] of given elements. */ -fun LongBuffer(vararg longs: Long): LongBuffer = LongBuffer(longs) +public fun LongBuffer(vararg longs: Long): LongBuffer = LongBuffer(longs) /** * Returns a [IntArray] containing all of the elements of this [MutableBuffer]. */ -val MutableBuffer.array: LongArray +public val MutableBuffer.array: LongArray get() = (if (this is LongBuffer) array else LongArray(size) { get(it) }) /** @@ -53,4 +53,4 @@ val MutableBuffer.array: LongArray * @receiver the array. * @return the new buffer. */ -fun LongArray.asBuffer(): LongBuffer = LongBuffer(this) +public fun LongArray.asBuffer(): LongBuffer = LongBuffer(this) diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/NDAlgebra.kt b/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/NDAlgebra.kt index f09db3c72..a28eda9b9 100644 --- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/NDAlgebra.kt +++ b/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/NDAlgebra.kt @@ -5,12 +5,10 @@ import scientifik.kmath.operations.Field import scientifik.kmath.operations.Ring import scientifik.kmath.operations.Space - /** * An exception is thrown when the expected ans actual shape of NDArray differs */ -class ShapeMismatchException(val expected: IntArray, val actual: IntArray) : RuntimeException() - +public class ShapeMismatchException(public val expected: IntArray, public val actual: IntArray) : RuntimeException() /** * The base interface for all nd-algebra implementations @@ -18,53 +16,49 @@ class ShapeMismatchException(val expected: IntArray, val actual: IntArray) : Run * @param C the type of the element context * @param N the type of the structure */ -interface NDAlgebra> { - val shape: IntArray - val elementContext: C +public interface NDAlgebra> { + public val shape: IntArray + public val elementContext: C /** * Produce a new [N] structure using given initializer function */ - fun produce(initializer: C.(IntArray) -> T): N + public fun produce(initializer: C.(IntArray) -> T): N /** * Map elements from one structure to another one */ - fun map(arg: N, transform: C.(T) -> T): N + public fun map(arg: N, transform: C.(T) -> T): N /** * Map indexed elements */ - fun mapIndexed(arg: N, transform: C.(index: IntArray, T) -> T): N + public fun mapIndexed(arg: N, transform: C.(index: IntArray, T) -> T): N /** * Combine two structures into one */ - fun combine(a: N, b: N, transform: C.(T, T) -> T): N + public fun combine(a: N, b: N, transform: C.(T, T) -> T): N /** * Check if given elements are consistent with this context */ - fun check(vararg elements: N) { - elements.forEach { - if (!shape.contentEquals(it.shape)) { - throw ShapeMismatchException(shape, it.shape) - } - } + public fun check(vararg elements: N): Unit = elements.forEach { + if (!shape.contentEquals(it.shape)) throw ShapeMismatchException(shape, it.shape) } /** * element-by-element invoke a function working on [T] on a [NDStructure] */ - operator fun Function1.invoke(structure: N): N = map(structure) { value -> this@invoke(value) } + public operator fun Function1.invoke(structure: N): N = map(structure) { value -> this@invoke(value) } - companion object + public companion object } /** * An nd-space over element space */ -interface NDSpace, N : NDStructure> : Space, NDAlgebra { +public interface NDSpace, N : NDStructure> : Space, NDAlgebra { /** * Element-by-element addition */ @@ -76,32 +70,31 @@ interface NDSpace, N : NDStructure> : Space, NDAlgebra add(arg, value) } + public operator fun N.plus(arg: T): N = map(this) { value -> add(arg, value) } - operator fun N.minus(arg: T): N = map(this) { value -> add(arg, -value) } + public operator fun N.minus(arg: T): N = map(this) { value -> add(arg, -value) } - operator fun T.plus(arg: N): N = map(arg) { value -> add(this@plus, value) } - operator fun T.minus(arg: N): N = map(arg) { value -> add(-this@minus, value) } + public operator fun T.plus(arg: N): N = map(arg) { value -> add(this@plus, value) } + public operator fun T.minus(arg: N): N = map(arg) { value -> add(-this@minus, value) } - companion object + public companion object } /** * An nd-ring over element ring */ -interface NDRing, N : NDStructure> : Ring, NDSpace { - +public interface NDRing, N : NDStructure> : Ring, NDSpace { /** * Element-by-element multiplication */ override fun multiply(a: N, b: N): N = combine(a, b) { aValue, bValue -> multiply(aValue, bValue) } //TODO move to extensions after KEEP-176 - operator fun N.times(arg: T): N = map(this) { value -> multiply(arg, value) } + public operator fun N.times(arg: T): N = map(this) { value -> multiply(arg, value) } - operator fun T.times(arg: N): N = map(arg) { value -> multiply(this@times, value) } + public operator fun T.times(arg: N): N = map(arg) { value -> multiply(this@times, value) } - companion object + public companion object } /** @@ -111,17 +104,16 @@ interface NDRing, N : NDStructure> : Ring, NDSpace * @param N the type of ND structure. * @param F field of structure elements. */ -interface NDField, N : NDStructure> : Field, NDRing { - +public interface NDField, N : NDStructure> : Field, NDRing { /** * Element-by-element division */ override fun divide(a: N, b: N): N = combine(a, b) { aValue, bValue -> divide(aValue, bValue) } //TODO move to extensions after KEEP-176 - operator fun N.div(arg: T): N = map(this) { value -> divide(arg, value) } + public operator fun N.div(arg: T): N = map(this) { value -> divide(arg, value) } - operator fun T.div(arg: N): N = map(arg) { divide(it, this@div) } + public operator fun T.div(arg: N): N = map(arg) { divide(it, this@div) } companion object { diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/RealNDField.kt b/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/RealNDField.kt index 6533f64be..ac2adbe9b 100644 --- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/RealNDField.kt +++ b/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/RealNDField.kt @@ -3,9 +3,9 @@ package scientifik.kmath.structures import scientifik.kmath.operations.FieldElement import scientifik.kmath.operations.RealField -typealias RealNDElement = BufferedNDFieldElement +public typealias RealNDElement = BufferedNDFieldElement -class RealNDField(override val shape: IntArray) : +public class RealNDField(override val shape: IntArray) : BufferedNDField, ExtendedNDField> { @@ -15,7 +15,7 @@ class RealNDField(override val shape: IntArray) : override val zero: RealNDElement by lazy { produce { zero } } override val one: RealNDElement by lazy { produce { one } } - inline fun buildBuffer(size: Int, crossinline initializer: (Int) -> Double): Buffer = + public inline fun buildBuffer(size: Int, crossinline initializer: (Int) -> Double): Buffer = RealBuffer(DoubleArray(size) { initializer(it) }) /** @@ -90,7 +90,7 @@ class RealNDField(override val shape: IntArray) : /** * Fast element production using function inlining */ -inline fun BufferedNDField.produceInline(crossinline initializer: RealField.(Int) -> Double): RealNDElement { +public inline fun BufferedNDField.produceInline(crossinline initializer: RealField.(Int) -> Double): RealNDElement { val array = DoubleArray(strides.linearSize) { offset -> RealField.initializer(offset) } return BufferedNDFieldElement(this, RealBuffer(array)) } @@ -98,13 +98,13 @@ inline fun BufferedNDField.produceInline(crossinline initiali /** * Map one [RealNDElement] using function with indices. */ -inline fun RealNDElement.mapIndexed(crossinline transform: RealField.(index: IntArray, Double) -> Double): RealNDElement = +public inline fun RealNDElement.mapIndexed(crossinline transform: RealField.(index: IntArray, Double) -> Double): RealNDElement = context.produceInline { offset -> transform(strides.index(offset), buffer[offset]) } /** * Map one [RealNDElement] using function without indices. */ -inline fun RealNDElement.map(crossinline transform: RealField.(Double) -> Double): RealNDElement { +public inline fun RealNDElement.map(crossinline transform: RealField.(Double) -> Double): RealNDElement { val array = DoubleArray(strides.linearSize) { offset -> RealField.transform(buffer[offset]) } return BufferedNDFieldElement(context, RealBuffer(array)) } diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/ShortBuffer.kt b/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/ShortBuffer.kt index 9aa674177..82deb9275 100644 --- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/ShortBuffer.kt +++ b/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/ShortBuffer.kt @@ -8,7 +8,7 @@ import kotlin.contracts.contract * * @property array the underlying array. */ -inline class ShortBuffer(val array: ShortArray) : MutableBuffer { +public inline class ShortBuffer(public val array: ShortArray) : MutableBuffer { override val size: Int get() = array.size override operator fun get(index: Int): Short = array[index] @@ -30,7 +30,7 @@ inline class ShortBuffer(val array: ShortArray) : MutableBuffer { * The function [init] is called for each array element sequentially starting from the first one. * It should return the value for an buffer element given its index. */ -inline fun ShortBuffer(size: Int, init: (Int) -> Short): ShortBuffer { +public inline fun ShortBuffer(size: Int, init: (Int) -> Short): ShortBuffer { contract { callsInPlace(init) } return ShortBuffer(ShortArray(size) { init(it) }) } @@ -38,12 +38,12 @@ inline fun ShortBuffer(size: Int, init: (Int) -> Short): ShortBuffer { /** * Returns a new [ShortBuffer] of given elements. */ -fun ShortBuffer(vararg shorts: Short): ShortBuffer = ShortBuffer(shorts) +public fun ShortBuffer(vararg shorts: Short): ShortBuffer = ShortBuffer(shorts) /** * Returns a [ShortArray] containing all of the elements of this [MutableBuffer]. */ -val MutableBuffer.array: ShortArray +public val MutableBuffer.array: ShortArray get() = (if (this is ShortBuffer) array else ShortArray(size) { get(it) }) /** @@ -52,4 +52,4 @@ val MutableBuffer.array: ShortArray * @receiver the array. * @return the new buffer. */ -fun ShortArray.asBuffer(): ShortBuffer = ShortBuffer(this) +public fun ShortArray.asBuffer(): ShortBuffer = ShortBuffer(this) diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/ShortNDRing.kt b/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/ShortNDRing.kt index f404a2a27..9a2ec1c88 100644 --- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/ShortNDRing.kt +++ b/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/ShortNDRing.kt @@ -2,20 +2,19 @@ package scientifik.kmath.structures import scientifik.kmath.operations.RingElement import scientifik.kmath.operations.ShortRing +import kotlin.contracts.contract +public typealias ShortNDElement = BufferedNDRingElement -typealias ShortNDElement = BufferedNDRingElement - -class ShortNDRing(override val shape: IntArray) : +public class ShortNDRing(override val shape: IntArray) : BufferedNDRing { override val strides: Strides = DefaultStrides(shape) - override val elementContext: ShortRing get() = ShortRing override val zero: ShortNDElement by lazy { produce { zero } } override val one: ShortNDElement by lazy { produce { one } } - inline fun buildBuffer(size: Int, crossinline initializer: (Int) -> Short): Buffer = + public inline fun buildBuffer(size: Int, crossinline initializer: (Int) -> Short): Buffer = ShortBuffer(ShortArray(size) { initializer(it) }) /** @@ -70,7 +69,8 @@ class ShortNDRing(override val shape: IntArray) : /** * Fast element production using function inlining. */ -inline fun BufferedNDRing.produceInline(crossinline initializer: ShortRing.(Int) -> Short): ShortNDElement { +public inline fun BufferedNDRing.produceInline(crossinline initializer: ShortRing.(Int) -> Short): ShortNDElement { + contract { callsInPlace(initializer) } val array = ShortArray(strides.linearSize) { offset -> ShortRing.initializer(offset) } return BufferedNDRingElement(this, ShortBuffer(array)) } @@ -78,7 +78,7 @@ inline fun BufferedNDRing.produceInline(crossinline initialize /** * Element by element application of any operation on elements to the whole array. */ -operator fun Function1.invoke(ndElement: ShortNDElement): ShortNDElement = +public operator fun Function1.invoke(ndElement: ShortNDElement): ShortNDElement = ndElement.context.produceInline { i -> invoke(ndElement.buffer[i]) } @@ -87,11 +87,11 @@ operator fun Function1.invoke(ndElement: ShortNDElement): ShortNDE /** * Summation operation for [ShortNDElement] and single element. */ -operator fun ShortNDElement.plus(arg: Short): ShortNDElement = +public operator fun ShortNDElement.plus(arg: Short): ShortNDElement = context.produceInline { i -> (buffer[i] + arg).toShort() } /** * Subtraction operation between [ShortNDElement] and single element. */ -operator fun ShortNDElement.minus(arg: Short): ShortNDElement = +public operator fun ShortNDElement.minus(arg: Short): ShortNDElement = context.produceInline { i -> (buffer[i] - arg).toShort() } diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/Structure2D.kt b/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/Structure2D.kt index eeb6bd3dc..e0ae4d4a2 100644 --- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/Structure2D.kt +++ b/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/Structure2D.kt @@ -3,26 +3,22 @@ package scientifik.kmath.structures /** * A structure that is guaranteed to be two-dimensional */ -interface Structure2D : NDStructure { - val rowNum: Int get() = shape[0] - val colNum: Int get() = shape[1] +public interface Structure2D : NDStructure { + public val rowNum: Int get() = shape[0] + public val colNum: Int get() = shape[1] - operator fun get(i: Int, j: Int): T + public operator fun get(i: Int, j: Int): T override operator fun get(index: IntArray): T { require(index.size == 2) { "Index dimension mismatch. Expected 2 but found ${index.size}" } return get(index[0], index[1]) } - val rows: Buffer> - get() = VirtualBuffer(rowNum) { i -> - VirtualBuffer(colNum) { j -> get(i, j) } - } + public val rows: Buffer> + get() = VirtualBuffer(rowNum) { i -> VirtualBuffer(colNum) { j -> get(i, j) } } - val columns: Buffer> - get() = VirtualBuffer(colNum) { j -> - VirtualBuffer(rowNum) { i -> get(i, j) } - } + public val columns: Buffer> + get() = VirtualBuffer(colNum) { j -> VirtualBuffer(rowNum) { i -> get(i, j) } } override fun elements(): Sequence> = sequence { for (i in (0 until rowNum)) { @@ -32,7 +28,7 @@ interface Structure2D : NDStructure { } } - companion object + public companion object } /** @@ -49,10 +45,10 @@ private inline class Structure2DWrapper(val structure: NDStructure) : Stru /** * Represent a [NDStructure] as [Structure1D]. Throw error in case of dimension mismatch */ -fun NDStructure.as2D(): Structure2D = if (shape.size == 2) { +public fun NDStructure.as2D(): Structure2D = if (shape.size == 2) { Structure2DWrapper(this) } else { error("Can't create 2d-structure from ${shape.size}d-structure") } -typealias Matrix = Structure2D +public typealias Matrix = Structure2D diff --git a/kmath-core/src/jvmMain/kotlin/scientifik/kmath/operations/BigNumbers.kt b/kmath-core/src/jvmMain/kotlin/scientifik/kmath/operations/BigNumbers.kt index f10ef24da..e5ec374c9 100644 --- a/kmath-core/src/jvmMain/kotlin/scientifik/kmath/operations/BigNumbers.kt +++ b/kmath-core/src/jvmMain/kotlin/scientifik/kmath/operations/BigNumbers.kt @@ -7,7 +7,7 @@ import java.math.MathContext /** * A field over [BigInteger]. */ -object JBigIntegerField : Field { +public object JBigIntegerField : Field { override val zero: BigInteger get() = BigInteger.ZERO @@ -28,7 +28,7 @@ object JBigIntegerField : Field { * * @property mathContext the [MathContext] to use. */ -abstract class JBigDecimalFieldBase internal constructor(val mathContext: MathContext = MathContext.DECIMAL64) : +public abstract class JBigDecimalFieldBase internal constructor(public val mathContext: MathContext = MathContext.DECIMAL64) : Field, PowerOperations { override val zero: BigDecimal @@ -54,6 +54,6 @@ abstract class JBigDecimalFieldBase internal constructor(val mathContext: MathCo /** * A field over [BigDecimal]. */ -class JBigDecimalField(mathContext: MathContext = MathContext.DECIMAL64) : JBigDecimalFieldBase(mathContext) { - companion object : JBigDecimalFieldBase() +public class JBigDecimalField(mathContext: MathContext = MathContext.DECIMAL64) : JBigDecimalFieldBase(mathContext) { + public companion object : JBigDecimalFieldBase() } diff --git a/kmath-coroutines/build.gradle.kts b/kmath-coroutines/build.gradle.kts index 4469a9ef6..e108c2755 100644 --- a/kmath-coroutines/build.gradle.kts +++ b/kmath-coroutines/build.gradle.kts @@ -1,12 +1,8 @@ -plugins { - id("scientifik.mpp") - //id("scientifik.atomic") -} +plugins { id("ru.mipt.npm.mpp") } kotlin.sourceSets { all { with(languageSettings) { - useExperimentalAnnotation("kotlin.contracts.ExperimentalContracts") useExperimentalAnnotation("kotlinx.coroutines.InternalCoroutinesApi") useExperimentalAnnotation("kotlinx.coroutines.ExperimentalCoroutinesApi") useExperimentalAnnotation("kotlinx.coroutines.FlowPreview") @@ -16,15 +12,7 @@ kotlin.sourceSets { commonMain { dependencies { api(project(":kmath-core")) - api("org.jetbrains.kotlinx:kotlinx-coroutines-core-common:${Scientifik.coroutinesVersion}") + api("org.jetbrains.kotlinx:kotlinx-coroutines-core:${ru.mipt.npm.gradle.KScienceVersions.coroutinesVersion}") } } - - jvmMain { - dependencies { api("org.jetbrains.kotlinx:kotlinx-coroutines-core:${Scientifik.coroutinesVersion}") } - } - - jsMain { - dependencies { api("org.jetbrains.kotlinx:kotlinx-coroutines-core-js:${Scientifik.coroutinesVersion}") } - } } diff --git a/kmath-coroutines/src/commonMain/kotlin/scientifik/kmath/chains/Chain.kt b/kmath-coroutines/src/commonMain/kotlin/scientifik/kmath/chains/Chain.kt index f0ffd13cd..e899f8ece 100644 --- a/kmath-coroutines/src/commonMain/kotlin/scientifik/kmath/chains/Chain.kt +++ b/kmath-coroutines/src/commonMain/kotlin/scientifik/kmath/chains/Chain.kt @@ -26,31 +26,31 @@ import kotlinx.coroutines.sync.withLock * A not-necessary-Markov chain of some type * @param R - the chain element type */ -interface Chain : Flow { +public interface Chain : Flow { /** * Generate next value, changing state if needed */ - suspend fun next(): R + public suspend fun next(): R /** * Create a copy of current chain state. Consuming resulting chain does not affect initial chain */ - fun fork(): Chain + public fun fork(): Chain override suspend fun collect(collector: FlowCollector): Unit = flow { while (true) emit(next()) }.collect(collector) - companion object + public companion object } -fun Iterator.asChain(): Chain = SimpleChain { next() } -fun Sequence.asChain(): Chain = iterator().asChain() +public fun Iterator.asChain(): Chain = SimpleChain { next() } +public fun Sequence.asChain(): Chain = iterator().asChain() /** * A simple chain of independent tokens */ -class SimpleChain(private val gen: suspend () -> R) : Chain { +public class SimpleChain(private val gen: suspend () -> R) : Chain { override suspend fun next(): R = gen() override fun fork(): Chain = this } @@ -58,13 +58,13 @@ class SimpleChain(private val gen: suspend () -> R) : Chain { /** * A stateless Markov chain */ -class MarkovChain(private val seed: suspend () -> R, private val gen: suspend (R) -> R) : Chain { +public class MarkovChain(private val seed: suspend () -> R, private val gen: suspend (R) -> R) : Chain { private val mutex = Mutex() private var value: R? = null - fun value(): R? = value + public fun value(): R? = value override suspend fun next(): R { mutex.withLock { @@ -84,7 +84,7 @@ class MarkovChain(private val seed: suspend () -> R, private val ge * @param S - the state of the chain * @param forkState - the function to copy current state without modifying it */ -class StatefulChain( +public class StatefulChain( private val state: S, private val seed: S.() -> R, private val forkState: ((S) -> S), @@ -94,7 +94,7 @@ class StatefulChain( private var value: R? = null - fun value(): R? = value + public fun value(): R? = value override suspend fun next(): R { mutex.withLock { @@ -110,19 +110,17 @@ class StatefulChain( /** * A chain that repeats the same value */ -class ConstantChain(val value: T) : Chain { +public class ConstantChain(public val value: T) : Chain { override suspend fun next(): T = value - override fun fork(): Chain { - return this - } + override fun fork(): Chain = this } /** * Map the chain result using suspended transformation. Initial chain result can no longer be safely consumed * since mapped chain consumes tokens. Accepts regular transformation function */ -fun Chain.map(func: suspend (T) -> R): Chain = object : Chain { +public fun Chain.map(func: suspend (T) -> R): Chain = object : Chain { override suspend fun next(): R = func(this@map.next()) override fun fork(): Chain = this@map.fork().map(func) } @@ -130,7 +128,7 @@ fun Chain.map(func: suspend (T) -> R): Chain = object : Chain { /** * [block] must be a pure function or at least not use external random variables, otherwise fork could be broken */ -fun Chain.filter(block: (T) -> Boolean): Chain = object : Chain { +public fun Chain.filter(block: (T) -> Boolean): Chain = object : Chain { override suspend fun next(): T { var next: T @@ -146,12 +144,12 @@ fun Chain.filter(block: (T) -> Boolean): Chain = object : Chain { /** * Map the whole chain */ -fun Chain.collect(mapper: suspend (Chain) -> R): Chain = object : Chain { +public fun Chain.collect(mapper: suspend (Chain) -> R): Chain = object : Chain { override suspend fun next(): R = mapper(this@collect) override fun fork(): Chain = this@collect.fork().collect(mapper) } -fun Chain.collectWithState(state: S, stateFork: (S) -> S, mapper: suspend S.(Chain) -> R): Chain = +public fun Chain.collectWithState(state: S, stateFork: (S) -> S, mapper: suspend S.(Chain) -> R): Chain = object : Chain { override suspend fun next(): R = state.mapper(this@collectWithState) @@ -162,7 +160,7 @@ fun Chain.collectWithState(state: S, stateFork: (S) -> S, mapper: s /** * Zip two chains together using given transformation */ -fun Chain.zip(other: Chain, block: suspend (T, U) -> R): Chain = object : Chain { +public fun Chain.zip(other: Chain, block: suspend (T, U) -> R): Chain = object : Chain { override suspend fun next(): R = block(this@zip.next(), other.next()) override fun fork(): Chain = this@zip.fork().zip(other.fork(), block) } diff --git a/kmath-dimensions/build.gradle.kts b/kmath-dimensions/build.gradle.kts index dda6cd2f0..0a36e4435 100644 --- a/kmath-dimensions/build.gradle.kts +++ b/kmath-dimensions/build.gradle.kts @@ -1,8 +1,6 @@ -plugins { - id("scientifik.mpp") -} +plugins { id("ru.mipt.npm.mpp") } -description = "A proof of concept module for adding typ-safe dimensions to structures" +description = "A proof of concept module for adding type-safe dimensions to structures" kotlin.sourceSets { commonMain { @@ -11,9 +9,9 @@ kotlin.sourceSets { } } - jvmMain{ - dependencies{ + jvmMain { + dependencies { api(kotlin("reflect")) } } -} \ No newline at end of file +} diff --git a/kmath-dimensions/src/commonMain/kotlin/scientifik/kmath/dimensions/Dimensions.kt b/kmath-dimensions/src/commonMain/kotlin/scientifik/kmath/dimensions/Dimensions.kt index f40483cfd..e96367443 100644 --- a/kmath-dimensions/src/commonMain/kotlin/scientifik/kmath/dimensions/Dimensions.kt +++ b/kmath-dimensions/src/commonMain/kotlin/scientifik/kmath/dimensions/Dimensions.kt @@ -6,30 +6,28 @@ 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 */ -interface Dimension { +public interface Dimension { + public val dim: UInt - val dim: UInt - companion object { - - } + public companion object } -fun KClass.dim(): UInt = Dimension.resolve(this).dim +public fun KClass.dim(): UInt = Dimension.resolve(this).dim -expect fun Dimension.Companion.resolve(type: KClass): D +public expect fun Dimension.Companion.resolve(type: KClass): D -expect fun Dimension.Companion.of(dim: UInt): Dimension +public expect fun Dimension.Companion.of(dim: UInt): Dimension -inline fun Dimension.Companion.dim(): UInt = D::class.dim() +public inline fun Dimension.Companion.dim(): UInt = D::class.dim() -object D1 : Dimension { +public object D1 : Dimension { override val dim: UInt get() = 1U } -object D2 : Dimension { +public object D2 : Dimension { override val dim: UInt get() = 2U } -object D3 : Dimension { +public object D3 : Dimension { override val dim: UInt get() = 3U } diff --git a/kmath-dimensions/src/jsMain/kotlin/scientifik/kmath/dimensions/dim.kt b/kmath-dimensions/src/jsMain/kotlin/scientifik/kmath/dimensions/dim.kt index bbd580629..e5cc451d1 100644 --- a/kmath-dimensions/src/jsMain/kotlin/scientifik/kmath/dimensions/dim.kt +++ b/kmath-dimensions/src/jsMain/kotlin/scientifik/kmath/dimensions/dim.kt @@ -9,11 +9,11 @@ private val dimensionMap = hashMapOf( ) @Suppress("UNCHECKED_CAST") -actual fun Dimension.Companion.resolve(type: KClass): D { +public actual fun Dimension.Companion.resolve(type: KClass): D { return dimensionMap.entries.find { it.value::class == type }?.value as? D ?: error("Can't resolve dimension $type") } -actual fun Dimension.Companion.of(dim: UInt): Dimension { +public actual fun Dimension.Companion.of(dim: UInt): Dimension { return dimensionMap.getOrPut(dim) { object : Dimension { override val dim: UInt get() = dim diff --git a/kmath-dimensions/src/jvmMain/kotlin/scientifik/kmath/dimensions/dim.kt b/kmath-dimensions/src/jvmMain/kotlin/scientifik/kmath/dimensions/dim.kt index e8fe8f59b..42310cb3a 100644 --- a/kmath-dimensions/src/jvmMain/kotlin/scientifik/kmath/dimensions/dim.kt +++ b/kmath-dimensions/src/jvmMain/kotlin/scientifik/kmath/dimensions/dim.kt @@ -2,11 +2,11 @@ package scientifik.kmath.dimensions import kotlin.reflect.KClass -actual fun Dimension.Companion.resolve(type: KClass): D{ +public actual fun Dimension.Companion.resolve(type: KClass): D{ return type.objectInstance ?: error("No object instance for dimension class") } -actual fun Dimension.Companion.of(dim: UInt): Dimension{ +public actual fun Dimension.Companion.of(dim: UInt): Dimension{ return when(dim){ 1u -> D1 2u -> D2 diff --git a/kmath-for-real/build.gradle.kts b/kmath-for-real/build.gradle.kts index 46d2682f7..00abcb934 100644 --- a/kmath-for-real/build.gradle.kts +++ b/kmath-for-real/build.gradle.kts @@ -1,6 +1,7 @@ -plugins { id("scientifik.mpp") } +plugins { id("ru.mipt.npm.mpp") } -kotlin.sourceSets { - all { languageSettings.useExperimentalAnnotation("kotlin.contracts.ExperimentalContracts") } - commonMain { dependencies { api(project(":kmath-core")) } } +kotlin.sourceSets.commonMain { + dependencies { + api(project(":kmath-core")) + } } diff --git a/kmath-for-real/src/commonMain/kotlin/scientifik/kmath/real/realMatrix.kt b/kmath-for-real/src/commonMain/kotlin/scientifik/kmath/real/realMatrix.kt index 3752fc3ca..a3b41288a 100644 --- a/kmath-for-real/src/commonMain/kotlin/scientifik/kmath/real/realMatrix.kt +++ b/kmath-for-real/src/commonMain/kotlin/scientifik/kmath/real/realMatrix.kt @@ -25,20 +25,20 @@ import kotlin.math.pow * Functions that help create a real (Double) matrix */ -typealias RealMatrix = Matrix +public typealias RealMatrix = Matrix -fun realMatrix(rowNum: Int, colNum: Int, initializer: (i: Int, j: Int) -> Double): RealMatrix = +public fun realMatrix(rowNum: Int, colNum: Int, initializer: (i: Int, j: Int) -> Double): RealMatrix = MatrixContext.real.produce(rowNum, colNum, initializer) -fun Array.toMatrix(): RealMatrix { +public fun Array.toMatrix(): RealMatrix { return MatrixContext.real.produce(size, this[0].size) { row, col -> this[row][col] } } -fun Sequence.toMatrix(): RealMatrix = toList().let { +public fun Sequence.toMatrix(): RealMatrix = toList().let { MatrixContext.real.produce(it.size, it[0].size) { row, col -> it[row][col] } } -fun Matrix.repeatStackVertical(n: Int): RealMatrix = +public fun Matrix.repeatStackVertical(n: Int): RealMatrix = VirtualMatrix(rowNum * n, colNum) { row, col -> get(if (row == 0) 0 else row % rowNum, col) } @@ -47,37 +47,37 @@ fun Matrix.repeatStackVertical(n: Int): RealMatrix = * Operations for matrix and real number */ -operator fun Matrix.times(double: Double): RealMatrix = +public operator fun Matrix.times(double: Double): RealMatrix = MatrixContext.real.produce(rowNum, colNum) { row, col -> this[row, col] * double } -operator fun Matrix.plus(double: Double): RealMatrix = +public operator fun Matrix.plus(double: Double): RealMatrix = MatrixContext.real.produce(rowNum, colNum) { row, col -> this[row, col] + double } -operator fun Matrix.minus(double: Double): RealMatrix = +public operator fun Matrix.minus(double: Double): RealMatrix = MatrixContext.real.produce(rowNum, colNum) { row, col -> this[row, col] - double } -operator fun Matrix.div(double: Double): RealMatrix = +public operator fun Matrix.div(double: Double): RealMatrix = MatrixContext.real.produce(rowNum, colNum) { row, col -> this[row, col] / double } -operator fun Double.times(matrix: Matrix): RealMatrix = +public operator fun Double.times(matrix: Matrix): RealMatrix = MatrixContext.real.produce(matrix.rowNum, matrix.colNum) { row, col -> this * matrix[row, col] } -operator fun Double.plus(matrix: Matrix): RealMatrix = +public operator fun Double.plus(matrix: Matrix): RealMatrix = MatrixContext.real.produce(matrix.rowNum, matrix.colNum) { row, col -> this + matrix[row, col] } -operator fun Double.minus(matrix: Matrix): RealMatrix = +public operator fun Double.minus(matrix: Matrix): RealMatrix = MatrixContext.real.produce(matrix.rowNum, matrix.colNum) { row, col -> this - matrix[row, col] } @@ -91,11 +91,11 @@ operator fun Double.minus(matrix: Matrix): RealMatrix = * Per-element (!) square and power operations */ -fun Matrix.square(): RealMatrix = MatrixContext.real.produce(rowNum, colNum) { row, col -> +public fun Matrix.square(): RealMatrix = MatrixContext.real.produce(rowNum, colNum) { row, col -> this[row, col].pow(2) } -fun Matrix.pow(n: Int): RealMatrix = MatrixContext.real.produce(rowNum, colNum) { i, j -> +public fun Matrix.pow(n: Int): RealMatrix = MatrixContext.real.produce(rowNum, colNum) { i, j -> this[i, j].pow(n) } @@ -103,24 +103,20 @@ fun Matrix.pow(n: Int): RealMatrix = MatrixContext.real.produce(rowNum, * Operations on two matrices (per-element!) */ -operator fun Matrix.times(other: Matrix): RealMatrix = - MatrixContext.real.produce(rowNum, colNum) { row, col -> - this[row, col] * other[row, col] - } +public operator fun Matrix.times(other: Matrix): RealMatrix = + MatrixContext.real.produce(rowNum, colNum) { row, col -> this[row, col] * other[row, col] } -operator fun Matrix.plus(other: Matrix): RealMatrix = +public operator fun Matrix.plus(other: Matrix): RealMatrix = MatrixContext.real.add(this, other) -operator fun Matrix.minus(other: Matrix): RealMatrix = - MatrixContext.real.produce(rowNum, colNum) { row, col -> - this[row, col] - other[row, col] - } +public operator fun Matrix.minus(other: Matrix): RealMatrix = + MatrixContext.real.produce(rowNum, colNum) { row, col -> this[row, col] - other[row, col] } /* * Operations on columns */ -inline fun Matrix.appendColumn(crossinline mapper: (Buffer) -> Double): Matrix { +public inline fun Matrix.appendColumn(crossinline mapper: (Buffer) -> Double): Matrix { contract { callsInPlace(mapper) } return MatrixContext.real.produce(rowNum, colNum + 1) { row, col -> @@ -131,28 +127,28 @@ inline fun Matrix.appendColumn(crossinline mapper: (Buffer) -> D } } -fun Matrix.extractColumns(columnRange: IntRange): RealMatrix = +public fun Matrix.extractColumns(columnRange: IntRange): RealMatrix = MatrixContext.real.produce(rowNum, columnRange.count()) { row, col -> this[row, columnRange.first + col] } -fun Matrix.extractColumn(columnIndex: Int): RealMatrix = +public fun Matrix.extractColumn(columnIndex: Int): RealMatrix = extractColumns(columnIndex..columnIndex) -fun Matrix.sumByColumn(): RealBuffer = RealBuffer(colNum) { j -> +public fun Matrix.sumByColumn(): RealBuffer = RealBuffer(colNum) { j -> val column = columns[j] elementContext { sum(column.asIterable()) } } -fun Matrix.minByColumn(): RealBuffer = RealBuffer(colNum) { j -> +public fun Matrix.minByColumn(): RealBuffer = RealBuffer(colNum) { j -> columns[j].asIterable().min() ?: error("Cannot produce min on empty column") } -fun Matrix.maxByColumn(): RealBuffer = RealBuffer(colNum) { j -> +public fun Matrix.maxByColumn(): RealBuffer = RealBuffer(colNum) { j -> columns[j].asIterable().max() ?: error("Cannot produce min on empty column") } -fun Matrix.averageByColumn(): RealBuffer = RealBuffer(colNum) { j -> +public fun Matrix.averageByColumn(): RealBuffer = RealBuffer(colNum) { j -> columns[j].asIterable().average() } @@ -160,7 +156,7 @@ fun Matrix.averageByColumn(): RealBuffer = RealBuffer(colNum) { j -> * Operations processing all elements */ -fun Matrix.sum(): Double = elements().map { (_, value) -> value }.sum() -fun Matrix.min(): Double? = elements().map { (_, value) -> value }.min() -fun Matrix.max(): Double? = elements().map { (_, value) -> value }.max() -fun Matrix.average(): Double = elements().map { (_, value) -> value }.average() +public fun Matrix.sum(): Double = elements().map { (_, value) -> value }.sum() +public fun Matrix.min(): Double? = elements().map { (_, value) -> value }.min() +public fun Matrix.max(): Double? = elements().map { (_, value) -> value }.max() +public fun Matrix.average(): Double = elements().map { (_, value) -> value }.average() diff --git a/kmath-functions/build.gradle.kts b/kmath-functions/build.gradle.kts index 46d2682f7..00abcb934 100644 --- a/kmath-functions/build.gradle.kts +++ b/kmath-functions/build.gradle.kts @@ -1,6 +1,7 @@ -plugins { id("scientifik.mpp") } +plugins { id("ru.mipt.npm.mpp") } -kotlin.sourceSets { - all { languageSettings.useExperimentalAnnotation("kotlin.contracts.ExperimentalContracts") } - commonMain { dependencies { api(project(":kmath-core")) } } +kotlin.sourceSets.commonMain { + dependencies { + api(project(":kmath-core")) + } } diff --git a/kmath-functions/src/commonMain/kotlin/scientifik/kmath/functions/Piecewise.kt b/kmath-functions/src/commonMain/kotlin/scientifik/kmath/functions/Piecewise.kt index 16f8aa12b..b11469ccf 100644 --- a/kmath-functions/src/commonMain/kotlin/scientifik/kmath/functions/Piecewise.kt +++ b/kmath-functions/src/commonMain/kotlin/scientifik/kmath/functions/Piecewise.kt @@ -2,17 +2,17 @@ package scientifik.kmath.functions import scientifik.kmath.operations.Ring -interface Piecewise { - fun findPiece(arg: T): R? +public fun interface Piecewise { + public fun findPiece(arg: T): R? } -interface PiecewisePolynomial : +public fun interface PiecewisePolynomial : Piecewise> /** * Ordered list of pieces in piecewise function */ -class OrderedPiecewisePolynomial>(delimeter: T) : +public class OrderedPiecewisePolynomial>(delimeter: T) : PiecewisePolynomial { private val delimiters: ArrayList = arrayListOf(delimeter) @@ -22,13 +22,13 @@ class OrderedPiecewisePolynomial>(delimeter: T) : * Dynamically add a piece to the "right" side (beyond maximum argument value of previous piece) * @param right new rightmost position. If is less then current rightmost position, a error is thrown. */ - fun putRight(right: T, piece: Polynomial) { + public fun putRight(right: T, piece: Polynomial) { require(right > delimiters.last()) { "New delimiter should be to the right of old one" } delimiters.add(right) pieces.add(piece) } - fun putLeft(left: T, piece: Polynomial) { + public fun putLeft(left: T, piece: Polynomial) { require(left < delimiters.first()) { "New delimiter should be to the left of old one" } delimiters.add(0, left) pieces.add(0, piece) @@ -51,7 +51,7 @@ class OrderedPiecewisePolynomial>(delimeter: T) : /** * Return a value of polynomial function with given [ring] an given [arg] or null if argument is outside of piecewise definition. */ -fun , C : Ring> PiecewisePolynomial.value(ring: C, arg: T): T? = +public fun , C : Ring> PiecewisePolynomial.value(ring: C, arg: T): T? = findPiece(arg)?.value(ring, arg) -fun , C : Ring> PiecewisePolynomial.asFunction(ring: C): (T) -> T? = { value(ring, it) } \ No newline at end of file +public fun , C : Ring> PiecewisePolynomial.asFunction(ring: C): (T) -> T? = { value(ring, it) } \ No newline at end of file diff --git a/kmath-functions/src/commonMain/kotlin/scientifik/kmath/functions/Polynomial.kt b/kmath-functions/src/commonMain/kotlin/scientifik/kmath/functions/Polynomial.kt index c4470ad27..35f1a1e16 100644 --- a/kmath-functions/src/commonMain/kotlin/scientifik/kmath/functions/Polynomial.kt +++ b/kmath-functions/src/commonMain/kotlin/scientifik/kmath/functions/Polynomial.kt @@ -3,7 +3,6 @@ package scientifik.kmath.functions import scientifik.kmath.operations.Ring import scientifik.kmath.operations.Space import scientifik.kmath.operations.invoke -import kotlin.contracts.ExperimentalContracts import kotlin.contracts.InvocationKind import kotlin.contracts.contract import kotlin.math.max @@ -13,14 +12,14 @@ import kotlin.math.pow * Polynomial coefficients without fixation on specific context they are applied to * @param coefficients constant is the leftmost coefficient */ -inline class Polynomial(val coefficients: List) { - constructor(vararg coefficients: T) : this(coefficients.toList()) +public inline class Polynomial(public val coefficients: List) { + public constructor(vararg coefficients: T) : this(coefficients.toList()) } -fun Polynomial.value(): Double = +public fun Polynomial.value(): Double = coefficients.reduceIndexed { index: Int, acc: Double, d: Double -> acc + d.pow(index) } -fun > Polynomial.value(ring: C, arg: T): T = ring { +public fun > Polynomial.value(ring: C, arg: T): T = ring { if (coefficients.isEmpty()) return@ring zero var res = coefficients.first() var powerArg = arg @@ -37,20 +36,19 @@ fun > Polynomial.value(ring: C, arg: T): T = ring { /** * Represent a polynomial as a context-dependent function */ -fun > Polynomial.asMathFunction(): MathFunction = object : - MathFunction { - override operator fun C.invoke(arg: T): T = value(this, arg) -} +public fun > Polynomial.asMathFunction(): MathFunction = + MathFunction { arg -> value(this, arg) } /** * Represent the polynomial as a regular context-less function */ -fun > Polynomial.asFunction(ring: C): (T) -> T = { value(ring, it) } +public fun > Polynomial.asFunction(ring: C): (T) -> T = { value(ring, it) } /** * An algebra for polynomials */ -class PolynomialSpace>(val ring: C) : Space> { +public class PolynomialSpace>(public val ring: C) : Space> { + override val zero: Polynomial = Polynomial(emptyList()) override fun add(a: Polynomial, b: Polynomial): Polynomial { val dim = max(a.coefficients.size, b.coefficients.size) @@ -65,13 +63,10 @@ class PolynomialSpace>(val ring: C) : Space> override fun multiply(a: Polynomial, k: Number): Polynomial = ring { Polynomial(List(a.coefficients.size) { index -> a.coefficients[index] * k }) } - override val zero: Polynomial = - Polynomial(emptyList()) - - operator fun Polynomial.invoke(arg: T): T = value(ring, arg) + public operator fun Polynomial.invoke(arg: T): T = value(ring, arg) } -inline fun , R> C.polynomial(block: PolynomialSpace.() -> R): R { +public inline fun , R> C.polynomial(block: PolynomialSpace.() -> R): R { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } return PolynomialSpace(this).block() } diff --git a/kmath-functions/src/commonMain/kotlin/scientifik/kmath/functions/functions.kt b/kmath-functions/src/commonMain/kotlin/scientifik/kmath/functions/functions.kt index 2b822b3ba..ce6156c0b 100644 --- a/kmath-functions/src/commonMain/kotlin/scientifik/kmath/functions/functions.kt +++ b/kmath-functions/src/commonMain/kotlin/scientifik/kmath/functions/functions.kt @@ -9,25 +9,25 @@ import scientifik.kmath.operations.RealField * @param C source algebra constraint * @param R result type */ -interface MathFunction, R> { - operator fun C.invoke(arg: T): R +public fun interface MathFunction, R> { + public operator fun C.invoke(arg: T): R } -fun MathFunction.invoke(arg: Double): R = RealField.invoke(arg) +public fun MathFunction.invoke(arg: Double): R = RealField.invoke(arg) /** * A suspendable function defined in algebraic context */ -interface SuspendableMathFunction, R> { - suspend operator fun C.invoke(arg: T): R +// TODO make fun interface, when the new JVM IR is enabled +public interface SuspendableMathFunction, R> { + public suspend operator fun C.invoke(arg: T): R } -suspend fun SuspendableMathFunction.invoke(arg: Double) = RealField.invoke(arg) - +public suspend fun SuspendableMathFunction.invoke(arg: Double) = RealField.invoke(arg) /** * A parametric function with parameter */ -interface ParametricFunction> { - operator fun C.invoke(arg: T, parameter: P): T +public fun interface ParametricFunction> { + public operator fun C.invoke(arg: T, parameter: P): T } diff --git a/kmath-functions/src/commonMain/kotlin/scientifik/kmath/interpolation/Interpolator.kt b/kmath-functions/src/commonMain/kotlin/scientifik/kmath/interpolation/Interpolator.kt index 8d83e4198..95e734da8 100644 --- a/kmath-functions/src/commonMain/kotlin/scientifik/kmath/interpolation/Interpolator.kt +++ b/kmath-functions/src/commonMain/kotlin/scientifik/kmath/interpolation/Interpolator.kt @@ -6,16 +6,16 @@ import scientifik.kmath.operations.Ring import scientifik.kmath.structures.Buffer import scientifik.kmath.structures.asBuffer -interface Interpolator { - fun interpolate(points: XYPointSet): (X) -> Y +public fun interface Interpolator { + public fun interpolate(points: XYPointSet): (X) -> Y } -interface PolynomialInterpolator> : Interpolator { - val algebra: Ring +public interface PolynomialInterpolator> : Interpolator { + public val algebra: Ring - fun getDefaultValue(): T = error("Out of bounds") + public fun getDefaultValue(): T = error("Out of bounds") - fun interpolatePolynomials(points: XYPointSet): PiecewisePolynomial + public fun interpolatePolynomials(points: XYPointSet): PiecewisePolynomial override fun interpolate(points: XYPointSet): (T) -> T = { x -> interpolatePolynomials(points).value(algebra, x) ?: getDefaultValue() diff --git a/kmath-functions/src/commonMain/kotlin/scientifik/kmath/interpolation/LinearInterpolator.kt b/kmath-functions/src/commonMain/kotlin/scientifik/kmath/interpolation/LinearInterpolator.kt index a7925180d..03a4625fc 100644 --- a/kmath-functions/src/commonMain/kotlin/scientifik/kmath/interpolation/LinearInterpolator.kt +++ b/kmath-functions/src/commonMain/kotlin/scientifik/kmath/interpolation/LinearInterpolator.kt @@ -9,7 +9,7 @@ import scientifik.kmath.operations.invoke /** * Reference JVM implementation: https://github.com/apache/commons-math/blob/master/src/main/java/org/apache/commons/math4/analysis/interpolation/LinearInterpolator.java */ -class LinearInterpolator>(override val algebra: Field) : PolynomialInterpolator { +public class LinearInterpolator>(override val algebra: Field) : PolynomialInterpolator { override fun interpolatePolynomials(points: XYPointSet): PiecewisePolynomial = algebra { require(points.size > 0) { "Point array should not be empty" } insureSorted(points) diff --git a/kmath-functions/src/commonMain/kotlin/scientifik/kmath/interpolation/SplineInterpolator.kt b/kmath-functions/src/commonMain/kotlin/scientifik/kmath/interpolation/SplineInterpolator.kt index b709c4e87..c8ab42bf4 100644 --- a/kmath-functions/src/commonMain/kotlin/scientifik/kmath/interpolation/SplineInterpolator.kt +++ b/kmath-functions/src/commonMain/kotlin/scientifik/kmath/interpolation/SplineInterpolator.kt @@ -11,9 +11,9 @@ import scientifik.kmath.structures.MutableBufferFactory * Generic spline interpolator. Not recommended for performance critical places, use platform-specific and type specific ones. * Based on https://github.com/apache/commons-math/blob/eb57d6d457002a0bb5336d789a3381a24599affe/src/main/java/org/apache/commons/math4/analysis/interpolation/SplineInterpolator.java */ -class SplineInterpolator>( +public class SplineInterpolator>( override val algebra: Field, - val bufferFactory: MutableBufferFactory + public val bufferFactory: MutableBufferFactory ) : PolynomialInterpolator { //TODO possibly optimize zeroed buffers diff --git a/kmath-functions/src/commonMain/kotlin/scientifik/kmath/interpolation/XYPointSet.kt b/kmath-functions/src/commonMain/kotlin/scientifik/kmath/interpolation/XYPointSet.kt index 56953f9fc..19297036b 100644 --- a/kmath-functions/src/commonMain/kotlin/scientifik/kmath/interpolation/XYPointSet.kt +++ b/kmath-functions/src/commonMain/kotlin/scientifik/kmath/interpolation/XYPointSet.kt @@ -3,21 +3,21 @@ package scientifik.kmath.interpolation import scientifik.kmath.structures.Buffer import scientifik.kmath.structures.Structure2D -interface XYPointSet { - val size: Int - val x: Buffer - val y: Buffer +public interface XYPointSet { + public val size: Int + public val x: Buffer + public val y: Buffer } -interface XYZPointSet : XYPointSet { - val z: Buffer +public interface XYZPointSet : XYPointSet { + public val z: Buffer } internal fun > insureSorted(points: XYPointSet) { for (i in 0 until points.size - 1) require(points.x[i + 1] > points.x[i]) { "Input data is not sorted at index $i" } } -class NDStructureColumn(val structure: Structure2D, val column: Int) : Buffer { +public class NDStructureColumn(public val structure: Structure2D, public val column: Int) : Buffer { init { require(column < structure.colNum) { "Column index is outside of structure column range" } } @@ -33,7 +33,7 @@ class NDStructureColumn(val structure: Structure2D, val column: Int) : Buf }.iterator() } -class BufferXYPointSet(override val x: Buffer, override val y: Buffer) : XYPointSet { +public class BufferXYPointSet(override val x: Buffer, override val y: Buffer) : XYPointSet { init { require(x.size == y.size) { "Sizes of x and y buffers should be the same" } } @@ -42,11 +42,12 @@ class BufferXYPointSet(override val x: Buffer, override val y: Buffer Structure2D.asXYPointSet(): XYPointSet { +public fun Structure2D.asXYPointSet(): XYPointSet { require(shape[1] == 2) { "Structure second dimension should be of size 2" } + return object : XYPointSet { override val size: Int get() = this@asXYPointSet.shape[0] override val x: Buffer get() = NDStructureColumn(this@asXYPointSet, 0) override val y: Buffer get() = NDStructureColumn(this@asXYPointSet, 1) } -} \ No newline at end of file +} diff --git a/kmath-functions/src/commonTest/kotlin/scientifik/kmath/interpolation/LinearInterpolatorTest.kt b/kmath-functions/src/commonTest/kotlin/scientifik/kmath/interpolation/LinearInterpolatorTest.kt index 23acd835c..540494caf 100644 --- a/kmath-functions/src/commonTest/kotlin/scientifik/kmath/interpolation/LinearInterpolatorTest.kt +++ b/kmath-functions/src/commonTest/kotlin/scientifik/kmath/interpolation/LinearInterpolatorTest.kt @@ -6,7 +6,6 @@ import scientifik.kmath.operations.RealField import kotlin.test.Test import kotlin.test.assertEquals - class LinearInterpolatorTest { @Test fun testInterpolation() { @@ -24,4 +23,4 @@ class LinearInterpolatorTest { assertEquals(2.0, function(1.5)) assertEquals(3.0, function(2.0)) } -} \ No newline at end of file +} diff --git a/kmath-geometry/build.gradle.kts b/kmath-geometry/build.gradle.kts index 39aa833ad..00abcb934 100644 --- a/kmath-geometry/build.gradle.kts +++ b/kmath-geometry/build.gradle.kts @@ -1,9 +1,7 @@ -plugins { - id("scientifik.mpp") -} +plugins { id("ru.mipt.npm.mpp") } kotlin.sourceSets.commonMain { dependencies { api(project(":kmath-core")) } -} \ No newline at end of file +} diff --git a/kmath-histograms/build.gradle.kts b/kmath-histograms/build.gradle.kts index 993bfed8e..7de21ad89 100644 --- a/kmath-histograms/build.gradle.kts +++ b/kmath-histograms/build.gradle.kts @@ -1,10 +1,8 @@ -plugins { - id("scientifik.mpp") -} +plugins { id("ru.mipt.npm.mpp") } kotlin.sourceSets.commonMain { dependencies { api(project(":kmath-core")) api(project(":kmath-for-real")) } -} \ No newline at end of file +} diff --git a/kmath-koma/build.gradle.kts b/kmath-koma/build.gradle.kts index 26955bca7..606113e75 100644 --- a/kmath-koma/build.gradle.kts +++ b/kmath-koma/build.gradle.kts @@ -1,10 +1,6 @@ -plugins { - id("scientifik.mpp") -} +plugins { id("ru.mipt.npm.mpp") } -repositories { - maven("http://dl.bintray.com/kyonifer/maven") -} +repositories.maven("http://dl.bintray.com/kyonifer/maven") kotlin.sourceSets { commonMain { @@ -13,16 +9,19 @@ kotlin.sourceSets { api("com.kyonifer:koma-core-api-common:0.12") } } + jvmMain { dependencies { api("com.kyonifer:koma-core-api-jvm:0.12") } } + jvmTest { dependencies { implementation("com.kyonifer:koma-core-ejml:0.12") } } + jsMain { dependencies { api("com.kyonifer:koma-core-api-js:0.12") diff --git a/kmath-memory/build.gradle.kts b/kmath-memory/build.gradle.kts index 44a5ae24d..94527a6a3 100644 --- a/kmath-memory/build.gradle.kts +++ b/kmath-memory/build.gradle.kts @@ -1,2 +1 @@ -plugins { id("scientifik.mpp") } -kotlin.sourceSets.all { languageSettings.useExperimentalAnnotation("kotlin.contracts.ExperimentalContracts") } +plugins { id("ru.mipt.npm.mpp") } diff --git a/kmath-memory/src/commonMain/kotlin/scientifik/memory/Memory.kt b/kmath-memory/src/commonMain/kotlin/scientifik/memory/Memory.kt index 177c6b46b..9b6eb0435 100644 --- a/kmath-memory/src/commonMain/kotlin/scientifik/memory/Memory.kt +++ b/kmath-memory/src/commonMain/kotlin/scientifik/memory/Memory.kt @@ -6,84 +6,84 @@ import kotlin.contracts.contract /** * Represents a display of certain memory structure. */ -interface Memory { +public interface Memory { /** * The length of this memory in bytes. */ - val size: Int + public val size: Int /** * Get a projection of this memory (it reflects the changes in the parent memory block). */ - fun view(offset: Int, length: Int): Memory + public fun view(offset: Int, length: Int): Memory /** * Creates an independent copy of this memory. */ - fun copy(): Memory + public fun copy(): Memory /** * Gets or creates a reader of this memory. */ - fun reader(): MemoryReader + public fun reader(): MemoryReader /** * Gets or creates a writer of this memory. */ - fun writer(): MemoryWriter + public fun writer(): MemoryWriter - companion object + public companion object } /** * The interface to read primitive types in this memory. */ -interface MemoryReader { +public interface MemoryReader { /** * The underlying memory. */ - val memory: Memory + public val memory: Memory /** * Reads [Double] at certain [offset]. */ - fun readDouble(offset: Int): Double + public fun readDouble(offset: Int): Double /** * Reads [Float] at certain [offset]. */ - fun readFloat(offset: Int): Float + public fun readFloat(offset: Int): Float /** * Reads [Byte] at certain [offset]. */ - fun readByte(offset: Int): Byte + public fun readByte(offset: Int): Byte /** * Reads [Short] at certain [offset]. */ - fun readShort(offset: Int): Short + public fun readShort(offset: Int): Short /** * Reads [Int] at certain [offset]. */ - fun readInt(offset: Int): Int + public fun readInt(offset: Int): Int /** * Reads [Long] at certain [offset]. */ - fun readLong(offset: Int): Long + public fun readLong(offset: Int): Long /** * Disposes this reader if needed. */ - fun release() + public fun release() } /** * Uses the memory for read then releases the reader. */ -inline fun Memory.read(block: MemoryReader.() -> R): R { +public inline fun Memory.read(block: MemoryReader.() -> R): R { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } val reader = reader() val result = reader.block() @@ -94,52 +94,52 @@ inline fun Memory.read(block: MemoryReader.() -> R): R { /** * The interface to write primitive types into this memory. */ -interface MemoryWriter { +public interface MemoryWriter { /** * The underlying memory. */ - val memory: Memory + public val memory: Memory /** * Writes [Double] at certain [offset]. */ - fun writeDouble(offset: Int, value: Double) + public fun writeDouble(offset: Int, value: Double) /** * Writes [Float] at certain [offset]. */ - fun writeFloat(offset: Int, value: Float) + public fun writeFloat(offset: Int, value: Float) /** * Writes [Byte] at certain [offset]. */ - fun writeByte(offset: Int, value: Byte) + public fun writeByte(offset: Int, value: Byte) /** * Writes [Short] at certain [offset]. */ - fun writeShort(offset: Int, value: Short) + public fun writeShort(offset: Int, value: Short) /** * Writes [Int] at certain [offset]. */ - fun writeInt(offset: Int, value: Int) + public fun writeInt(offset: Int, value: Int) /** * Writes [Long] at certain [offset]. */ - fun writeLong(offset: Int, value: Long) + public fun writeLong(offset: Int, value: Long) /** * Disposes this writer if needed. */ - fun release() + public fun release() } /** * Uses the memory for write then releases the writer. */ -inline fun Memory.write(block: MemoryWriter.() -> Unit) { +public inline fun Memory.write(block: MemoryWriter.() -> Unit) { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } writer().apply(block).release() } @@ -147,10 +147,10 @@ inline fun Memory.write(block: MemoryWriter.() -> Unit) { /** * Allocates the most effective platform-specific memory. */ -expect fun Memory.Companion.allocate(length: Int): Memory +public expect 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]. */ -expect fun Memory.Companion.wrap(array: ByteArray): Memory +public expect fun Memory.Companion.wrap(array: ByteArray): Memory diff --git a/kmath-memory/src/commonMain/kotlin/scientifik/memory/MemorySpec.kt b/kmath-memory/src/commonMain/kotlin/scientifik/memory/MemorySpec.kt index 1381afbec..5bb163bc1 100644 --- a/kmath-memory/src/commonMain/kotlin/scientifik/memory/MemorySpec.kt +++ b/kmath-memory/src/commonMain/kotlin/scientifik/memory/MemorySpec.kt @@ -5,45 +5,45 @@ package scientifik.memory * * @param T the type of object this spec manages. */ -interface MemorySpec { +public interface MemorySpec { /** * Size of [T] in bytes after serialization. */ - val objectSize: Int + public val objectSize: Int /** * Reads the object starting from [offset]. */ - fun MemoryReader.read(offset: Int): T + public fun MemoryReader.read(offset: Int): T // TODO consider thread safety /** * Writes the object [value] starting from [offset]. */ - fun MemoryWriter.write(offset: Int, value: T) + public fun MemoryWriter.write(offset: Int, value: T) } /** * Reads the object with [spec] starting from [offset]. */ -fun MemoryReader.read(spec: MemorySpec, offset: Int): T = with(spec) { read(offset) } +public fun MemoryReader.read(spec: MemorySpec, offset: Int): T = with(spec) { read(offset) } /** * Writes the object [value] with [spec] starting from [offset]. */ -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]. */ -inline fun MemoryReader.readArray(spec: MemorySpec, offset: Int, size: Int): Array = +public inline fun MemoryReader.readArray(spec: MemorySpec, offset: Int, size: Int): Array = Array(size) { i -> with(spec) { read(offset + i * objectSize) } } /** * Writes [array] of objects mapped by [spec] at certain [offset]. */ -fun MemoryWriter.writeArray(spec: MemorySpec, offset: Int, array: Array): Unit = +public fun MemoryWriter.writeArray(spec: MemorySpec, offset: Int, array: Array): Unit = with(spec) { array.indices.forEach { i -> write(offset + i * objectSize, array[i]) } } // TODO It is possible to add elastic MemorySpec with unknown object size diff --git a/kmath-memory/src/jsMain/kotlin/scientifik/memory/DataViewMemory.kt b/kmath-memory/src/jsMain/kotlin/scientifik/memory/DataViewMemory.kt index 974750502..452ef1fea 100644 --- a/kmath-memory/src/jsMain/kotlin/scientifik/memory/DataViewMemory.kt +++ b/kmath-memory/src/jsMain/kotlin/scientifik/memory/DataViewMemory.kt @@ -83,7 +83,7 @@ private class DataViewMemory(val view: DataView) : Memory { /** * Allocates memory based on a [DataView]. */ -actual fun Memory.Companion.allocate(length: Int): Memory { +public actual fun Memory.Companion.allocate(length: Int): Memory { val buffer = ArrayBuffer(length) return DataViewMemory(DataView(buffer, 0, length)) } @@ -92,7 +92,7 @@ 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]. */ -actual fun Memory.Companion.wrap(array: ByteArray): Memory { +public actual fun Memory.Companion.wrap(array: ByteArray): Memory { @Suppress("CAST_NEVER_SUCCEEDS") val int8Array = array as Int8Array return DataViewMemory(DataView(int8Array.buffer, int8Array.byteOffset, int8Array.length)) } diff --git a/kmath-memory/src/jvmMain/kotlin/scientifik/memory/ByteBufferMemory.kt b/kmath-memory/src/jvmMain/kotlin/scientifik/memory/ByteBufferMemory.kt index f4967bf5c..e98340a44 100644 --- a/kmath-memory/src/jvmMain/kotlin/scientifik/memory/ByteBufferMemory.kt +++ b/kmath-memory/src/jvmMain/kotlin/scientifik/memory/ByteBufferMemory.kt @@ -94,14 +94,14 @@ internal class ByteBufferMemory( /** * Allocates memory based on a [ByteBuffer]. */ -actual fun Memory.Companion.allocate(length: Int): Memory = +public actual fun Memory.Companion.allocate(length: Int): Memory = ByteBufferMemory(checkNotNull(ByteBuffer.allocate(length))) /** * 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]. */ -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. @@ -111,14 +111,14 @@ actual fun Memory.Companion.wrap(array: ByteArray): Memory = ByteBufferMemory(ch * @param size the size of memory to map. * @return the [Memory] object. */ -fun ByteBuffer.asMemory(startOffset: Int = 0, size: Int = limit()): Memory = +public fun ByteBuffer.asMemory(startOffset: Int = 0, size: Int = limit()): Memory = ByteBufferMemory(this, startOffset, size) /** * Uses direct memory-mapped buffer from file to read something and close it afterwards. */ @Throws(IOException::class) -inline fun Path.readAsMemory(position: Long = 0, size: Long = Files.size(this), block: Memory.() -> R): R { +public inline fun Path.readAsMemory(position: Long = 0, size: Long = Files.size(this), block: Memory.() -> R): R { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } return FileChannel diff --git a/kmath-prob/build.gradle.kts b/kmath-prob/build.gradle.kts index a69d61b73..4c9663e5f 100644 --- a/kmath-prob/build.gradle.kts +++ b/kmath-prob/build.gradle.kts @@ -1,6 +1,4 @@ -plugins { - id("scientifik.mpp") -} +plugins { id("ru.mipt.npm.mpp") } kotlin.sourceSets { commonMain { @@ -8,10 +6,11 @@ kotlin.sourceSets { api(project(":kmath-coroutines")) } } - jvmMain{ - dependencies{ + + jvmMain { + dependencies { api("org.apache.commons:commons-rng-sampling:1.3") api("org.apache.commons:commons-rng-simple:1.3") } } -} \ No newline at end of file +} diff --git a/kmath-prob/src/jvmMain/kotlin/scientifik/kmath/prob/distributions.kt b/kmath-prob/src/jvmMain/kotlin/scientifik/kmath/prob/distributions.kt index 412454994..ddb50ef42 100644 --- a/kmath-prob/src/jvmMain/kotlin/scientifik/kmath/prob/distributions.kt +++ b/kmath-prob/src/jvmMain/kotlin/scientifik/kmath/prob/distributions.kt @@ -11,7 +11,7 @@ import kotlin.math.exp import kotlin.math.pow import kotlin.math.sqrt -abstract class ContinuousSamplerDistribution : Distribution { +public abstract class ContinuousSamplerDistribution : Distribution { private inner class ContinuousSamplerChain(val generator: RandomGenerator) : BlockingRealChain() { private val sampler = buildCMSampler(generator) @@ -26,7 +26,7 @@ abstract class ContinuousSamplerDistribution : Distribution { override fun sample(generator: RandomGenerator): BlockingRealChain = ContinuousSamplerChain(generator) } -abstract class DiscreteSamplerDistribution : Distribution { +public abstract class DiscreteSamplerDistribution : Distribution { private inner class ContinuousSamplerChain(val generator: RandomGenerator) : BlockingIntChain() { private val sampler = buildSampler(generator) @@ -41,7 +41,7 @@ abstract class DiscreteSamplerDistribution : Distribution { override fun sample(generator: RandomGenerator): BlockingIntChain = ContinuousSamplerChain(generator) } -enum class NormalSamplerMethod { +public enum class NormalSamplerMethod { BoxMuller, Marsaglia, Ziggurat @@ -54,7 +54,7 @@ private fun normalSampler(method: NormalSamplerMethod, provider: UniformRandomPr NormalSamplerMethod.Ziggurat -> ZigguratNormalizedGaussianSampler(provider) } -fun Distribution.Companion.normal( +public fun Distribution.Companion.normal( method: NormalSamplerMethod = NormalSamplerMethod.Ziggurat ): Distribution = object : ContinuousSamplerDistribution() { override fun buildCMSampler(generator: RandomGenerator): ContinuousSampler { @@ -67,7 +67,7 @@ fun Distribution.Companion.normal( } } -fun Distribution.Companion.normal( +public fun Distribution.Companion.normal( mean: Double, sigma: Double, method: NormalSamplerMethod = NormalSamplerMethod.Ziggurat @@ -86,7 +86,7 @@ fun Distribution.Companion.normal( } } -fun Distribution.Companion.poisson( +public fun Distribution.Companion.poisson( lambda: Double ): DiscreteSamplerDistribution = object : DiscreteSamplerDistribution() { diff --git a/kmath-viktor/build.gradle.kts b/kmath-viktor/build.gradle.kts index 52ee7c497..6fe8ad878 100644 --- a/kmath-viktor/build.gradle.kts +++ b/kmath-viktor/build.gradle.kts @@ -1,10 +1,8 @@ -plugins { - id("scientifik.jvm") -} +plugins { id("ru.mipt.npm.jvm") } description = "Binding for https://github.com/JetBrains-Research/viktor" dependencies { api(project(":kmath-core")) api("org.jetbrains.bio:viktor:1.0.1") -} \ No newline at end of file +} diff --git a/settings.gradle.kts b/settings.gradle.kts index 487e1d87f..102cde93f 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,14 +1,12 @@ pluginManagement { - - val toolsVersion = "0.5.0" + val toolsVersion = "0.6.0-dev-3" plugins { - id("kotlinx.benchmark") version "0.2.0-dev-8" - id("scientifik.mpp") version toolsVersion - id("scientifik.jvm") version toolsVersion - id("scientifik.atomic") version toolsVersion - id("scientifik.publish") version toolsVersion - kotlin("plugin.allopen") version "1.3.72" + id("kotlinx.benchmark") version "0.2.0-dev-20" + id("ru.mipt.npm.mpp") version toolsVersion + id("ru.mipt.npm.jvm") version toolsVersion + id("ru.mipt.npm.publish") version toolsVersion + kotlin("plugin.allopen") version "1.4.0" } repositories { @@ -20,17 +18,10 @@ pluginManagement { maven("https://dl.bintray.com/mipt-npm/dev") maven("https://dl.bintray.com/kotlin/kotlinx") } - - resolutionStrategy { - eachPlugin { - when (requested.id.id) { - "scientifik.mpp", "scientifik.jvm", "scientifik.publish" -> useModule("scientifik:gradle-tools:$toolsVersion") - } - } - } } rootProject.name = "kmath" + include( ":kmath-memory", ":kmath-core",