diff --git a/build.gradle.kts b/build.gradle.kts index 437f0030a..702373b1e 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -22,8 +22,8 @@ plugins { } allprojects { - apply(plugin = "maven-publish") - if(project.name.startsWith("kmath")) { + if (project.name.startsWith("kmath")) { + apply(plugin = "maven-publish") apply(plugin = "com.jfrog.artifactory") } diff --git a/doc/buffers.md b/doc/buffers.md new file mode 100644 index 000000000..6208deaff --- /dev/null +++ b/doc/buffers.md @@ -0,0 +1 @@ +**TODO** \ No newline at end of file diff --git a/doc/expressions.md b/doc/expressions.md new file mode 100644 index 000000000..1e05e5340 --- /dev/null +++ b/doc/expressions.md @@ -0,0 +1,26 @@ +# Expressions + +**Experimental: this API is in early stage and could change any time** + +Expressions is an experimental feature which allows to construct lazily or immediately calculated parametric mathematical +expressions. + +The potential use-cases for it (so far) are following: + +* Lazy evaluation (in general simple lambda is better, but there are some border cases) + +* Automatic differentiation in single-dimension and in multiple dimensions + +* Generation of mathematical syntax trees with subsequent code generation for other languages + +* Maybe symbolic computations (needs additional research) + +The workhorse of this API is `Expression` interface which exposes single `operator fun invoke(arguments: Map): T` +method. `ExpressionContext` is used to generate expressions and introduce variables. + +Currently there are two implementations: + +* Generic `ExpressionField` in `kmath-core` which allows construction of custom lazy expressions + +* Auto-differentiation expression in `kmath-commons` module allows to use full power of `DerivativeStructure` +from commons-math. **TODO: add example** diff --git a/doc/features.md b/doc/features.md new file mode 100644 index 000000000..e69de29bb diff --git a/doc/histograms.md b/doc/histograms.md new file mode 100644 index 000000000..6208deaff --- /dev/null +++ b/doc/histograms.md @@ -0,0 +1 @@ +**TODO** \ No newline at end of file diff --git a/doc/linear.md b/doc/linear.md new file mode 100644 index 000000000..e69de29bb diff --git a/doc/operations.md b/doc/operations.md index ff4a407ee..425d791e8 100644 --- a/doc/operations.md +++ b/doc/operations.md @@ -14,7 +14,7 @@ val c3 = c1 + c2 `ComplexField` also features special operations to mix complex and real numbers, for example: ```kotlin -val c1 = Complex(1.0,2.0) +val c1 = Complex(1.0, 2.0) val c2 = ComplexField.run{ c1 - 1.0} // Returns: [re:0.0, im: 2.0] val c3 = ComplexField.run{ c1 - i*2.0} ``` @@ -27,8 +27,8 @@ that. Watch [KT-10468](https://youtrack.jetbrains.com/issue/KT-10468) and [KEEP- Contexts allow one to build more complex structures. For example, it is possible to create a `Matrix` from complex elements like so: ```kotlin -val element = NDElements.create(field = ComplexField, shape = intArrayOf(2,2)){index: IntArray -> - Complex(index[0] - index[1], index[0] + index[1]) +val element = NDElement.complex(shape = intArrayOf(2,2)){ index: IntArray -> + Complex(index[0].toDouble() - index[1].toDouble(), index[0].toDouble() + index[1].toDouble()) } ``` diff --git a/examples/build.gradle.kts b/examples/build.gradle.kts deleted file mode 100644 index 86ed9ced6..000000000 --- a/examples/build.gradle.kts +++ /dev/null @@ -1,15 +0,0 @@ -plugins { - kotlin("jvm") -} - -description = "Examples for different kmath features" - -dependencies { - implementation(project(":kmath-core")) - implementation(project(":kmath-coroutines")) - implementation(project(":kmath-commons")) - implementation(project(":kmath-koma")) - implementation(group = "com.kyonifer", name = "koma-core-ejml", version = "0.12") - testImplementation("org.jetbrains.kotlin:kotlin-test") - testImplementation("org.jetbrains.kotlin:kotlin-test-junit") -} diff --git a/examples/expressions.main.kts b/examples/expressions.main.kts new file mode 100644 index 000000000..baf6a4ed0 --- /dev/null +++ b/examples/expressions.main.kts @@ -0,0 +1 @@ +@file:DependsOn("scientifik:kmath-core-jvm:0.0.3-dev") \ No newline at end of file diff --git a/kmath-commons/src/main/kotlin/scientifik/kmath/expressions/DiffExpression.kt b/kmath-commons/src/main/kotlin/scientifik/kmath/expressions/DiffExpression.kt index 4d5ea1b94..79cf92c94 100644 --- a/kmath-commons/src/main/kotlin/scientifik/kmath/expressions/DiffExpression.kt +++ b/kmath-commons/src/main/kotlin/scientifik/kmath/expressions/DiffExpression.kt @@ -2,6 +2,7 @@ package scientifik.kmath.expressions import org.apache.commons.math3.analysis.differentiation.DerivativeStructure import scientifik.kmath.operations.ExtendedField +import scientifik.kmath.operations.Field import kotlin.properties.ReadOnlyProperty import kotlin.reflect.KProperty @@ -25,8 +26,8 @@ class DerivativeStructureField(val order: Int, val parameters: Map DerivativeStru fun DiffExpression.derivative(vararg orders: Pair) = derivative(mapOf(*orders)) fun DiffExpression.derivative(name: String) = derivative(name to 1) +/** + * A context for [DiffExpression] (not to be confused with [DerivativeStructure]) + */ +object DiffExpressionContext : ExpressionContext, Field { + override fun variable(name: String, default: Double?) = DiffExpression { variable(name, default?.const()) } + + override fun const(value: Double): DiffExpression = DiffExpression { value.const() } + + override fun add(a: DiffExpression, b: DiffExpression) = DiffExpression { a.function(this) + b.function(this) } + + override val zero = DiffExpression { 0.0.const() } + + override fun multiply(a: DiffExpression, k: Number) = DiffExpression { a.function(this) * k } + + override val one = DiffExpression { 1.0.const() } + + override fun multiply(a: DiffExpression, b: DiffExpression) = DiffExpression { a.function(this) * b.function(this) } + + override fun divide(a: DiffExpression, b: DiffExpression) = DiffExpression { a.function(this) / b.function(this) } +} + 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 2f54ae1b2..ad345bc5a 100644 --- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/expressions/Expression.kt +++ b/kmath-core/src/commonMain/kotlin/scientifik/kmath/expressions/Expression.kt @@ -4,16 +4,27 @@ import scientifik.kmath.operations.Field import scientifik.kmath.operations.Ring import scientifik.kmath.operations.Space - +/** + * An elementary function that could be invoked on a map of arguments + */ interface Expression { operator fun invoke(arguments: Map): T } operator fun Expression.invoke(vararg pairs: Pair): T = invoke(mapOf(*pairs)) +/** + * A context for expression construction + */ interface ExpressionContext { + /** + * Introduce a variable into expression context + */ fun variable(name: String, default: T? = null): Expression + /** + * A constant expression which does not depend on arguments + */ fun const(value: T): Expression } diff --git a/kmath-coroutines/src/commonTest/kotlin/scientifik/kmath/structures/LazyNDFieldTest.kt b/kmath-coroutines/src/commonTest/kotlin/scientifik/kmath/structures/LazyNDFieldTest.kt deleted file mode 100644 index ea3cb9494..000000000 --- a/kmath-coroutines/src/commonTest/kotlin/scientifik/kmath/structures/LazyNDFieldTest.kt +++ /dev/null @@ -1,16 +0,0 @@ -package scientifik.kmath.structures - - -class LazyNDFieldTest { -// @Test -// fun testLazyStructure() { -// var counter = 0 -// val regularStructure = NDField.auto(intArrayOf(2, 2, 2), IntRing).produce { it[0] + it[1] - it[2] } -// val result = (regularStructure.lazy(IntRing) + 2).map { -// counter++ -// it * it -// } -// assertEquals(4, result[0, 0, 0]) -// assertEquals(1, counter) -// } -} \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts index d6fd42594..b306d1c8d 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -25,6 +25,5 @@ include( ":kmath-commons", ":kmath-koma", ":kmath-sequential", - ":benchmarks", - ":examples" + ":benchmarks" )