Merge pull request #504 from SciProgCentre/dev

Merge to update docs and contributions
This commit is contained in:
SPC-code 2022-10-03 20:58:00 +03:00 committed by GitHub
commit 2376d278c3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
531 changed files with 43184 additions and 2203 deletions

3
.github/CODEOWNERS vendored Normal file
View File

@ -0,0 +1,3 @@
@altavir
/kmath-trajectory @ESchouten

View File

@ -1,6 +1,7 @@
<component name="CopyrightManager"> <component name="CopyrightManager">
<copyright> <copyright>
<option name="notice" value="Copyright 2018-2021 KMath contributors.&#10;Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file." /> <option name="allowReplaceRegexp" value="Copyright \d{4}-\d{4} KMath" />
<option name="notice" value="Copyright 2018-&amp;#36;today.year KMath contributors.&#10;Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file." />
<option name="myName" value="kmath" /> <option name="myName" value="kmath" />
</copyright> </copyright>
</component> </component>

View File

@ -1,5 +1,5 @@
<component name="CopyrightManager"> <component name="CopyrightManager">
<settings default="kmath"> <settings>
<module2copyright> <module2copyright>
<element module="Apply copyright" copyright="kmath" /> <element module="Apply copyright" copyright="kmath" />
</module2copyright> </module2copyright>

0
.space/CODEOWNERS Normal file
View File

View File

@ -2,8 +2,16 @@
## [Unreleased] ## [Unreleased]
### Added ### Added
- 2D optimal trajectory computation in a separate module `kmath-trajectory`
- Autodiff for generic algebra elements in core!
- Algebra now has an obligatory `bufferFactory` (#477).
### Changed ### Changed
- Major refactor of tensors (only minor API changes)
- Kotlin 1.7.20
- `LazyStructure` `deffered` -> `async` to comply with coroutines code style
- Default `dot` operation in tensor algebra no longer support broadcasting. Instead `matmul` operation is added to `DoubleTensorAlgebra`.
- Multik went MPP
### Deprecated ### Deprecated

View File

@ -1,6 +1,6 @@
[![JetBrains Research](https://jb.gg/badges/research.svg)](https://confluence.jetbrains.com/display/ALL/JetBrains+on+GitHub) [![JetBrains Research](https://jb.gg/badges/research.svg)](https://confluence.jetbrains.com/display/ALL/JetBrains+on+GitHub)
[![DOI](https://zenodo.org/badge/129486382.svg)](https://zenodo.org/badge/latestdoi/129486382) [![DOI](https://zenodo.org/badge/129486382.svg)](https://zenodo.org/badge/latestdoi/129486382)
![Gradle build](https://github.com/mipt-npm/kmath/workflows/Gradle%20build/badge.svg) ![Gradle build](https://github.com/SciProgCentre/kmath/workflows/Gradle%20build/badge.svg)
[![Maven Central](https://img.shields.io/maven-central/v/space.kscience/kmath-core.svg?label=Maven%20Central)](https://search.maven.org/search?q=g:%22space.kscience%22) [![Maven Central](https://img.shields.io/maven-central/v/space.kscience/kmath-core.svg?label=Maven%20Central)](https://search.maven.org/search?q=g:%22space.kscience%22)
[![Space](https://img.shields.io/badge/dynamic/xml?color=orange&label=Space&query=//metadata/versioning/latest&url=https%3A%2F%2Fmaven.pkg.jetbrains.space%2Fmipt-npm%2Fp%2Fsci%2Fmaven%2Fspace%2Fkscience%2Fkmath-core%2Fmaven-metadata.xml)](https://maven.pkg.jetbrains.space/mipt-npm/p/sci/maven/space/kscience/) [![Space](https://img.shields.io/badge/dynamic/xml?color=orange&label=Space&query=//metadata/versioning/latest&url=https%3A%2F%2Fmaven.pkg.jetbrains.space%2Fmipt-npm%2Fp%2Fsci%2Fmaven%2Fspace%2Fkscience%2Fkmath-core%2Fmaven-metadata.xml)](https://maven.pkg.jetbrains.space/mipt-npm/p/sci/maven/space/kscience/)
@ -11,7 +11,7 @@ analog to Python's NumPy library. Later we found that kotlin is much more flexib
architecture designs. In contrast to `numpy` and `scipy` it is modular and has a lightweight core. The `numpy`-like architecture designs. In contrast to `numpy` and `scipy` it is modular and has a lightweight core. The `numpy`-like
experience could be achieved with [kmath-for-real](/kmath-for-real) extension module. experience could be achieved with [kmath-for-real](/kmath-for-real) extension module.
[Documentation site (**WIP**)](https://mipt-npm.github.io/kmath/) [Documentation site (**WIP**)](https://SciProgCentre.github.io/kmath/)
## Publications and talks ## Publications and talks
@ -44,7 +44,7 @@ module definitions below. The module stability could have the following levels:
* **PROTOTYPE**. On this level there are no compatibility guarantees. All methods and classes form those modules could * **PROTOTYPE**. On this level there are no compatibility guarantees. All methods and classes form those modules could
break any moment. You can still use it, but be sure to fix the specific version. break any moment. You can still use it, but be sure to fix the specific version.
* **EXPERIMENTAL**. The general API is decided, but some changes could be made. Volatile API is marked * **EXPERIMENTAL**. The general API is decided, but some changes could be made. Volatile API is marked
with `@UnstableKmathAPI` or other stability warning annotations. with `@UnstableKMathAPI` or other stability warning annotations.
* **DEVELOPMENT**. API breaking generally follows semantic versioning ideology. There could be changes in minor * **DEVELOPMENT**. API breaking generally follows semantic versioning ideology. There could be changes in minor
versions, but not in patch versions. API is protected versions, but not in patch versions. API is protected
with [binary-compatibility-validator](https://github.com/Kotlin/binary-compatibility-validator) tool. with [binary-compatibility-validator](https://github.com/Kotlin/binary-compatibility-validator) tool.
@ -86,8 +86,8 @@ module definitions below. The module stability could have the following levels:
> **Maturity**: PROTOTYPE > **Maturity**: PROTOTYPE
> >
> **Features:** > **Features:**
> - [complex](kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/Complex.kt) : Complex Numbers > - [complex](kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/Complex.kt) : Complex numbers operations
> - [quaternion](kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/Quaternion.kt) : Quaternions > - [quaternion](kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/Quaternion.kt) : Quaternions and their composition
### [kmath-core](kmath-core) ### [kmath-core](kmath-core)
@ -214,6 +214,28 @@ One can still use generic algebras though.
> >
> **Maturity**: EXPERIMENTAL > **Maturity**: EXPERIMENTAL
### [kmath-polynomial](kmath-polynomial)
>
>
> **Maturity**: PROTOTYPE
>
> **Features:**
> - [polynomial abstraction](kmath-polynomial/src/commonMain/kotlin/space/kscience/kmath/functions/Polynomial.kt) : Abstraction for polynomial spaces.
> - [rational function abstraction](kmath-polynomial/src/commonMain/kotlin/space/kscience/kmath/functions/RationalFunction.kt) : Abstraction for rational functions spaces.
> - ["list" polynomials](kmath-polynomial/src/commonMain/kotlin/space/kscience/kmath/functions/ListRationalFunction.kt) : List implementation of univariate polynomials.
> - ["list" rational functions](kmath-polynomial/src/commonMain/kotlin/space/kscience/kmath/functions/ListPolynomial.kt) : List implementation of univariate rational functions.
> - ["list" polynomials and rational functions constructors](kmath-polynomial/src/commonMain/kotlin/space/kscience/kmath/functions/listConstructors.kt) : Constructors for list polynomials and rational functions.
> - ["list" polynomials and rational functions utilities](kmath-polynomial/src/commonMain/kotlin/space/kscience/kmath/functions/listUtil.kt) : Utilities for list polynomials and rational functions.
> - ["numbered" polynomials](kmath-polynomial/src/commonMain/kotlin/space/kscience/kmath/functions/NumberedRationalFunction.kt) : Numbered implementation of multivariate polynomials.
> - ["numbered" rational functions](kmath-polynomial/src/commonMain/kotlin/space/kscience/kmath/functions/NumberedPolynomial.kt) : Numbered implementation of multivariate rational functions.
> - ["numbered" polynomials and rational functions constructors](kmath-polynomial/src/commonMain/kotlin/space/kscience/kmath/functions/numberedConstructors.kt) : Constructors for numbered polynomials and rational functions.
> - ["numbered" polynomials and rational functions utilities](kmath-polynomial/src/commonMain/kotlin/space/kscience/kmath/functions/numberedUtil.kt) : Utilities for numbered polynomials and rational functions.
> - ["labeled" polynomials](kmath-polynomial/src/commonMain/kotlin/space/kscience/kmath/functions/LabeledRationalFunction.kt) : Labeled implementation of multivariate polynomials.
> - ["labeled" rational functions](kmath-polynomial/src/commonMain/kotlin/space/kscience/kmath/functions/LabeledPolynomial.kt) : Labeled implementation of multivariate rational functions.
> - ["labeled" polynomials and rational functions constructors](kmath-polynomial/src/commonMain/kotlin/space/kscience/kmath/functions/labeledConstructors.kt) : Constructors for labeled polynomials and rational functions.
> - ["labeled" polynomials and rational functions utilities](kmath-polynomial/src/commonMain/kotlin/space/kscience/kmath/functions/labeledUtil.kt) : Utilities for labeled polynomials and rational functions.
### [kmath-stat](kmath-stat) ### [kmath-stat](kmath-stat)
> >
> >
@ -240,11 +262,21 @@ One can still use generic algebras though.
> - [linear algebra operations](kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/api/LinearOpsTensorAlgebra.kt) : Advanced linear algebra operations like LU decomposition, SVD, etc. > - [linear algebra operations](kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/api/LinearOpsTensorAlgebra.kt) : Advanced linear algebra operations like LU decomposition, SVD, etc.
### [kmath-trajectory](kmath-trajectory)
> Path and trajectory optimization
>
> **Maturity**: PROTOTYPE
### [kmath-viktor](kmath-viktor) ### [kmath-viktor](kmath-viktor)
> >
> >
> **Maturity**: DEVELOPMENT > **Maturity**: DEVELOPMENT
### [test-utils](test-utils)
>
>
> **Maturity**: EXPERIMENTAL
## Multi-platform support ## Multi-platform support
@ -261,8 +293,7 @@ performance and flexibility.
We expect to focus on creating convenient universal API first and then work on increasing performance for specific We expect to focus on creating convenient universal API first and then work on increasing performance for specific
cases. We expect the worst KMath benchmarks will perform better than native Python, but worse than optimized cases. We expect the worst KMath benchmarks will perform better than native Python, but worse than optimized
native/SciPy (mostly due to boxing operations on primitive numbers). The best performance of optimized parts could be native/SciPy (mostly due to boxing operations on primitive numbers). The best performance of optimized parts could be better than SciPy.
better than SciPy.
## Requirements ## Requirements
@ -294,4 +325,4 @@ Gradle `6.0+` is required for multiplatform artifacts.
The project requires a lot of additional work. The most important thing we need is a feedback about what features are The project requires a lot of additional work. The most important thing we need is a feedback about what features are
required the most. Feel free to create feature requests. We are also welcome to code contributions, especially in issues required the most. Feel free to create feature requests. We are also welcome to code contributions, especially in issues
marked with marked with
[waiting for a hero](https://github.com/mipt-npm/kmath/labels/waiting%20for%20a%20hero) label. [waiting for a hero](https://github.com/SciProgCentre/kmath/labels/waiting%20for%20a%20hero) label.

View File

@ -1,5 +1,6 @@
@file:Suppress("UNUSED_VARIABLE") @file:Suppress("UNUSED_VARIABLE")
import org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile
import space.kscience.kmath.benchmarks.addBenchmarkProperties import space.kscience.kmath.benchmarks.addBenchmarkProperties
plugins { plugins {
@ -15,6 +16,8 @@ repositories {
mavenCentral() mavenCentral()
} }
val multikVersion: String by rootProject.extra
kotlin { kotlin {
jvm() jvm()
@ -39,7 +42,9 @@ kotlin {
implementation(project(":kmath-dimensions")) implementation(project(":kmath-dimensions"))
implementation(project(":kmath-for-real")) implementation(project(":kmath-for-real"))
implementation(project(":kmath-tensors")) implementation(project(":kmath-tensors"))
implementation("org.jetbrains.kotlinx:kotlinx-benchmark-runtime:0.4.2") implementation(project(":kmath-multik"))
implementation("org.jetbrains.kotlinx:multik-default:$multikVersion")
implementation(npmlibs.kotlinx.benchmark.runtime)
} }
} }
@ -51,7 +56,6 @@ kotlin {
implementation(project(":kmath-kotlingrad")) implementation(project(":kmath-kotlingrad"))
implementation(project(":kmath-viktor")) implementation(project(":kmath-viktor"))
implementation(project(":kmath-jafama")) implementation(project(":kmath-jafama"))
implementation(project(":kmath-multik"))
implementation(projects.kmath.kmathTensorflow) implementation(projects.kmath.kmathTensorflow)
implementation("org.tensorflow:tensorflow-core-platform:0.4.0") implementation("org.tensorflow:tensorflow-core-platform:0.4.0")
implementation("org.nd4j:nd4j-native:1.0.0-M1") implementation("org.nd4j:nd4j-native:1.0.0-M1")
@ -155,7 +159,7 @@ kotlin.sourceSets.all {
} }
} }
tasks.withType<org.jetbrains.kotlin.gradle.dsl.KotlinJvmCompile> { tasks.withType<KotlinJvmCompile> {
kotlinOptions { kotlinOptions {
jvmTarget = "11" jvmTarget = "11"
freeCompilerArgs = freeCompilerArgs + "-Xjvm-default=all" + "-Xlambdas=indy" freeCompilerArgs = freeCompilerArgs + "-Xjvm-default=all" + "-Xlambdas=indy"
@ -163,7 +167,7 @@ tasks.withType<org.jetbrains.kotlin.gradle.dsl.KotlinJvmCompile> {
} }
readme { readme {
maturity = ru.mipt.npm.gradle.Maturity.EXPERIMENTAL maturity = space.kscience.gradle.Maturity.EXPERIMENTAL
} }
addBenchmarkProperties() addBenchmarkProperties()

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2022 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2022 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2022 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2022 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2022 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
@ -13,10 +13,8 @@ import space.kscience.kmath.commons.linear.CMLinearSpace
import space.kscience.kmath.ejml.EjmlLinearSpaceDDRM import space.kscience.kmath.ejml.EjmlLinearSpaceDDRM
import space.kscience.kmath.linear.invoke import space.kscience.kmath.linear.invoke
import space.kscience.kmath.linear.linearSpace import space.kscience.kmath.linear.linearSpace
import space.kscience.kmath.multik.multikAlgebra
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.DoubleField
import space.kscience.kmath.operations.invoke import space.kscience.kmath.operations.invoke
import space.kscience.kmath.structures.Buffer
import space.kscience.kmath.tensorflow.produceWithTF import space.kscience.kmath.tensorflow.produceWithTF
import space.kscience.kmath.tensors.core.DoubleTensorAlgebra import space.kscience.kmath.tensors.core.DoubleTensorAlgebra
import space.kscience.kmath.tensors.core.tensorAlgebra import space.kscience.kmath.tensors.core.tensorAlgebra
@ -79,12 +77,12 @@ internal class DotBenchmark {
} }
@Benchmark @Benchmark
fun multikDot(blackhole: Blackhole) = with(DoubleField.multikAlgebra) { fun multikDot(blackhole: Blackhole) = with(multikAlgebra) {
blackhole.consume(matrix1 dot matrix2) blackhole.consume(matrix1 dot matrix2)
} }
@Benchmark @Benchmark
fun bufferedDot(blackhole: Blackhole) = with(DoubleField.linearSpace(Buffer.Companion::auto)) { fun bufferedDot(blackhole: Blackhole) = with(DoubleField.linearSpace) {
blackhole.consume(matrix1 dot matrix2) blackhole.consume(matrix1 dot matrix2)
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2022 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2022 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2022 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2022 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
@ -13,14 +13,12 @@ import org.jetbrains.kotlinx.multik.api.Multik
import org.jetbrains.kotlinx.multik.api.ones import org.jetbrains.kotlinx.multik.api.ones
import org.jetbrains.kotlinx.multik.ndarray.data.DN import org.jetbrains.kotlinx.multik.ndarray.data.DN
import org.jetbrains.kotlinx.multik.ndarray.data.DataType import org.jetbrains.kotlinx.multik.ndarray.data.DataType
import space.kscience.kmath.multik.multikAlgebra
import space.kscience.kmath.nd.BufferedFieldOpsND import space.kscience.kmath.nd.BufferedFieldOpsND
import space.kscience.kmath.nd.StructureND import space.kscience.kmath.nd.StructureND
import space.kscience.kmath.nd.ndAlgebra import space.kscience.kmath.nd.ndAlgebra
import space.kscience.kmath.nd.one import space.kscience.kmath.nd.one
import space.kscience.kmath.nd4j.nd4j import space.kscience.kmath.nd4j.nd4j
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.DoubleField
import space.kscience.kmath.structures.Buffer
import space.kscience.kmath.tensors.core.DoubleTensor import space.kscience.kmath.tensors.core.DoubleTensor
import space.kscience.kmath.tensors.core.one import space.kscience.kmath.tensors.core.one
import space.kscience.kmath.tensors.core.tensorAlgebra import space.kscience.kmath.tensors.core.tensorAlgebra
@ -28,12 +26,6 @@ import space.kscience.kmath.viktor.viktorAlgebra
@State(Scope.Benchmark) @State(Scope.Benchmark)
internal class NDFieldBenchmark { internal class NDFieldBenchmark {
@Benchmark
fun autoFieldAdd(blackhole: Blackhole) = with(autoField) {
var res: StructureND<Double> = one(shape)
repeat(n) { res += 1.0 }
blackhole.consume(res)
}
@Benchmark @Benchmark
fun specializedFieldAdd(blackhole: Blackhole) = with(specializedField) { fun specializedFieldAdd(blackhole: Blackhole) = with(specializedField) {
@ -50,7 +42,7 @@ internal class NDFieldBenchmark {
} }
@Benchmark @Benchmark
fun multikAdd(blackhole: Blackhole) = with(multikField) { fun multikAdd(blackhole: Blackhole) = with(multikAlgebra) {
var res: StructureND<Double> = one(shape) var res: StructureND<Double> = one(shape)
repeat(n) { res += 1.0 } repeat(n) { res += 1.0 }
blackhole.consume(res) blackhole.consume(res)
@ -78,7 +70,7 @@ internal class NDFieldBenchmark {
} }
@Benchmark @Benchmark
fun multikInPlaceAdd(blackhole: Blackhole) = with(DoubleField.multikAlgebra) { fun multikInPlaceAdd(blackhole: Blackhole) = with(multikAlgebra) {
val res = Multik.ones<Double, DN>(shape, DataType.DoubleDataType).wrap() val res = Multik.ones<Double, DN>(shape, DataType.DoubleDataType).wrap()
repeat(n) { res += 1.0 } repeat(n) { res += 1.0 }
blackhole.consume(res) blackhole.consume(res)
@ -95,11 +87,9 @@ internal class NDFieldBenchmark {
private const val dim = 1000 private const val dim = 1000
private const val n = 100 private const val n = 100
private val shape = intArrayOf(dim, dim) private val shape = intArrayOf(dim, dim)
private val autoField = BufferedFieldOpsND(DoubleField, Buffer.Companion::auto)
private val specializedField = DoubleField.ndAlgebra private val specializedField = DoubleField.ndAlgebra
private val genericField = BufferedFieldOpsND(DoubleField, Buffer.Companion::boxing) private val genericField = BufferedFieldOpsND(DoubleField)
private val nd4jField = DoubleField.nd4j private val nd4jField = DoubleField.nd4j
private val multikField = DoubleField.multikAlgebra
private val viktorField = DoubleField.viktorAlgebra private val viktorField = DoubleField.viktorAlgebra
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2022 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2022 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
@ -10,25 +10,19 @@ import kotlinx.benchmark.Blackhole
import kotlinx.benchmark.Scope import kotlinx.benchmark.Scope
import kotlinx.benchmark.State import kotlinx.benchmark.State
import org.jetbrains.bio.viktor.F64Array import org.jetbrains.bio.viktor.F64Array
import space.kscience.kmath.nd.* import space.kscience.kmath.nd.Shape
import space.kscience.kmath.nd.StructureND
import space.kscience.kmath.nd.ndAlgebra
import space.kscience.kmath.nd.one
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.DoubleField
import space.kscience.kmath.structures.Buffer
import space.kscience.kmath.viktor.ViktorFieldND import space.kscience.kmath.viktor.ViktorFieldND
@State(Scope.Benchmark) @State(Scope.Benchmark)
internal class ViktorBenchmark { internal class ViktorBenchmark {
@Benchmark
fun automaticFieldAddition(blackhole: Blackhole) {
with(autoField) {
var res: StructureND<Double> = one(shape)
repeat(n) { res += 1.0 }
blackhole.consume(res)
}
}
@Benchmark @Benchmark
fun realFieldAddition(blackhole: Blackhole) { fun doubleFieldAddition(blackhole: Blackhole) {
with(realField) { with(doubleField) {
var res: StructureND<Double> = one(shape) var res: StructureND<Double> = one(shape)
repeat(n) { res += 1.0 } repeat(n) { res += 1.0 }
blackhole.consume(res) blackhole.consume(res)
@ -58,8 +52,7 @@ internal class ViktorBenchmark {
private val shape = Shape(dim, dim) private val shape = Shape(dim, dim)
// automatically build context most suited for given type. // automatically build context most suited for given type.
private val autoField = BufferedFieldOpsND(DoubleField, Buffer.Companion::auto) private val doubleField = DoubleField.ndAlgebra
private val realField = DoubleField.ndAlgebra
private val viktorField = ViktorFieldND(dim, dim) private val viktorField = ViktorFieldND(dim, dim)
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2022 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
@ -10,19 +10,17 @@ import kotlinx.benchmark.Blackhole
import kotlinx.benchmark.Scope import kotlinx.benchmark.Scope
import kotlinx.benchmark.State import kotlinx.benchmark.State
import org.jetbrains.bio.viktor.F64Array import org.jetbrains.bio.viktor.F64Array
import space.kscience.kmath.nd.BufferedFieldOpsND
import space.kscience.kmath.nd.Shape import space.kscience.kmath.nd.Shape
import space.kscience.kmath.nd.ndAlgebra import space.kscience.kmath.nd.ndAlgebra
import space.kscience.kmath.nd.one import space.kscience.kmath.nd.one
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.DoubleField
import space.kscience.kmath.structures.Buffer
import space.kscience.kmath.viktor.ViktorFieldND import space.kscience.kmath.viktor.ViktorFieldND
@State(Scope.Benchmark) @State(Scope.Benchmark)
internal class ViktorLogBenchmark { internal class ViktorLogBenchmark {
@Benchmark @Benchmark
fun realFieldLog(blackhole: Blackhole) { fun realFieldLog(blackhole: Blackhole) {
with(realField) { with(doubleField) {
val fortyTwo = structureND(shape) { 42.0 } val fortyTwo = structureND(shape) { 42.0 }
var res = one(shape) var res = one(shape)
repeat(n) { res = ln(fortyTwo) } repeat(n) { res = ln(fortyTwo) }
@ -54,8 +52,7 @@ internal class ViktorLogBenchmark {
private val shape = Shape(dim, dim) private val shape = Shape(dim, dim)
// automatically build context most suited for given type. // automatically build context most suited for given type.
private val autoField = BufferedFieldOpsND(DoubleField, Buffer.Companion::auto) private val doubleField = DoubleField.ndAlgebra
private val realField = DoubleField.ndAlgebra
private val viktorField = ViktorFieldND(dim, dim) private val viktorField = ViktorFieldND(dim, dim)
} }
} }

View File

@ -0,0 +1,11 @@
/*
* Copyright 2018-2022 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package space.kscience.kmath.benchmarks
import org.jetbrains.kotlinx.multik.default.DefaultEngine
import space.kscience.kmath.multik.MultikDoubleAlgebra
val multikAlgebra = MultikDoubleAlgebra(DefaultEngine())

View File

@ -1,6 +1,10 @@
import space.kscience.gradle.isInDevelopment
import space.kscience.gradle.useApache2Licence
import space.kscience.gradle.useSPCTeam
plugins { plugins {
id("ru.mipt.npm.gradle.project") id("space.kscience.gradle.project")
id("org.jetbrains.kotlinx.kover") version "0.5.0" id("org.jetbrains.kotlinx.kover") version "0.6.0"
} }
allprojects { allprojects {
@ -11,13 +15,13 @@ allprojects {
} }
group = "space.kscience" group = "space.kscience"
version = "0.3.0" version = "0.3.1-dev-4"
} }
subprojects { subprojects {
if (name.startsWith("kmath")) apply<MavenPublishPlugin>() if (name.startsWith("kmath")) apply<MavenPublishPlugin>()
plugins.withId("org.jetbrains.dokka"){ plugins.withId("org.jetbrains.dokka") {
tasks.withType<org.jetbrains.dokka.gradle.DokkaTaskPartial> { tasks.withType<org.jetbrains.dokka.gradle.DokkaTaskPartial> {
dependsOn(tasks["assemble"]) dependsOn(tasks["assemble"])
@ -31,7 +35,7 @@ subprojects {
localDirectory.set(kotlinDir) localDirectory.set(kotlinDir)
remoteUrl.set( remoteUrl.set(
java.net.URL("https://github.com/mipt-npm/kmath/tree/master/${this@subprojects.name}/$kotlinDirPath") java.net.URL("https://github.com/SciProgCentre/kmath/tree/master/${this@subprojects.name}/$kotlinDirPath")
) )
} }
@ -51,14 +55,38 @@ subprojects {
} }
} }
} }
plugins.withId("org.jetbrains.kotlin.multiplatform") {
configure<org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension> {
sourceSets {
val commonTest by getting {
dependencies {
implementation(projects.testUtils)
}
}
}
}
}
} }
readme.readmeTemplate = file("docs/templates/README-TEMPLATE.md") readme.readmeTemplate = file("docs/templates/README-TEMPLATE.md")
ksciencePublish { ksciencePublish {
github("kmath", addToRelease = false) pom("https://github.com/SciProgCentre/kmath") {
space() useApache2Licence()
useSPCTeam()
}
github("kmath", "SciProgCentre")
space(
if (isInDevelopment) {
"https://maven.pkg.jetbrains.space/mipt-npm/p/sci/dev"
} else {
"https://maven.pkg.jetbrains.space/mipt-npm/p/sci/release"
}
)
sonatype() sonatype()
} }
apiValidation.nonPublicMarkers.add("space.kscience.kmath.misc.UnstableKMathAPI") apiValidation.nonPublicMarkers.add("space.kscience.kmath.misc.UnstableKMathAPI")
val multikVersion by extra("0.2.0")

View File

@ -1,7 +1,7 @@
plugins { plugins {
`kotlin-dsl` `kotlin-dsl`
`version-catalog` `version-catalog`
alias(miptNpmLibs.plugins.kotlin.plugin.serialization) kotlin("plugin.serialization") version "1.6.21"
} }
java.targetCompatibility = JavaVersion.VERSION_11 java.targetCompatibility = JavaVersion.VERSION_11
@ -13,17 +13,18 @@ repositories {
gradlePluginPortal() gradlePluginPortal()
} }
val toolsVersion: String by extra val toolsVersion = npmlibs.versions.tools.get()
val kotlinVersion = miptNpmLibs.versions.kotlin.asProvider().get() val kotlinVersion = npmlibs.versions.kotlin.asProvider().get()
val benchmarksVersion = miptNpmLibs.versions.kotlinx.benchmark.get() val benchmarksVersion = npmlibs.versions.kotlinx.benchmark.get()
dependencies { dependencies {
api("ru.mipt.npm:gradle-tools:$toolsVersion") api("space.kscience:gradle-tools:$toolsVersion")
api(npmlibs.atomicfu.gradle)
//plugins form benchmarks //plugins form benchmarks
api("org.jetbrains.kotlinx:kotlinx-benchmark-plugin:$benchmarksVersion") api("org.jetbrains.kotlinx:kotlinx-benchmark-plugin:$benchmarksVersion")
api("org.jetbrains.kotlin:kotlin-allopen:$kotlinVersion") api("org.jetbrains.kotlin:kotlin-allopen:$kotlinVersion")
//to be used inside build-script only //to be used inside build-script only
implementation(miptNpmLibs.kotlinx.serialization.json) implementation(npmlibs.kotlinx.serialization.json)
} }
kotlin.sourceSets.all { kotlin.sourceSets.all {

View File

@ -1,7 +0,0 @@
#
# Copyright 2018-2021 KMath contributors.
# Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
#
kotlin.code.style=official
toolsVersion=0.11.2-kotlin-1.6.10

View File

@ -6,7 +6,17 @@
enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")
dependencyResolutionManagement { dependencyResolutionManagement {
val toolsVersion: String by extra val projectProperties = java.util.Properties()
file("../gradle.properties").inputStream().use {
projectProperties.load(it)
}
projectProperties.forEach { key, value ->
extra.set(key.toString(), value)
}
val toolsVersion: String = projectProperties["toolsVersion"].toString()
repositories { repositories {
mavenLocal() mavenLocal()
@ -16,8 +26,8 @@ dependencyResolutionManagement {
} }
versionCatalogs { versionCatalogs {
create("miptNpmLibs") { create("npmlibs") {
from("ru.mipt.npm:version-catalog:$toolsVersion") from("space.kscience:version-catalog:$toolsVersion")
} }
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2022 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2022 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
@ -9,7 +9,7 @@ import kotlinx.benchmark.gradle.BenchmarksExtension
import kotlinx.serialization.decodeFromString import kotlinx.serialization.decodeFromString
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
import org.gradle.api.Project import org.gradle.api.Project
import ru.mipt.npm.gradle.KScienceReadmeExtension import space.kscience.gradle.KScienceReadmeExtension
import java.time.LocalDateTime import java.time.LocalDateTime
import java.time.ZoneId import java.time.ZoneId
import java.time.format.DateTimeFormatter import java.time.format.DateTimeFormatter

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2022 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
@ -319,7 +319,9 @@ public object EjmlLinearSpace${ops} : EjmlLinearSpace<${type}, ${kmathAlgebra},
} }
else -> null else -> null
}?.let(type::cast) }?.let{
type.cast(it)
}
} }
/** /**

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- <!--
- Copyright 2018-2021 KMath contributors. - Copyright 2018-2022 KMath contributors.
- Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. - Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
--> -->

Before

Width:  |  Height:  |  Size: 249 KiB

After

Width:  |  Height:  |  Size: 249 KiB

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- <!--
- Copyright 2018-2021 KMath contributors. - Copyright 2018-2022 KMath contributors.
- Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. - Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
--> -->

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- <!--
- Copyright 2018-2021 KMath contributors. - Copyright 2018-2022 KMath contributors.
- Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. - Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
--> -->

Before

Width:  |  Height:  |  Size: 278 KiB

After

Width:  |  Height:  |  Size: 278 KiB

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- <!--
- Copyright 2018-2021 KMath contributors. - Copyright 2018-2022 KMath contributors.
- Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. - Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
--> -->

Before

Width:  |  Height:  |  Size: 118 KiB

After

Width:  |  Height:  |  Size: 118 KiB

172
docs/polynomials.md Normal file
View File

@ -0,0 +1,172 @@
# Polynomials and Rational Functions
KMath provides a way to work with uni- and multivariate polynomials and rational functions. It includes full support of arithmetic operations of integers, **constants** (elements of ring polynomials are build over), variables (for certain multivariate implementations), polynomials and rational functions encapsulated in so-called **polynomial space** and **rational function space** and some other utilities such as algebraic differentiation and substitution.
## Concrete realizations
There are 3 approaches to represent polynomials:
1. For univariate polynomials one can represent and store polynomial as a list of coefficients for each power of the variable. I.e. polynomial $a_0 + \dots + a_n x^n $ can be represented as a finite sequence $(a_0; \dots; a_n)$. (Compare to sequential definition of polynomials.)
2. For multivariate polynomials one can represent and store polynomial as a matching (in programming it is called "map" or "dictionary", in math it is called [functional relation](https://en.wikipedia.org/wiki/Binary_relation#Special_types_of_binary_relations)) of each "**term signature**" (that describes what variables and in what powers appear in the term) with corresponding coefficient of the term. But there are 2 possible approaches of term signature representation:
1. One can number all the variables, so term signature can be represented as a sequence describing powers of the variables. I.e. signature of term $c \\; x_0^{d_0} \dots x_n^{d_n} $ (for natural or zero $d_i $) can be represented as a finite sequence $(d_0; \dots; d_n)$.
2. One can represent variables as objects ("**labels**"), so term signature can be also represented as a matching of each appeared variable with its power in the term. I.e. signature of term $c \\; x_0^{d_0} \dots x_n^{d_n} $ (for natural non-zero $d_i $) can be represented as a finite matching $(x_0 \to d_1; \dots; x_n \to d_n)$.
All that three approaches are implemented by "list", "numbered", and "labeled" versions of polynomials and polynomial spaces respectively. Whereas all rational functions are represented as fractions with corresponding polynomial numerator and denominator, and rational functions' spaces are implemented in the same way as usual field of rational numbers (or more precisely, as any field of fractions over integral domain) should be implemented.
So here are a bit of details. Let `C` by type of constants. Then:
1. `ListPolynomial`, `ListPolynomialSpace`, `ListRationalFunction` and `ListRationalFunctionSpace` implement the first scenario. `ListPolynomial` stores polynomial $a_0 + \dots + a_n x^n $ as a coefficients list `listOf(a_0, ..., a_n)` (of type `List<C>`).
They also have variation `ScalableListPolynomialSpace` that replaces former polynomials and implements `ScaleOperations`.
2. `NumberedPolynomial`, `NumberedPolynomialSpace`, `NumberedRationalFunction` and `NumberedRationalFunctionSpace` implement second scenario. `NumberedPolynomial` stores polynomials as structures of type `Map<List<UInt>, C>`. Signatures are stored as `List<UInt>`. To prevent ambiguity signatures should not end with zeros.
3. `LabeledPolynomial`, `LabeledPolynomialSpace`, `LabeledRationalFunction` and `LabeledRationalFunctionSpace` implement third scenario using common `Symbol` as variable type. `LabeledPolynomial` stores polynomials as structures of type `Map<Map<Symbol, UInt>, C>`. Signatures are stored as `Map<Symbol, UInt>`. To prevent ambiguity each signature should not map any variable to zero.
### Example: `ListPolynomial`
For example, polynomial $2 - 3x + x^2 $ (with `Int` coefficients) is represented
```kotlin
val polynomial: ListPolynomial<Int> = ListPolynomial(listOf(2, -3, 1))
// or
val polynomial: ListPolynomial<Int> = ListPolynomial(2, -3, 1)
```
All algebraic operations can be used in corresponding space:
```kotlin
val computationResult = Int.algebra.listPolynomialSpace {
ListPolynomial(2, -3, 1) + ListPolynomial(0, 6) == ListPolynomial(2, 3, 1)
}
println(computationResult) // true
```
For more see [examples](../examples/src/main/kotlin/space/kscience/kmath/functions/polynomials.kt).
### Example: `NumberedPolynomial`
For example, polynomial $3 + 5 x_1 - 7 x_0^2 x_2 $ (with `Int` coefficients) is represented
```kotlin
val polynomial: NumberedPolynomial<Int> = NumberedPolynomial(
mapOf(
listOf<UInt>() to 3,
listOf(0u, 1u) to 5,
listOf(2u, 0u, 1u) to -7,
)
)
// or
val polynomial: NumberedPolynomial<Int> = NumberedPolynomial(
listOf<UInt>() to 3,
listOf(0u, 1u) to 5,
listOf(2u, 0u, 1u) to -7,
)
```
All algebraic operations can be used in corresponding space:
```kotlin
val computationResult = Int.algebra.numberedPolynomialSpace {
NumberedPolynomial(
listOf<UInt>() to 3,
listOf(0u, 1u) to 5,
listOf(2u, 0u, 1u) to -7,
) + NumberedPolynomial(
listOf(0u, 1u) to -5,
listOf(0u, 0u, 0u, 4u) to 4,
) == NumberedPolynomial(
listOf<UInt>() to 3,
listOf(0u, 1u) to 0,
listOf(2u, 0u, 1u) to -7,
listOf(0u, 0u, 0u, 4u) to 4,
)
}
println(computationResult) // true
```
For more see [examples](../examples/src/main/kotlin/space/kscience/kmath/functions/polynomials.kt).
### Example: `LabeledPolynomial`
For example, polynomial $3 + 5 y - 7 x^2 z $ (with `Int` coefficients) is represented
```kotlin
val polynomial: LabeledPolynomial<Int> = LabeledPolynomial(
mapOf(
mapOf<Symbol, UInt>() to 3,
mapOf(y to 1u) to 5,
mapOf(x to 2u, z to 1u) to -7,
)
)
// or
val polynomial: LabeledPolynomial<Int> = LabeledPolynomial(
mapOf<Symbol, UInt>() to 3,
mapOf(y to 1u) to 5,
mapOf(x to 2u, z to 1u) to -7,
)
```
All algebraic operations can be used in corresponding space:
```kotlin
val computationResult = Int.algebra.labeledPolynomialSpace {
LabeledPolynomial(
listOf<UInt>() to 3,
listOf(0u, 1u) to 5,
listOf(2u, 0u, 1u) to -7,
) + LabeledPolynomial(
listOf(0u, 1u) to -5,
listOf(0u, 0u, 0u, 4u) to 4,
) == LabeledPolynomial(
listOf<UInt>() to 3,
listOf(0u, 1u) to 0,
listOf(2u, 0u, 1u) to -7,
listOf(0u, 0u, 0u, 4u) to 4,
)
}
println(computationResult) // true
```
For more see [examples](../examples/src/main/kotlin/space/kscience/kmath/functions/polynomials.kt).
## Abstract entities (interfaces and abstract classes)
```mermaid
classDiagram
Polynomial <|-- ListPolynomial
Polynomial <|-- NumberedPolynomial
Polynomial <|-- LabeledPolynomial
RationalFunction <|-- ListRationalFunction
RationalFunction <|-- NumberedRationalFunction
RationalFunction <|-- LabeledRationalFunction
Ring <|-- PolynomialSpace
PolynomialSpace <|-- MultivariatePolynomialSpace
PolynomialSpace <|-- PolynomialSpaceOverRing
Ring <|-- RationalFunctionSpace
RationalFunctionSpace <|-- MultivariateRationalFunctionSpace
RationalFunctionSpace <|-- RationalFunctionSpaceOverRing
RationalFunctionSpace <|-- RationalFunctionSpaceOverPolynomialSpace
RationalFunctionSpace <|-- PolynomialSpaceOfFractions
RationalFunctionSpaceOverPolynomialSpace <|-- MultivariateRationalFunctionSpaceOverMultivariatePolynomialSpace
MultivariateRationalFunctionSpace <|-- MultivariateRationalFunctionSpaceOverMultivariatePolynomialSpace
MultivariateRationalFunctionSpace <|-- MultivariatePolynomialSpaceOfFractions
PolynomialSpaceOfFractions <|-- MultivariatePolynomialSpaceOfFractions
```
There are implemented `Polynomial` and `RationalFunction` interfaces as abstractions of polynomials and rational functions respectively (although, there is not a lot of logic in them) and `PolynomialSpace` and `RationalFunctionSpace` (that implement `Ring` interface) as abstractions of polynomials' and rational functions' spaces respectively. More precisely, that means they allow to declare common logic of interaction with such objects and spaces:
- `Polynomial` does not provide any logic. It is marker interface.
- `RationalFunction` provides numerator and denominator of rational function and destructuring declaration for them.
- `PolynomialSpace` provides all possible arithmetic interactions of integers, constants (of type `C`), and polynomials (of type `P`) like addition, subtraction, multiplication, and some others and common properties like degree of polynomial.
- `RationalFunctionSpace` provides the same as `PolynomialSpace` but also for rational functions: all possible arithmetic interactions of integers, constants (of type `C`), polynomials (of type `P`), and rational functions (of type `R`) like addition, subtraction, multiplication, division (in some cases), and some others and common properties like degree of polynomial.
Then to add abstraction of similar behaviour with variables (in multivariate case) there are implemented `MultivariatePolynomialSpace` and `MultivariateRationalFunctionSpace`. They just include variables (of type `V`) in the interactions of the entities.
Also, to remove boilerplates there were provided helping subinterfaces and abstract subclasses:
- `PolynomialSpaceOverRing` allows to replace implementation of interactions of integers and constants with implementations from provided ring over constants (of type `A: Ring<C>`).
- `RationalFunctionSpaceOverRing` &mdash; the same but for `RationalFunctionSpace`.
- `RationalFunctionSpaceOverPolynomialSpace` &mdash; the same but "the inheritance" includes interactions with polynomials from provided `PolynomialSpace`.
- `PolynomialSpaceOfFractions` is actually abstract subclass of `RationalFunctionSpace` that implements all fractions boilerplates with provided (`protected`) constructor of rational functions by polynomial numerator and denominator.
- `MultivariateRationalFunctionSpaceOverMultivariatePolynomialSpace` and `MultivariatePolynomialSpaceOfFractions` &mdash; the same stories of operators inheritance and fractions boilerplates respectively but in multivariate case.
## Utilities
For all kinds of polynomials there are provided (implementation details depend on kind of polynomials) such common utilities as:
1. differentiation and anti-differentiation,
2. substitution, invocation and functional representation.

View File

@ -1,6 +1,6 @@
[![JetBrains Research](https://jb.gg/badges/research.svg)](https://confluence.jetbrains.com/display/ALL/JetBrains+on+GitHub) [![JetBrains Research](https://jb.gg/badges/research.svg)](https://confluence.jetbrains.com/display/ALL/JetBrains+on+GitHub)
[![DOI](https://zenodo.org/badge/129486382.svg)](https://zenodo.org/badge/latestdoi/129486382) [![DOI](https://zenodo.org/badge/129486382.svg)](https://zenodo.org/badge/latestdoi/129486382)
![Gradle build](https://github.com/mipt-npm/kmath/workflows/Gradle%20build/badge.svg) ![Gradle build](https://github.com/SciProgCentre/kmath/workflows/Gradle%20build/badge.svg)
[![Maven Central](https://img.shields.io/maven-central/v/space.kscience/kmath-core.svg?label=Maven%20Central)](https://search.maven.org/search?q=g:%22space.kscience%22) [![Maven Central](https://img.shields.io/maven-central/v/space.kscience/kmath-core.svg?label=Maven%20Central)](https://search.maven.org/search?q=g:%22space.kscience%22)
[![Space](https://img.shields.io/badge/dynamic/xml?color=orange&label=Space&query=//metadata/versioning/latest&url=https%3A%2F%2Fmaven.pkg.jetbrains.space%2Fmipt-npm%2Fp%2Fsci%2Fmaven%2Fspace%2Fkscience%2Fkmath-core%2Fmaven-metadata.xml)](https://maven.pkg.jetbrains.space/mipt-npm/p/sci/maven/space/kscience/) [![Space](https://img.shields.io/badge/dynamic/xml?color=orange&label=Space&query=//metadata/versioning/latest&url=https%3A%2F%2Fmaven.pkg.jetbrains.space%2Fmipt-npm%2Fp%2Fsci%2Fmaven%2Fspace%2Fkscience%2Fkmath-core%2Fmaven-metadata.xml)](https://maven.pkg.jetbrains.space/mipt-npm/p/sci/maven/space/kscience/)
@ -11,7 +11,7 @@ analog to Python's NumPy library. Later we found that kotlin is much more flexib
architecture designs. In contrast to `numpy` and `scipy` it is modular and has a lightweight core. The `numpy`-like architecture designs. In contrast to `numpy` and `scipy` it is modular and has a lightweight core. The `numpy`-like
experience could be achieved with [kmath-for-real](/kmath-for-real) extension module. experience could be achieved with [kmath-for-real](/kmath-for-real) extension module.
[Documentation site (**WIP**)](https://mipt-npm.github.io/kmath/) [Documentation site (**WIP**)](https://SciProgCentre.github.io/kmath/)
## Publications and talks ## Publications and talks
@ -44,7 +44,7 @@ module definitions below. The module stability could have the following levels:
* **PROTOTYPE**. On this level there are no compatibility guarantees. All methods and classes form those modules could * **PROTOTYPE**. On this level there are no compatibility guarantees. All methods and classes form those modules could
break any moment. You can still use it, but be sure to fix the specific version. break any moment. You can still use it, but be sure to fix the specific version.
* **EXPERIMENTAL**. The general API is decided, but some changes could be made. Volatile API is marked * **EXPERIMENTAL**. The general API is decided, but some changes could be made. Volatile API is marked
with `@UnstableKmathAPI` or other stability warning annotations. with `@UnstableKMathAPI` or other stability warning annotations.
* **DEVELOPMENT**. API breaking generally follows semantic versioning ideology. There could be changes in minor * **DEVELOPMENT**. API breaking generally follows semantic versioning ideology. There could be changes in minor
versions, but not in patch versions. API is protected versions, but not in patch versions. API is protected
with [binary-compatibility-validator](https://github.com/Kotlin/binary-compatibility-validator) tool. with [binary-compatibility-validator](https://github.com/Kotlin/binary-compatibility-validator) tool.
@ -69,8 +69,7 @@ performance and flexibility.
We expect to focus on creating convenient universal API first and then work on increasing performance for specific We expect to focus on creating convenient universal API first and then work on increasing performance for specific
cases. We expect the worst KMath benchmarks will perform better than native Python, but worse than optimized cases. We expect the worst KMath benchmarks will perform better than native Python, but worse than optimized
native/SciPy (mostly due to boxing operations on primitive numbers). The best performance of optimized parts could be native/SciPy (mostly due to boxing operations on primitive numbers). The best performance of optimized parts could be better than SciPy.
better than SciPy.
## Requirements ## Requirements

View File

@ -8,6 +8,8 @@ repositories {
maven("https://maven.pkg.jetbrains.space/kotlin/p/kotlin/kotlin-js-wrappers") maven("https://maven.pkg.jetbrains.space/kotlin/p/kotlin/kotlin-js-wrappers")
} }
val multikVersion: String by rootProject.extra
dependencies { dependencies {
implementation(project(":kmath-ast")) implementation(project(":kmath-ast"))
implementation(project(":kmath-kotlingrad")) implementation(project(":kmath-kotlingrad"))
@ -15,6 +17,8 @@ dependencies {
implementation(project(":kmath-coroutines")) implementation(project(":kmath-coroutines"))
implementation(project(":kmath-commons")) implementation(project(":kmath-commons"))
implementation(project(":kmath-complex")) implementation(project(":kmath-complex"))
implementation(project(":kmath-functions"))
implementation(project(":kmath-polynomial"))
implementation(project(":kmath-optimization")) implementation(project(":kmath-optimization"))
implementation(project(":kmath-stat")) implementation(project(":kmath-stat"))
implementation(project(":kmath-viktor")) implementation(project(":kmath-viktor"))
@ -28,6 +32,7 @@ dependencies {
implementation(project(":kmath-jafama")) implementation(project(":kmath-jafama"))
//multik //multik
implementation(project(":kmath-multik")) implementation(project(":kmath-multik"))
implementation("org.jetbrains.kotlinx:multik-default:$multikVersion")
implementation("org.nd4j:nd4j-native:1.0.0-beta7") implementation("org.nd4j:nd4j-native:1.0.0-beta7")
@ -66,5 +71,5 @@ tasks.withType<org.jetbrains.kotlin.gradle.dsl.KotlinJvmCompile> {
} }
readme { readme {
maturity = ru.mipt.npm.gradle.Maturity.EXPERIMENTAL maturity = space.kscience.gradle.Maturity.EXPERIMENTAL
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2022 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2022 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2022 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2022 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2022 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2022 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2022 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2022 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2022 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2022 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */

View File

@ -0,0 +1,399 @@
/*
* Copyright 2018-2022 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
@file:Suppress("LocalVariableName")
package space.kscience.kmath.functions
import space.kscience.kmath.expressions.Symbol
import space.kscience.kmath.expressions.symbol
import space.kscience.kmath.operations.algebra
import space.kscience.kmath.operations.invoke
/**
* Shows [ListPolynomial]s' and [ListRationalFunction]s' capabilities.
*/
fun listPolynomialsExample() {
// [ListPolynomial] is a representation of a univariate polynomial as a list of coefficients from the least term to
// the greatest term. For example,
val polynomial1: ListPolynomial<Int> = ListPolynomial(listOf(2, -3, 1))
// represents polynomial 2 + (-3) x + x^2
// There are also shortcut fabrics:
val polynomial2: ListPolynomial<Int> = ListPolynomial(2, -3, 1)
println(polynomial1 == polynomial2) // true
// and even
val polynomial3: ListPolynomial<Int> = 57.asListPolynomial()
val polynomial4: ListPolynomial<Int> = ListPolynomial(listOf(57))
println(polynomial3 == polynomial4) // true
val polynomial5: ListPolynomial<Int> = ListPolynomial(3, -1)
// For every ring there can be provided a polynomial ring:
Int.algebra.listPolynomialSpace {
println(-polynomial5 == ListPolynomial(-3, 1)) // true
println(polynomial1 + polynomial5 == ListPolynomial(5, -4, 1)) // true
println(polynomial1 - polynomial5 == ListPolynomial(-1, -2, 1)) // true
println(polynomial1 * polynomial5 == ListPolynomial(6, -11, 6, -1)) // true
}
// You can even write
val x: ListPolynomial<Double> = ListPolynomial(0.0, 1.0)
val polynomial6: ListPolynomial<Double> = ListPolynomial(2.0, -3.0, 1.0)
Double.algebra.listPolynomialSpace {
println(2 - 3 * x + x * x == polynomial6)
println(2.0 - 3.0 * x + x * x == polynomial6)
}
// Also there are some utilities for polynomials:
println(polynomial1.substitute(Int.algebra, 1) == 0) // true, because 2 + (-3) * 1 + 1^2 = 0
println(polynomial1.substitute(Int.algebra, polynomial5) == polynomial1) // true, because 2 + (-3) * (3-x) + (3-x)^2 = 2 - 3x + x^2
println(polynomial1.derivative(Int.algebra) == ListPolynomial(-3, 2)) // true, (2 - 3x + x^2)' = -3 + 2x
println(polynomial1.nthDerivative(Int.algebra, 2) == 2.asListPolynomial()) // true, (2 - 3x + x^2)'' = 2
// Lastly, there are rational functions and some other utilities:
Double.algebra.listRationalFunctionSpace {
val rationalFunction1: ListRationalFunction<Double> = ListRationalFunction(listOf(2.0, -3.0, 1.0), listOf(3.0, -1.0))
// It's just (2 - 3x + x^2)/(3 - x)
val rationalFunction2 : ListRationalFunction<Double> = ListRationalFunction(listOf(5.0, -4.0, 1.0), listOf(3.0, -1.0))
// It's just (5 - 4x + x^2)/(3 - x)
println(rationalFunction1 + 1 == rationalFunction2)
}
}
/**
* Shows [NumberedPolynomial]s' and [NumberedRationalFunction]s' capabilities.
*/
fun numberedPolynomialsExample() {
// Consider polynomial
// 3 + 5 x_2 - 7 x_1^2 x_3
// Consider, for example, its term -7 x_1^2 x_3. -7 is a coefficient of the term, whereas (2, 0, 1, 0, 0, ...) is
// description of degrees of variables x_1, x_2, ... in the term. Such description with removed leading zeros
// [2, 0, 1] is called "signature" of the term -7 x_1^2 x_3.
val polynomial1: NumberedPolynomial<Int>
with(Int.algebra) {
// [NumberedPolynomial] is a representation of a multivariate polynomial, that stores terms in a map with terms'
// signatures as the map's keys and terms' coefficients as corresponding values. For example,
polynomial1 = NumberedPolynomial(
mapOf(
listOf<UInt>() to 3,
listOf(0u, 1u) to 5,
listOf(2u, 0u, 1u) to -7,
)
)
// represents polynomial 3 + 5 x_2 - 7 x_1^2 x_3
// This `NumberedPolynomial` function needs context of either ring of constant (as `Int.algebra` in this example)
// or space of NumberedPolynomials over it. To understand why it is like this see documentations of functions
// NumberedPolynomial and NumberedPolynomialWithoutCheck
// There are also shortcut fabrics:
val polynomial2: NumberedPolynomial<Int> = NumberedPolynomial(
listOf<UInt>() to 3,
listOf(0u, 1u) to 5,
listOf(2u, 0u, 1u) to -7,
)
println(polynomial1 == polynomial2) // true
// and even
val polynomial3: NumberedPolynomial<Int> = 57.asNumberedPolynomial() // This one actually does not algebraic context!
val polynomial4: NumberedPolynomial<Int> = NumberedPolynomial(listOf<UInt>() to 57)
println(polynomial3 == polynomial4) // true
numberedPolynomialSpace {
// Also there is DSL for constructing NumberedPolynomials:
val polynomial5: NumberedPolynomial<Int> = NumberedPolynomialDSL1 {
3 {}
5 { 1 inPowerOf 1u }
-7 with { 0 pow 2u; 2 pow 1u }
// `pow` and `inPowerOf` are the same
// `with` is omittable
}
println(polynomial1 == polynomial5) // true
// Unfortunately the DSL does not work good in bare context of constants' ring, so for now it's disabled and
// works only in NumberedPolynomialSpace and NumberedRationalFunctionSpace
}
}
val polynomial6: NumberedPolynomial<Int> = Int.algebra {
NumberedPolynomial(
listOf<UInt>() to 7,
listOf(0u, 1u) to -5,
listOf(2u, 0u, 1u) to 0,
listOf(0u, 0u, 0u, 4u) to 4,
)
}
// For every ring there can be provided a polynomial ring:
Int.algebra.numberedPolynomialSpace {
println(
-polynomial6 == NumberedPolynomial(
listOf<UInt>() to -7,
listOf(0u, 1u) to 5,
listOf(2u, 0u, 1u) to 0,
listOf(0u, 0u, 0u, 4u) to (-4),
)
) // true
println(
polynomial1 + polynomial6 == NumberedPolynomial(
listOf<UInt>() to 10,
listOf(0u, 1u) to 0,
listOf(2u, 0u, 1u) to -7,
listOf(0u, 0u, 0u, 4u) to 4,
)
) // true
println(
polynomial1 - polynomial6 == NumberedPolynomial(
listOf<UInt>() to -4,
listOf(0u, 1u) to 10,
listOf(2u, 0u, 1u) to -7,
listOf(0u, 0u, 0u, 4u) to -4,
)
) // true
polynomial1 * polynomial6 // Multiplication works too
}
Double.algebra.numberedPolynomialSpace {
// You can even write
val x_1: NumberedPolynomial<Double> = NumberedPolynomial(listOf(1u) to 1.0)
val x_2: NumberedPolynomial<Double> = NumberedPolynomial(listOf(0u, 1u) to 1.0)
val x_3: NumberedPolynomial<Double> = NumberedPolynomial(listOf(0u, 0u, 1u) to 1.0)
val polynomial7: NumberedPolynomial<Double> = NumberedPolynomial(
listOf<UInt>() to 3.0,
listOf(0u, 1u) to 5.0,
listOf(2u, 0u, 1u) to -7.0,
)
Double.algebra.listPolynomialSpace {
println(3 + 5 * x_2 - 7 * x_1 * x_1 * x_3 == polynomial7)
println(3.0 + 5.0 * x_2 - 7.0 * x_1 * x_1 * x_3 == polynomial7)
}
}
Int.algebra.numberedPolynomialSpace {
val x_4: NumberedPolynomial<Int> = NumberedPolynomial(listOf(0u, 0u, 0u, 4u) to 1)
// Also there are some utilities for polynomials:
println(polynomial1.substitute(mapOf(0 to 1, 1 to -2, 2 to -1)) == 0.asNumberedPolynomial()) // true,
// because it's substitution x_1 -> 1, x_2 -> -2, x_3 -> -1,
// so 3 + 5 x_2 - 7 x_1^2 x_3 = 3 + 5 * (-2) - 7 * 1^2 * (-1) = 3 - 10 + 7 = 0
println(
polynomial1.substitute(mapOf(1 to x_4)) == NumberedPolynomial(
listOf<UInt>() to 3,
listOf(0u, 1u) to 5,
listOf(2u, 0u, 1u) to -7,
)
) // true, because it's substitution x_2 -> x_4, so result is 3 + 5 x_4 - 7 x_1^2 x_3
println(
polynomial1.derivativeWithRespectTo(Int.algebra, 1) ==
NumberedPolynomial(listOf<UInt>() to 5)
) // true, d/dx_2 (3 + 5 x_2 - 7 x_1^2 x_3) = 5
}
// Lastly, there are rational functions and some other utilities:
Double.algebra.numberedRationalFunctionSpace {
val rationalFunction1: NumberedRationalFunction<Double> = NumberedRationalFunction(
NumberedPolynomial(
listOf<UInt>() to 2.0,
listOf(1u) to -3.0,
listOf(2u) to 1.0,
),
NumberedPolynomial(
listOf<UInt>() to 3.0,
listOf(1u) to -1.0,
)
)
// It's just (2 - 3x + x^2)/(3 - x) where x = x_1
val rationalFunction2: NumberedRationalFunction<Double> = NumberedRationalFunction(
NumberedPolynomial(
listOf<UInt>() to 5.0,
listOf(1u) to -4.0,
listOf(2u) to 1.0,
),
NumberedPolynomial(
listOf<UInt>() to 3.0,
listOf(1u) to -1.0,
)
)
// It's just (5 - 4x + x^2)/(3 - x) where x = x_1
println(rationalFunction1 + 1 == rationalFunction2)
}
}
/**
* Shows [LabeledPolynomial]s' and [LabeledRationalFunction]s' capabilities.
*/
fun labeledPolynomialsExample() {
val x by symbol
val y by symbol
val z by symbol
val t by symbol
// Consider polynomial
// 3 + 5 y - 7 x^2 z
// Consider, for example, its term -7 x^2 z. -7 is a coefficient of the term, whereas matching (x -> 2, z -> 3) is
// description of degrees of variables x_1, x_2, ... in the term. Such description is called "signature" of the
// term -7 x_1^2 x_3.
val polynomial1: LabeledPolynomial<Int>
with(Int.algebra) {
// [LabeledPolynomial] is a representation of a multivariate polynomial, that stores terms in a map with terms'
// signatures as the map's keys and terms' coefficients as corresponding values. For example,
polynomial1 = LabeledPolynomial(
mapOf(
mapOf<Symbol, UInt>() to 3,
mapOf(y to 1u) to 5,
mapOf(x to 2u, z to 1u) to -7,
)
)
// represents polynomial 3 + 5 y - 7 x^2 z
// This `LabeledPolynomial` function needs context of either ring of constant (as `Int.algebra` in this example)
// or space of LabeledPolynomials over it. To understand why it is like this see documentations of functions
// LabeledPolynomial and LabeledPolynomialWithoutCheck
// There are also shortcut fabrics:
val polynomial2: LabeledPolynomial<Int> = LabeledPolynomial(
mapOf<Symbol, UInt>() to 3,
mapOf(y to 1u) to 5,
mapOf(x to 2u, z to 1u) to -7,
)
println(polynomial1 == polynomial2) // true
// and even
val polynomial3: LabeledPolynomial<Int> = 57.asLabeledPolynomial() // This one actually does not algebraic context!
val polynomial4: LabeledPolynomial<Int> = LabeledPolynomial(mapOf<Symbol, UInt>() to 57)
println(polynomial3 == polynomial4) // true
labeledPolynomialSpace {
// Also there is DSL for constructing NumberedPolynomials:
val polynomial5: LabeledPolynomial<Int> = LabeledPolynomialDSL1 {
3 {}
5 { y inPowerOf 1u }
-7 with { x pow 2u; z pow 1u }
// `pow` and `inPowerOf` are the same
// `with` is omittable
}
println(polynomial1 == polynomial5) // true
// Unfortunately the DSL does not work good in bare context of constants' ring, so for now it's disabled and
// works only in NumberedPolynomialSpace and NumberedRationalFunctionSpace
}
}
val polynomial6: LabeledPolynomial<Int> = Int.algebra {
LabeledPolynomial(
mapOf<Symbol, UInt>() to 7,
mapOf(y to 1u) to -5,
mapOf(x to 2u, z to 1u) to 0,
mapOf(t to 4u) to 4,
)
}
// For every ring there can be provided a polynomial ring:
Int.algebra.labeledPolynomialSpace {
println(
-polynomial6 == LabeledPolynomial(
mapOf<Symbol, UInt>() to -7,
mapOf(y to 1u) to 5,
mapOf(x to 2u, z to 1u) to 0,
mapOf(t to 4u) to -4,
)
) // true
println(
polynomial1 + polynomial6 == LabeledPolynomial(
mapOf<Symbol, UInt>() to 10,
mapOf(y to 1u) to 0,
mapOf(x to 2u, z to 1u) to -7,
mapOf(t to 4u) to 4,
)
) // true
println(
polynomial1 - polynomial6 == LabeledPolynomial(
mapOf<Symbol, UInt>() to -4,
mapOf(y to 1u) to 10,
mapOf(x to 2u, z to 1u) to -7,
mapOf(t to 4u) to -4,
)
) // true
polynomial1 * polynomial6 // Multiplication works too
}
Double.algebra.labeledPolynomialSpace {
// You can even write
val polynomial7: LabeledPolynomial<Double> = LabeledPolynomial(
mapOf<Symbol, UInt>() to 3.0,
mapOf(y to 1u) to 5.0,
mapOf(x to 2u, z to 1u) to -7.0,
)
Double.algebra.listPolynomialSpace {
println(3 + 5 * y - 7 * x * x * z == polynomial7)
println(3.0 + 5.0 * y - 7.0 * x * x * z == polynomial7)
}
}
Int.algebra.labeledPolynomialSpace {
// Also there are some utilities for polynomials:
println(polynomial1.substitute(mapOf(x to 1, y to -2, z to -1)) == 0.asLabeledPolynomial()) // true,
// because it's substitution x -> 1, y -> -2, z -> -1,
// so 3 + 5 y - 7 x^2 z = 3 + 5 * (-2) - 7 * 1^2 * (-1) = 3 - 10 + 7 = 0
println(
polynomial1.substitute(mapOf(y to t.asPolynomial())) == LabeledPolynomial(
mapOf<Symbol, UInt>() to 3,
mapOf(t to 1u) to 5,
mapOf(x to 2u, z to 1u) to -7,
)
) // true, because it's substitution y -> t, so result is 3 + 5 t - 7 x^2 z
println(
polynomial1.derivativeWithRespectTo(Int.algebra, y) == LabeledPolynomial(mapOf<Symbol, UInt>() to 5)
) // true, d/dy (3 + 5 y - 7 x^2 z) = 5
}
// Lastly, there are rational functions and some other utilities:
Double.algebra.labeledRationalFunctionSpace {
val rationalFunction1: LabeledRationalFunction<Double> = LabeledRationalFunction(
LabeledPolynomial(
mapOf<Symbol, UInt>() to 2.0,
mapOf(x to 1u) to -3.0,
mapOf(x to 2u) to 1.0,
),
LabeledPolynomial(
mapOf<Symbol, UInt>() to 3.0,
mapOf(x to 1u) to -1.0,
)
)
// It's just (2 - 3x + x^2)/(3 - x)
val rationalFunction2: LabeledRationalFunction<Double> = LabeledRationalFunction(
LabeledPolynomial(
mapOf<Symbol, UInt>() to 5.0,
mapOf(x to 1u) to -4.0,
mapOf(x to 2u) to 1.0,
),
LabeledPolynomial(
mapOf<Symbol, UInt>() to 3.0,
mapOf(x to 1u) to -1.0,
)
)
// It's just (5 - 4x + x^2)/(3 - x)
println(rationalFunction1 + 1 == rationalFunction2)
}
}
fun main() {
println("ListPolynomials:")
listPolynomialsExample()
println()
println("NumberedPolynomials:")
numberedPolynomialsExample()
println()
println("ListPolynomials:")
labeledPolynomialsExample()
println()
}

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2022 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2022 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2022 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2022 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2022 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
@ -7,7 +7,6 @@ package space.kscience.kmath.operations
import space.kscience.kmath.complex.Complex import space.kscience.kmath.complex.Complex
import space.kscience.kmath.complex.algebra import space.kscience.kmath.complex.algebra
import space.kscience.kmath.complex.bufferAlgebra
import space.kscience.kmath.complex.ndAlgebra import space.kscience.kmath.complex.ndAlgebra
import space.kscience.kmath.nd.BufferND import space.kscience.kmath.nd.BufferND
import space.kscience.kmath.nd.StructureND import space.kscience.kmath.nd.StructureND
@ -18,7 +17,7 @@ fun main() = Complex.algebra {
println(complex * 8 - 5 * i) println(complex * 8 - 5 * i)
//flat buffer //flat buffer
val buffer = with(bufferAlgebra){ val buffer = with(bufferAlgebra) {
buffer(8) { Complex(it, -it) }.map { Complex(it.im, it.re) } buffer(8) { Complex(it, -it) }.map { Complex(it.im, it.re) }
} }
println(buffer) println(buffer)
@ -30,7 +29,7 @@ fun main() = Complex.algebra {
println(element) println(element)
// 1d element operation // 1d element operation
val result: StructureND<Complex> = ndAlgebra{ val result: StructureND<Complex> = ndAlgebra {
val a = structureND(8) { (it) -> i * it - it.toDouble() } val a = structureND(8) { (it) -> i * it - it.toDouble() }
val b = 3 val b = 3
val c = Complex(1.0, 1.0) val c = Complex(1.0, 1.0)

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2022 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2022 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2022 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2022 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2022 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
@ -32,12 +32,10 @@ fun main() {
val shape = Shape(dim, dim) val shape = Shape(dim, dim)
// automatically build context most suited for given type.
val autoField = BufferedFieldOpsND(DoubleField, Buffer.Companion::auto)
// specialized nd-field for Double. It works as generic Double field as well. // specialized nd-field for Double. It works as generic Double field as well.
val realField = DoubleField.ndAlgebra val doubleField = DoubleField.ndAlgebra
//A generic boxing field. It should be used for objects, not primitives. //A generic field. It should be used for objects, not primitives.
val boxingField = BufferedFieldOpsND(DoubleField, Buffer.Companion::boxing) val genericField = BufferedFieldOpsND(DoubleField)
// Nd4j specialized field. // Nd4j specialized field.
val nd4jField = DoubleField.nd4j val nd4jField = DoubleField.nd4j
//viktor field //viktor field
@ -46,14 +44,14 @@ fun main() {
val parallelField = DoubleField.ndStreaming(dim, dim) val parallelField = DoubleField.ndStreaming(dim, dim)
measureAndPrint("Boxing addition") { measureAndPrint("Boxing addition") {
boxingField { genericField {
var res: StructureND<Double> = one(shape) var res: StructureND<Double> = one(shape)
repeat(n) { res += 1.0 } repeat(n) { res += 1.0 }
} }
} }
measureAndPrint("Specialized addition") { measureAndPrint("Specialized addition") {
realField { doubleField {
var res: StructureND<Double> = one(shape) var res: StructureND<Double> = one(shape)
repeat(n) { res += 1.0 } repeat(n) { res += 1.0 }
} }
@ -80,15 +78,8 @@ fun main() {
} }
} }
measureAndPrint("Automatic field addition") {
autoField {
var res: StructureND<Double> = one(shape)
repeat(n) { res += 1.0 }
}
}
measureAndPrint("Lazy addition") { measureAndPrint("Lazy addition") {
val res = realField.one(shape).mapAsync(GlobalScope) { val res = doubleField.one(shape).mapAsync(GlobalScope) {
var c = 0.0 var c = 0.0
repeat(n) { repeat(n) {
c += 1.0 c += 1.0

View File

@ -1,10 +1,11 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2022 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
package space.kscience.kmath.structures package space.kscience.kmath.structures
import space.kscience.kmath.misc.PerformancePitfall
import space.kscience.kmath.nd.* import space.kscience.kmath.nd.*
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.DoubleField
import space.kscience.kmath.operations.ExtendedField import space.kscience.kmath.operations.ExtendedField
@ -49,6 +50,7 @@ class StreamDoubleFieldND(override val shape: IntArray) : FieldND<Double, Double
return BufferND(strides, array.asBuffer()) return BufferND(strides, array.asBuffer())
} }
@OptIn(PerformancePitfall::class)
override fun StructureND<Double>.map( override fun StructureND<Double>.map(
transform: DoubleField.(Double) -> Double, transform: DoubleField.(Double) -> Double,
): BufferND<Double> { ): BufferND<Double> {
@ -56,6 +58,7 @@ class StreamDoubleFieldND(override val shape: IntArray) : FieldND<Double, Double
return BufferND(strides, array.asBuffer()) return BufferND(strides, array.asBuffer())
} }
@OptIn(PerformancePitfall::class)
override fun StructureND<Double>.mapIndexed( override fun StructureND<Double>.mapIndexed(
transform: DoubleField.(index: IntArray, Double) -> Double, transform: DoubleField.(index: IntArray, Double) -> Double,
): BufferND<Double> { ): BufferND<Double> {
@ -69,6 +72,7 @@ class StreamDoubleFieldND(override val shape: IntArray) : FieldND<Double, Double
return BufferND(strides, array.asBuffer()) return BufferND(strides, array.asBuffer())
} }
@OptIn(PerformancePitfall::class)
override fun zip( override fun zip(
left: StructureND<Double>, left: StructureND<Double>,
right: StructureND<Double>, right: StructureND<Double>,

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2022 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2022 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2022 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2022 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */

View File

@ -1,10 +1,11 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2022 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
package space.kscience.kmath.tensors package space.kscience.kmath.tensors
import space.kscience.kmath.misc.PerformancePitfall
import space.kscience.kmath.operations.invoke import space.kscience.kmath.operations.invoke
import space.kscience.kmath.tensors.core.DoubleTensor import space.kscience.kmath.tensors.core.DoubleTensor
import space.kscience.kmath.tensors.core.DoubleTensorAlgebra import space.kscience.kmath.tensors.core.DoubleTensorAlgebra
@ -13,6 +14,7 @@ import kotlin.math.abs
// OLS estimator using SVD // OLS estimator using SVD
@OptIn(PerformancePitfall::class)
fun main() { fun main() {
//seed for random //seed for random
val randSeed = 100500L val randSeed = 100500L
@ -50,7 +52,7 @@ fun main() {
// inverse Sigma matrix can be restored from singular values with diagonalEmbedding function // inverse Sigma matrix can be restored from singular values with diagonalEmbedding function
val sigma = diagonalEmbedding(singValues.map{ if (abs(it) < 1e-3) 0.0 else 1.0/it }) val sigma = diagonalEmbedding(singValues.map{ if (abs(it) < 1e-3) 0.0 else 1.0/it })
val alphaOLS = v dot sigma dot u.transpose() dot y val alphaOLS = v dot sigma dot u.transposed() dot y
println("Estimated alpha:\n" + println("Estimated alpha:\n" +
"$alphaOLS") "$alphaOLS")

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2022 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
@ -27,7 +27,7 @@ fun main(): Unit = Double.tensorAlgebra.withBroadcast { // work in context with
println("y:\n$y") println("y:\n$y")
// stack them into single dataset // stack them into single dataset
val dataset = stack(listOf(x, y)).transpose() val dataset = stack(listOf(x, y)).transposed()
// normalize both x and y // normalize both x and y
val xMean = x.mean() val xMean = x.mean()
@ -58,7 +58,7 @@ fun main(): Unit = Double.tensorAlgebra.withBroadcast { // work in context with
// and find out eigenvector of it // and find out eigenvector of it
val (_, evecs) = covMatrix.symEig() val (_, evecs) = covMatrix.symEig()
val v = evecs[0] val v = evecs.getTensor(0)
println("Eigenvector:\n$v") println("Eigenvector:\n$v")
// reduce dimension of dataset // reduce dimension of dataset
@ -68,7 +68,7 @@ fun main(): Unit = Double.tensorAlgebra.withBroadcast { // work in context with
// we can restore original data from reduced data; // we can restore original data from reduced data;
// for example, find 7th element of dataset. // for example, find 7th element of dataset.
val n = 7 val n = 7
val restored = (datasetReduced[n] dot v.view(intArrayOf(1, 2))) * std + mean val restored = (datasetReduced.getTensor(n) dot v.view(intArrayOf(1, 2))) * std + mean
println("Original value:\n${dataset[n]}") println("Original value:\n${dataset.getTensor(n)}")
println("Restored value:\n$restored") println("Restored value:\n$restored")
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2022 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2022 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
@ -66,7 +66,7 @@ fun main() = Double.tensorAlgebra.withBroadcast {// work in context with linear
val n = l.shape[0] val n = l.shape[0]
val x = zeros(intArrayOf(n)) val x = zeros(intArrayOf(n))
for (i in 0 until n) { for (i in 0 until n) {
x[intArrayOf(i)] = (b[intArrayOf(i)] - l[i].dot(x).value()) / l[intArrayOf(i, i)] x[intArrayOf(i)] = (b[intArrayOf(i)] - l.getTensor(i).dot(x).value()) / l[intArrayOf(i, i)]
} }
return x return x
} }
@ -75,7 +75,7 @@ fun main() = Double.tensorAlgebra.withBroadcast {// work in context with linear
// solveLT(l, b) function can be easily adapted for upper triangular matrix by the permutation matrix revMat // solveLT(l, b) function can be easily adapted for upper triangular matrix by the permutation matrix revMat
// create it by placing ones on side diagonal // create it by placing ones on side diagonal
val revMat = u.zeroesLike() val revMat = zeroesLike(u)
val n = revMat.shape[0] val n = revMat.shape[0]
for (i in 0 until n) { for (i in 0 until n) {
revMat[intArrayOf(i, n - 1 - i)] = 1.0 revMat[intArrayOf(i, n - 1 - i)] = 1.0

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2022 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
@ -7,11 +7,14 @@ package space.kscience.kmath.tensors
import org.jetbrains.kotlinx.multik.api.Multik import org.jetbrains.kotlinx.multik.api.Multik
import org.jetbrains.kotlinx.multik.api.ndarray import org.jetbrains.kotlinx.multik.api.ndarray
import space.kscience.kmath.multik.multikAlgebra import org.jetbrains.kotlinx.multik.default.DefaultEngine
import space.kscience.kmath.multik.MultikDoubleAlgebra
import space.kscience.kmath.nd.one import space.kscience.kmath.nd.one
import space.kscience.kmath.operations.DoubleField
fun main(): Unit = with(DoubleField.multikAlgebra) {
val multikAlgebra = MultikDoubleAlgebra(DefaultEngine())
fun main(): Unit = with(multikAlgebra) {
val a = Multik.ndarray(intArrayOf(1, 2, 3)).asType<Double>().wrap() val a = Multik.ndarray(intArrayOf(1, 2, 3)).asType<Double>().wrap()
val b = Multik.ndarray(doubleArrayOf(1.0, 2.0, 3.0)).wrap() val b = Multik.ndarray(doubleArrayOf(1.0, 2.0, 3.0)).wrap()
one(a.shape) - a + b * 3.0 one(a.shape) - a + b * 3.0

View File

@ -1,15 +1,16 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2022 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
package space.kscience.kmath.tensors package space.kscience.kmath.tensors
import space.kscience.kmath.operations.asIterable
import space.kscience.kmath.operations.invoke import space.kscience.kmath.operations.invoke
import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra
import space.kscience.kmath.tensors.core.DoubleTensor import space.kscience.kmath.tensors.core.DoubleTensor
import space.kscience.kmath.tensors.core.DoubleTensorAlgebra import space.kscience.kmath.tensors.core.DoubleTensorAlgebra
import space.kscience.kmath.tensors.core.copyArray import space.kscience.kmath.tensors.core.toDoubleTensor
import kotlin.math.sqrt import kotlin.math.sqrt
const val seed = 100500L const val seed = 100500L
@ -79,9 +80,9 @@ class Dense(
} }
override fun backward(input: DoubleTensor, outputError: DoubleTensor): DoubleTensor = DoubleTensorAlgebra { override fun backward(input: DoubleTensor, outputError: DoubleTensor): DoubleTensor = DoubleTensorAlgebra {
val gradInput = outputError dot weights.transpose() val gradInput = outputError dot weights.transposed()
val gradW = input.transpose() dot outputError val gradW = input.transposed() dot outputError
val gradBias = outputError.mean(dim = 0, keepDim = false) * input.shape[0].toDouble() val gradBias = outputError.mean(dim = 0, keepDim = false) * input.shape[0].toDouble()
weights -= learningRate * gradW weights -= learningRate * gradW
@ -106,12 +107,11 @@ fun accuracy(yPred: DoubleTensor, yTrue: DoubleTensor): Double {
} }
// neural network class // neural network class
@OptIn(ExperimentalStdlibApi::class)
class NeuralNetwork(private val layers: List<Layer>) { class NeuralNetwork(private val layers: List<Layer>) {
private fun softMaxLoss(yPred: DoubleTensor, yTrue: DoubleTensor): DoubleTensor = BroadcastDoubleTensorAlgebra { private fun softMaxLoss(yPred: DoubleTensor, yTrue: DoubleTensor): DoubleTensor = BroadcastDoubleTensorAlgebra {
val onesForAnswers = yPred.zeroesLike() val onesForAnswers = zeroesLike(yPred)
yTrue.copyArray().forEachIndexed { index, labelDouble -> yTrue.source.asIterable().forEachIndexed { index, labelDouble ->
val label = labelDouble.toInt() val label = labelDouble.toInt()
onesForAnswers[intArrayOf(index, label)] = 1.0 onesForAnswers[intArrayOf(index, label)] = 1.0
} }
@ -163,7 +163,7 @@ class NeuralNetwork(private val layers: List<Layer>) {
for ((xBatch, yBatch) in iterBatch(xTrain, yTrain)) { for ((xBatch, yBatch) in iterBatch(xTrain, yTrain)) {
train(xBatch, yBatch) train(xBatch, yBatch)
} }
println("Accuracy:${accuracy(yTrain, predict(xTrain).argMax(1, true).asDouble())}") println("Accuracy:${accuracy(yTrain, predict(xTrain).argMax(1, true).toDoubleTensor())}")
} }
} }
@ -194,7 +194,7 @@ fun main() = BroadcastDoubleTensorAlgebra {
val y = fromArray( val y = fromArray(
intArrayOf(sampleSize, 1), intArrayOf(sampleSize, 1),
DoubleArray(sampleSize) { i -> DoubleArray(sampleSize) { i ->
if (x[i].sum() > 0.0) { if (x.getTensor(i).sum() > 0.0) {
1.0 1.0
} else { } else {
0.0 0.0
@ -230,7 +230,7 @@ fun main() = BroadcastDoubleTensorAlgebra {
val prediction = model.predict(xTest) val prediction = model.predict(xTest)
// process raw prediction via argMax // process raw prediction via argMax
val predictionLabels = prediction.argMax(1, true).asDouble() val predictionLabels = prediction.argMax(1, true).toDoubleTensor()
// find out accuracy // find out accuracy
val acc = accuracy(yTest, predictionLabels) val acc = accuracy(yTest, predictionLabels)

View File

@ -6,8 +6,10 @@ kotlin.code.style=official
kotlin.jupyter.add.scanner=false kotlin.jupyter.add.scanner=false
kotlin.mpp.stability.nowarn=true kotlin.mpp.stability.nowarn=true
kotlin.native.ignoreDisabledTargets=true kotlin.native.ignoreDisabledTargets=true
#kotlin.incremental.js.ir=true kotlin.incremental.js.ir=true
org.gradle.configureondemand=true org.gradle.configureondemand=true
org.gradle.jvmargs=-XX:MaxMetaspaceSize=1G
org.gradle.parallel=true org.gradle.parallel=true
org.gradle.jvmargs=-Xmx4096m
toolsVersion=0.13.0-kotlin-1.7.20-Beta

View File

@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-bin.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

View File

@ -10,7 +10,7 @@ Extensions to MST API: transformations, dynamic compilation and visualization.
## Artifact: ## Artifact:
The Maven coordinates of this project are `space.kscience:kmath-ast:0.3.0`. The Maven coordinates of this project are `space.kscience:kmath-ast:0.3.1-dev-1`.
**Gradle Groovy:** **Gradle Groovy:**
```groovy ```groovy
@ -20,7 +20,7 @@ repositories {
} }
dependencies { dependencies {
implementation 'space.kscience:kmath-ast:0.3.0' implementation 'space.kscience:kmath-ast:0.3.1-dev-1'
} }
``` ```
**Gradle Kotlin DSL:** **Gradle Kotlin DSL:**
@ -31,7 +31,7 @@ repositories {
} }
dependencies { dependencies {
implementation("space.kscience:kmath-ast:0.3.0") implementation("space.kscience:kmath-ast:0.3.1-dev-1")
} }
``` ```
@ -199,10 +199,7 @@ public fun main() {
Result LaTeX: Result LaTeX:
<div style="background-color:white;"> $$\operatorname{exp}\\,\left(\sqrt{x}\right)-\frac{\frac{\operatorname{arcsin}\\,\left(2\\,x\right)}{2\times10^{10}+x^{3}}}{12}+x^{2/3}$$
![](https://latex.codecogs.com/gif.latex?%5Coperatorname{exp}%5C,%5Cleft(%5Csqrt{x}%5Cright)-%5Cfrac{%5Cfrac{%5Coperatorname{arcsin}%5C,%5Cleft(2%5C,x%5Cright)}{2%5Ctimes10^{10}%2Bx^{3}}}{12}+x^{2/3})
</div>
Result MathML (can be used with MathJax or other renderers): Result MathML (can be used with MathJax or other renderers):

View File

@ -1,6 +1,9 @@
plugins { plugins {
kotlin("multiplatform") id("space.kscience.gradle.mpp")
id("ru.mipt.npm.gradle.common") }
kscience{
native()
} }
kotlin.js { kotlin.js {
@ -24,7 +27,7 @@ kotlin.sourceSets {
commonMain { commonMain {
dependencies { dependencies {
api("com.github.h0tk3y.betterParse:better-parse:0.4.2") api("com.github.h0tk3y.betterParse:better-parse:0.4.4")
api(project(":kmath-core")) api(project(":kmath-core"))
} }
} }
@ -57,11 +60,11 @@ tasks.dokkaHtml {
if (System.getProperty("space.kscience.kmath.ast.dump.generated.classes") == "1") if (System.getProperty("space.kscience.kmath.ast.dump.generated.classes") == "1")
tasks.jvmTest { tasks.jvmTest {
jvmArgs = (jvmArgs ?: emptyList()) + listOf("-Dspace.kscience.kmath.ast.dump.generated.classes=1") jvmArgs("-Dspace.kscience.kmath.ast.dump.generated.classes=1")
} }
readme { readme {
maturity = ru.mipt.npm.gradle.Maturity.EXPERIMENTAL maturity = space.kscience.gradle.Maturity.EXPERIMENTAL
propertyByTemplate("artifact", rootProject.file("docs/templates/ARTIFACT-TEMPLATE.md")) propertyByTemplate("artifact", rootProject.file("docs/templates/ARTIFACT-TEMPLATE.md"))
feature( feature(

View File

@ -170,10 +170,7 @@ public fun main() {
Result LaTeX: Result LaTeX:
<div style="background-color:white;"> $$\operatorname{exp}\\,\left(\sqrt{x}\right)-\frac{\frac{\operatorname{arcsin}\\,\left(2\\,x\right)}{2\times10^{10}+x^{3}}}{12}+x^{2/3}$$
![](https://latex.codecogs.com/gif.latex?%5Coperatorname{exp}%5C,%5Cleft(%5Csqrt{x}%5Cright)-%5Cfrac{%5Cfrac{%5Coperatorname{arcsin}%5C,%5Cleft(2%5C,x%5Cright)}{2%5Ctimes10^{10}%2Bx^{3}}}{12}+x^{2/3})
</div>
Result MathML (can be used with MathJax or other renderers): Result MathML (can be used with MathJax or other renderers):

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2022 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2022 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2022 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2022 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2022 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2022 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2022 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2022 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2022 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2022 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2022 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2022 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2022 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2022 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2022 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2022 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2022 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2022 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2022 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2022 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2022 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2022 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2022 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2022 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2022 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
@ -36,7 +36,7 @@ public fun <T : Any> MST.compileToExpression(algebra: Algebra<T>): Expression<T>
) )
} }
return ESTreeBuilder<T> { visit(typed) }.instance return ESTreeBuilder { visit(typed) }.instance
} }
/** /**

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2022 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
@ -22,28 +22,20 @@ internal class ESTreeBuilder<T>(val bodyCallback: ESTreeBuilder<T>.() -> BaseExp
} }
} }
@Suppress("UNUSED_VARIABLE")
val instance: Expression<T> by lazy { val instance: Expression<T> by lazy {
val node = Program( val node = Program(
sourceType = "script", sourceType = "script",
VariableDeclaration( ReturnStatement(bodyCallback())
kind = "var",
VariableDeclarator(
id = Identifier("executable"),
init = FunctionExpression(
params = arrayOf(Identifier("constants"), Identifier("arguments")),
body = BlockStatement(ReturnStatement(bodyCallback())),
),
),
),
) )
eval(generate(node)) val code = generate(node)
GeneratedExpression(js("executable"), constants.toTypedArray()) GeneratedExpression(js("new Function('constants', 'arguments_0', code)"), constants.toTypedArray())
} }
private val constants = mutableListOf<Any>() private val constants = mutableListOf<Any>()
fun constant(value: Any?) = when { fun constant(value: Any?): BaseExpression = when {
value == null || jsTypeOf(value) == "number" || jsTypeOf(value) == "string" || jsTypeOf(value) == "boolean" -> value == null || jsTypeOf(value) == "number" || jsTypeOf(value) == "string" || jsTypeOf(value) == "boolean" ->
SimpleLiteral(value) SimpleLiteral(value)
@ -61,7 +53,8 @@ internal class ESTreeBuilder<T>(val bodyCallback: ESTreeBuilder<T>.() -> BaseExp
} }
} }
fun variable(name: Symbol): BaseExpression = call(getOrFail, Identifier("arguments"), SimpleLiteral(name.identity)) fun variable(name: Symbol): BaseExpression =
call(getOrFail, Identifier("arguments_0"), SimpleLiteral(name.identity))
fun call(function: Function<T>, vararg args: BaseExpression): BaseExpression = SimpleCallExpression( fun call(function: Function<T>, vararg args: BaseExpression): BaseExpression = SimpleCallExpression(
optional = false, optional = false,

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2022 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2022 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2022 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */

Some files were not shown because too many files have changed in this diff Show More