diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index f39e12a12..9a9f04621 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -13,9 +13,11 @@ jobs:
- name: Checkout the repo
uses: actions/checkout@v2
- name: Set up JDK 11
- uses: actions/setup-java@v1
+ uses: DeLaGuardo/setup-graalvm@4.0
with:
- java-version: 11
+ graalvm: 21.1.0
+ java: java11
+ arch: amd64
- name: Add msys to path
if: matrix.os == 'windows-latest'
run: SETX PATH "%PATH%;C:\msys64\mingw64\bin"
diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml
index 82b0fb303..86fdac6a6 100644
--- a/.github/workflows/pages.yml
+++ b/.github/workflows/pages.yml
@@ -15,24 +15,8 @@ jobs:
uses: actions/setup-java@v1
with:
java-version: 11
- - name: Cache gradle
- uses: actions/cache@v2
- with:
- path: ~/.gradle/caches
- key: ubuntu-20.04-gradle-${{ hashFiles('*.gradle.kts') }}
- restore-keys: |
- ubuntu-20.04-gradle-
- - name: Cache konan
- uses: actions/cache@v2
- with:
- path: ~/.konan
- key: ${{ runner.os }}-gradle-${{ hashFiles('*.gradle.kts') }}
- restore-keys: |
- ${{ runner.os }}-gradle-
- name: Build
- run: |
- ./gradlew dokkaHtmlMultiModule --no-daemon --no-parallel --stacktrace
- mv build/dokka/htmlMultiModule/-modules.html build/dokka/htmlMultiModule/index.html
+ run: ./gradlew dokkaHtmlMultiModule --no-daemon --no-parallel --stacktrace
- name: Deploy to GitHub Pages
uses: JamesIves/github-pages-deploy-action@4.1.0
with:
diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml
index ca374574e..c5c110e89 100644
--- a/.github/workflows/publish.yml
+++ b/.github/workflows/publish.yml
@@ -18,9 +18,11 @@ jobs:
- name: Checkout the repo
uses: actions/checkout@v2
- name: Set up JDK 11
- uses: actions/setup-java@v1
+ uses: DeLaGuardo/setup-graalvm@4.0
with:
- java-version: 11
+ graalvm: 21.1.0
+ java: java11
+ arch: amd64
- name: Add msys to path
if: matrix.os == 'windows-latest'
run: SETX PATH "%PATH%;C:\msys64\mingw64\bin"
diff --git a/.gitignore b/.gitignore
index 2a13b9e3c..d6c4af4e3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,6 +5,7 @@ out/
.idea/
!.idea/copyright/
+!.idea/scopes/
.vscode/
diff --git a/.idea/copyright/kmath.xml b/.idea/copyright/kmath.xml
new file mode 100644
index 000000000..17e44e4d0
--- /dev/null
+++ b/.idea/copyright/kmath.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml
new file mode 100644
index 000000000..b538bdf41
--- /dev/null
+++ b/.idea/copyright/profiles_settings.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/scopes/Apply_copyright.xml b/.idea/scopes/Apply_copyright.xml
new file mode 100644
index 000000000..0eb589133
--- /dev/null
+++ b/.idea/scopes/Apply_copyright.xml
@@ -0,0 +1,4 @@
+
+
+
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f1d33a75a..286be25e5 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -10,6 +10,9 @@
- Blocking chains and Statistics
- Multiplatform integration
- Integration for any Field element
+- Extended operations for ND4J fields
+- Jupyter Notebook integration module (kmath-jupyter)
+- `@PerformancePitfall` annotation to mark possibly slow API
### Changed
- Exponential operations merged with hyperbolic functions
@@ -23,6 +26,8 @@
- Redesign MST. Remove MSTExpression.
- Move MST to core
- Separated benchmarks and examples
+- Rewritten EJML module without ejml-simple
+- Stability of kmath-ast and kmath-kotilngrad promoted to EXPERIMENTAL.
### Deprecated
@@ -31,6 +36,8 @@
- Number multiplication and division in main Algebra chain
- `contentEquals` from Buffer. It moved to the companion.
- MSTExpression
+- Expression algebra builders
+- Complex and Quaternion no longer are elements.
### Fixed
- Ring inherits RingOperations, not GroupOperations
diff --git a/README.md b/README.md
index 0210b4caf..519472a69 100644
--- a/README.md
+++ b/README.md
@@ -76,6 +76,12 @@ KMath is a modular library. Different modules provide different features with di
+* ### [benchmarks](benchmarks)
+>
+>
+> **Maturity**: EXPERIMENTAL
+
+
* ### [examples](examples)
>
>
@@ -85,15 +91,13 @@ KMath is a modular library. Different modules provide different features with di
* ### [kmath-ast](kmath-ast)
>
>
-> **Maturity**: PROTOTYPE
+> **Maturity**: EXPERIMENTAL
>
> **Features:**
-> - [expression-language](kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/ast/parser.kt) : Expression language and its parser
-> - [mst](kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/MST.kt) : MST (Mathematical Syntax Tree) as expression language's syntax intermediate representation
-> - [mst-building](kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/MstAlgebra.kt) : MST building algebraic structure
-> - [mst-interpreter](kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/MST.kt) : MST interpreter
+> - [expression-language](kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/parser.kt) : Expression language and its parser
> - [mst-jvm-codegen](kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/asm/asm.kt) : Dynamic MST to JVM bytecode compiler
> - [mst-js-codegen](kmath-ast/src/jsMain/kotlin/space/kscience/kmath/estree/estree.kt) : Dynamic MST to JS compiler
+> - [rendering](kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/MathRenderer.kt) : Extendable MST rendering
@@ -150,9 +154,9 @@ performance calculations to code generation.
> **Maturity**: PROTOTYPE
>
> **Features:**
-> - [ejml-vector](kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/EjmlVector.kt) : The Point implementation using SimpleMatrix.
-> - [ejml-matrix](kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/EjmlMatrix.kt) : The Matrix implementation using SimpleMatrix.
-> - [ejml-linear-space](kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/EjmlLinearSpace.kt) : The LinearSpace implementation using SimpleMatrix.
+> - [ejml-vector](kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/EjmlVector.kt) : Point implementations.
+> - [ejml-matrix](kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/EjmlMatrix.kt) : Matrix implementation.
+> - [ejml-linear-space](kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/EjmlLinearSpace.kt) : LinearSpace implementations.
@@ -196,12 +200,23 @@ One can still use generic algebras though.
> **Maturity**: PROTOTYPE
-* ### [kmath-kotlingrad](kmath-kotlingrad)
+* ### [kmath-jupyter](kmath-jupyter)
>
>
> **Maturity**: PROTOTYPE
+* ### [kmath-kotlingrad](kmath-kotlingrad)
+> Functions, integration and interpolation
+>
+> **Maturity**: EXPERIMENTAL
+>
+> **Features:**
+> - [differentiable-mst-expression](kmath-kotlingrad/src/main/kotlin/space/kscience/kmath/kotlingrad/DifferentiableMstExpression.kt) : MST based DifferentiableExpression.
+> - [differentiable-mst-expression](kmath-kotlingrad/src/main/kotlin/space/kscience/kmath/kotlingrad/DifferentiableMstExpression.kt) : Conversions between Kotlin∇'s SFun and MST
+
+
+
* ### [kmath-memory](kmath-memory)
> An API and basic implementation for arranging objects in a continous memory block.
>
@@ -226,6 +241,19 @@ One can still use generic algebras though.
> **Maturity**: EXPERIMENTAL
+* ### [kmath-tensors](kmath-tensors)
+>
+>
+> **Maturity**: PROTOTYPE
+>
+> **Features:**
+> - [tensor algebra](kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/api/TensorAlgebra.kt) : Interface for basic linear algebra operations on tensors (plus, dot, etc.)
+> - [linear algebra operations](kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/api/LinearOpsTensorAlgebra.kt) : Interface for advanced linear algebra operations like LU decomposition, SVD, etc.
+> - [tensor algebra over Double](kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensorAlgebra.kt): Full implementation of operations for tensors over `Double`'s.
+> - [tensor algebra with broadcasting](kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/BroadcastDoubleTensorAlgebra.kt) : Basic linear algebra operations implemented with broadcasting for tensors over `Double`'s.
+
+
+
* ### [kmath-viktor](kmath-viktor)
>
>
@@ -266,8 +294,8 @@ repositories {
}
dependencies {
- api("space.kscience:kmath-core:0.3.0-dev-6")
- // api("space.kscience:kmath-core-jvm:0.3.0-dev-6") for jvm-specific version
+ api("space.kscience:kmath-core:0.3.0-dev-8")
+ // api("space.kscience:kmath-core-jvm:0.3.0-dev-8") for jvm-specific version
}
```
diff --git a/benchmarks/build.gradle.kts b/benchmarks/build.gradle.kts
index f8e85395b..98ffc5a96 100644
--- a/benchmarks/build.gradle.kts
+++ b/benchmarks/build.gradle.kts
@@ -1,10 +1,3 @@
-/*
- * 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.
- */
-
-import ru.mipt.npm.gradle.Maturity
-
plugins {
kotlin("multiplatform")
kotlin("plugin.allopen")
@@ -14,18 +7,12 @@ plugins {
allOpen.annotation("org.openjdk.jmh.annotations.State")
sourceSets.register("benchmarks")
-
-
repositories {
mavenCentral()
- jcenter()
maven("https://repo.kotlin.link")
maven("https://clojars.org/repo")
- maven("https://dl.bintray.com/egor-bogomolov/astminer/")
- maven("https://dl.bintray.com/hotkeytlt/maven")
maven("https://jitpack.io")
- maven {
- setUrl("http://logicrunch.research.it.uu.se/maven/")
+ maven("http://logicrunch.research.it.uu.se/maven") {
isAllowInsecureProtocol = true
}
}
@@ -77,43 +64,35 @@ benchmark {
register("jvm")
}
+ fun kotlinx.benchmark.gradle.BenchmarkConfiguration.commonConfiguration() {
+ warmups = 1
+ iterations = 5
+ iterationTime = 1000
+ iterationTimeUnit = "ms"
+ }
+
configurations.register("buffer") {
- warmups = 1 // number of warmup iterations
- iterations = 3 // number of iterations
- iterationTime = 500 // time in seconds per iteration
- iterationTimeUnit = "ms" // time unity for iterationTime, default is seconds
+ commonConfiguration()
include("BufferBenchmark")
}
configurations.register("dot") {
- warmups = 1 // number of warmup iterations
- iterations = 3 // number of iterations
- iterationTime = 500 // time in seconds per iteration
- iterationTimeUnit = "ms" // time unity for iterationTime, default is seconds
+ commonConfiguration()
include("DotBenchmark")
}
configurations.register("expressions") {
- warmups = 1 // number of warmup iterations
- iterations = 3 // number of iterations
- iterationTime = 500 // time in seconds per iteration
- iterationTimeUnit = "ms" // time unity for iterationTime, default is seconds
+ commonConfiguration()
include("ExpressionsInterpretersBenchmark")
}
configurations.register("matrixInverse") {
- warmups = 1 // number of warmup iterations
- iterations = 3 // number of iterations
- iterationTime = 500 // time in seconds per iteration
- iterationTimeUnit = "ms" // time unity for iterationTime, default is seconds
+ commonConfiguration()
include("MatrixInverseBenchmark")
}
configurations.register("bigInt") {
- warmups = 1 // number of warmup iterations
- iterations = 3 // number of iterations
- iterationTime = 500 // time in seconds per iteration
- iterationTimeUnit = "ms" // time unity for iterationTime, default is seconds
+ commonConfiguration()
include("BigIntBenchmark")
}
}
@@ -121,7 +100,7 @@ benchmark {
// Fix kotlinx-benchmarks bug
afterEvaluate {
val jvmBenchmarkJar by tasks.getting(org.gradle.jvm.tasks.Jar::class) {
- duplicatesStrategy = org.gradle.api.file.DuplicatesStrategy.EXCLUDE
+ duplicatesStrategy = DuplicatesStrategy.EXCLUDE
}
}
@@ -143,5 +122,5 @@ tasks.withType {
readme {
- maturity = Maturity.EXPERIMENTAL
+ maturity = ru.mipt.npm.gradle.Maturity.EXPERIMENTAL
}
diff --git a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/DotBenchmark.kt b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/DotBenchmark.kt
index 23e73cb5f..2c5a03a97 100644
--- a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/DotBenchmark.kt
+++ b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/DotBenchmark.kt
@@ -10,7 +10,7 @@ import kotlinx.benchmark.Blackhole
import kotlinx.benchmark.Scope
import kotlinx.benchmark.State
import space.kscience.kmath.commons.linear.CMLinearSpace
-import space.kscience.kmath.ejml.EjmlLinearSpace
+import space.kscience.kmath.ejml.EjmlLinearSpaceDDRM
import space.kscience.kmath.linear.LinearSpace
import space.kscience.kmath.linear.invoke
import space.kscience.kmath.operations.DoubleField
@@ -29,8 +29,8 @@ internal class DotBenchmark {
val cmMatrix1 = CMLinearSpace { matrix1.toCM() }
val cmMatrix2 = CMLinearSpace { matrix2.toCM() }
- val ejmlMatrix1 = EjmlLinearSpace { matrix1.toEjml() }
- val ejmlMatrix2 = EjmlLinearSpace { matrix2.toEjml() }
+ val ejmlMatrix1 = EjmlLinearSpaceDDRM { matrix1.toEjml() }
+ val ejmlMatrix2 = EjmlLinearSpaceDDRM { matrix2.toEjml() }
}
@Benchmark
@@ -42,14 +42,14 @@ internal class DotBenchmark {
@Benchmark
fun ejmlDot(blackhole: Blackhole) {
- EjmlLinearSpace {
+ EjmlLinearSpaceDDRM {
blackhole.consume(ejmlMatrix1 dot ejmlMatrix2)
}
}
@Benchmark
fun ejmlDotWithConversion(blackhole: Blackhole) {
- EjmlLinearSpace {
+ EjmlLinearSpaceDDRM {
blackhole.consume(matrix1 dot matrix2)
}
}
diff --git a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/ExpressionsInterpretersBenchmark.kt b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/ExpressionsInterpretersBenchmark.kt
index d6fde8398..942fba308 100644
--- a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/ExpressionsInterpretersBenchmark.kt
+++ b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/ExpressionsInterpretersBenchmark.kt
@@ -11,6 +11,7 @@ import kotlinx.benchmark.Scope
import kotlinx.benchmark.State
import space.kscience.kmath.asm.compileToExpression
import space.kscience.kmath.expressions.*
+import space.kscience.kmath.misc.Symbol
import space.kscience.kmath.misc.symbol
import space.kscience.kmath.operations.DoubleField
import space.kscience.kmath.operations.bindSymbol
@@ -20,50 +21,22 @@ import kotlin.random.Random
@State(Scope.Benchmark)
internal class ExpressionsInterpretersBenchmark {
@Benchmark
- fun functionalExpression(blackhole: Blackhole) {
- val expr = algebra.expressionInField {
- val x = bindSymbol(x)
- x * const(2.0) + const(2.0) / x - const(16.0)
- }
-
- invokeAndSum(expr, blackhole)
- }
+ fun functionalExpression(blackhole: Blackhole) = invokeAndSum(functional, blackhole)
@Benchmark
- fun mstExpression(blackhole: Blackhole) {
- val expr = MstField {
- val x = bindSymbol(x)
- x * 2.0 + number(2.0) / x - 16.0
- }.toExpression(algebra)
-
- invokeAndSum(expr, blackhole)
- }
+ fun mstExpression(blackhole: Blackhole) = invokeAndSum(mst, blackhole)
@Benchmark
- fun asmExpression(blackhole: Blackhole) {
- val expr = MstField {
- val x = bindSymbol(x)
- x * 2.0 + number(2.0) / x - 16.0
- }.compileToExpression(algebra)
-
- invokeAndSum(expr, blackhole)
- }
+ fun asmExpression(blackhole: Blackhole) = invokeAndSum(asm, blackhole)
@Benchmark
- fun rawExpression(blackhole: Blackhole) {
- val expr = Expression { args ->
- val x = args.getValue(x)
- x * 2.0 + 2.0 / x - 16.0
- }
-
- invokeAndSum(expr, blackhole)
- }
+ fun rawExpression(blackhole: Blackhole) = invokeAndSum(raw, blackhole)
private fun invokeAndSum(expr: Expression, blackhole: Blackhole) {
val random = Random(0)
var sum = 0.0
- repeat(1000000) {
+ repeat(times) {
sum += expr(x to random.nextDouble())
}
@@ -71,7 +44,23 @@ internal class ExpressionsInterpretersBenchmark {
}
private companion object {
- private val algebra = DoubleField
- private val x by symbol
+ private val x: Symbol by symbol
+ private val algebra: DoubleField = DoubleField
+ private const val times = 1_000_000
+
+ private val functional: Expression = DoubleField.expressionInExtendedField {
+ bindSymbol(x) * number(2.0) + number(2.0) / bindSymbol(x) - number(16.0) / sin(bindSymbol(x))
+ }
+
+ private val node = MstExtendedField {
+ bindSymbol(x) * 2.0 + number(2.0) / bindSymbol(x) - number(16.0) / sin(bindSymbol(x))
+ }
+
+ private val mst: Expression = node.toExpression(DoubleField)
+ private val asm: Expression = node.compileToExpression(DoubleField)
+
+ private val raw: Expression = Expression { args ->
+ args.getValue(x) * 2.0 + 2.0 / args.getValue(x) - 16.0 / kotlin.math.sin(args.getValue(x))
+ }
}
}
diff --git a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/MatrixInverseBenchmark.kt b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/MatrixInverseBenchmark.kt
index d1803e389..7bb32af28 100644
--- a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/MatrixInverseBenchmark.kt
+++ b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/MatrixInverseBenchmark.kt
@@ -11,25 +11,26 @@ import kotlinx.benchmark.Scope
import kotlinx.benchmark.State
import space.kscience.kmath.commons.linear.CMLinearSpace
import space.kscience.kmath.commons.linear.inverse
-import space.kscience.kmath.ejml.EjmlLinearSpace
-import space.kscience.kmath.ejml.inverse
+import space.kscience.kmath.ejml.EjmlLinearSpaceDDRM
+import space.kscience.kmath.linear.InverseMatrixFeature
import space.kscience.kmath.linear.LinearSpace
import space.kscience.kmath.linear.inverseWithLup
import space.kscience.kmath.linear.invoke
+import space.kscience.kmath.nd.getFeature
import kotlin.random.Random
@State(Scope.Benchmark)
internal class MatrixInverseBenchmark {
- companion object {
- val random = Random(1224)
- const val dim = 100
+ private companion object {
+ private val random = Random(1224)
+ private const val dim = 100
private val space = LinearSpace.real
//creating invertible matrix
- val u = space.buildMatrix(dim, dim) { i, j -> if (i <= j) random.nextDouble() else 0.0 }
- val l = space.buildMatrix(dim, dim) { i, j -> if (i >= j) random.nextDouble() else 0.0 }
- val matrix = space { l dot u }
+ private val u = space.buildMatrix(dim, dim) { i, j -> if (i <= j) random.nextDouble() else 0.0 }
+ private val l = space.buildMatrix(dim, dim) { i, j -> if (i >= j) random.nextDouble() else 0.0 }
+ private val matrix = space { l dot u }
}
@Benchmark
@@ -46,8 +47,8 @@ internal class MatrixInverseBenchmark {
@Benchmark
fun ejmlInverse(blackhole: Blackhole) {
- with(EjmlLinearSpace) {
- blackhole.consume(inverse(matrix))
+ with(EjmlLinearSpaceDDRM) {
+ blackhole.consume(matrix.getFeature>()?.inverse)
}
}
}
diff --git a/build.gradle.kts b/build.gradle.kts
index aeb4a6061..406a46810 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -1,53 +1,37 @@
-/*
- * 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.
- */
-
-import org.jetbrains.dokka.gradle.DokkaTask
-import java.net.URL
-
plugins {
id("ru.mipt.npm.gradle.project")
+ kotlin("jupyter.api") apply false
}
allprojects {
repositories {
- jcenter()
maven("https://clojars.org/repo")
- maven("https://dl.bintray.com/egor-bogomolov/astminer/")
- maven("https://dl.bintray.com/hotkeytlt/maven")
maven("https://jitpack.io")
- maven{
- setUrl("http://logicrunch.research.it.uu.se/maven/")
+ maven("http://logicrunch.research.it.uu.se/maven") {
isAllowInsecureProtocol = true
}
+ maven("https://maven.pkg.jetbrains.space/public/p/kotlinx-html/maven")
mavenCentral()
}
group = "space.kscience"
- version = "0.3.0-dev-7"
+ version = "0.3.0-dev-8"
}
subprojects {
if (name.startsWith("kmath")) apply()
afterEvaluate {
- tasks.withType {
- dokkaSourceSets.all {
- val readmeFile = File(this@subprojects.projectDir, "./README.md")
- if (readmeFile.exists())
- includes.setFrom(includes + readmeFile.absolutePath)
+ tasks.withType {
+ dependsOn(tasks.getByName("assemble"))
- arrayOf(
- "http://ejml.org/javadoc/",
- "https://commons.apache.org/proper/commons-math/javadocs/api-3.6.1/",
- "https://deeplearning4j.org/api/latest/"
- ).map { URL("${it}package-list") to URL(it) }.forEach { (a, b) ->
- externalDocumentationLink {
- packageListUrl.set(a)
- url.set(b)
- }
- }
+ dokkaSourceSets.all {
+ val readmeFile = File(this@subprojects.projectDir, "README.md")
+ if (readmeFile.exists()) includes.setFrom(includes + readmeFile.absolutePath)
+ externalDocumentationLink("http://ejml.org/javadoc/")
+ externalDocumentationLink("https://commons.apache.org/proper/commons-math/javadocs/api-3.6.1/")
+ externalDocumentationLink("https://deeplearning4j.org/api/latest/")
+ externalDocumentationLink("https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/")
}
}
}
diff --git a/docs/templates/ARTIFACT-TEMPLATE.md b/docs/templates/ARTIFACT-TEMPLATE.md
index 01d9c51da..1bac2a8ff 100644
--- a/docs/templates/ARTIFACT-TEMPLATE.md
+++ b/docs/templates/ARTIFACT-TEMPLATE.md
@@ -6,8 +6,7 @@ The Maven coordinates of this project are `${group}:${name}:${version}`.
```gradle
repositories {
maven { url 'https://repo.kotlin.link' }
- maven { url 'https://dl.bintray.com/hotkeytlt/maven' }
- maven { url "https://dl.bintray.com/kotlin/kotlin-eap" } // include for builds based on kotlin-eap
+ mavenCentral()
}
dependencies {
@@ -18,8 +17,7 @@ dependencies {
```kotlin
repositories {
maven("https://repo.kotlin.link")
- maven("https://dl.bintray.com/kotlin/kotlin-eap") // include for builds based on kotlin-eap
- maven("https://dl.bintray.com/hotkeytlt/maven") // required for a
+ mavenCentral()
}
dependencies {
diff --git a/examples/build.gradle.kts b/examples/build.gradle.kts
index 8bd9423fe..1c7caf1b9 100644
--- a/examples/build.gradle.kts
+++ b/examples/build.gradle.kts
@@ -1,25 +1,14 @@
-/*
- * 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.
- */
-
-import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
-import ru.mipt.npm.gradle.Maturity
-
plugins {
kotlin("jvm")
}
repositories {
mavenCentral()
- jcenter()
maven("https://repo.kotlin.link")
maven("https://clojars.org/repo")
- maven("https://dl.bintray.com/egor-bogomolov/astminer/")
- maven("https://dl.bintray.com/hotkeytlt/maven")
maven("https://jitpack.io")
- maven{
- setUrl("http://logicrunch.research.it.uu.se/maven/")
+ maven("https://maven.pkg.jetbrains.space/kotlin/p/kotlin/kotlin-js-wrappers")
+ maven("http://logicrunch.research.it.uu.se/maven") {
isAllowInsecureProtocol = true
}
}
@@ -36,6 +25,7 @@ dependencies {
implementation(project(":kmath-dimensions"))
implementation(project(":kmath-ejml"))
implementation(project(":kmath-nd4j"))
+ implementation(project(":kmath-tensors"))
implementation(project(":kmath-for-real"))
@@ -64,7 +54,7 @@ kotlin.sourceSets.all {
}
}
-tasks.withType {
+tasks.withType {
kotlinOptions{
jvmTarget = "11"
freeCompilerArgs = freeCompilerArgs + "-Xjvm-default=all"
@@ -72,5 +62,5 @@ tasks.withType {
}
readme {
- maturity = Maturity.EXPERIMENTAL
+ maturity = ru.mipt.npm.gradle.Maturity.EXPERIMENTAL
}
diff --git a/examples/src/main/kotlin/space/kscience/kmath/ast/kotlingradSupport.kt b/examples/src/main/kotlin/space/kscience/kmath/ast/kotlingradSupport.kt
index 4a31f33a3..25f42f5a9 100644
--- a/examples/src/main/kotlin/space/kscience/kmath/ast/kotlingradSupport.kt
+++ b/examples/src/main/kotlin/space/kscience/kmath/ast/kotlingradSupport.kt
@@ -25,5 +25,5 @@ fun main() {
val expectedDerivative = "2*x-4".parseMath().compileToExpression(DoubleField)
- assert(actualDerivative("x" to 123.0) == expectedDerivative("x" to 123.0))
+ assert(actualDerivative(x to 123.0) == expectedDerivative(x to 123.0))
}
diff --git a/examples/src/main/kotlin/space/kscience/kmath/functions/integrate.kt b/examples/src/main/kotlin/space/kscience/kmath/functions/integrate.kt
index 90542adf4..6990e8c8f 100644
--- a/examples/src/main/kotlin/space/kscience/kmath/functions/integrate.kt
+++ b/examples/src/main/kotlin/space/kscience/kmath/functions/integrate.kt
@@ -1,3 +1,8 @@
+/*
+ * Copyright 2018-2021 KMath contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
package space.kscience.kmath.functions
import space.kscience.kmath.integration.integrate
diff --git a/examples/src/main/kotlin/space/kscience/kmath/functions/matrixIntegration.kt b/examples/src/main/kotlin/space/kscience/kmath/functions/matrixIntegration.kt
index bd431c22c..8020df8f6 100644
--- a/examples/src/main/kotlin/space/kscience/kmath/functions/matrixIntegration.kt
+++ b/examples/src/main/kotlin/space/kscience/kmath/functions/matrixIntegration.kt
@@ -1,3 +1,8 @@
+/*
+ * Copyright 2018-2021 KMath contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
package space.kscience.kmath.functions
import space.kscience.kmath.integration.integrate
diff --git a/examples/src/main/kotlin/space/kscience/kmath/linear/gradient.kt b/examples/src/main/kotlin/space/kscience/kmath/linear/gradient.kt
index f7b284e89..a01ea7fe2 100644
--- a/examples/src/main/kotlin/space/kscience/kmath/linear/gradient.kt
+++ b/examples/src/main/kotlin/space/kscience/kmath/linear/gradient.kt
@@ -22,8 +22,8 @@ fun main() {
return DoubleBuffer(x.size) { i ->
val h = sigma[i] / 5
val dVector = DoubleBuffer(x.size) { if (it == i) h else 0.0 }
- val f1 = invoke(x + dVector / 2)
- val f0 = invoke(x - dVector / 2)
+ val f1 = this(x + dVector / 2)
+ val f0 = this(x - dVector / 2)
(f1 - f0) / h
}
}
diff --git a/examples/src/main/kotlin/space/kscience/kmath/structures/NDField.kt b/examples/src/main/kotlin/space/kscience/kmath/structures/NDField.kt
index cc1f5f680..501bf98db 100644
--- a/examples/src/main/kotlin/space/kscience/kmath/structures/NDField.kt
+++ b/examples/src/main/kotlin/space/kscience/kmath/structures/NDField.kt
@@ -5,6 +5,7 @@
package space.kscience.kmath.structures
+import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.GlobalScope
import org.nd4j.linalg.factory.Nd4j
import space.kscience.kmath.nd.*
@@ -22,6 +23,7 @@ internal inline fun measureAndPrint(title: String, block: () -> Unit) {
println("$title completed in $time millis")
}
+@OptIn(DelicateCoroutinesApi::class)
fun main() {
// initializing Nd4j
Nd4j.zeros(0)
diff --git a/examples/src/main/kotlin/space/kscience/kmath/tensors/DataSetNormalization.kt b/examples/src/main/kotlin/space/kscience/kmath/tensors/DataSetNormalization.kt
new file mode 100644
index 000000000..6fbf16a91
--- /dev/null
+++ b/examples/src/main/kotlin/space/kscience/kmath/tensors/DataSetNormalization.kt
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2018-2021 KMath contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package space.kscience.kmath.tensors
+
+import space.kscience.kmath.operations.invoke
+import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra
+
+
+// Dataset normalization
+
+fun main() {
+
+ // work in context with broadcast methods
+ BroadcastDoubleTensorAlgebra {
+ // take dataset of 5-element vectors from normal distribution
+ val dataset = randomNormal(intArrayOf(100, 5)) * 1.5 // all elements from N(0, 1.5)
+
+ dataset += fromArray(
+ intArrayOf(5),
+ doubleArrayOf(0.0, 1.0, 1.5, 3.0, 5.0) // rows means
+ )
+
+
+ // find out mean and standard deviation of each column
+ val mean = dataset.mean(0, false)
+ val std = dataset.std(0, false)
+
+ println("Mean:\n$mean")
+ println("Standard deviation:\n$std")
+
+ // also we can calculate other statistic as minimum and maximum of rows
+ println("Minimum:\n${dataset.min(0, false)}")
+ println("Maximum:\n${dataset.max(0, false)}")
+
+ // now we can scale dataset with mean normalization
+ val datasetScaled = (dataset - mean) / std
+
+ // find out mean and std of scaled dataset
+
+ println("Mean of scaled:\n${datasetScaled.mean(0, false)}")
+ println("Mean of scaled:\n${datasetScaled.std(0, false)}")
+ }
+}
\ No newline at end of file
diff --git a/examples/src/main/kotlin/space/kscience/kmath/tensors/LinearSystemSolvingWithLUP.kt b/examples/src/main/kotlin/space/kscience/kmath/tensors/LinearSystemSolvingWithLUP.kt
new file mode 100644
index 000000000..78370b517
--- /dev/null
+++ b/examples/src/main/kotlin/space/kscience/kmath/tensors/LinearSystemSolvingWithLUP.kt
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2018-2021 KMath contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package space.kscience.kmath.tensors
+
+import space.kscience.kmath.operations.invoke
+import space.kscience.kmath.tensors.core.DoubleTensor
+import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra
+
+// solving linear system with LUP decomposition
+
+fun main () {
+
+ // work in context with linear operations
+ BroadcastDoubleTensorAlgebra {
+
+ // set true value of x
+ val trueX = fromArray(
+ intArrayOf(4),
+ doubleArrayOf(-2.0, 1.5, 6.8, -2.4)
+ )
+
+ // and A matrix
+ val a = fromArray(
+ intArrayOf(4, 4),
+ doubleArrayOf(
+ 0.5, 10.5, 4.5, 1.0,
+ 8.5, 0.9, 12.8, 0.1,
+ 5.56, 9.19, 7.62, 5.45,
+ 1.0, 2.0, -3.0, -2.5
+ )
+ )
+
+ // calculate y value
+ val b = a dot trueX
+
+ // check out A and b
+ println("A:\n$a")
+ println("b:\n$b")
+
+ // solve `Ax = b` system using LUP decomposition
+
+ // get P, L, U such that PA = LU
+ val (p, l, u) = a.lu()
+
+ // check that P is permutation matrix
+ println("P:\n$p")
+ // L is lower triangular matrix and U is upper triangular matrix
+ println("L:\n$l")
+ println("U:\n$u")
+ // and PA = LU
+ println("PA:\n${p dot a}")
+ println("LU:\n${l dot u}")
+
+ /* Ax = b;
+ PAx = Pb;
+ LUx = Pb;
+ let y = Ux, then
+ Ly = Pb -- this system can be easily solved, since the matrix L is lower triangular;
+ Ux = y can be solved the same way, since the matrix L is upper triangular
+ */
+
+
+
+ // this function returns solution x of a system lx = b, l should be lower triangular
+ fun solveLT(l: DoubleTensor, b: DoubleTensor): DoubleTensor {
+ val n = l.shape[0]
+ val x = zeros(intArrayOf(n))
+ for (i in 0 until n){
+ x[intArrayOf(i)] = (b[intArrayOf(i)] - l[i].dot(x).value()) / l[intArrayOf(i, i)]
+ }
+ return x
+ }
+
+ val y = solveLT(l, p dot b)
+
+ // 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
+ val revMat = u.zeroesLike()
+ val n = revMat.shape[0]
+ for (i in 0 until n) {
+ revMat[intArrayOf(i, n - 1 - i)] = 1.0
+ }
+
+ // solution of system ux = b, u should be upper triangular
+ fun solveUT(u: DoubleTensor, b: DoubleTensor): DoubleTensor = revMat dot solveLT(
+ revMat dot u dot revMat, revMat dot b
+ )
+
+ val x = solveUT(u, y)
+
+ println("True x:\n$trueX")
+ println("x founded with LU method:\n$x")
+ }
+}
\ No newline at end of file
diff --git a/examples/src/main/kotlin/space/kscience/kmath/tensors/NeuralNetwork.kt b/examples/src/main/kotlin/space/kscience/kmath/tensors/NeuralNetwork.kt
new file mode 100644
index 000000000..5b3c2e1cd
--- /dev/null
+++ b/examples/src/main/kotlin/space/kscience/kmath/tensors/NeuralNetwork.kt
@@ -0,0 +1,241 @@
+/*
+ * Copyright 2018-2021 KMath contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package space.kscience.kmath.tensors
+
+import space.kscience.kmath.operations.invoke
+import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra
+import space.kscience.kmath.tensors.core.DoubleTensor
+import space.kscience.kmath.tensors.core.DoubleTensorAlgebra
+import space.kscience.kmath.tensors.core.toDoubleArray
+import kotlin.math.sqrt
+
+const val seed = 100500L
+
+// Simple feedforward neural network with backpropagation training
+
+// interface of network layer
+interface Layer {
+ fun forward(input: DoubleTensor): DoubleTensor
+ fun backward(input: DoubleTensor, outputError: DoubleTensor): DoubleTensor
+}
+
+// activation layer
+open class Activation(
+ val activation: (DoubleTensor) -> DoubleTensor,
+ val activationDer: (DoubleTensor) -> DoubleTensor
+) : Layer {
+ override fun forward(input: DoubleTensor): DoubleTensor {
+ return activation(input)
+ }
+
+ override fun backward(input: DoubleTensor, outputError: DoubleTensor): DoubleTensor {
+ return DoubleTensorAlgebra { outputError * activationDer(input) }
+ }
+}
+
+fun relu(x: DoubleTensor): DoubleTensor = DoubleTensorAlgebra {
+ x.map { if (it > 0) it else 0.0 }
+}
+
+fun reluDer(x: DoubleTensor): DoubleTensor = DoubleTensorAlgebra {
+ x.map { if (it > 0) 1.0 else 0.0 }
+}
+
+// activation layer with relu activator
+class ReLU : Activation(::relu, ::reluDer)
+
+fun sigmoid(x: DoubleTensor): DoubleTensor = DoubleTensorAlgebra {
+ 1.0 / (1.0 + (-x).exp())
+}
+
+fun sigmoidDer(x: DoubleTensor): DoubleTensor = DoubleTensorAlgebra {
+ sigmoid(x) * (1.0 - sigmoid(x))
+}
+
+// activation layer with sigmoid activator
+class Sigmoid : Activation(::sigmoid, ::sigmoidDer)
+
+// dense layer
+class Dense(
+ private val inputUnits: Int,
+ private val outputUnits: Int,
+ private val learningRate: Double = 0.1
+) : Layer {
+
+ private val weights: DoubleTensor = DoubleTensorAlgebra {
+ randomNormal(
+ intArrayOf(inputUnits, outputUnits),
+ seed
+ ) * sqrt(2.0 / (inputUnits + outputUnits))
+ }
+
+ private val bias: DoubleTensor = DoubleTensorAlgebra { zeros(intArrayOf(outputUnits)) }
+
+ override fun forward(input: DoubleTensor): DoubleTensor {
+ return BroadcastDoubleTensorAlgebra { (input dot weights) + bias }
+ }
+
+ override fun backward(input: DoubleTensor, outputError: DoubleTensor): DoubleTensor = DoubleTensorAlgebra {
+ val gradInput = outputError dot weights.transpose()
+
+ val gradW = input.transpose() dot outputError
+ val gradBias = outputError.mean(dim = 0, keepDim = false) * input.shape[0].toDouble()
+
+ weights -= learningRate * gradW
+ bias -= learningRate * gradBias
+
+ gradInput
+ }
+
+}
+
+// simple accuracy equal to the proportion of correct answers
+fun accuracy(yPred: DoubleTensor, yTrue: DoubleTensor): Double {
+ check(yPred.shape contentEquals yTrue.shape)
+ val n = yPred.shape[0]
+ var correctCnt = 0
+ for (i in 0 until n) {
+ if (yPred[intArrayOf(i, 0)] == yTrue[intArrayOf(i, 0)]) {
+ correctCnt += 1
+ }
+ }
+ return correctCnt.toDouble() / n.toDouble()
+}
+
+// neural network class
+@OptIn(ExperimentalStdlibApi::class)
+class NeuralNetwork(private val layers: List) {
+ private fun softMaxLoss(yPred: DoubleTensor, yTrue: DoubleTensor): DoubleTensor = BroadcastDoubleTensorAlgebra {
+
+ val onesForAnswers = yPred.zeroesLike()
+ yTrue.toDoubleArray().forEachIndexed { index, labelDouble ->
+ val label = labelDouble.toInt()
+ onesForAnswers[intArrayOf(index, label)] = 1.0
+ }
+
+ val softmaxValue = yPred.exp() / yPred.exp().sum(dim = 1, keepDim = true)
+
+ (-onesForAnswers + softmaxValue) / (yPred.shape[0].toDouble())
+ }
+
+
+ private fun forward(x: DoubleTensor): List {
+ var input = x
+
+ return buildList {
+ layers.forEach { layer ->
+ val output = layer.forward(input)
+ add(output)
+ input = output
+ }
+ }
+ }
+
+ private fun train(xTrain: DoubleTensor, yTrain: DoubleTensor) {
+ val layerInputs = buildList {
+ add(xTrain)
+ addAll(forward(xTrain))
+ }
+
+ var lossGrad = softMaxLoss(layerInputs.last(), yTrain)
+
+ layers.zip(layerInputs).reversed().forEach { (layer, input) ->
+ lossGrad = layer.backward(input, lossGrad)
+ }
+ }
+
+ fun fit(xTrain: DoubleTensor, yTrain: DoubleTensor, batchSize: Int, epochs: Int) = DoubleTensorAlgebra {
+ fun iterBatch(x: DoubleTensor, y: DoubleTensor): Sequence> = sequence {
+ val n = x.shape[0]
+ val shuffledIndices = (0 until n).shuffled()
+ for (i in 0 until n step batchSize) {
+ val excerptIndices = shuffledIndices.drop(i).take(batchSize).toIntArray()
+ val batch = x.rowsByIndices(excerptIndices) to y.rowsByIndices(excerptIndices)
+ yield(batch)
+ }
+ }
+
+ for (epoch in 0 until epochs) {
+ println("Epoch ${epoch + 1}/$epochs")
+ for ((xBatch, yBatch) in iterBatch(xTrain, yTrain)) {
+ train(xBatch, yBatch)
+ }
+ println("Accuracy:${accuracy(yTrain, predict(xTrain).argMax(1, true))}")
+ }
+ }
+
+ fun predict(x: DoubleTensor): DoubleTensor {
+ return forward(x).last()
+ }
+
+}
+
+
+@OptIn(ExperimentalStdlibApi::class)
+fun main() {
+ BroadcastDoubleTensorAlgebra {
+ val features = 5
+ val sampleSize = 250
+ val trainSize = 180
+ //val testSize = sampleSize - trainSize
+
+ // take sample of features from normal distribution
+ val x = randomNormal(intArrayOf(sampleSize, features), seed) * 2.5
+
+ x += fromArray(
+ intArrayOf(5),
+ doubleArrayOf(0.0, -1.0, -2.5, -3.0, 5.5) // rows means
+ )
+
+
+ // define class like '1' if the sum of features > 0 and '0' otherwise
+ val y = fromArray(
+ intArrayOf(sampleSize, 1),
+ DoubleArray(sampleSize) { i ->
+ if (x[i].sum() > 0.0) {
+ 1.0
+ } else {
+ 0.0
+ }
+ }
+ )
+
+ // split train ans test
+ val trainIndices = (0 until trainSize).toList().toIntArray()
+ val testIndices = (trainSize until sampleSize).toList().toIntArray()
+
+ val xTrain = x.rowsByIndices(trainIndices)
+ val yTrain = y.rowsByIndices(trainIndices)
+
+ val xTest = x.rowsByIndices(testIndices)
+ val yTest = y.rowsByIndices(testIndices)
+
+ // build model
+ val layers = buildList {
+ add(Dense(features, 64))
+ add(ReLU())
+ add(Dense(64, 16))
+ add(ReLU())
+ add(Dense(16, 2))
+ add(Sigmoid())
+ }
+ val model = NeuralNetwork(layers)
+
+ // fit it with train data
+ model.fit(xTrain, yTrain, batchSize = 20, epochs = 10)
+
+ // make prediction
+ val prediction = model.predict(xTest)
+
+ // process raw prediction via argMax
+ val predictionLabels = prediction.argMax(1, true)
+
+ // find out accuracy
+ val acc = accuracy(yTest, predictionLabels)
+ println("Test accuracy:$acc")
+
+ }
+}
diff --git a/examples/src/main/kotlin/space/kscience/kmath/tensors/OLSWithSVD.kt b/examples/src/main/kotlin/space/kscience/kmath/tensors/OLSWithSVD.kt
new file mode 100644
index 000000000..b42602988
--- /dev/null
+++ b/examples/src/main/kotlin/space/kscience/kmath/tensors/OLSWithSVD.kt
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2018-2021 KMath contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package space.kscience.kmath.tensors
+
+import space.kscience.kmath.operations.invoke
+import space.kscience.kmath.tensors.core.DoubleTensor
+import space.kscience.kmath.tensors.core.DoubleTensorAlgebra
+
+import kotlin.math.abs
+
+// OLS estimator using SVD
+
+fun main() {
+ //seed for random
+ val randSeed = 100500L
+
+ // work in context with linear operations
+ DoubleTensorAlgebra {
+ // take coefficient vector from normal distribution
+ val alpha = randomNormal(
+ intArrayOf(5),
+ randSeed
+ ) + fromArray(
+ intArrayOf(5),
+ doubleArrayOf(1.0, 2.5, 3.4, 5.0, 10.1)
+ )
+
+ println("Real alpha:\n$alpha")
+
+ // also take sample of size 20 from normal distribution for x
+ val x = randomNormal(
+ intArrayOf(20, 5),
+ randSeed
+ )
+
+ // calculate y and add gaussian noise (N(0, 0.05))
+ val y = x dot alpha
+ y += y.randomNormalLike(randSeed) * 0.05
+
+ // now restore the coefficient vector with OSL estimator with SVD
+ val (u, singValues, v) = x.svd()
+
+ // we have to make sure the singular values of the matrix are not close to zero
+ println("Singular values:\n$singValues")
+
+
+ // 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 alphaOLS = v dot sigma dot u.transpose() dot y
+ println("Estimated alpha:\n" +
+ "$alphaOLS")
+
+ // figure out MSE of approximation
+ fun mse(yTrue: DoubleTensor, yPred: DoubleTensor): Double {
+ require(yTrue.shape.size == 1)
+ require(yTrue.shape contentEquals yPred.shape)
+
+ val diff = yTrue - yPred
+ return diff.dot(diff).sqrt().value()
+ }
+
+ println("MSE: ${mse(alpha, alphaOLS)}")
+ }
+}
\ No newline at end of file
diff --git a/examples/src/main/kotlin/space/kscience/kmath/tensors/PCA.kt b/examples/src/main/kotlin/space/kscience/kmath/tensors/PCA.kt
new file mode 100644
index 000000000..f8ac13d3f
--- /dev/null
+++ b/examples/src/main/kotlin/space/kscience/kmath/tensors/PCA.kt
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2018-2021 KMath contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package space.kscience.kmath.tensors
+
+import space.kscience.kmath.operations.invoke
+import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra
+
+
+// simple PCA
+
+fun main(){
+ val seed = 100500L
+
+ // work in context with broadcast methods
+ BroadcastDoubleTensorAlgebra {
+
+ // assume x is range from 0 until 10
+ val x = fromArray(
+ intArrayOf(10),
+ (0 until 10).toList().map { it.toDouble() }.toDoubleArray()
+ )
+
+ // take y dependent on x with noise
+ val y = 2.0 * x + (3.0 + x.randomNormalLike(seed) * 1.5)
+
+ println("x:\n$x")
+ println("y:\n$y")
+
+ // stack them into single dataset
+ val dataset = stack(listOf(x, y)).transpose()
+
+ // normalize both x and y
+ val xMean = x.mean()
+ val yMean = y.mean()
+
+ val xStd = x.std()
+ val yStd = y.std()
+
+ val xScaled = (x - xMean) / xStd
+ val yScaled = (y - yMean) / yStd
+
+ // save means ans standard deviations for further recovery
+ val mean = fromArray(
+ intArrayOf(2),
+ doubleArrayOf(xMean, yMean)
+ )
+ println("Means:\n$mean")
+
+ val std = fromArray(
+ intArrayOf(2),
+ doubleArrayOf(xStd, yStd)
+ )
+ println("Standard deviations:\n$std")
+
+ // calculate the covariance matrix of scaled x and y
+ val covMatrix = cov(listOf(xScaled, yScaled))
+ println("Covariance matrix:\n$covMatrix")
+
+ // and find out eigenvector of it
+ val (_, evecs) = covMatrix.symEig()
+ val v = evecs[0]
+ println("Eigenvector:\n$v")
+
+ // reduce dimension of dataset
+ val datasetReduced = v dot stack(listOf(xScaled, yScaled))
+ println("Reduced data:\n$datasetReduced")
+
+ // we can restore original data from reduced data.
+ // for example, find 7th element of dataset
+ val n = 7
+ val restored = (datasetReduced[n] dot v.view(intArrayOf(1, 2))) * std + mean
+ println("Original value:\n${dataset[n]}")
+ println("Restored value:\n$restored")
+ }
+}
diff --git a/gradlew b/gradlew
index 6ad9eb930..4f906e0c8 100755
--- a/gradlew
+++ b/gradlew
@@ -1,8 +1,19 @@
#!/usr/bin/env sh
#
-# 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.
+# Copyright 2015 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
#
##############################################################################
diff --git a/kmath-ast/README.md b/kmath-ast/README.md
index b1ef9c7d3..646ab4306 100644
--- a/kmath-ast/README.md
+++ b/kmath-ast/README.md
@@ -1,41 +1,37 @@
# Module kmath-ast
-Abstract syntax tree expression representation and related optimizations.
+Performance and visualization extensions to MST API.
- - [expression-language](src/jvmMain/kotlin/space/kscience/kmath/ast/parser.kt) : Expression language and its parser
- - [mst](src/commonMain/kotlin/space/kscience/kmath/ast/MST.kt) : MST (Mathematical Syntax Tree) as expression language's syntax intermediate representation
- - [mst-building](src/commonMain/kotlin/space/kscience/kmath/ast/MstAlgebra.kt) : MST building algebraic structure
- - [mst-interpreter](src/commonMain/kotlin/space/kscience/kmath/ast/MST.kt) : MST interpreter
+ - [expression-language](src/commonMain/kotlin/space/kscience/kmath/ast/parser.kt) : Expression language and its parser
- [mst-jvm-codegen](src/jvmMain/kotlin/space/kscience/kmath/asm/asm.kt) : Dynamic MST to JVM bytecode compiler
- [mst-js-codegen](src/jsMain/kotlin/space/kscience/kmath/estree/estree.kt) : Dynamic MST to JS compiler
+ - [rendering](src/commonMain/kotlin/space/kscience/kmath/ast/rendering/MathRenderer.kt) : Extendable MST rendering
## Artifact:
-The Maven coordinates of this project are `space.kscience:kmath-ast:0.3.0-dev-6`.
+The Maven coordinates of this project are `space.kscience:kmath-ast:0.3.0-dev-8`.
**Gradle:**
```gradle
repositories {
maven { url 'https://repo.kotlin.link' }
- maven { url 'https://dl.bintray.com/hotkeytlt/maven' }
- maven { url "https://dl.bintray.com/kotlin/kotlin-eap" } // include for builds based on kotlin-eap
+ mavenCentral()
}
dependencies {
- implementation 'space.kscience:kmath-ast:0.3.0-dev-6'
+ implementation 'space.kscience:kmath-ast:0.3.0-dev-8'
}
```
**Gradle Kotlin DSL:**
```kotlin
repositories {
maven("https://repo.kotlin.link")
- maven("https://dl.bintray.com/kotlin/kotlin-eap") // include for builds based on kotlin-eap
- maven("https://dl.bintray.com/hotkeytlt/maven") // required for a
+ mavenCentral()
}
dependencies {
- implementation("space.kscience:kmath-ast:0.3.0-dev-6")
+ implementation("space.kscience:kmath-ast:0.3.0-dev-8")
}
```
@@ -43,21 +39,26 @@ dependencies {
### On JVM
-`kmath-ast` JVM module supports runtime code generation to eliminate overhead of tree traversal. Code generator builds
-a special implementation of `Expression` with implemented `invoke` function.
+`kmath-ast` JVM module supports runtime code generation to eliminate overhead of tree traversal. Code generator builds a
+special implementation of `Expression` with implemented `invoke` function.
For example, the following builder:
```kotlin
-DoubleField.mstInField { symbol("x") + 2 }.compile()
+import space.kscience.kmath.expressions.*
+import space.kscience.kmath.operations.*
+import space.kscience.kmath.asm.*
+
+MstField { bindSymbol("x") + 2 }.compileToExpression(DoubleField)
```
-… leads to generation of bytecode, which can be decompiled to the following Java class:
+... leads to generation of bytecode, which can be decompiled to the following Java class:
```java
package space.kscience.kmath.asm.generated;
import java.util.Map;
+
import kotlin.jvm.functions.Function2;
import space.kscience.kmath.asm.internal.MapIntrinsics;
import space.kscience.kmath.expressions.Expression;
@@ -67,7 +68,7 @@ public final class AsmCompiledExpression_45045_0 implements Expression {
private final Object[] constants;
public final Double invoke(Map arguments) {
- return (Double)((Function2)this.constants[0]).invoke((Double)MapIntrinsics.getOrFail(arguments, "x"), 2);
+ return (Double) ((Function2) this.constants[0]).invoke((Double) MapIntrinsics.getOrFail(arguments, "x"), 2);
}
public AsmCompiledExpression_45045_0(Object[] constants) {
@@ -77,19 +78,10 @@ public final class AsmCompiledExpression_45045_0 implements Expression {
```
-### Example Usage
-
-This API extends MST and MstExpression, so you may optimize as both of them:
-
-```kotlin
-DoubleField.mstInField { symbol("x") + 2 }.compile()
-DoubleField.expression("x+2".parseMath())
-```
-
#### Known issues
-- The same classes may be generated and loaded twice, so it is recommended to cache compiled expressions to avoid
- class loading overhead.
+- The same classes may be generated and loaded twice, so it is recommended to cache compiled expressions to avoid class
+ loading overhead.
- This API is not supported by non-dynamic JVM implementations (like TeaVM and GraalVM) because of using class loaders.
### On JS
@@ -97,33 +89,62 @@ DoubleField.expression("x+2".parseMath())
A similar feature is also available on JS.
```kotlin
-DoubleField.mstInField { symbol("x") + 2 }.compile()
+import space.kscience.kmath.expressions.*
+import space.kscience.kmath.operations.*
+import space.kscience.kmath.estree.*
+
+MstField { bindSymbol("x") + 2 }.compileToExpression(DoubleField)
```
The code above returns expression implemented with such a JS function:
```js
var executable = function (constants, arguments) {
- return constants[1](constants[0](arguments, "x"), 2);
+ return constants[1](constants[0](arguments, "x"), 2);
};
```
+JS also supports very experimental expression optimization with [WebAssembly](https://webassembly.org/) IR generation.
+Currently, only expressions inside `DoubleField` and `IntRing` are supported.
+
+```kotlin
+import space.kscience.kmath.expressions.*
+import space.kscience.kmath.operations.*
+import space.kscience.kmath.wasm.*
+
+MstField { bindSymbol("x") + 2 }.compileToExpression(DoubleField)
+```
+
+An example of emitted Wasm IR in the form of WAT:
+
+```lisp
+(func $executable (param $0 f64) (result f64)
+ (f64.add
+ (local.get $0)
+ (f64.const 2)
+ )
+)
+```
+
#### Known issues
-- This feature uses `eval` which can be unavailable in several environments.
+- ESTree expression compilation uses `eval` which can be unavailable in several environments.
+- WebAssembly isn't supported by old versions of browsers (see https://webassembly.org/roadmap/).
## Rendering expressions
-kmath-ast also includes an extensible engine to display expressions in LaTeX or MathML syntax.
+kmath-ast also includes an extensible engine to display expressions in LaTeX or MathML syntax.
Example usage:
```kotlin
import space.kscience.kmath.ast.*
import space.kscience.kmath.ast.rendering.*
+import space.kscience.kmath.misc.*
+@OptIn(UnstableKMathAPI::class)
public fun main() {
- val mst = "exp(sqrt(x))-asin(2*x)/(2e10+x^3)/(-12)".parseMath()
+ val mst = "exp(sqrt(x))-asin(2*x)/(2e10+x^3)/(12)+x^(2/3)".parseMath()
val syntax = FeaturedMathRendererWithPostProcess.Default.render(mst)
val latex = LatexSyntaxRenderer.renderWithStringBuilder(syntax)
println("LaTeX:")
@@ -135,15 +156,80 @@ public fun main() {
}
```
-Result LaTeX:
+Result LaTeX:
-![](http://chart.googleapis.com/chart?cht=tx&chl=e%5E%7B%5Csqrt%7Bx%7D%7D-%5Cfrac%7B%5Cfrac%7B%5Coperatorname%7Bsin%7D%5E%7B-1%7D%5C,%5Cleft(2%5C,x%5Cright)%7D%7B2%5Ctimes10%5E%7B10%7D%2Bx%5E%7B3%7D%7D%7D%7B-12%7D)
+![](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})
-Result MathML (embedding MathML is not allowed by GitHub Markdown):
+Result MathML (can be used with MathJax or other renderers):
+
+
```html
-e x - sin - 1 2 x 2 × 10 10 + x 3 - 12
+
+
+ exp
+
+
+
+ x
+
+
+ -
+
+
+
+
+ arcsin
+
+
+ 2
+
+ x
+
+
+
+ 2
+ ×
+
+
+ 10
+
+
+ 10
+
+
+ +
+
+
+ x
+
+
+ 3
+
+
+
+
+
+
+ 12
+
+
+ +
+
+
+ x
+
+
+ 2
+ /
+ 3
+
+
+
+
```
-It is also possible to create custom algorithms of render, and even add support of other markup languages
+
+
+It is also possible to create custom algorithms of render, and even add support of other markup languages
(see API reference).
diff --git a/kmath-ast/build.gradle.kts b/kmath-ast/build.gradle.kts
index 3f309b67c..508374d82 100644
--- a/kmath-ast/build.gradle.kts
+++ b/kmath-ast/build.gradle.kts
@@ -1,10 +1,3 @@
-/*
- * 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.
- */
-
-import ru.mipt.npm.gradle.Maturity
-
plugins {
kotlin("multiplatform")
id("ru.mipt.npm.gradle.common")
@@ -25,8 +18,13 @@ kotlin.js {
}
kotlin.sourceSets {
+ filter { it.name.contains("test", true) }
+ .map(org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet::languageSettings)
+ .forEach { it.useExperimentalAnnotation("space.kscience.kmath.misc.UnstableKMathAPI") }
+
commonMain {
dependencies {
+ api("com.github.h0tk3y.betterParse:better-parse:0.4.2")
api(project(":kmath-core"))
}
}
@@ -39,13 +37,15 @@ kotlin.sourceSets {
jsMain {
dependencies {
- implementation(npm("astring", "1.7.0"))
+ implementation(npm("astring", "1.7.4"))
+ implementation(npm("binaryen", "100.0"))
+ implementation(npm("js-base64", "3.6.0"))
+ implementation(npm("webassembly", "0.11.0"))
}
}
jvmMain {
dependencies {
- api("com.github.h0tk3y.betterParse:better-parse:0.4.1")
implementation("org.ow2.asm:asm:9.1")
implementation("org.ow2.asm:asm-commons:9.1")
}
@@ -58,31 +58,13 @@ tasks.dokkaHtml {
}
readme {
- maturity = Maturity.PROTOTYPE
+ maturity = ru.mipt.npm.gradle.Maturity.EXPERIMENTAL
propertyByTemplate("artifact", rootProject.file("docs/templates/ARTIFACT-TEMPLATE.md"))
feature(
id = "expression-language",
description = "Expression language and its parser",
- ref = "src/jvmMain/kotlin/space/kscience/kmath/ast/parser.kt"
- )
-
- feature(
- id = "mst",
- description = "MST (Mathematical Syntax Tree) as expression language's syntax intermediate representation",
- ref = "src/commonMain/kotlin/space/kscience/kmath/ast/MST.kt"
- )
-
- feature(
- id = "mst-building",
- description = "MST building algebraic structure",
- ref = "src/commonMain/kotlin/space/kscience/kmath/ast/MstAlgebra.kt"
- )
-
- feature(
- id = "mst-interpreter",
- description = "MST interpreter",
- ref = "src/commonMain/kotlin/space/kscience/kmath/ast/MST.kt"
+ ref = "src/commonMain/kotlin/space/kscience/kmath/ast/parser.kt"
)
feature(
@@ -96,4 +78,10 @@ readme {
description = "Dynamic MST to JS compiler",
ref = "src/jsMain/kotlin/space/kscience/kmath/estree/estree.kt"
)
+
+ feature(
+ id = "rendering",
+ description = "Extendable MST rendering",
+ ref = "src/commonMain/kotlin/space/kscience/kmath/ast/rendering/MathRenderer.kt"
+ )
}
diff --git a/kmath-ast/docs/README-TEMPLATE.md b/kmath-ast/docs/README-TEMPLATE.md
index 9ed44d584..80ea31642 100644
--- a/kmath-ast/docs/README-TEMPLATE.md
+++ b/kmath-ast/docs/README-TEMPLATE.md
@@ -1,6 +1,6 @@
# Module kmath-ast
-Abstract syntax tree expression representation and related optimizations.
+Performance and visualization extensions to MST API.
${features}
@@ -10,21 +10,26 @@ ${artifact}
### On JVM
-`kmath-ast` JVM module supports runtime code generation to eliminate overhead of tree traversal. Code generator builds
-a special implementation of `Expression` with implemented `invoke` function.
+`kmath-ast` JVM module supports runtime code generation to eliminate overhead of tree traversal. Code generator builds a
+special implementation of `Expression` with implemented `invoke` function.
For example, the following builder:
```kotlin
-DoubleField.mstInField { symbol("x") + 2 }.compile()
+import space.kscience.kmath.expressions.*
+import space.kscience.kmath.operations.*
+import space.kscience.kmath.asm.*
+
+MstField { bindSymbol("x") + 2 }.compileToExpression(DoubleField)
```
-… leads to generation of bytecode, which can be decompiled to the following Java class:
+... leads to generation of bytecode, which can be decompiled to the following Java class:
```java
package space.kscience.kmath.asm.generated;
import java.util.Map;
+
import kotlin.jvm.functions.Function2;
import space.kscience.kmath.asm.internal.MapIntrinsics;
import space.kscience.kmath.expressions.Expression;
@@ -34,7 +39,7 @@ public final class AsmCompiledExpression_45045_0 implements Expression {
private final Object[] constants;
public final Double invoke(Map arguments) {
- return (Double)((Function2)this.constants[0]).invoke((Double)MapIntrinsics.getOrFail(arguments, "x"), 2);
+ return (Double) ((Function2) this.constants[0]).invoke((Double) MapIntrinsics.getOrFail(arguments, "x"), 2);
}
public AsmCompiledExpression_45045_0(Object[] constants) {
@@ -44,19 +49,10 @@ public final class AsmCompiledExpression_45045_0 implements Expression {
```
-### Example Usage
-
-This API extends MST and MstExpression, so you may optimize as both of them:
-
-```kotlin
-DoubleField.mstInField { symbol("x") + 2 }.compile()
-DoubleField.expression("x+2".parseMath())
-```
-
#### Known issues
-- The same classes may be generated and loaded twice, so it is recommended to cache compiled expressions to avoid
- class loading overhead.
+- The same classes may be generated and loaded twice, so it is recommended to cache compiled expressions to avoid class
+ loading overhead.
- This API is not supported by non-dynamic JVM implementations (like TeaVM and GraalVM) because of using class loaders.
### On JS
@@ -64,33 +60,62 @@ DoubleField.expression("x+2".parseMath())
A similar feature is also available on JS.
```kotlin
-DoubleField.mstInField { symbol("x") + 2 }.compile()
+import space.kscience.kmath.expressions.*
+import space.kscience.kmath.operations.*
+import space.kscience.kmath.estree.*
+
+MstField { bindSymbol("x") + 2 }.compileToExpression(DoubleField)
```
The code above returns expression implemented with such a JS function:
```js
var executable = function (constants, arguments) {
- return constants[1](constants[0](arguments, "x"), 2);
+ return constants[1](constants[0](arguments, "x"), 2);
};
```
+JS also supports very experimental expression optimization with [WebAssembly](https://webassembly.org/) IR generation.
+Currently, only expressions inside `DoubleField` and `IntRing` are supported.
+
+```kotlin
+import space.kscience.kmath.expressions.*
+import space.kscience.kmath.operations.*
+import space.kscience.kmath.wasm.*
+
+MstField { bindSymbol("x") + 2 }.compileToExpression(DoubleField)
+```
+
+An example of emitted Wasm IR in the form of WAT:
+
+```lisp
+(func \$executable (param \$0 f64) (result f64)
+ (f64.add
+ (local.get \$0)
+ (f64.const 2)
+ )
+)
+```
+
#### Known issues
-- This feature uses `eval` which can be unavailable in several environments.
+- ESTree expression compilation uses `eval` which can be unavailable in several environments.
+- WebAssembly isn't supported by old versions of browsers (see https://webassembly.org/roadmap/).
## Rendering expressions
-kmath-ast also includes an extensible engine to display expressions in LaTeX or MathML syntax.
+kmath-ast also includes an extensible engine to display expressions in LaTeX or MathML syntax.
Example usage:
```kotlin
import space.kscience.kmath.ast.*
import space.kscience.kmath.ast.rendering.*
+import space.kscience.kmath.misc.*
+@OptIn(UnstableKMathAPI::class)
public fun main() {
- val mst = "exp(sqrt(x))-asin(2*x)/(2e10+x^3)/(-12)".parseMath()
+ val mst = "exp(sqrt(x))-asin(2*x)/(2e10+x^3)/(12)+x^(2/3)".parseMath()
val syntax = FeaturedMathRendererWithPostProcess.Default.render(mst)
val latex = LatexSyntaxRenderer.renderWithStringBuilder(syntax)
println("LaTeX:")
@@ -102,15 +127,80 @@ public fun main() {
}
```
-Result LaTeX:
+Result LaTeX:
-![](http://chart.googleapis.com/chart?cht=tx&chl=e%5E%7B%5Csqrt%7Bx%7D%7D-%5Cfrac%7B%5Cfrac%7B%5Coperatorname%7Bsin%7D%5E%7B-1%7D%5C,%5Cleft(2%5C,x%5Cright)%7D%7B2%5Ctimes10%5E%7B10%7D%2Bx%5E%7B3%7D%7D%7D%7B-12%7D)
+![](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})
-Result MathML (embedding MathML is not allowed by GitHub Markdown):
+Result MathML (can be used with MathJax or other renderers):
+
+
```html
-e x - sin - 1 2 x 2 × 10 10 + x 3 - 12
+
+
+ exp
+
+
+
+ x
+
+
+ -
+
+
+
+
+ arcsin
+
+
+ 2
+
+ x
+
+
+
+ 2
+ ×
+
+
+ 10
+
+
+ 10
+
+
+ +
+
+
+ x
+
+
+ 3
+
+
+
+
+
+
+ 12
+
+
+ +
+
+
+ x
+
+
+ 2
+ /
+ 3
+
+
+
+
```
-It is also possible to create custom algorithms of render, and even add support of other markup languages
+
+
+It is also possible to create custom algorithms of render, and even add support of other markup languages
(see API reference).
diff --git a/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/ast/parser.kt b/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/parser.kt
similarity index 96%
rename from kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/ast/parser.kt
rename to kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/parser.kt
index 025f4984c..246625d29 100644
--- a/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/ast/parser.kt
+++ b/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/parser.kt
@@ -3,8 +3,6 @@
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
-// TODO move to common when https://github.com/h0tk3y/better-parse/pull/37 is merged
-
package space.kscience.kmath.ast
import com.github.h0tk3y.betterParse.combinators.*
@@ -31,7 +29,6 @@ import space.kscience.kmath.operations.RingOperations
* @author Iaroslav Postovalov
*/
public object ArithmeticsEvaluator : Grammar() {
- // TODO replace with "...".toRegex() when better-parse 0.4.1 is released
private val num: Token by regexToken("[\\d.]+(?:[eE][-+]?\\d+)?".toRegex())
private val id: Token by regexToken("[a-z_A-Z][\\da-z_A-Z]*".toRegex())
private val lpar: Token by literalToken("(")
diff --git a/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/LatexSyntaxRenderer.kt b/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/LatexSyntaxRenderer.kt
index 34230f3c8..01717b0f9 100644
--- a/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/LatexSyntaxRenderer.kt
+++ b/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/LatexSyntaxRenderer.kt
@@ -5,6 +5,8 @@
package space.kscience.kmath.ast.rendering
+import space.kscience.kmath.misc.UnstableKMathAPI
+
/**
* [SyntaxRenderer] implementation for LaTeX.
*
@@ -23,6 +25,7 @@ package space.kscience.kmath.ast.rendering
*
* @author Iaroslav Postovalov
*/
+@UnstableKMathAPI
public object LatexSyntaxRenderer : SyntaxRenderer {
public override fun render(node: MathSyntax, output: Appendable): Unit = output.run {
fun render(syntax: MathSyntax) = render(syntax, output)
@@ -71,6 +74,15 @@ public object LatexSyntaxRenderer : SyntaxRenderer {
append('}')
}
+ is ExponentSyntax -> if (node.useOperatorForm) {
+ append("\\operatorname{exp}\\,")
+ render(node.operand)
+ } else {
+ append("e^{")
+ render(node.operand)
+ append('}')
+ }
+
is SuperscriptSyntax -> {
render(node.left)
append("^{")
@@ -106,7 +118,11 @@ public object LatexSyntaxRenderer : SyntaxRenderer {
render(node.right)
}
- is FractionSyntax -> {
+ is FractionSyntax -> if (node.infix) {
+ render(node.left)
+ append('/')
+ render(node.right)
+ } else {
append("\\frac{")
render(node.left)
append("}{")
diff --git a/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/MathMLSyntaxRenderer.kt b/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/MathMLSyntaxRenderer.kt
index f7487a356..cda8e2322 100644
--- a/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/MathMLSyntaxRenderer.kt
+++ b/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/MathMLSyntaxRenderer.kt
@@ -5,6 +5,8 @@
package space.kscience.kmath.ast.rendering
+import space.kscience.kmath.misc.UnstableKMathAPI
+
/**
* [SyntaxRenderer] implementation for MathML.
*
@@ -12,14 +14,18 @@ package space.kscience.kmath.ast.rendering
*
* @author Iaroslav Postovalov
*/
+@UnstableKMathAPI
public object MathMLSyntaxRenderer : SyntaxRenderer {
public override fun render(node: MathSyntax, output: Appendable) {
- output.append("")
- render0(node, output)
+ output.append("")
+ renderPart(node, output)
output.append(" ")
}
- private fun render0(node: MathSyntax, output: Appendable): Unit = output.run {
+ /**
+ * Renders a part of syntax returning a correct MathML tag not the whole MathML instance.
+ */
+ public fun renderPart(node: MathSyntax, output: Appendable): Unit = output.run {
fun tag(tagName: String, vararg attr: Pair, block: () -> Unit = {}) {
append('<')
append(tagName)
@@ -44,7 +50,7 @@ public object MathMLSyntaxRenderer : SyntaxRenderer {
append('>')
}
- fun render(syntax: MathSyntax) = render0(syntax, output)
+ fun render(syntax: MathSyntax) = renderPart(syntax, output)
when (node) {
is NumberSyntax -> tag("mn") { append(node.string) }
@@ -82,6 +88,19 @@ public object MathMLSyntaxRenderer : SyntaxRenderer {
is RadicalSyntax -> tag("msqrt") { render(node.operand) }
+ is ExponentSyntax -> if (node.useOperatorForm) {
+ tag("mo") { append("exp") }
+ tag("mspace", "width" to "0.167em")
+ render(node.operand)
+ } else {
+ tag("msup") {
+ tag("mrow") {
+ tag("mi") { append("e") }
+ }
+ tag("mrow") { render(node.operand) }
+ }
+ }
+
is SuperscriptSyntax -> tag("msup") {
tag("mrow") { render(node.left) }
tag("mrow") { render(node.right) }
@@ -114,14 +133,13 @@ public object MathMLSyntaxRenderer : SyntaxRenderer {
render(node.right)
}
- is FractionSyntax -> tag("mfrac") {
- tag("mrow") {
- render(node.left)
- }
-
- tag("mrow") {
- render(node.right)
- }
+ is FractionSyntax -> if (node.infix) {
+ render(node.left)
+ tag("mo") { append('/') }
+ render(node.right)
+ } else tag("mfrac") {
+ tag("mrow") { render(node.left) }
+ tag("mrow") { render(node.right) }
}
is RadicalWithIndexSyntax -> tag("mroot") {
diff --git a/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/MathRenderer.kt b/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/MathRenderer.kt
index 891e8f05b..c33f95483 100644
--- a/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/MathRenderer.kt
+++ b/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/MathRenderer.kt
@@ -6,12 +6,14 @@
package space.kscience.kmath.ast.rendering
import space.kscience.kmath.expressions.MST
+import space.kscience.kmath.misc.UnstableKMathAPI
/**
* Renders [MST] to [MathSyntax].
*
* @author Iaroslav Postovalov
*/
+@UnstableKMathAPI
public fun interface MathRenderer {
/**
* Renders [MST] to [MathSyntax].
@@ -25,6 +27,7 @@ public fun interface MathRenderer {
* @property features The applied features.
* @author Iaroslav Postovalov
*/
+@UnstableKMathAPI
public open class FeaturedMathRenderer(public val features: List) : MathRenderer {
public override fun render(mst: MST): MathSyntax {
for (feature in features) feature.render(this, mst)?.let { return it }
@@ -48,6 +51,7 @@ public open class FeaturedMathRenderer(public val features: List)
* @property stages The applied stages.
* @author Iaroslav Postovalov
*/
+@UnstableKMathAPI
public open class FeaturedMathRendererWithPostProcess(
features: List,
public val stages: List,
@@ -83,8 +87,9 @@ public open class FeaturedMathRendererWithPostProcess(
Fraction.Default,
Power.Default,
SquareRoot.Default,
- Exponential.Default,
+ Exponent.Default,
InverseTrigonometricOperations.Default,
+ InverseHyperbolicOperations.Default,
// Fallback option for unknown operations - printing them as operator
BinaryOperator.Default,
@@ -100,6 +105,8 @@ public open class FeaturedMathRendererWithPostProcess(
PrintSymbolic,
),
listOf(
+ BetterExponent,
+ BetterFraction,
SimplifyParentheses.Default,
BetterMultiplication,
),
diff --git a/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/MathSyntax.kt b/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/MathSyntax.kt
index 069e56c71..a71985fbc 100644
--- a/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/MathSyntax.kt
+++ b/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/MathSyntax.kt
@@ -5,11 +5,14 @@
package space.kscience.kmath.ast.rendering
+import space.kscience.kmath.misc.UnstableKMathAPI
+
/**
* Mathematical typography syntax node.
*
* @author Iaroslav Postovalov
*/
+@UnstableKMathAPI
public sealed class MathSyntax {
/**
* The parent node of this syntax node.
@@ -22,6 +25,7 @@ public sealed class MathSyntax {
*
* @author Iaroslav Postovalov
*/
+@UnstableKMathAPI
public sealed class TerminalSyntax : MathSyntax()
/**
@@ -29,6 +33,7 @@ public sealed class TerminalSyntax : MathSyntax()
*
* @author Iaroslav Postovalov
*/
+@UnstableKMathAPI
public sealed class OperationSyntax : MathSyntax() {
/**
* The operation token.
@@ -41,6 +46,7 @@ public sealed class OperationSyntax : MathSyntax() {
*
* @author Iaroslav Postovalov
*/
+@UnstableKMathAPI
public sealed class UnarySyntax : OperationSyntax() {
/**
* The operand of this node.
@@ -53,6 +59,7 @@ public sealed class UnarySyntax : OperationSyntax() {
*
* @author Iaroslav Postovalov
*/
+@UnstableKMathAPI
public sealed class BinarySyntax : OperationSyntax() {
/**
* The left-hand side operand.
@@ -71,6 +78,7 @@ public sealed class BinarySyntax : OperationSyntax() {
* @property string The digits of number.
* @author Iaroslav Postovalov
*/
+@UnstableKMathAPI
public data class NumberSyntax(public var string: String) : TerminalSyntax()
/**
@@ -79,6 +87,7 @@ public data class NumberSyntax(public var string: String) : TerminalSyntax()
* @property string The symbol.
* @author Iaroslav Postovalov
*/
+@UnstableKMathAPI
public data class SymbolSyntax(public var string: String) : TerminalSyntax()
/**
@@ -89,14 +98,16 @@ public data class SymbolSyntax(public var string: String) : TerminalSyntax()
* @see UnaryOperatorSyntax
* @author Iaroslav Postovalov
*/
+@UnstableKMathAPI
public data class OperatorNameSyntax(public var name: String) : TerminalSyntax()
/**
- * Represents a usage of special symbols.
+ * Represents a usage of special symbols (e.g., *∞*).
*
* @property kind The kind of symbol.
* @author Iaroslav Postovalov
*/
+@UnstableKMathAPI
public data class SpecialSymbolSyntax(public var kind: Kind) : TerminalSyntax() {
/**
* The kind of symbol.
@@ -121,6 +132,7 @@ public data class SpecialSymbolSyntax(public var kind: Kind) : TerminalSyntax()
* @property parentheses Whether the operand should be wrapped with parentheses.
* @author Iaroslav Postovalov
*/
+@UnstableKMathAPI
public data class OperandSyntax(
public val operand: MathSyntax,
public var parentheses: Boolean,
@@ -131,11 +143,12 @@ public data class OperandSyntax(
}
/**
- * Represents unary, prefix operator syntax (like f x).
+ * Represents unary, prefix operator syntax (like *f(x)*).
*
* @property prefix The prefix.
* @author Iaroslav Postovalov
*/
+@UnstableKMathAPI
public data class UnaryOperatorSyntax(
public override val operation: String,
public var prefix: MathSyntax,
@@ -147,10 +160,11 @@ public data class UnaryOperatorSyntax(
}
/**
- * Represents prefix, unary plus operator.
+ * Represents prefix, unary plus operator (*+x*).
*
* @author Iaroslav Postovalov
*/
+@UnstableKMathAPI
public data class UnaryPlusSyntax(
public override val operation: String,
public override val operand: OperandSyntax,
@@ -161,10 +175,11 @@ public data class UnaryPlusSyntax(
}
/**
- * Represents prefix, unary minus operator.
+ * Represents prefix, unary minus operator (*-x*).
*
* @author Iaroslav Postovalov
*/
+@UnstableKMathAPI
public data class UnaryMinusSyntax(
public override val operation: String,
public override val operand: OperandSyntax,
@@ -175,11 +190,12 @@ public data class UnaryMinusSyntax(
}
/**
- * Represents radical with a node inside it.
+ * Represents radical with a node inside it (*√x*).
*
* @property operand The radicand.
* @author Iaroslav Postovalov
*/
+@UnstableKMathAPI
public data class RadicalSyntax(
public override val operation: String,
public override val operand: MathSyntax,
@@ -190,12 +206,32 @@ public data class RadicalSyntax(
}
/**
- * Represents a syntax node with superscript (usually, for exponentiation).
+ * Represents exponential function.
+ *
+ * @property operand The argument of function.
+ * @property useOperatorForm `true` if operator form is used (*exp (x)*), `false` if exponentiation form is used
+ * (*ex *).
+ * @author Iaroslav Postovalov
+ */
+@UnstableKMathAPI
+public data class ExponentSyntax(
+ public override val operation: String,
+ public override val operand: OperandSyntax,
+ public var useOperatorForm: Boolean,
+) : UnarySyntax() {
+ init {
+ operand.parent = this
+ }
+}
+
+/**
+ * Represents a syntax node with superscript (*x2 *).
*
* @property left The node.
* @property right The superscript.
* @author Iaroslav Postovalov
*/
+@UnstableKMathAPI
public data class SuperscriptSyntax(
public override val operation: String,
public override val left: MathSyntax,
@@ -208,12 +244,13 @@ public data class SuperscriptSyntax(
}
/**
- * Represents a syntax node with subscript.
+ * Represents a syntax node with subscript (*xi*).
*
* @property left The node.
* @property right The subscript.
* @author Iaroslav Postovalov
*/
+@UnstableKMathAPI
public data class SubscriptSyntax(
public override val operation: String,
public override val left: MathSyntax,
@@ -226,11 +263,12 @@ public data class SubscriptSyntax(
}
/**
- * Represents binary, prefix operator syntax (like f(a, b)).
+ * Represents binary, prefix operator syntax (like *f(a, b)*).
*
* @property prefix The prefix.
* @author Iaroslav Postovalov
*/
+@UnstableKMathAPI
public data class BinaryOperatorSyntax(
public override val operation: String,
public var prefix: MathSyntax,
@@ -244,12 +282,13 @@ public data class BinaryOperatorSyntax(
}
/**
- * Represents binary, infix addition.
+ * Represents binary, infix addition (*42 + 42*).
*
* @param left The augend.
* @param right The addend.
* @author Iaroslav Postovalov
*/
+@UnstableKMathAPI
public data class BinaryPlusSyntax(
public override val operation: String,
public override val left: OperandSyntax,
@@ -262,12 +301,13 @@ public data class BinaryPlusSyntax(
}
/**
- * Represents binary, infix subtraction.
+ * Represents binary, infix subtraction (*42 - 42*).
*
* @param left The minuend.
* @param right The subtrahend.
* @author Iaroslav Postovalov
*/
+@UnstableKMathAPI
public data class BinaryMinusSyntax(
public override val operation: String,
public override val left: OperandSyntax,
@@ -284,12 +324,15 @@ public data class BinaryMinusSyntax(
*
* @property left The numerator.
* @property right The denominator.
+ * @property infix Whether infix (*1 / 2*) or normal (*½*) fraction should be made.
* @author Iaroslav Postovalov
*/
+@UnstableKMathAPI
public data class FractionSyntax(
public override val operation: String,
- public override val left: MathSyntax,
- public override val right: MathSyntax,
+ public override val left: OperandSyntax,
+ public override val right: OperandSyntax,
+ public var infix: Boolean,
) : BinarySyntax() {
init {
left.parent = this
@@ -298,12 +341,13 @@ public data class FractionSyntax(
}
/**
- * Represents radical syntax with index.
+ * Represents radical syntax with index (*3 √x*).
*
* @property left The index.
* @property right The radicand.
* @author Iaroslav Postovalov
*/
+@UnstableKMathAPI
public data class RadicalWithIndexSyntax(
public override val operation: String,
public override val left: MathSyntax,
@@ -316,13 +360,14 @@ public data class RadicalWithIndexSyntax(
}
/**
- * Represents binary, infix multiplication in the form of coefficient (2 x) or with operator (x×2).
+ * Represents binary, infix multiplication in the form of coefficient (*2 x*) or with operator (*x × 2*).
*
* @property left The multiplicand.
* @property right The multiplier.
- * @property times whether the times (×) symbol should be used.
+ * @property times Whether the times (×) symbol should be used.
* @author Iaroslav Postovalov
*/
+@UnstableKMathAPI
public data class MultiplicationSyntax(
public override val operation: String,
public override val left: OperandSyntax,
diff --git a/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/SyntaxRenderer.kt b/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/SyntaxRenderer.kt
index 7fa91e158..fb2b3b66f 100644
--- a/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/SyntaxRenderer.kt
+++ b/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/SyntaxRenderer.kt
@@ -5,12 +5,15 @@
package space.kscience.kmath.ast.rendering
+import space.kscience.kmath.misc.UnstableKMathAPI
+
/**
* Abstraction of writing [MathSyntax] as a string of an actual markup language. Typical implementation should
* involve traversal of MathSyntax with handling each its subtype.
*
* @author Iaroslav Postovalov
*/
+@UnstableKMathAPI
public fun interface SyntaxRenderer {
/**
* Renders the [MathSyntax] to [output].
@@ -23,6 +26,7 @@ public fun interface SyntaxRenderer {
*
* @author Iaroslav Postovalov
*/
+@UnstableKMathAPI
public fun SyntaxRenderer.renderWithStringBuilder(node: MathSyntax): String {
val sb = StringBuilder()
render(node, sb)
diff --git a/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/features.kt b/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/features.kt
index 5d6c7bb0a..ac716f9ff 100644
--- a/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/features.kt
+++ b/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/features.kt
@@ -7,6 +7,7 @@ package space.kscience.kmath.ast.rendering
import space.kscience.kmath.ast.rendering.FeaturedMathRenderer.RenderFeature
import space.kscience.kmath.expressions.MST
+import space.kscience.kmath.misc.UnstableKMathAPI
import space.kscience.kmath.operations.*
import kotlin.reflect.KClass
@@ -15,11 +16,12 @@ import kotlin.reflect.KClass
*
* @author Iaroslav Postovalov
*/
+@UnstableKMathAPI
public object PrintSymbolic : RenderFeature {
- public override fun render(renderer: FeaturedMathRenderer, node: MST): MathSyntax? {
- if (node !is MST.Symbolic) return null
- return SymbolSyntax(string = node.value)
- }
+ public override fun render(renderer: FeaturedMathRenderer, node: MST): SymbolSyntax? =
+ if (node !is MST.Symbolic) null
+ else
+ SymbolSyntax(string = node.value)
}
/**
@@ -27,39 +29,46 @@ public object PrintSymbolic : RenderFeature {
*
* @author Iaroslav Postovalov
*/
+@UnstableKMathAPI
public object PrintNumeric : RenderFeature {
- public override fun render(renderer: FeaturedMathRenderer, node: MST): MathSyntax? {
- if (node !is MST.Numeric) return null
- return NumberSyntax(string = node.value.toString())
- }
+ public override fun render(renderer: FeaturedMathRenderer, node: MST): NumberSyntax? = if (node !is MST.Numeric)
+ null
+ else
+ NumberSyntax(string = node.value.toString())
}
-private fun printSignedNumberString(s: String): MathSyntax {
- if (s.startsWith('-'))
- return UnaryMinusSyntax(
- operation = GroupOperations.MINUS_OPERATION,
- operand = OperandSyntax(
- operand = NumberSyntax(string = s.removePrefix("-")),
- parentheses = true,
- ),
- )
-
- return NumberSyntax(string = s)
-}
+@UnstableKMathAPI
+private fun printSignedNumberString(s: String): MathSyntax = if (s.startsWith('-'))
+ UnaryMinusSyntax(
+ operation = GroupOperations.MINUS_OPERATION,
+ operand = OperandSyntax(
+ operand = NumberSyntax(string = s.removePrefix("-")),
+ parentheses = true,
+ ),
+ )
+else
+ NumberSyntax(string = s)
/**
* Special printing for numeric types which are printed in form of
* *('-'? (DIGIT+ ('.' DIGIT+)? ('E' '-'? DIGIT+)? | 'Infinity')) | 'NaN'*.
*
* @property types The suitable types.
+ * @author Iaroslav Postovalov
*/
+@UnstableKMathAPI
public class PrettyPrintFloats(public val types: Set>) : RenderFeature {
public override fun render(renderer: FeaturedMathRenderer, node: MST): MathSyntax? {
if (node !is MST.Numeric || node.value::class !in types) return null
- val toString = node.value.toString().removeSuffix(".0")
- if ('E' in toString) {
- val (beforeE, afterE) = toString.split('E')
+ val toString = when (val v = node.value) {
+ is Float -> v.multiplatformToString()
+ is Double -> v.multiplatformToString()
+ else -> v.toString()
+ }.removeSuffix(".0")
+
+ if (toString.contains('E', ignoreCase = true)) {
+ val (beforeE, afterE) = toString.split('E', ignoreCase = true)
val significand = beforeE.toDouble().toString().removeSuffix(".0")
val exponent = afterE.toDouble().toString().removeSuffix(".0")
@@ -105,14 +114,15 @@ public class PrettyPrintFloats(public val types: Set>) : Rend
* Special printing for numeric types which are printed in form of *'-'? DIGIT+*.
*
* @property types The suitable types.
+ * @author Iaroslav Postovalov
*/
+@UnstableKMathAPI
public class PrettyPrintIntegers(public val types: Set>) : RenderFeature {
- public override fun render(renderer: FeaturedMathRenderer, node: MST): MathSyntax? {
+ public override fun render(renderer: FeaturedMathRenderer, node: MST): MathSyntax? =
if (node !is MST.Numeric || node.value::class !in types)
- return null
-
- return printSignedNumberString(node.value.toString())
- }
+ null
+ else
+ printSignedNumberString(node.value.toString())
public companion object {
/**
@@ -127,12 +137,15 @@ public class PrettyPrintIntegers(public val types: Set>) : Re
* Special printing for symbols meaning Pi.
*
* @property symbols The allowed symbols.
+ * @author Iaroslav Postovalov
*/
+@UnstableKMathAPI
public class PrettyPrintPi(public val symbols: Set) : RenderFeature {
- public override fun render(renderer: FeaturedMathRenderer, node: MST): MathSyntax? {
- if (node !is MST.Symbolic || node.value !in symbols) return null
- return SpecialSymbolSyntax(kind = SpecialSymbolSyntax.Kind.SMALL_PI)
- }
+ public override fun render(renderer: FeaturedMathRenderer, node: MST): SpecialSymbolSyntax? =
+ if (node !is MST.Symbolic || node.value !in symbols)
+ null
+ else
+ SpecialSymbolSyntax(kind = SpecialSymbolSyntax.Kind.SMALL_PI)
public companion object {
/**
@@ -147,17 +160,20 @@ public class PrettyPrintPi(public val symbols: Set) : RenderFeature {
* not [MST.Unary].
*
* @param operations the allowed operations. If `null`, any operation is accepted.
+ * @author Iaroslav Postovalov
*/
+@UnstableKMathAPI
public abstract class Unary(public val operations: Collection?) : RenderFeature {
/**
- * The actual render function.
+ * The actual render function specialized for [MST.Unary].
*/
- protected abstract fun render0(parent: FeaturedMathRenderer, node: MST.Unary): MathSyntax?
+ protected abstract fun renderUnary(parent: FeaturedMathRenderer, node: MST.Unary): MathSyntax?
- public final override fun render(renderer: FeaturedMathRenderer, node: MST): MathSyntax? {
- if (node !is MST.Unary || operations != null && node.operation !in operations) return null
- return render0(renderer, node)
- }
+ public final override fun render(renderer: FeaturedMathRenderer, node: MST): MathSyntax? =
+ if (node !is MST.Unary || operations != null && node.operation !in operations)
+ null
+ else
+ renderUnary(renderer, node)
}
/**
@@ -165,169 +181,301 @@ public abstract class Unary(public val operations: Collection?) : Render
* not [MST.Binary].
*
* @property operations the allowed operations. If `null`, any operation is accepted.
+ * @author Iaroslav Postovalov
*/
+@UnstableKMathAPI
public abstract class Binary(public val operations: Collection?) : RenderFeature {
/**
- * The actual render function.
+ * The actual render function specialized for [MST.Binary].
*/
- protected abstract fun render0(parent: FeaturedMathRenderer, node: MST.Binary): MathSyntax?
+ protected abstract fun renderBinary(parent: FeaturedMathRenderer, node: MST.Binary): MathSyntax?
public final override fun render(renderer: FeaturedMathRenderer, node: MST): MathSyntax? {
if (node !is MST.Binary || operations != null && node.operation !in operations) return null
- return render0(renderer, node)
+ return renderBinary(renderer, node)
}
}
+/**
+ * Handles binary nodes by producing [BinaryPlusSyntax].
+ *
+ * @author Iaroslav Postovalov
+ */
+@UnstableKMathAPI
public class BinaryPlus(operations: Collection?) : Binary(operations) {
- public override fun render0(parent: FeaturedMathRenderer, node: MST.Binary): MathSyntax = BinaryPlusSyntax(
- operation = node.operation,
- left = OperandSyntax(parent.render(node.left), true),
- right = OperandSyntax(parent.render(node.right), true),
- )
+ public override fun renderBinary(parent: FeaturedMathRenderer, node: MST.Binary): BinaryPlusSyntax =
+ BinaryPlusSyntax(
+ operation = node.operation,
+ left = OperandSyntax(parent.render(node.left), true),
+ right = OperandSyntax(parent.render(node.right), true),
+ )
public companion object {
+ /**
+ * The default instance configured with [GroupOperations.PLUS_OPERATION].
+ */
public val Default: BinaryPlus = BinaryPlus(setOf(GroupOperations.PLUS_OPERATION))
}
}
+/**
+ * Handles binary nodes by producing [BinaryMinusSyntax].
+ *
+ * @author Iaroslav Postovalov
+ */
+@UnstableKMathAPI
public class BinaryMinus(operations: Collection?) : Binary(operations) {
- public override fun render0(parent: FeaturedMathRenderer, node: MST.Binary): MathSyntax = BinaryMinusSyntax(
- operation = node.operation,
- left = OperandSyntax(operand = parent.render(node.left), parentheses = true),
- right = OperandSyntax(operand = parent.render(node.right), parentheses = true),
- )
+ public override fun renderBinary(parent: FeaturedMathRenderer, node: MST.Binary): BinaryMinusSyntax =
+ BinaryMinusSyntax(
+ operation = node.operation,
+ left = OperandSyntax(operand = parent.render(node.left), parentheses = true),
+ right = OperandSyntax(operand = parent.render(node.right), parentheses = true),
+ )
public companion object {
+ /**
+ * The default instance configured with [GroupOperations.MINUS_OPERATION].
+ */
public val Default: BinaryMinus = BinaryMinus(setOf(GroupOperations.MINUS_OPERATION))
}
}
+/**
+ * Handles unary nodes by producing [UnaryPlusSyntax].
+ *
+ * @author Iaroslav Postovalov
+ */
+@UnstableKMathAPI
public class UnaryPlus(operations: Collection?) : Unary(operations) {
- public override fun render0(parent: FeaturedMathRenderer, node: MST.Unary): MathSyntax = UnaryPlusSyntax(
+ public override fun renderUnary(parent: FeaturedMathRenderer, node: MST.Unary): UnaryPlusSyntax = UnaryPlusSyntax(
operation = node.operation,
operand = OperandSyntax(operand = parent.render(node.value), parentheses = true),
)
public companion object {
+ /**
+ * The default instance configured with [GroupOperations.PLUS_OPERATION].
+ */
public val Default: UnaryPlus = UnaryPlus(setOf(GroupOperations.PLUS_OPERATION))
}
}
+/**
+ * Handles binary nodes by producing [UnaryMinusSyntax].
+ *
+ * @author Iaroslav Postovalov
+ */
+@UnstableKMathAPI
public class UnaryMinus(operations: Collection?) : Unary(operations) {
- public override fun render0(parent: FeaturedMathRenderer, node: MST.Unary): MathSyntax = UnaryMinusSyntax(
+ public override fun renderUnary(parent: FeaturedMathRenderer, node: MST.Unary): UnaryMinusSyntax = UnaryMinusSyntax(
operation = node.operation,
operand = OperandSyntax(operand = parent.render(node.value), parentheses = true),
)
public companion object {
+ /**
+ * The default instance configured with [GroupOperations.MINUS_OPERATION].
+ */
public val Default: UnaryMinus = UnaryMinus(setOf(GroupOperations.MINUS_OPERATION))
}
}
+/**
+ * Handles binary nodes by producing [FractionSyntax].
+ *
+ * @author Iaroslav Postovalov
+ */
+@UnstableKMathAPI
public class Fraction(operations: Collection?) : Binary(operations) {
- public override fun render0(parent: FeaturedMathRenderer, node: MST.Binary): MathSyntax = FractionSyntax(
+ public override fun renderBinary(parent: FeaturedMathRenderer, node: MST.Binary): FractionSyntax = FractionSyntax(
operation = node.operation,
- left = parent.render(node.left),
- right = parent.render(node.right),
+ left = OperandSyntax(operand = parent.render(node.left), parentheses = true),
+ right = OperandSyntax(operand = parent.render(node.right), parentheses = true),
+ infix = true,
)
public companion object {
+ /**
+ * The default instance configured with [FieldOperations.DIV_OPERATION].
+ */
public val Default: Fraction = Fraction(setOf(FieldOperations.DIV_OPERATION))
}
}
+/**
+ * Handles binary nodes by producing [BinaryOperatorSyntax].
+ *
+ * @author Iaroslav Postovalov
+ */
+@UnstableKMathAPI
public class BinaryOperator(operations: Collection?) : Binary(operations) {
- public override fun render0(parent: FeaturedMathRenderer, node: MST.Binary): MathSyntax = BinaryOperatorSyntax(
- operation = node.operation,
- prefix = OperatorNameSyntax(name = node.operation),
- left = parent.render(node.left),
- right = parent.render(node.right),
- )
+ public override fun renderBinary(parent: FeaturedMathRenderer, node: MST.Binary): BinaryOperatorSyntax =
+ BinaryOperatorSyntax(
+ operation = node.operation,
+ prefix = OperatorNameSyntax(name = node.operation),
+ left = parent.render(node.left),
+ right = parent.render(node.right),
+ )
public companion object {
+ /**
+ * The default instance configured with `null`.
+ */
public val Default: BinaryOperator = BinaryOperator(null)
}
}
+/**
+ * Handles unary nodes by producing [UnaryOperatorSyntax].
+ *
+ * @author Iaroslav Postovalov
+ */
+@UnstableKMathAPI
public class UnaryOperator(operations: Collection?) : Unary(operations) {
- public override fun render0(parent: FeaturedMathRenderer, node: MST.Unary): MathSyntax = UnaryOperatorSyntax(
- operation = node.operation,
- prefix = OperatorNameSyntax(node.operation),
- operand = OperandSyntax(parent.render(node.value), true),
- )
+ public override fun renderUnary(parent: FeaturedMathRenderer, node: MST.Unary): UnaryOperatorSyntax =
+ UnaryOperatorSyntax(
+ operation = node.operation,
+ prefix = OperatorNameSyntax(node.operation),
+ operand = OperandSyntax(parent.render(node.value), true),
+ )
public companion object {
+ /**
+ * The default instance configured with `null`.
+ */
public val Default: UnaryOperator = UnaryOperator(null)
}
}
+/**
+ * Handles binary nodes by producing [SuperscriptSyntax].
+ *
+ * @author Iaroslav Postovalov
+ */
+@UnstableKMathAPI
public class Power(operations: Collection?) : Binary(operations) {
- public override fun render0(parent: FeaturedMathRenderer, node: MST.Binary): MathSyntax = SuperscriptSyntax(
- operation = node.operation,
- left = OperandSyntax(parent.render(node.left), true),
- right = OperandSyntax(parent.render(node.right), true),
- )
+ public override fun renderBinary(parent: FeaturedMathRenderer, node: MST.Binary): SuperscriptSyntax =
+ SuperscriptSyntax(
+ operation = node.operation,
+ left = OperandSyntax(parent.render(node.left), true),
+ right = OperandSyntax(parent.render(node.right), true),
+ )
public companion object {
+ /**
+ * The default instance configured with [PowerOperations.POW_OPERATION].
+ */
public val Default: Power = Power(setOf(PowerOperations.POW_OPERATION))
}
}
+/**
+ * Handles binary nodes by producing [RadicalSyntax] with no index.
+ */
+@UnstableKMathAPI
public class SquareRoot(operations: Collection?) : Unary(operations) {
- public override fun render0(parent: FeaturedMathRenderer, node: MST.Unary): MathSyntax =
+ public override fun renderUnary(parent: FeaturedMathRenderer, node: MST.Unary): RadicalSyntax =
RadicalSyntax(operation = node.operation, operand = parent.render(node.value))
public companion object {
+ /**
+ * The default instance configured with [PowerOperations.SQRT_OPERATION].
+ */
public val Default: SquareRoot = SquareRoot(setOf(PowerOperations.SQRT_OPERATION))
}
}
-public class Exponential(operations: Collection?) : Unary(operations) {
- public override fun render0(parent: FeaturedMathRenderer, node: MST.Unary): MathSyntax = SuperscriptSyntax(
+/**
+ * Handles unary nodes by producing [ExponentSyntax].
+ *
+ * @author Iaroslav Postovalov
+ */
+@UnstableKMathAPI
+public class Exponent(operations: Collection?) : Unary(operations) {
+ public override fun renderUnary(parent: FeaturedMathRenderer, node: MST.Unary): ExponentSyntax = ExponentSyntax(
operation = node.operation,
- left = SymbolSyntax(string = "e"),
- right = parent.render(node.value),
- )
-
- public companion object {
- public val Default: Exponential = Exponential(setOf(ExponentialOperations.EXP_OPERATION))
- }
-}
-
-public class Multiplication(operations: Collection?) : Binary(operations) {
- public override fun render0(parent: FeaturedMathRenderer, node: MST.Binary): MathSyntax = MultiplicationSyntax(
- operation = node.operation,
- left = OperandSyntax(operand = parent.render(node.left), parentheses = true),
- right = OperandSyntax(operand = parent.render(node.right), parentheses = true),
- times = true,
- )
-
- public companion object {
- public val Default: Multiplication = Multiplication(setOf(
- RingOperations.TIMES_OPERATION,
- ))
- }
-}
-
-public class InverseTrigonometricOperations(operations: Collection?) : Unary(operations) {
- public override fun render0(parent: FeaturedMathRenderer, node: MST.Unary): MathSyntax = UnaryOperatorSyntax(
- operation = node.operation,
- prefix = SuperscriptSyntax(
- operation = PowerOperations.POW_OPERATION,
- left = OperatorNameSyntax(name = node.operation.removePrefix("a")),
- right = UnaryMinusSyntax(
- operation = GroupOperations.MINUS_OPERATION,
- operand = OperandSyntax(operand = NumberSyntax(string = "1"), parentheses = true),
- ),
- ),
operand = OperandSyntax(operand = parent.render(node.value), parentheses = true),
+ useOperatorForm = true,
)
public companion object {
+ /**
+ * The default instance configured with [ExponentialOperations.EXP_OPERATION].
+ */
+ public val Default: Exponent = Exponent(setOf(ExponentialOperations.EXP_OPERATION))
+ }
+}
+
+/**
+ * Handles binary nodes by producing [MultiplicationSyntax].
+ *
+ * @author Iaroslav Postovalov
+ */
+@UnstableKMathAPI
+public class Multiplication(operations: Collection?) : Binary(operations) {
+ public override fun renderBinary(parent: FeaturedMathRenderer, node: MST.Binary): MultiplicationSyntax =
+ MultiplicationSyntax(
+ operation = node.operation,
+ left = OperandSyntax(operand = parent.render(node.left), parentheses = true),
+ right = OperandSyntax(operand = parent.render(node.right), parentheses = true),
+ times = true,
+ )
+
+ public companion object {
+ /**
+ * The default instance configured with [RingOperations.TIMES_OPERATION].
+ */
+ public val Default: Multiplication = Multiplication(setOf(RingOperations.TIMES_OPERATION))
+ }
+}
+
+/**
+ * Handles binary nodes by producing inverse [UnaryOperatorSyntax] with *arc* prefix instead of *a*.
+ *
+ * @author Iaroslav Postovalov
+ */
+@UnstableKMathAPI
+public class InverseTrigonometricOperations(operations: Collection?) : Unary(operations) {
+ public override fun renderUnary(parent: FeaturedMathRenderer, node: MST.Unary): UnaryOperatorSyntax =
+ UnaryOperatorSyntax(
+ operation = node.operation,
+ prefix = OperatorNameSyntax(name = node.operation.replaceFirst("a", "arc")),
+ operand = OperandSyntax(operand = parent.render(node.value), parentheses = true),
+ )
+
+ public companion object {
+ /**
+ * The default instance configured with [TrigonometricOperations.ACOS_OPERATION],
+ * [TrigonometricOperations.ASIN_OPERATION], [TrigonometricOperations.ATAN_OPERATION].
+ */
public val Default: InverseTrigonometricOperations = InverseTrigonometricOperations(setOf(
TrigonometricOperations.ACOS_OPERATION,
TrigonometricOperations.ASIN_OPERATION,
TrigonometricOperations.ATAN_OPERATION,
+ ))
+ }
+}
+
+/**
+ * Handles binary nodes by producing inverse [UnaryOperatorSyntax] with *ar* prefix instead of *a*.
+ *
+ * @author Iaroslav Postovalov
+ */
+@UnstableKMathAPI
+public class InverseHyperbolicOperations(operations: Collection?) : Unary(operations) {
+ public override fun renderUnary(parent: FeaturedMathRenderer, node: MST.Unary): UnaryOperatorSyntax =
+ UnaryOperatorSyntax(
+ operation = node.operation,
+ prefix = OperatorNameSyntax(name = node.operation.replaceFirst("a", "ar")),
+ operand = OperandSyntax(operand = parent.render(node.value), parentheses = true),
+ )
+
+ public companion object {
+ /**
+ * The default instance configured with [ExponentialOperations.ACOSH_OPERATION],
+ * [ExponentialOperations.ASINH_OPERATION], and [ExponentialOperations.ATANH_OPERATION].
+ */
+ public val Default: InverseHyperbolicOperations = InverseHyperbolicOperations(setOf(
ExponentialOperations.ACOSH_OPERATION,
ExponentialOperations.ASINH_OPERATION,
ExponentialOperations.ATANH_OPERATION,
diff --git a/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/multiplatformToString.kt b/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/multiplatformToString.kt
new file mode 100644
index 000000000..291399cee
--- /dev/null
+++ b/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/multiplatformToString.kt
@@ -0,0 +1,9 @@
+/*
+ * Copyright 2018-2021 KMath contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package space.kscience.kmath.ast.rendering
+
+internal expect fun Double.multiplatformToString(): String
+internal expect fun Float.multiplatformToString(): String
diff --git a/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/stages.kt b/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/stages.kt
index 0ebb41b28..1f31af853 100644
--- a/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/stages.kt
+++ b/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/stages.kt
@@ -5,6 +5,7 @@
package space.kscience.kmath.ast.rendering
+import space.kscience.kmath.misc.UnstableKMathAPI
import space.kscience.kmath.operations.FieldOperations
import space.kscience.kmath.operations.GroupOperations
import space.kscience.kmath.operations.PowerOperations
@@ -15,70 +16,182 @@ import space.kscience.kmath.operations.RingOperations
*
* @author Iaroslav Postovalov
*/
+@UnstableKMathAPI
public object BetterMultiplication : FeaturedMathRendererWithPostProcess.PostProcessStage {
- public override fun perform(node: MathSyntax) {
- when (node) {
- is NumberSyntax -> Unit
- is SymbolSyntax -> Unit
- is OperatorNameSyntax -> Unit
- is SpecialSymbolSyntax -> Unit
- is OperandSyntax -> perform(node.operand)
+ public override fun perform(node: MathSyntax): Unit = when (node) {
+ is NumberSyntax -> Unit
+ is SymbolSyntax -> Unit
+ is OperatorNameSyntax -> Unit
+ is SpecialSymbolSyntax -> Unit
+ is OperandSyntax -> perform(node.operand)
- is UnaryOperatorSyntax -> {
- perform(node.prefix)
- perform(node.operand)
- }
-
- is UnaryPlusSyntax -> perform(node.operand)
- is UnaryMinusSyntax -> perform(node.operand)
- is RadicalSyntax -> perform(node.operand)
-
- is SuperscriptSyntax -> {
- perform(node.left)
- perform(node.right)
- }
-
- is SubscriptSyntax -> {
- perform(node.left)
- perform(node.right)
- }
-
- is BinaryOperatorSyntax -> {
- perform(node.prefix)
- perform(node.left)
- perform(node.right)
- }
-
- is BinaryPlusSyntax -> {
- perform(node.left)
- perform(node.right)
- }
-
- is BinaryMinusSyntax -> {
- perform(node.left)
- perform(node.right)
- }
-
- is FractionSyntax -> {
- perform(node.left)
- perform(node.right)
- }
-
- is RadicalWithIndexSyntax -> {
- perform(node.left)
- perform(node.right)
- }
-
- is MultiplicationSyntax -> {
- node.times = node.right.operand is NumberSyntax && !node.right.parentheses
- || node.left.operand is NumberSyntax && node.right.operand is FractionSyntax
- || node.left.operand is NumberSyntax && node.right.operand is NumberSyntax
- || node.left.operand is NumberSyntax && node.right.operand is SuperscriptSyntax && node.right.operand.left is NumberSyntax
-
- perform(node.left)
- perform(node.right)
- }
+ is UnaryOperatorSyntax -> {
+ perform(node.prefix)
+ perform(node.operand)
}
+
+ is UnaryPlusSyntax -> perform(node.operand)
+ is UnaryMinusSyntax -> perform(node.operand)
+ is RadicalSyntax -> perform(node.operand)
+ is ExponentSyntax -> perform(node.operand)
+
+ is SuperscriptSyntax -> {
+ perform(node.left)
+ perform(node.right)
+ }
+
+ is SubscriptSyntax -> {
+ perform(node.left)
+ perform(node.right)
+ }
+
+ is BinaryOperatorSyntax -> {
+ perform(node.prefix)
+ perform(node.left)
+ perform(node.right)
+ }
+
+ is BinaryPlusSyntax -> {
+ perform(node.left)
+ perform(node.right)
+ }
+
+ is BinaryMinusSyntax -> {
+ perform(node.left)
+ perform(node.right)
+ }
+
+ is FractionSyntax -> {
+ perform(node.left)
+ perform(node.right)
+ }
+
+ is RadicalWithIndexSyntax -> {
+ perform(node.left)
+ perform(node.right)
+ }
+
+ is MultiplicationSyntax -> {
+ node.times = node.right.operand is NumberSyntax && !node.right.parentheses
+ || node.left.operand is NumberSyntax && node.right.operand is FractionSyntax
+ || node.left.operand is NumberSyntax && node.right.operand is NumberSyntax
+ || node.left.operand is NumberSyntax && node.right.operand is SuperscriptSyntax && node.right.operand.left is NumberSyntax
+
+ perform(node.left)
+ perform(node.right)
+ }
+ }
+}
+
+/**
+ * Chooses [FractionSyntax.infix] depending on the context.
+ *
+ * @author Iaroslav Postovalov
+ */
+@UnstableKMathAPI
+public object BetterFraction : FeaturedMathRendererWithPostProcess.PostProcessStage {
+ private fun perform0(node: MathSyntax, infix: Boolean = false): Unit = when (node) {
+ is NumberSyntax -> Unit
+ is SymbolSyntax -> Unit
+ is OperatorNameSyntax -> Unit
+ is SpecialSymbolSyntax -> Unit
+ is OperandSyntax -> perform0(node.operand, infix)
+
+ is UnaryOperatorSyntax -> {
+ perform0(node.prefix, infix)
+ perform0(node.operand, infix)
+ }
+
+ is UnaryPlusSyntax -> perform0(node.operand, infix)
+ is UnaryMinusSyntax -> perform0(node.operand, infix)
+ is RadicalSyntax -> perform0(node.operand, infix)
+ is ExponentSyntax -> perform0(node.operand, infix)
+
+ is SuperscriptSyntax -> {
+ perform0(node.left, true)
+ perform0(node.right, true)
+ }
+
+ is SubscriptSyntax -> {
+ perform0(node.left, true)
+ perform0(node.right, true)
+ }
+
+ is BinaryOperatorSyntax -> {
+ perform0(node.prefix, infix)
+ perform0(node.left, infix)
+ perform0(node.right, infix)
+ }
+
+ is BinaryPlusSyntax -> {
+ perform0(node.left, infix)
+ perform0(node.right, infix)
+ }
+
+ is BinaryMinusSyntax -> {
+ perform0(node.left, infix)
+ perform0(node.right, infix)
+ }
+
+ is FractionSyntax -> {
+ node.infix = infix
+ perform0(node.left, infix)
+ perform0(node.right, infix)
+ }
+
+ is RadicalWithIndexSyntax -> {
+ perform0(node.left, true)
+ perform0(node.right, true)
+ }
+
+ is MultiplicationSyntax -> {
+ perform0(node.left, infix)
+ perform0(node.right, infix)
+ }
+ }
+
+ public override fun perform(node: MathSyntax): Unit = perform0(node)
+}
+
+/**
+ * Applies [ExponentSyntax.useOperatorForm] to [ExponentSyntax] when the operand contains a fraction, a
+ * superscript or a subscript to improve readability.
+ *
+ * @author Iaroslav Postovalov
+ */
+@UnstableKMathAPI
+public object BetterExponent : FeaturedMathRendererWithPostProcess.PostProcessStage {
+ private fun perform0(node: MathSyntax): Boolean {
+ return when (node) {
+ is NumberSyntax -> false
+ is SymbolSyntax -> false
+ is OperatorNameSyntax -> false
+ is SpecialSymbolSyntax -> false
+ is OperandSyntax -> perform0(node.operand)
+ is UnaryOperatorSyntax -> perform0(node.prefix) || perform0(node.operand)
+ is UnaryPlusSyntax -> perform0(node.operand)
+ is UnaryMinusSyntax -> perform0(node.operand)
+ is RadicalSyntax -> true
+
+ is ExponentSyntax -> {
+ val r = perform0(node.operand)
+ node.useOperatorForm = r
+ r
+ }
+
+ is SuperscriptSyntax -> true
+ is SubscriptSyntax -> true
+ is BinaryOperatorSyntax -> perform0(node.prefix) || perform0(node.left) || perform0(node.right)
+ is BinaryPlusSyntax -> perform0(node.left) || perform0(node.right)
+ is BinaryMinusSyntax -> perform0(node.left) || perform0(node.right)
+ is FractionSyntax -> true
+ is RadicalWithIndexSyntax -> true
+ is MultiplicationSyntax -> perform0(node.left) || perform0(node.right)
+ }
+ }
+
+ public override fun perform(node: MathSyntax) {
+ perform0(node)
}
}
@@ -88,91 +201,95 @@ public object BetterMultiplication : FeaturedMathRendererWithPostProcess.PostPro
* @property precedenceFunction Returns the precedence number for syntax node. Higher number is lower priority.
* @author Iaroslav Postovalov
*/
+@UnstableKMathAPI
public class SimplifyParentheses(public val precedenceFunction: (MathSyntax) -> Int) :
FeaturedMathRendererWithPostProcess.PostProcessStage {
- public override fun perform(node: MathSyntax) {
- when (node) {
- is NumberSyntax -> Unit
- is SymbolSyntax -> Unit
- is OperatorNameSyntax -> Unit
- is SpecialSymbolSyntax -> Unit
+ public override fun perform(node: MathSyntax): Unit = when (node) {
+ is NumberSyntax -> Unit
+ is SymbolSyntax -> Unit
+ is OperatorNameSyntax -> Unit
+ is SpecialSymbolSyntax -> Unit
- is OperandSyntax -> {
- val isRightOfSuperscript =
- (node.parent is SuperscriptSyntax) && (node.parent as SuperscriptSyntax).right === node
+ is OperandSyntax -> {
+ val isRightOfSuperscript =
+ (node.parent is SuperscriptSyntax) && (node.parent as SuperscriptSyntax).right === node
- val precedence = precedenceFunction(node.operand)
+ val precedence = precedenceFunction(node.operand)
- val needParenthesesByPrecedence = when (val parent = node.parent) {
- null -> false
+ val needParenthesesByPrecedence = when (val parent = node.parent) {
+ null -> false
- is BinarySyntax -> {
- val parentPrecedence = precedenceFunction(parent)
+ is BinarySyntax -> {
+ val parentPrecedence = precedenceFunction(parent)
- parentPrecedence < precedence ||
- parentPrecedence == precedence && parentPrecedence != 0 && node === parent.right
- }
-
- else -> precedence > precedenceFunction(parent)
+ parentPrecedence < precedence ||
+ parentPrecedence == precedence && parentPrecedence != 0 && node === parent.right
}
- node.parentheses = !isRightOfSuperscript
- && (needParenthesesByPrecedence || node.parent is UnaryOperatorSyntax)
-
- perform(node.operand)
+ else -> precedence > precedenceFunction(parent)
}
- is UnaryOperatorSyntax -> {
- perform(node.prefix)
- perform(node.operand)
- }
+ val isInsideExpOperator =
+ node.parent is ExponentSyntax && (node.parent as ExponentSyntax).useOperatorForm
- is UnaryPlusSyntax -> perform(node.operand)
- is UnaryMinusSyntax -> {
- perform(node.operand)
- }
- is RadicalSyntax -> perform(node.operand)
+ val isOnOrUnderNormalFraction = node.parent is FractionSyntax && !((node.parent as FractionSyntax).infix)
- is SuperscriptSyntax -> {
- perform(node.left)
- perform(node.right)
- }
+ node.parentheses = !isRightOfSuperscript
+ && (needParenthesesByPrecedence || node.parent is UnaryOperatorSyntax || isInsideExpOperator)
+ && !isOnOrUnderNormalFraction
- is SubscriptSyntax -> {
- perform(node.left)
- perform(node.right)
- }
+ perform(node.operand)
+ }
- is BinaryOperatorSyntax -> {
- perform(node.prefix)
- perform(node.left)
- perform(node.right)
- }
+ is UnaryOperatorSyntax -> {
+ perform(node.prefix)
+ perform(node.operand)
+ }
- is BinaryPlusSyntax -> {
- perform(node.left)
- perform(node.right)
- }
+ is UnaryPlusSyntax -> perform(node.operand)
+ is UnaryMinusSyntax -> perform(node.operand)
+ is RadicalSyntax -> perform(node.operand)
+ is ExponentSyntax -> perform(node.operand)
- is BinaryMinusSyntax -> {
- perform(node.left)
- perform(node.right)
- }
+ is SuperscriptSyntax -> {
+ perform(node.left)
+ perform(node.right)
+ }
- is FractionSyntax -> {
- perform(node.left)
- perform(node.right)
- }
+ is SubscriptSyntax -> {
+ perform(node.left)
+ perform(node.right)
+ }
- is MultiplicationSyntax -> {
- perform(node.left)
- perform(node.right)
- }
+ is BinaryOperatorSyntax -> {
+ perform(node.prefix)
+ perform(node.left)
+ perform(node.right)
+ }
- is RadicalWithIndexSyntax -> {
- perform(node.left)
- perform(node.right)
- }
+ is BinaryPlusSyntax -> {
+ perform(node.left)
+ perform(node.right)
+ }
+
+ is BinaryMinusSyntax -> {
+ perform(node.left)
+ perform(node.right)
+ }
+
+ is FractionSyntax -> {
+ perform(node.left)
+ perform(node.right)
+ }
+
+ is MultiplicationSyntax -> {
+ perform(node.left)
+ perform(node.right)
+ }
+
+ is RadicalWithIndexSyntax -> {
+ perform(node.left)
+ perform(node.right)
}
}
diff --git a/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/TestCompilerConsistencyWithInterpreter.kt b/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/TestCompilerConsistencyWithInterpreter.kt
new file mode 100644
index 000000000..0d018070c
--- /dev/null
+++ b/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/TestCompilerConsistencyWithInterpreter.kt
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2018-2021 KMath contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package space.kscience.kmath.ast
+
+import space.kscience.kmath.expressions.MstField
+import space.kscience.kmath.expressions.MstRing
+import space.kscience.kmath.expressions.interpret
+import space.kscience.kmath.misc.Symbol.Companion.x
+import space.kscience.kmath.operations.DoubleField
+import space.kscience.kmath.operations.IntRing
+import space.kscience.kmath.operations.bindSymbol
+import space.kscience.kmath.operations.invoke
+import kotlin.test.Test
+import kotlin.test.assertEquals
+
+internal class TestCompilerConsistencyWithInterpreter {
+ @Test
+ fun intRing() = runCompilerTest {
+ val mst = MstRing {
+ binaryOperationFunction("+")(
+ unaryOperationFunction("+")(
+ (bindSymbol(x) - (2.toByte() + (scale(
+ add(number(1), number(1)),
+ 2.0,
+ ) + 1.toByte()))) * 3.0 - 1.toByte()
+ ),
+
+ number(1),
+ ) * number(2)
+ }
+
+ assertEquals(
+ mst.interpret(IntRing, x to 3),
+ mst.compile(IntRing, x to 3),
+ )
+ }
+
+ @Test
+ fun doubleField() = runCompilerTest {
+ val mst = MstField {
+ +(3 - 2 + 2 * number(1) + 1.0) + binaryOperationFunction("+")(
+ (3.0 - (bindSymbol(x) + (scale(add(number(1.0), number(1.0)), 2.0) + 1.0))) * 3 - 1.0
+ + number(1),
+ number(1) / 2 + number(2.0) * one,
+ ) + zero
+ }
+
+ assertEquals(
+ mst.interpret(DoubleField, x to 2.0),
+ mst.compile(DoubleField, x to 2.0),
+ )
+ }
+}
diff --git a/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/TestCompilerOperations.kt b/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/TestCompilerOperations.kt
new file mode 100644
index 000000000..7d2af31c2
--- /dev/null
+++ b/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/TestCompilerOperations.kt
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2018-2021 KMath contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package space.kscience.kmath.ast
+
+import space.kscience.kmath.expressions.MstExtendedField
+import space.kscience.kmath.expressions.invoke
+import space.kscience.kmath.misc.Symbol.Companion.x
+import space.kscience.kmath.operations.DoubleField
+import space.kscience.kmath.operations.bindSymbol
+import space.kscience.kmath.operations.invoke
+import kotlin.test.Test
+import kotlin.test.assertEquals
+
+internal class TestCompilerOperations {
+ @Test
+ fun testUnaryPlus() = runCompilerTest {
+ val expr = MstExtendedField { +bindSymbol(x) }.compileToExpression(DoubleField)
+ assertEquals(2.0, expr(x to 2.0))
+ }
+
+ @Test
+ fun testUnaryMinus() = runCompilerTest {
+ val expr = MstExtendedField { -bindSymbol(x) }.compileToExpression(DoubleField)
+ assertEquals(-2.0, expr(x to 2.0))
+ }
+
+ @Test
+ fun testAdd() = runCompilerTest {
+ val expr = MstExtendedField { bindSymbol(x) + bindSymbol(x) }.compileToExpression(DoubleField)
+ assertEquals(4.0, expr(x to 2.0))
+ }
+
+ @Test
+ fun testSine() = runCompilerTest {
+ val expr = MstExtendedField { sin(bindSymbol(x)) }.compileToExpression(DoubleField)
+ assertEquals(0.0, expr(x to 0.0))
+ }
+
+ @Test
+ fun testCosine() = runCompilerTest {
+ val expr = MstExtendedField { cos(bindSymbol(x)) }.compileToExpression(DoubleField)
+ assertEquals(1.0, expr(x to 0.0))
+ }
+
+ @Test
+ fun testSubtract() = runCompilerTest {
+ val expr = MstExtendedField { bindSymbol(x) - bindSymbol(x) }.compileToExpression(DoubleField)
+ assertEquals(0.0, expr(x to 2.0))
+ }
+
+ @Test
+ fun testDivide() = runCompilerTest {
+ val expr = MstExtendedField { bindSymbol(x) / bindSymbol(x) }.compileToExpression(DoubleField)
+ assertEquals(1.0, expr(x to 2.0))
+ }
+
+ @Test
+ fun testPower() = runCompilerTest {
+ val expr = MstExtendedField { bindSymbol(x) pow 2 }.compileToExpression(DoubleField)
+ assertEquals(4.0, expr(x to 2.0))
+ }
+}
diff --git a/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/TestCompilerVariables.kt b/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/TestCompilerVariables.kt
new file mode 100644
index 000000000..ecf8ed367
--- /dev/null
+++ b/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/TestCompilerVariables.kt
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2018-2021 KMath contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package space.kscience.kmath.ast
+
+import space.kscience.kmath.expressions.MstRing
+import space.kscience.kmath.expressions.invoke
+import space.kscience.kmath.misc.Symbol.Companion.x
+import space.kscience.kmath.operations.IntRing
+import space.kscience.kmath.operations.bindSymbol
+import space.kscience.kmath.operations.invoke
+import kotlin.test.Test
+import kotlin.test.assertEquals
+import kotlin.test.assertFailsWith
+
+internal class TestCompilerVariables {
+ @Test
+ fun testVariable() = runCompilerTest {
+ val expr = MstRing { bindSymbol(x) }.compileToExpression(IntRing)
+ assertEquals(1, expr(x to 1))
+ }
+
+ @Test
+ fun testUndefinedVariableFails() = runCompilerTest {
+ val expr = MstRing { bindSymbol(x) }.compileToExpression(IntRing)
+ assertFailsWith { expr() }
+ }
+}
diff --git a/kmath-ast/src/jvmTest/kotlin/space/kscience/kmath/ast/ParserTest.kt b/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/TestParser.kt
similarity index 75%
rename from kmath-ast/src/jvmTest/kotlin/space/kscience/kmath/ast/ParserTest.kt
rename to kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/TestParser.kt
index 53afaa674..b838245e1 100644
--- a/kmath-ast/src/jvmTest/kotlin/space/kscience/kmath/ast/ParserTest.kt
+++ b/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/TestParser.kt
@@ -7,31 +7,22 @@ package space.kscience.kmath.ast
import space.kscience.kmath.complex.Complex
import space.kscience.kmath.complex.ComplexField
-import space.kscience.kmath.expressions.MstField
import space.kscience.kmath.expressions.evaluate
-import space.kscience.kmath.expressions.interpret
import space.kscience.kmath.operations.Algebra
import space.kscience.kmath.operations.DoubleField
-import space.kscience.kmath.operations.invoke
import kotlin.test.Test
import kotlin.test.assertEquals
-internal class ParserTest {
+internal class TestParser {
@Test
- fun `evaluate MST`() {
+ fun evaluateParsedMst() {
val mst = "2+2*(2+2)".parseMath()
val res = ComplexField.evaluate(mst)
assertEquals(Complex(10.0, 0.0), res)
}
@Test
- fun `evaluate MSTExpression`() {
- val res = MstField.invoke { number(2) + number(2) * (number(2) + number(2)) }.interpret(ComplexField)
- assertEquals(Complex(10.0, 0.0), res)
- }
-
- @Test
- fun `evaluate MST with singular`() {
+ fun evaluateMstSymbol() {
val mst = "i".parseMath()
val res = ComplexField.evaluate(mst)
assertEquals(ComplexField.i, res)
@@ -39,14 +30,14 @@ internal class ParserTest {
@Test
- fun `evaluate MST with unary function`() {
+ fun evaluateMstUnary() {
val mst = "sin(0)".parseMath()
val res = DoubleField.evaluate(mst)
assertEquals(0.0, res)
}
@Test
- fun `evaluate MST with binary function`() {
+ fun evaluateMstBinary() {
val magicalAlgebra = object : Algebra {
override fun bindSymbolOrNull(value: String): String = value
diff --git a/kmath-ast/src/jvmTest/kotlin/space/kscience/kmath/ast/ParserPrecedenceTest.kt b/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/TestParserPrecedence.kt
similarity index 89%
rename from kmath-ast/src/jvmTest/kotlin/space/kscience/kmath/ast/ParserPrecedenceTest.kt
rename to kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/TestParserPrecedence.kt
index 6273eff27..bb6bb3ce1 100644
--- a/kmath-ast/src/jvmTest/kotlin/space/kscience/kmath/ast/ParserPrecedenceTest.kt
+++ b/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/TestParserPrecedence.kt
@@ -7,13 +7,10 @@ package space.kscience.kmath.ast
import space.kscience.kmath.expressions.evaluate
import space.kscience.kmath.operations.DoubleField
-import space.kscience.kmath.operations.Field
import kotlin.test.Test
import kotlin.test.assertEquals
-internal class ParserPrecedenceTest {
- private val f: Field = DoubleField
-
+internal class TestParserPrecedence {
@Test
fun test1(): Unit = assertEquals(6.0, f.evaluate("2*2+2".parseMath()))
@@ -37,4 +34,8 @@ internal class ParserPrecedenceTest {
@Test
fun test8(): Unit = assertEquals(18.0, f.evaluate("2*2^3+2".parseMath()))
+
+ private companion object {
+ private val f = DoubleField
+ }
}
diff --git a/kmath-ast/src/jvmTest/kotlin/space/kscience/kmath/ast/rendering/TestFeatures.kt b/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/rendering/TestFeatures.kt
similarity index 68%
rename from kmath-ast/src/jvmTest/kotlin/space/kscience/kmath/ast/rendering/TestFeatures.kt
rename to kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/rendering/TestFeatures.kt
index 1584293ce..a40c785b9 100644
--- a/kmath-ast/src/jvmTest/kotlin/space/kscience/kmath/ast/rendering/TestFeatures.kt
+++ b/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/rendering/TestFeatures.kt
@@ -42,6 +42,22 @@ internal class TestFeatures {
testLatex(Numeric(1.1e-10), "1.1\\times10^{-10}")
testLatex(Numeric(-1.1e-10), "-1.1\\times10^{-10}")
testLatex(Numeric(-1.1e10), "-1.1\\times10^{10}")
+ testLatex(Numeric(0.001), "0.001")
+ testLatex(Numeric(0.0000001), "1\\times10^{-7}")
+
+ testLatex(Numeric(Float.NaN), "NaN")
+ testLatex(Numeric(Float.POSITIVE_INFINITY), "\\infty")
+ testLatex(Numeric(Float.NEGATIVE_INFINITY), "-\\infty")
+ testLatex(Numeric(1.0f), "1")
+ testLatex(Numeric(-1.0f), "-1")
+ testLatex(Numeric(1.42f), "1.42")
+ testLatex(Numeric(-1.42f), "-1.42")
+ testLatex(Numeric(1e10f), "1\\times10^{10}")
+ testLatex(Numeric(1e-10f), "1\\times10^{-10}")
+ testLatex(Numeric(-1e-10f), "-1\\times10^{-10}")
+ testLatex(Numeric(-1e10f), "-1\\times10^{10}")
+ testLatex(Numeric(0.001f), "0.001")
+ testLatex(Numeric(0.0000001f), "1\\times10^{-7}")
}
@Test
@@ -83,13 +99,17 @@ internal class TestFeatures {
fun multiplication() = testLatex("x*1", "x\\times1")
@Test
- fun inverseTrigonometry() {
- testLatex("asin(x)", "\\operatorname{sin}^{-1}\\,\\left(x\\right)")
- testLatex("asinh(x)", "\\operatorname{sinh}^{-1}\\,\\left(x\\right)")
- testLatex("acos(x)", "\\operatorname{cos}^{-1}\\,\\left(x\\right)")
- testLatex("acosh(x)", "\\operatorname{cosh}^{-1}\\,\\left(x\\right)")
- testLatex("atan(x)", "\\operatorname{tan}^{-1}\\,\\left(x\\right)")
- testLatex("atanh(x)", "\\operatorname{tanh}^{-1}\\,\\left(x\\right)")
+ fun inverseTrigonometric() {
+ testLatex("asin(x)", "\\operatorname{arcsin}\\,\\left(x\\right)")
+ testLatex("acos(x)", "\\operatorname{arccos}\\,\\left(x\\right)")
+ testLatex("atan(x)", "\\operatorname{arctan}\\,\\left(x\\right)")
+ }
+
+ @Test
+ fun inverseHyperbolic() {
+ testLatex("asinh(x)", "\\operatorname{arsinh}\\,\\left(x\\right)")
+ testLatex("acosh(x)", "\\operatorname{arcosh}\\,\\left(x\\right)")
+ testLatex("atanh(x)", "\\operatorname{artanh}\\,\\left(x\\right)")
}
// @Test
diff --git a/kmath-ast/src/jvmTest/kotlin/space/kscience/kmath/ast/rendering/TestLatex.kt b/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/rendering/TestLatex.kt
similarity index 100%
rename from kmath-ast/src/jvmTest/kotlin/space/kscience/kmath/ast/rendering/TestLatex.kt
rename to kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/rendering/TestLatex.kt
diff --git a/kmath-ast/src/jvmTest/kotlin/space/kscience/kmath/ast/rendering/TestMathML.kt b/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/rendering/TestMathML.kt
similarity index 100%
rename from kmath-ast/src/jvmTest/kotlin/space/kscience/kmath/ast/rendering/TestMathML.kt
rename to kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/rendering/TestMathML.kt
diff --git a/kmath-ast/src/jvmTest/kotlin/space/kscience/kmath/ast/rendering/TestStages.kt b/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/rendering/TestStages.kt
similarity index 74%
rename from kmath-ast/src/jvmTest/kotlin/space/kscience/kmath/ast/rendering/TestStages.kt
rename to kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/rendering/TestStages.kt
index a4017fdb4..09ec127c7 100644
--- a/kmath-ast/src/jvmTest/kotlin/space/kscience/kmath/ast/rendering/TestStages.kt
+++ b/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/rendering/TestStages.kt
@@ -30,4 +30,17 @@ internal class TestStages {
testLatex("(x+x)^x+x*x", "\\left(x+x\\right)^{x}+x\\,x")
testLatex("x^(x+x)", "x^{x+x}")
}
+
+ @Test
+ fun exponent() {
+ testLatex("exp(x)", "e^{x}")
+ testLatex("exp(x/2)", "\\operatorname{exp}\\,\\left(\\frac{x}{2}\\right)")
+ testLatex("exp(x^2)", "\\operatorname{exp}\\,\\left(x^{2}\\right)")
+ }
+
+ @Test
+ fun fraction() {
+ testLatex("x/y", "\\frac{x}{y}")
+ testLatex("x^(x/y)", "x^{x/y}")
+ }
}
diff --git a/kmath-ast/src/jvmTest/kotlin/space/kscience/kmath/ast/rendering/TestUtils.kt b/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/rendering/TestUtils.kt
similarity index 82%
rename from kmath-ast/src/jvmTest/kotlin/space/kscience/kmath/ast/rendering/TestUtils.kt
rename to kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/rendering/TestUtils.kt
index 7c9400532..bf87b6fd0 100644
--- a/kmath-ast/src/jvmTest/kotlin/space/kscience/kmath/ast/rendering/TestUtils.kt
+++ b/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/rendering/TestUtils.kt
@@ -30,17 +30,17 @@ internal object TestUtils {
)
internal fun testMathML(mst: MST, expectedMathML: String) = assertEquals(
- expected = "$expectedMathML ",
+ expected = "$expectedMathML ",
actual = mathML(mst),
)
internal fun testMathML(expression: String, expectedMathML: String) = assertEquals(
- expected = "$expectedMathML ",
+ expected = "$expectedMathML ",
actual = mathML(expression.parseMath()),
)
internal fun testMathML(expression: MathSyntax, expectedMathML: String) = assertEquals(
- expected = "$expectedMathML ",
+ expected = "$expectedMathML ",
actual = MathMLSyntaxRenderer.renderWithStringBuilder(expression),
)
}
diff --git a/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/utils.kt b/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/utils.kt
new file mode 100644
index 000000000..abeaed0f8
--- /dev/null
+++ b/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/utils.kt
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2018-2021 KMath contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package space.kscience.kmath.ast
+
+import space.kscience.kmath.expressions.Expression
+import space.kscience.kmath.expressions.MST
+import space.kscience.kmath.misc.Symbol
+import space.kscience.kmath.operations.DoubleField
+import space.kscience.kmath.operations.IntRing
+
+internal interface CompilerTestContext {
+ fun MST.compileToExpression(algebra: IntRing): Expression
+ fun MST.compile(algebra: IntRing, arguments: Map): Int
+ fun MST.compile(algebra: IntRing, vararg arguments: Pair): Int = compile(algebra, mapOf(*arguments))
+ fun MST.compileToExpression(algebra: DoubleField): Expression
+ fun MST.compile(algebra: DoubleField, arguments: Map): Double
+
+ fun MST.compile(algebra: DoubleField, vararg arguments: Pair): Double =
+ compile(algebra, mapOf(*arguments))
+}
+
+internal expect inline fun runCompilerTest(action: CompilerTestContext.() -> Unit)
diff --git a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/ast/rendering/multiplatformToString.kt b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/ast/rendering/multiplatformToString.kt
new file mode 100644
index 000000000..521907d2c
--- /dev/null
+++ b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/ast/rendering/multiplatformToString.kt
@@ -0,0 +1,18 @@
+/*
+ * Copyright 2018-2021 KMath contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package space.kscience.kmath.ast.rendering
+
+internal actual fun Double.multiplatformToString(): String {
+ val d = this
+ if (d >= 1e7 || d <= -1e7) return js("d.toExponential()") as String
+ return toString()
+}
+
+internal actual fun Float.multiplatformToString(): String {
+ val d = this
+ if (d >= 1e7f || d <= -1e7f) return js("d.toExponential()") as String
+ return toString()
+}
diff --git a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/estree/estree.kt b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/estree/estree.kt
index 83914f3ec..40468f5ab 100644
--- a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/estree/estree.kt
+++ b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/estree/estree.kt
@@ -6,11 +6,11 @@
package space.kscience.kmath.estree
import space.kscience.kmath.estree.internal.ESTreeBuilder
-import space.kscience.kmath.estree.internal.estree.BaseExpression
import space.kscience.kmath.expressions.Expression
import space.kscience.kmath.expressions.MST
import space.kscience.kmath.expressions.MST.*
import space.kscience.kmath.expressions.invoke
+import space.kscience.kmath.internal.estree.BaseExpression
import space.kscience.kmath.misc.Symbol
import space.kscience.kmath.operations.Algebra
import space.kscience.kmath.operations.NumericAlgebra
diff --git a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/estree/internal/ESTreeBuilder.kt b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/estree/internal/ESTreeBuilder.kt
index 6f917a24c..ac20484a4 100644
--- a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/estree/internal/ESTreeBuilder.kt
+++ b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/estree/internal/ESTreeBuilder.kt
@@ -5,9 +5,14 @@
package space.kscience.kmath.estree.internal
-import space.kscience.kmath.estree.internal.astring.generate
-import space.kscience.kmath.estree.internal.estree.*
import space.kscience.kmath.expressions.Expression
+import space.kscience.kmath.internal.astring.generate
+import space.kscience.kmath.internal.estree.*
+import space.kscience.kmath.internal.estree.BaseExpression
+import space.kscience.kmath.internal.estree.BlockStatement
+import space.kscience.kmath.internal.estree.Program
+import space.kscience.kmath.internal.estree.VariableDeclaration
+import space.kscience.kmath.internal.estree.VariableDeclarator
import space.kscience.kmath.misc.Symbol
internal class ESTreeBuilder(val bodyCallback: ESTreeBuilder.() -> BaseExpression) {
diff --git a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/estree/internal/astring/astring.kt b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/astring/astring.kt
similarity index 90%
rename from kmath-ast/src/jsMain/kotlin/space/kscience/kmath/estree/internal/astring/astring.kt
rename to kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/astring/astring.kt
index 354757b83..cca2d83af 100644
--- a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/estree/internal/astring/astring.kt
+++ b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/astring/astring.kt
@@ -6,9 +6,9 @@
@file:JsModule("astring")
@file:JsNonModule
-package space.kscience.kmath.estree.internal.astring
+package space.kscience.kmath.internal.astring
-import space.kscience.kmath.estree.internal.estree.BaseNode
+import space.kscience.kmath.internal.estree.BaseNode
internal external interface Options {
var indent: String?
diff --git a/license/COPYRIGHT_HEADER.txt b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/astring/astring.typealises.kt
similarity index 65%
rename from license/COPYRIGHT_HEADER.txt
rename to kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/astring/astring.typealises.kt
index 3e7d28489..93b4f6ce6 100644
--- a/license/COPYRIGHT_HEADER.txt
+++ b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/astring/astring.typealises.kt
@@ -1,4 +1,8 @@
/*
* 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.
- */
\ No newline at end of file
+ */
+
+package space.kscience.kmath.internal.astring
+
+internal typealias Generator = Any
diff --git a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/base64/base64.kt b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/base64/base64.kt
new file mode 100644
index 000000000..86e0cede7
--- /dev/null
+++ b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/base64/base64.kt
@@ -0,0 +1,54 @@
+/*
+ * 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.
+ */
+
+@file:Suppress(
+ "INTERFACE_WITH_SUPERCLASS",
+ "OVERRIDING_FINAL_MEMBER",
+ "RETURN_TYPE_MISMATCH_ON_OVERRIDE",
+ "CONFLICTING_OVERLOADS",
+ "NO_EXPLICIT_VISIBILITY_IN_API_MODE_WARNING",
+ "ObjectPropertyName",
+ "ClassName",
+)
+@file:JsNonModule
+@file:JsModule("js-base64")
+
+package space.kscience.kmath.internal.base64
+
+import org.khronos.webgl.Uint8Array
+
+internal external var version: Any
+
+internal external var VERSION: Any
+
+internal external var btoaPolyfill: (bin: String) -> String
+
+internal external var _btoa: (bin: String) -> String
+
+internal external var fromUint8Array: (u8a: Uint8Array, urlsafe: Boolean) -> String
+
+internal external var utob: (u: String) -> String
+
+internal external var encode: (src: String, urlsafe: Boolean) -> String
+
+internal external var encodeURI: (src: String) -> String
+
+internal external var btou: (b: String) -> String
+
+internal external var atobPolyfill: (asc: String) -> String
+
+internal external var _atob: (asc: String) -> String
+
+internal external var toUint8Array: (a: String) -> Uint8Array
+
+internal external var decode: (src: String) -> String
+
+internal external var isValid: (src: Any) -> Boolean
+
+internal external var extendString: () -> Unit
+
+internal external var extendUint8Array: () -> Unit
+
+internal external var extendBuiltins: () -> Unit
diff --git a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/binaryen/index.binaryen.kt b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/binaryen/index.binaryen.kt
new file mode 100644
index 000000000..42b6ac7d8
--- /dev/null
+++ b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/binaryen/index.binaryen.kt
@@ -0,0 +1,2239 @@
+/*
+ * 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.
+ */
+
+@file:Suppress(
+ "INTERFACE_WITH_SUPERCLASS",
+ "OVERRIDING_FINAL_MEMBER",
+ "RETURN_TYPE_MISMATCH_ON_OVERRIDE",
+ "CONFLICTING_OVERLOADS",
+ "NO_EXPLICIT_VISIBILITY_IN_API_MODE_WARNING",
+ "PropertyName",
+ "ClassName",
+)
+
+@file:JsModule("binaryen")
+@file:JsNonModule
+
+package space.kscience.kmath.internal.binaryen
+
+import org.khronos.webgl.Uint8Array
+import kotlin.js.Promise
+
+internal external var isReady: Boolean
+
+internal external var ready: Promise
+
+internal external var none: Type
+
+internal external var i32: Type
+
+internal external var i64: Type
+
+internal external var f32: Type
+
+internal external var f64: Type
+
+internal external var v128: Type
+
+internal external var funcref: Type
+
+internal external var anyref: Type
+
+internal external var nullref: Type
+
+internal external var exnref: Type
+
+internal external var unreachable: Type
+
+internal external var auto: Type
+
+internal external fun createType(types: Array): Type
+
+internal external fun expandType(type: Type): Array
+
+internal external enum class ExpressionIds {
+ Invalid,
+ Block,
+ If,
+ Loop,
+ Break,
+ Switch,
+ Call,
+ CallIndirect,
+ LocalGet,
+ LocalSet,
+ GlobalGet,
+ GlobalSet,
+ Load,
+ Store,
+ Const,
+ Unary,
+ Binary,
+ Select,
+ Drop,
+ Return,
+ Host,
+ Nop,
+ Unreachable,
+ AtomicCmpxchg,
+ AtomicRMW,
+ AtomicWait,
+ AtomicNotify,
+ AtomicFence,
+ SIMDExtract,
+ SIMDReplace,
+ SIMDShuffle,
+ SIMDTernary,
+ SIMDShift,
+ SIMDLoad,
+ MemoryInit,
+ DataDrop,
+ MemoryCopy,
+ MemoryFill,
+ RefNull,
+ RefIsNull,
+ RefFunc,
+ Try,
+ Throw,
+ Rethrow,
+ BrOnExn,
+ TupleMake,
+ TupleExtract,
+ Push,
+ Pop
+}
+
+internal external var InvalidId: ExpressionIds
+
+internal external var BlockId: ExpressionIds
+
+internal external var IfId: ExpressionIds
+
+internal external var LoopId: ExpressionIds
+
+internal external var BreakId: ExpressionIds
+
+internal external var SwitchId: ExpressionIds
+
+internal external var CallId: ExpressionIds
+
+internal external var CallIndirectId: ExpressionIds
+
+internal external var LocalGetId: ExpressionIds
+
+internal external var LocalSetId: ExpressionIds
+
+internal external var GlobalGetId: ExpressionIds
+
+internal external var GlobalSetId: ExpressionIds
+
+internal external var LoadId: ExpressionIds
+
+internal external var StoreId: ExpressionIds
+
+internal external var ConstId: ExpressionIds
+
+internal external var UnaryId: ExpressionIds
+
+internal external var BinaryId: ExpressionIds
+
+internal external var SelectId: ExpressionIds
+
+internal external var DropId: ExpressionIds
+
+internal external var ReturnId: ExpressionIds
+
+internal external var HostId: ExpressionIds
+
+internal external var NopId: ExpressionIds
+
+internal external var UnreachableId: ExpressionIds
+
+internal external var AtomicCmpxchgId: ExpressionIds
+
+internal external var AtomicRMWId: ExpressionIds
+
+internal external var AtomicWaitId: ExpressionIds
+
+internal external var AtomicNotifyId: ExpressionIds
+
+internal external var AtomicFenceId: ExpressionIds
+
+internal external var SIMDExtractId: ExpressionIds
+
+internal external var SIMDReplaceId: ExpressionIds
+
+internal external var SIMDShuffleId: ExpressionIds
+
+internal external var SIMDTernaryId: ExpressionIds
+
+internal external var SIMDShiftId: ExpressionIds
+
+internal external var SIMDLoadId: ExpressionIds
+
+internal external var MemoryInitId: ExpressionIds
+
+internal external var DataDropId: ExpressionIds
+
+internal external var MemoryCopyId: ExpressionIds
+
+internal external var MemoryFillId: ExpressionIds
+
+internal external var RefNullId: ExpressionIds
+
+internal external var RefIsNullId: ExpressionIds
+
+internal external var RefFuncId: ExpressionIds
+
+internal external var TryId: ExpressionIds
+
+internal external var ThrowId: ExpressionIds
+
+internal external var RethrowId: ExpressionIds
+
+internal external var BrOnExnId: ExpressionIds
+
+internal external var TupleMakeId: ExpressionIds
+
+internal external var TupleExtractId: ExpressionIds
+
+internal external var PushId: ExpressionIds
+
+internal external var PopId: ExpressionIds
+
+internal external enum class ExternalKinds {
+ Function,
+ Table,
+ Memory,
+ Global,
+ Event
+}
+
+internal external var ExternalFunction: ExternalKinds
+
+internal external var ExternalTable: ExternalKinds
+
+internal external var ExternalMemory: ExternalKinds
+
+internal external var ExternalGlobal: ExternalKinds
+
+internal external var ExternalEvent: ExternalKinds
+
+internal external enum class Features {
+ MVP,
+ Atomics,
+ MutableGlobals,
+ TruncSat,
+ SIMD,
+ BulkMemory,
+ SignExt,
+ ExceptionHandling,
+ TailCall,
+ ReferenceTypes,
+ Multivalue,
+ GC,
+ Memory64,
+ All
+}
+
+internal external enum class Operations {
+ ClzInt32,
+ CtzInt32,
+ PopcntInt32,
+ NegFloat32,
+ AbsFloat32,
+ CeilFloat32,
+ FloorFloat32,
+ TruncFloat32,
+ NearestFloat32,
+ SqrtFloat32,
+ EqZInt32,
+ ClzInt64,
+ CtzInt64,
+ PopcntInt64,
+ NegFloat64,
+ AbsFloat64,
+ CeilFloat64,
+ FloorFloat64,
+ TruncFloat64,
+ NearestFloat64,
+ SqrtFloat64,
+ EqZInt64,
+ ExtendSInt32,
+ ExtendUInt32,
+ WrapInt64,
+ TruncSFloat32ToInt32,
+ TruncSFloat32ToInt64,
+ TruncUFloat32ToInt32,
+ TruncUFloat32ToInt64,
+ TruncSFloat64ToInt32,
+ TruncSFloat64ToInt64,
+ TruncUFloat64ToInt32,
+ TruncUFloat64ToInt64,
+ TruncSatSFloat32ToInt32,
+ TruncSatSFloat32ToInt64,
+ TruncSatUFloat32ToInt32,
+ TruncSatUFloat32ToInt64,
+ TruncSatSFloat64ToInt32,
+ TruncSatSFloat64ToInt64,
+ TruncSatUFloat64ToInt32,
+ TruncSatUFloat64ToInt64,
+ ReinterpretFloat32,
+ ReinterpretFloat64,
+ ConvertSInt32ToFloat32,
+ ConvertSInt32ToFloat64,
+ ConvertUInt32ToFloat32,
+ ConvertUInt32ToFloat64,
+ ConvertSInt64ToFloat32,
+ ConvertSInt64ToFloat64,
+ ConvertUInt64ToFloat32,
+ ConvertUInt64ToFloat64,
+ PromoteFloat32,
+ DemoteFloat64,
+ ReinterpretInt32,
+ ReinterpretInt64,
+ ExtendS8Int32,
+ ExtendS16Int32,
+ ExtendS8Int64,
+ ExtendS16Int64,
+ ExtendS32Int64,
+ AddInt32,
+ SubInt32,
+ MulInt32,
+ DivSInt32,
+ DivUInt32,
+ RemSInt32,
+ RemUInt32,
+ AndInt32,
+ OrInt32,
+ XorInt32,
+ ShlInt32,
+ ShrUInt32,
+ ShrSInt32,
+ RotLInt32,
+ RotRInt32,
+ EqInt32,
+ NeInt32,
+ LtSInt32,
+ LtUInt32,
+ LeSInt32,
+ LeUInt32,
+ GtSInt32,
+ GtUInt32,
+ GeSInt32,
+ GeUInt32,
+ AddInt64,
+ SubInt64,
+ MulInt64,
+ DivSInt64,
+ DivUInt64,
+ RemSInt64,
+ RemUInt64,
+ AndInt64,
+ OrInt64,
+ XorInt64,
+ ShlInt64,
+ ShrUInt64,
+ ShrSInt64,
+ RotLInt64,
+ RotRInt64,
+ EqInt64,
+ NeInt64,
+ LtSInt64,
+ LtUInt64,
+ LeSInt64,
+ LeUInt64,
+ GtSInt64,
+ GtUInt64,
+ GeSInt64,
+ GeUInt64,
+ AddFloat32,
+ SubFloat32,
+ MulFloat32,
+ DivFloat32,
+ CopySignFloat32,
+ MinFloat32,
+ MaxFloat32,
+ EqFloat32,
+ NeFloat32,
+ LtFloat32,
+ LeFloat32,
+ GtFloat32,
+ GeFloat32,
+ AddFloat64,
+ SubFloat64,
+ MulFloat64,
+ DivFloat64,
+ CopySignFloat64,
+ MinFloat64,
+ MaxFloat64,
+ EqFloat64,
+ NeFloat64,
+ LtFloat64,
+ LeFloat64,
+ GtFloat64,
+ GeFloat64,
+ MemorySize,
+ MemoryGrow,
+ AtomicRMWAdd,
+ AtomicRMWSub,
+ AtomicRMWAnd,
+ AtomicRMWOr,
+ AtomicRMWXor,
+ AtomicRMWXchg,
+ SplatVecI8x16,
+ ExtractLaneSVecI8x16,
+ ExtractLaneUVecI8x16,
+ ReplaceLaneVecI8x16,
+ SplatVecI16x8,
+ ExtractLaneSVecI16x8,
+ ExtractLaneUVecI16x8,
+ ReplaceLaneVecI16x8,
+ SplatVecI32x4,
+ ExtractLaneVecI32x4,
+ ReplaceLaneVecI32x4,
+ SplatVecI64x2,
+ ExtractLaneVecI64x2,
+ ReplaceLaneVecI64x2,
+ SplatVecF32x4,
+ ExtractLaneVecF32x4,
+ ReplaceLaneVecF32x4,
+ SplatVecF64x2,
+ ExtractLaneVecF64x2,
+ ReplaceLaneVecF64x2,
+ EqVecI8x16,
+ NeVecI8x16,
+ LtSVecI8x16,
+ LtUVecI8x16,
+ GtSVecI8x16,
+ GtUVecI8x16,
+ LeSVecI8x16,
+ LeUVecI8x16,
+ GeSVecI8x16,
+ GeUVecI8x16,
+ EqVecI16x8,
+ NeVecI16x8,
+ LtSVecI16x8,
+ LtUVecI16x8,
+ GtSVecI16x8,
+ GtUVecI16x8,
+ LeSVecI16x8,
+ LeUVecI16x8,
+ GeSVecI16x8,
+ GeUVecI16x8,
+ EqVecI32x4,
+ NeVecI32x4,
+ LtSVecI32x4,
+ LtUVecI32x4,
+ GtSVecI32x4,
+ GtUVecI32x4,
+ LeSVecI32x4,
+ LeUVecI32x4,
+ GeSVecI32x4,
+ GeUVecI32x4,
+ EqVecF32x4,
+ NeVecF32x4,
+ LtVecF32x4,
+ GtVecF32x4,
+ LeVecF32x4,
+ GeVecF32x4,
+ EqVecF64x2,
+ NeVecF64x2,
+ LtVecF64x2,
+ GtVecF64x2,
+ LeVecF64x2,
+ GeVecF64x2,
+ NotVec128,
+ AndVec128,
+ OrVec128,
+ XorVec128,
+ AndNotVec128,
+ BitselectVec128,
+ NegVecI8x16,
+ AnyTrueVecI8x16,
+ AllTrueVecI8x16,
+ ShlVecI8x16,
+ ShrSVecI8x16,
+ ShrUVecI8x16,
+ AddVecI8x16,
+ AddSatSVecI8x16,
+ AddSatUVecI8x16,
+ SubVecI8x16,
+ SubSatSVecI8x16,
+ SubSatUVecI8x16,
+ MulVecI8x16,
+ MinSVecI8x16,
+ MinUVecI8x16,
+ MaxSVecI8x16,
+ MaxUVecI8x16,
+ NegVecI16x8,
+ AnyTrueVecI16x8,
+ AllTrueVecI16x8,
+ ShlVecI16x8,
+ ShrSVecI16x8,
+ ShrUVecI16x8,
+ AddVecI16x8,
+ AddSatSVecI16x8,
+ AddSatUVecI16x8,
+ SubVecI16x8,
+ SubSatSVecI16x8,
+ SubSatUVecI16x8,
+ MulVecI16x8,
+ MinSVecI16x8,
+ MinUVecI16x8,
+ MaxSVecI16x8,
+ MaxUVecI16x8,
+ DotSVecI16x8ToVecI32x4,
+ NegVecI32x4,
+ AnyTrueVecI32x4,
+ AllTrueVecI32x4,
+ ShlVecI32x4,
+ ShrSVecI32x4,
+ ShrUVecI32x4,
+ AddVecI32x4,
+ SubVecI32x4,
+ MulVecI32x4,
+ MinSVecI32x4,
+ MinUVecI32x4,
+ MaxSVecI32x4,
+ MaxUVecI32x4,
+ NegVecI64x2,
+ AnyTrueVecI64x2,
+ AllTrueVecI64x2,
+ ShlVecI64x2,
+ ShrSVecI64x2,
+ ShrUVecI64x2,
+ AddVecI64x2,
+ SubVecI64x2,
+ AbsVecF32x4,
+ NegVecF32x4,
+ SqrtVecF32x4,
+ QFMAVecF32x4,
+ QFMSVecF32x4,
+ AddVecF32x4,
+ SubVecF32x4,
+ MulVecF32x4,
+ DivVecF32x4,
+ MinVecF32x4,
+ MaxVecF32x4,
+ AbsVecF64x2,
+ NegVecF64x2,
+ SqrtVecF64x2,
+ QFMAVecF64x2,
+ QFMSVecF64x2,
+ AddVecF64x2,
+ SubVecF64x2,
+ MulVecF64x2,
+ DivVecF64x2,
+ MinVecF64x2,
+ MaxVecF64x2,
+ TruncSatSVecF32x4ToVecI32x4,
+ TruncSatUVecF32x4ToVecI32x4,
+ TruncSatSVecF64x2ToVecI64x2,
+ TruncSatUVecF64x2ToVecI64x2,
+ ConvertSVecI32x4ToVecF32x4,
+ ConvertUVecI32x4ToVecF32x4,
+ ConvertSVecI64x2ToVecF64x2,
+ ConvertUVecI64x2ToVecF64x2,
+ LoadSplatVec8x16,
+ LoadSplatVec16x8,
+ LoadSplatVec32x4,
+ LoadSplatVec64x2,
+ LoadExtSVec8x8ToVecI16x8,
+ LoadExtUVec8x8ToVecI16x8,
+ LoadExtSVec16x4ToVecI32x4,
+ LoadExtUVec16x4ToVecI32x4,
+ LoadExtSVec32x2ToVecI64x2,
+ LoadExtUVec32x2ToVecI64x2,
+ NarrowSVecI16x8ToVecI8x16,
+ NarrowUVecI16x8ToVecI8x16,
+ NarrowSVecI32x4ToVecI16x8,
+ NarrowUVecI32x4ToVecI16x8,
+ WidenLowSVecI8x16ToVecI16x8,
+ WidenHighSVecI8x16ToVecI16x8,
+ WidenLowUVecI8x16ToVecI16x8,
+ WidenHighUVecI8x16ToVecI16x8,
+ WidenLowSVecI16x8ToVecI32x4,
+ WidenHighSVecI16x8ToVecI32x4,
+ WidenLowUVecI16x8ToVecI32x4,
+ WidenHighUVecI16x8ToVecI32x4,
+ SwizzleVec8x16
+}
+
+internal external var ClzInt32: Operations
+
+internal external var CtzInt32: Operations
+
+internal external var PopcntInt32: Operations
+
+internal external var NegFloat32: Operations
+
+internal external var AbsFloat32: Operations
+
+internal external var CeilFloat32: Operations
+
+internal external var FloorFloat32: Operations
+
+internal external var TruncFloat32: Operations
+
+internal external var NearestFloat32: Operations
+
+internal external var SqrtFloat32: Operations
+
+internal external var EqZInt32: Operations
+
+internal external var ClzInt64: Operations
+
+internal external var CtzInt64: Operations
+
+internal external var PopcntInt64: Operations
+
+internal external var NegFloat64: Operations
+
+internal external var AbsFloat64: Operations
+
+internal external var CeilFloat64: Operations
+
+internal external var FloorFloat64: Operations
+
+internal external var TruncFloat64: Operations
+
+internal external var NearestFloat64: Operations
+
+internal external var SqrtFloat64: Operations
+
+internal external var EqZInt64: Operations
+
+internal external var ExtendSInt32: Operations
+
+internal external var ExtendUInt32: Operations
+
+internal external var WrapInt64: Operations
+
+internal external var TruncSFloat32ToInt32: Operations
+
+internal external var TruncSFloat32ToInt64: Operations
+
+internal external var TruncUFloat32ToInt32: Operations
+
+internal external var TruncUFloat32ToInt64: Operations
+
+internal external var TruncSFloat64ToInt32: Operations
+
+internal external var TruncSFloat64ToInt64: Operations
+
+internal external var TruncUFloat64ToInt32: Operations
+
+internal external var TruncUFloat64ToInt64: Operations
+
+internal external var TruncSatSFloat32ToInt32: Operations
+
+internal external var TruncSatSFloat32ToInt64: Operations
+
+internal external var TruncSatUFloat32ToInt32: Operations
+
+internal external var TruncSatUFloat32ToInt64: Operations
+
+internal external var TruncSatSFloat64ToInt32: Operations
+
+internal external var TruncSatSFloat64ToInt64: Operations
+
+internal external var TruncSatUFloat64ToInt32: Operations
+
+internal external var TruncSatUFloat64ToInt64: Operations
+
+internal external var ReinterpretFloat32: Operations
+
+internal external var ReinterpretFloat64: Operations
+
+internal external var ConvertSInt32ToFloat32: Operations
+
+internal external var ConvertSInt32ToFloat64: Operations
+
+internal external var ConvertUInt32ToFloat32: Operations
+
+internal external var ConvertUInt32ToFloat64: Operations
+
+internal external var ConvertSInt64ToFloat32: Operations
+
+internal external var ConvertSInt64ToFloat64: Operations
+
+internal external var ConvertUInt64ToFloat32: Operations
+
+internal external var ConvertUInt64ToFloat64: Operations
+
+internal external var PromoteFloat32: Operations
+
+internal external var DemoteFloat64: Operations
+
+internal external var ReinterpretInt32: Operations
+
+internal external var ReinterpretInt64: Operations
+
+internal external var ExtendS8Int32: Operations
+
+internal external var ExtendS16Int32: Operations
+
+internal external var ExtendS8Int64: Operations
+
+internal external var ExtendS16Int64: Operations
+
+internal external var ExtendS32Int64: Operations
+
+internal external var AddInt32: Operations
+
+internal external var SubInt32: Operations
+
+internal external var MulInt32: Operations
+
+internal external var DivSInt32: Operations
+
+internal external var DivUInt32: Operations
+
+internal external var RemSInt32: Operations
+
+internal external var RemUInt32: Operations
+
+internal external var AndInt32: Operations
+
+internal external var OrInt32: Operations
+
+internal external var XorInt32: Operations
+
+internal external var ShlInt32: Operations
+
+internal external var ShrUInt32: Operations
+
+internal external var ShrSInt32: Operations
+
+internal external var RotLInt32: Operations
+
+internal external var RotRInt32: Operations
+
+internal external var EqInt32: Operations
+
+internal external var NeInt32: Operations
+
+internal external var LtSInt32: Operations
+
+internal external var LtUInt32: Operations
+
+internal external var LeSInt32: Operations
+
+internal external var LeUInt32: Operations
+
+internal external var GtSInt32: Operations
+
+internal external var GtUInt32: Operations
+
+internal external var GeSInt32: Operations
+
+internal external var GeUInt32: Operations
+
+internal external var AddInt64: Operations
+
+internal external var SubInt64: Operations
+
+internal external var MulInt64: Operations
+
+internal external var DivSInt64: Operations
+
+internal external var DivUInt64: Operations
+
+internal external var RemSInt64: Operations
+
+internal external var RemUInt64: Operations
+
+internal external var AndInt64: Operations
+
+internal external var OrInt64: Operations
+
+internal external var XorInt64: Operations
+
+internal external var ShlInt64: Operations
+
+internal external var ShrUInt64: Operations
+
+internal external var ShrSInt64: Operations
+
+internal external var RotLInt64: Operations
+
+internal external var RotRInt64: Operations
+
+internal external var EqInt64: Operations
+
+internal external var NeInt64: Operations
+
+internal external var LtSInt64: Operations
+
+internal external var LtUInt64: Operations
+
+internal external var LeSInt64: Operations
+
+internal external var LeUInt64: Operations
+
+internal external var GtSInt64: Operations
+
+internal external var GtUInt64: Operations
+
+internal external var GeSInt64: Operations
+
+internal external var GeUInt64: Operations
+
+internal external var AddFloat32: Operations
+
+internal external var SubFloat32: Operations
+
+internal external var MulFloat32: Operations
+
+internal external var DivFloat32: Operations
+
+internal external var CopySignFloat32: Operations
+
+internal external var MinFloat32: Operations
+
+internal external var MaxFloat32: Operations
+
+internal external var EqFloat32: Operations
+
+internal external var NeFloat32: Operations
+
+internal external var LtFloat32: Operations
+
+internal external var LeFloat32: Operations
+
+internal external var GtFloat32: Operations
+
+internal external var GeFloat32: Operations
+
+internal external var AddFloat64: Operations
+
+internal external var SubFloat64: Operations
+
+internal external var MulFloat64: Operations
+
+internal external var DivFloat64: Operations
+
+internal external var CopySignFloat64: Operations
+
+internal external var MinFloat64: Operations
+
+internal external var MaxFloat64: Operations
+
+internal external var EqFloat64: Operations
+
+internal external var NeFloat64: Operations
+
+internal external var LtFloat64: Operations
+
+internal external var LeFloat64: Operations
+
+internal external var GtFloat64: Operations
+
+internal external var GeFloat64: Operations
+
+internal external var MemorySize: Operations
+
+internal external var MemoryGrow: Operations
+
+internal external var AtomicRMWAdd: Operations
+
+internal external var AtomicRMWSub: Operations
+
+internal external var AtomicRMWAnd: Operations
+
+internal external var AtomicRMWOr: Operations
+
+internal external var AtomicRMWXor: Operations
+
+internal external var AtomicRMWXchg: Operations
+
+internal external var SplatVecI8x16: Operations
+
+internal external var ExtractLaneSVecI8x16: Operations
+
+internal external var ExtractLaneUVecI8x16: Operations
+
+internal external var ReplaceLaneVecI8x16: Operations
+
+internal external var SplatVecI16x8: Operations
+
+internal external var ExtractLaneSVecI16x8: Operations
+
+internal external var ExtractLaneUVecI16x8: Operations
+
+internal external var ReplaceLaneVecI16x8: Operations
+
+internal external var SplatVecI32x4: Operations
+
+internal external var ExtractLaneVecI32x4: Operations
+
+internal external var ReplaceLaneVecI32x4: Operations
+
+internal external var SplatVecI64x2: Operations
+
+internal external var ExtractLaneVecI64x2: Operations
+
+internal external var ReplaceLaneVecI64x2: Operations
+
+internal external var SplatVecF32x4: Operations
+
+internal external var ExtractLaneVecF32x4: Operations
+
+internal external var ReplaceLaneVecF32x4: Operations
+
+internal external var SplatVecF64x2: Operations
+
+internal external var ExtractLaneVecF64x2: Operations
+
+internal external var ReplaceLaneVecF64x2: Operations
+
+internal external var EqVecI8x16: Operations
+
+internal external var NeVecI8x16: Operations
+
+internal external var LtSVecI8x16: Operations
+
+internal external var LtUVecI8x16: Operations
+
+internal external var GtSVecI8x16: Operations
+
+internal external var GtUVecI8x16: Operations
+
+internal external var LeSVecI8x16: Operations
+
+internal external var LeUVecI8x16: Operations
+
+internal external var GeSVecI8x16: Operations
+
+internal external var GeUVecI8x16: Operations
+
+internal external var EqVecI16x8: Operations
+
+internal external var NeVecI16x8: Operations
+
+internal external var LtSVecI16x8: Operations
+
+internal external var LtUVecI16x8: Operations
+
+internal external var GtSVecI16x8: Operations
+
+internal external var GtUVecI16x8: Operations
+
+internal external var LeSVecI16x8: Operations
+
+internal external var LeUVecI16x8: Operations
+
+internal external var GeSVecI16x8: Operations
+
+internal external var GeUVecI16x8: Operations
+
+internal external var EqVecI32x4: Operations
+
+internal external var NeVecI32x4: Operations
+
+internal external var LtSVecI32x4: Operations
+
+internal external var LtUVecI32x4: Operations
+
+internal external var GtSVecI32x4: Operations
+
+internal external var GtUVecI32x4: Operations
+
+internal external var LeSVecI32x4: Operations
+
+internal external var LeUVecI32x4: Operations
+
+internal external var GeSVecI32x4: Operations
+
+internal external var GeUVecI32x4: Operations
+
+internal external var EqVecF32x4: Operations
+
+internal external var NeVecF32x4: Operations
+
+internal external var LtVecF32x4: Operations
+
+internal external var GtVecF32x4: Operations
+
+internal external var LeVecF32x4: Operations
+
+internal external var GeVecF32x4: Operations
+
+internal external var EqVecF64x2: Operations
+
+internal external var NeVecF64x2: Operations
+
+internal external var LtVecF64x2: Operations
+
+internal external var GtVecF64x2: Operations
+
+internal external var LeVecF64x2: Operations
+
+internal external var GeVecF64x2: Operations
+
+internal external var NotVec128: Operations
+
+internal external var AndVec128: Operations
+
+internal external var OrVec128: Operations
+
+internal external var XorVec128: Operations
+
+internal external var AndNotVec128: Operations
+
+internal external var BitselectVec128: Operations
+
+internal external var NegVecI8x16: Operations
+
+internal external var AnyTrueVecI8x16: Operations
+
+internal external var AllTrueVecI8x16: Operations
+
+internal external var ShlVecI8x16: Operations
+
+internal external var ShrSVecI8x16: Operations
+
+internal external var ShrUVecI8x16: Operations
+
+internal external var AddVecI8x16: Operations
+
+internal external var AddSatSVecI8x16: Operations
+
+internal external var AddSatUVecI8x16: Operations
+
+internal external var SubVecI8x16: Operations
+
+internal external var SubSatSVecI8x16: Operations
+
+internal external var SubSatUVecI8x16: Operations
+
+internal external var MulVecI8x16: Operations
+
+internal external var MinSVecI8x16: Operations
+
+internal external var MinUVecI8x16: Operations
+
+internal external var MaxSVecI8x16: Operations
+
+internal external var MaxUVecI8x16: Operations
+
+internal external var NegVecI16x8: Operations
+
+internal external var AnyTrueVecI16x8: Operations
+
+internal external var AllTrueVecI16x8: Operations
+
+internal external var ShlVecI16x8: Operations
+
+internal external var ShrSVecI16x8: Operations
+
+internal external var ShrUVecI16x8: Operations
+
+internal external var AddVecI16x8: Operations
+
+internal external var AddSatSVecI16x8: Operations
+
+internal external var AddSatUVecI16x8: Operations
+
+internal external var SubVecI16x8: Operations
+
+internal external var SubSatSVecI16x8: Operations
+
+internal external var SubSatUVecI16x8: Operations
+
+internal external var MulVecI16x8: Operations
+
+internal external var MinSVecI16x8: Operations
+
+internal external var MinUVecI16x8: Operations
+
+internal external var MaxSVecI16x8: Operations
+
+internal external var MaxUVecI16x8: Operations
+
+internal external var DotSVecI16x8ToVecI32x4: Operations
+
+internal external var NegVecI32x4: Operations
+
+internal external var AnyTrueVecI32x4: Operations
+
+internal external var AllTrueVecI32x4: Operations
+
+internal external var ShlVecI32x4: Operations
+
+internal external var ShrSVecI32x4: Operations
+
+internal external var ShrUVecI32x4: Operations
+
+internal external var AddVecI32x4: Operations
+
+internal external var SubVecI32x4: Operations
+
+internal external var MulVecI32x4: Operations
+
+internal external var MinSVecI32x4: Operations
+
+internal external var MinUVecI32x4: Operations
+
+internal external var MaxSVecI32x4: Operations
+
+internal external var MaxUVecI32x4: Operations
+
+internal external var NegVecI64x2: Operations
+
+internal external var AnyTrueVecI64x2: Operations
+
+internal external var AllTrueVecI64x2: Operations
+
+internal external var ShlVecI64x2: Operations
+
+internal external var ShrSVecI64x2: Operations
+
+internal external var ShrUVecI64x2: Operations
+
+internal external var AddVecI64x2: Operations
+
+internal external var SubVecI64x2: Operations
+
+internal external var AbsVecF32x4: Operations
+
+internal external var NegVecF32x4: Operations
+
+internal external var SqrtVecF32x4: Operations
+
+internal external var QFMAVecF32x4: Operations
+
+internal external var QFMSVecF32x4: Operations
+
+internal external var AddVecF32x4: Operations
+
+internal external var SubVecF32x4: Operations
+
+internal external var MulVecF32x4: Operations
+
+internal external var DivVecF32x4: Operations
+
+internal external var MinVecF32x4: Operations
+
+internal external var MaxVecF32x4: Operations
+
+internal external var AbsVecF64x2: Operations
+
+internal external var NegVecF64x2: Operations
+
+internal external var SqrtVecF64x2: Operations
+
+internal external var QFMAVecF64x2: Operations
+
+internal external var QFMSVecF64x2: Operations
+
+internal external var AddVecF64x2: Operations
+
+internal external var SubVecF64x2: Operations
+
+internal external var MulVecF64x2: Operations
+
+internal external var DivVecF64x2: Operations
+
+internal external var MinVecF64x2: Operations
+
+internal external var MaxVecF64x2: Operations
+
+internal external var TruncSatSVecF32x4ToVecI32x4: Operations
+
+internal external var TruncSatUVecF32x4ToVecI32x4: Operations
+
+internal external var TruncSatSVecF64x2ToVecI64x2: Operations
+
+internal external var TruncSatUVecF64x2ToVecI64x2: Operations
+
+internal external var ConvertSVecI32x4ToVecF32x4: Operations
+
+internal external var ConvertUVecI32x4ToVecF32x4: Operations
+
+internal external var ConvertSVecI64x2ToVecF64x2: Operations
+
+internal external var ConvertUVecI64x2ToVecF64x2: Operations
+
+internal external var LoadSplatVec8x16: Operations
+
+internal external var LoadSplatVec16x8: Operations
+
+internal external var LoadSplatVec32x4: Operations
+
+internal external var LoadSplatVec64x2: Operations
+
+internal external var LoadExtSVec8x8ToVecI16x8: Operations
+
+internal external var LoadExtUVec8x8ToVecI16x8: Operations
+
+internal external var LoadExtSVec16x4ToVecI32x4: Operations
+
+internal external var LoadExtUVec16x4ToVecI32x4: Operations
+
+internal external var LoadExtSVec32x2ToVecI64x2: Operations
+
+internal external var LoadExtUVec32x2ToVecI64x2: Operations
+
+internal external var NarrowSVecI16x8ToVecI8x16: Operations
+
+internal external var NarrowUVecI16x8ToVecI8x16: Operations
+
+internal external var NarrowSVecI32x4ToVecI16x8: Operations
+
+internal external var NarrowUVecI32x4ToVecI16x8: Operations
+
+internal external var WidenLowSVecI8x16ToVecI16x8: Operations
+
+internal external var WidenHighSVecI8x16ToVecI16x8: Operations
+
+internal external var WidenLowUVecI8x16ToVecI16x8: Operations
+
+internal external var WidenHighUVecI8x16ToVecI16x8: Operations
+
+internal external var WidenLowSVecI16x8ToVecI32x4: Operations
+
+internal external var WidenHighSVecI16x8ToVecI32x4: Operations
+
+internal external var WidenLowUVecI16x8ToVecI32x4: Operations
+
+internal external var WidenHighUVecI16x8ToVecI32x4: Operations
+
+internal external var SwizzleVec8x16: Operations
+
+internal external interface `T$2` {
+ fun get(index: Number, type: Type): ExpressionRef
+ fun set(index: Number, value: ExpressionRef): ExpressionRef
+ fun tee(index: Number, value: ExpressionRef, type: Type): ExpressionRef
+}
+
+internal external interface `T$3` {
+ fun get(name: String, type: Type): ExpressionRef
+ fun set(name: String, value: ExpressionRef): ExpressionRef
+}
+
+internal external interface `T$4` {
+ fun size(): ExpressionRef
+ fun grow(value: ExpressionRef): ExpressionRef
+ fun init(segment: Number, dest: ExpressionRef, offset: ExpressionRef, size: ExpressionRef): ExpressionRef
+ fun copy(dest: ExpressionRef, source: ExpressionRef, size: ExpressionRef): ExpressionRef
+ fun fill(dest: ExpressionRef, value: ExpressionRef, size: ExpressionRef): ExpressionRef
+}
+
+internal external interface `T$5` {
+ fun drop(segment: Number): ExpressionRef
+}
+
+internal external interface `T$6` {
+ fun f32(value: ExpressionRef): ExpressionRef
+ fun f64(value: ExpressionRef): ExpressionRef
+}
+
+internal external interface `T$7` {
+ fun add(offset: Number, ptr: ExpressionRef, value: ExpressionRef): ExpressionRef
+ fun sub(offset: Number, ptr: ExpressionRef, value: ExpressionRef): ExpressionRef
+ fun and(offset: Number, ptr: ExpressionRef, value: ExpressionRef): ExpressionRef
+ fun or(offset: Number, ptr: ExpressionRef, value: ExpressionRef): ExpressionRef
+ fun xor(offset: Number, ptr: ExpressionRef, value: ExpressionRef): ExpressionRef
+ fun xchg(offset: Number, ptr: ExpressionRef, value: ExpressionRef): ExpressionRef
+ fun cmpxchg(offset: Number, ptr: ExpressionRef, expected: ExpressionRef, replacement: ExpressionRef): ExpressionRef
+}
+
+internal external interface `T$8` {
+ fun load(offset: Number, ptr: ExpressionRef): ExpressionRef
+ fun load8_u(offset: Number, ptr: ExpressionRef): ExpressionRef
+ fun load16_u(offset: Number, ptr: ExpressionRef): ExpressionRef
+ fun store(offset: Number, ptr: ExpressionRef, value: ExpressionRef): ExpressionRef
+ fun store8(offset: Number, ptr: ExpressionRef, value: ExpressionRef): ExpressionRef
+ fun store16(offset: Number, ptr: ExpressionRef, value: ExpressionRef): ExpressionRef
+ var rmw: `T$7`
+ var rmw8_u: `T$7`
+ var rmw16_u: `T$7`
+ fun wait(ptr: ExpressionRef, expected: ExpressionRef, timeout: ExpressionRef): ExpressionRef
+}
+
+internal external interface `T$9` {
+ fun load(offset: Number, align: Number, ptr: ExpressionRef): ExpressionRef
+ fun load8_s(offset: Number, align: Number, ptr: ExpressionRef): ExpressionRef
+ fun load8_u(offset: Number, align: Number, ptr: ExpressionRef): ExpressionRef
+ fun load16_s(offset: Number, align: Number, ptr: ExpressionRef): ExpressionRef
+ fun load16_u(offset: Number, align: Number, ptr: ExpressionRef): ExpressionRef
+ fun store(offset: Number, align: Number, ptr: ExpressionRef, value: ExpressionRef): ExpressionRef
+ fun store8(offset: Number, align: Number, ptr: ExpressionRef, value: ExpressionRef): ExpressionRef
+ fun store16(offset: Number, align: Number, ptr: ExpressionRef, value: ExpressionRef): ExpressionRef
+ fun const(value: Number): ExpressionRef
+ fun clz(value: ExpressionRef): ExpressionRef
+ fun ctz(value: ExpressionRef): ExpressionRef
+ fun popcnt(value: ExpressionRef): ExpressionRef
+ fun eqz(value: ExpressionRef): ExpressionRef
+ var trunc_s: `T$6`
+ var trunc_u: `T$6`
+ var trunc_s_sat: `T$6`
+ var trunc_u_sat: `T$6`
+ fun reinterpret(value: ExpressionRef): ExpressionRef
+ fun extend8_s(value: ExpressionRef): ExpressionRef
+ fun extend16_s(value: ExpressionRef): ExpressionRef
+ fun wrap(value: ExpressionRef): ExpressionRef
+ fun add(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun sub(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun mul(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun div_s(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun div_u(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun rem_s(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun rem_u(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun and(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun or(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun xor(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun shl(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun shr_u(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun shr_s(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun rotl(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun rotr(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun eq(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun ne(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun lt_s(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun lt_u(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun le_s(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun le_u(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun gt_s(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun gt_u(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun ge_s(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun ge_u(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ var atomic: `T$8`
+ fun pop(): ExpressionRef
+}
+
+internal external interface `T$10` {
+ fun load(offset: Number, ptr: ExpressionRef): ExpressionRef
+ fun load8_u(offset: Number, ptr: ExpressionRef): ExpressionRef
+ fun load16_u(offset: Number, ptr: ExpressionRef): ExpressionRef
+ fun load32_u(offset: Number, ptr: ExpressionRef): ExpressionRef
+ fun store(offset: Number, ptr: ExpressionRef, value: ExpressionRef): ExpressionRef
+ fun store8(offset: Number, ptr: ExpressionRef, value: ExpressionRef): ExpressionRef
+ fun store16(offset: Number, ptr: ExpressionRef, value: ExpressionRef): ExpressionRef
+ fun store32(offset: Number, ptr: ExpressionRef, value: ExpressionRef): ExpressionRef
+ var rmw: `T$7`
+ var rmw8_u: `T$7`
+ var rmw16_u: `T$7`
+ var rmw32_u: `T$7`
+ fun wait(ptr: ExpressionRef, expected: ExpressionRef, timeout: ExpressionRef): ExpressionRef
+}
+
+internal external interface `T$11` {
+ fun load(offset: Number, align: Number, ptr: ExpressionRef): ExpressionRef
+ fun load8_s(offset: Number, align: Number, ptr: ExpressionRef): ExpressionRef
+ fun load8_u(offset: Number, align: Number, ptr: ExpressionRef): ExpressionRef
+ fun load16_s(offset: Number, align: Number, ptr: ExpressionRef): ExpressionRef
+ fun load16_u(offset: Number, align: Number, ptr: ExpressionRef): ExpressionRef
+ fun load32_s(offset: Number, align: Number, ptr: ExpressionRef): ExpressionRef
+ fun load32_u(offset: Number, align: Number, ptr: ExpressionRef): ExpressionRef
+ fun store(offset: Number, align: Number, ptr: ExpressionRef, value: ExpressionRef): ExpressionRef
+ fun store8(offset: Number, align: Number, ptr: ExpressionRef, value: ExpressionRef): ExpressionRef
+ fun store16(offset: Number, align: Number, ptr: ExpressionRef, value: ExpressionRef): ExpressionRef
+ fun store32(offset: Number, align: Number, ptr: ExpressionRef, value: ExpressionRef): ExpressionRef
+ fun const(low: Number, high: Number): ExpressionRef
+ fun clz(value: ExpressionRef): ExpressionRef
+ fun ctz(value: ExpressionRef): ExpressionRef
+ fun popcnt(value: ExpressionRef): ExpressionRef
+ fun eqz(value: ExpressionRef): ExpressionRef
+ var trunc_s: `T$6`
+ var trunc_u: `T$6`
+ var trunc_s_sat: `T$6`
+ var trunc_u_sat: `T$6`
+ fun reinterpret(value: ExpressionRef): ExpressionRef
+ fun extend8_s(value: ExpressionRef): ExpressionRef
+ fun extend16_s(value: ExpressionRef): ExpressionRef
+ fun extend32_s(value: ExpressionRef): ExpressionRef
+ fun extend_s(value: ExpressionRef): ExpressionRef
+ fun extend_u(value: ExpressionRef): ExpressionRef
+ fun add(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun sub(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun mul(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun div_s(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun div_u(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun rem_s(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun rem_u(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun and(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun or(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun xor(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun shl(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun shr_u(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun shr_s(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun rotl(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun rotr(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun eq(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun ne(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun lt_s(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun lt_u(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun le_s(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun le_u(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun gt_s(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun gt_u(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun ge_s(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun ge_u(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ var atomic: `T$10`
+ fun pop(): ExpressionRef
+}
+
+internal external interface `T$12` {
+ fun load(offset: Number, align: Number, ptr: ExpressionRef): ExpressionRef
+ fun store(offset: Number, align: Number, ptr: ExpressionRef, value: ExpressionRef): ExpressionRef
+ fun const(value: Number): ExpressionRef
+ fun const_bits(value: Number): ExpressionRef
+ fun neg(value: ExpressionRef): ExpressionRef
+ fun abs(value: ExpressionRef): ExpressionRef
+ fun ceil(value: ExpressionRef): ExpressionRef
+ fun floor(value: ExpressionRef): ExpressionRef
+ fun trunc(value: ExpressionRef): ExpressionRef
+ fun nearest(value: ExpressionRef): ExpressionRef
+ fun sqrt(value: ExpressionRef): ExpressionRef
+ fun reinterpret(value: ExpressionRef): ExpressionRef
+ var convert_s: `T$6`
+ var convert_u: `T$6`
+ fun demote(value: ExpressionRef): ExpressionRef
+ fun add(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun sub(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun mul(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun div(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun copysign(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun min(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun max(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun eq(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun ne(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun lt(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun le(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun gt(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun ge(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun pop(): ExpressionRef
+}
+
+internal external interface `T$13` {
+ fun load(offset: Number, align: Number, ptr: ExpressionRef): ExpressionRef
+ fun store(offset: Number, align: Number, ptr: ExpressionRef, value: ExpressionRef): ExpressionRef
+ fun const(value: Number): ExpressionRef
+ fun const_bits(low: Number, high: Number): ExpressionRef
+ fun neg(value: ExpressionRef): ExpressionRef
+ fun abs(value: ExpressionRef): ExpressionRef
+ fun ceil(value: ExpressionRef): ExpressionRef
+ fun floor(value: ExpressionRef): ExpressionRef
+ fun trunc(value: ExpressionRef): ExpressionRef
+ fun nearest(value: ExpressionRef): ExpressionRef
+ fun sqrt(value: ExpressionRef): ExpressionRef
+ fun reinterpret(value: ExpressionRef): ExpressionRef
+ var convert_s: `T$6`
+ var convert_u: `T$6`
+ fun promote(value: ExpressionRef): ExpressionRef
+ fun add(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun sub(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun mul(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun div(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun copysign(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun min(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun max(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun eq(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun ne(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun lt(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun le(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun gt(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun ge(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun pop(): ExpressionRef
+}
+
+internal external interface `T$14` {
+ fun load(offset: Number, align: Number, ptr: ExpressionRef): ExpressionRef
+ fun store(offset: Number, align: Number, ptr: ExpressionRef, value: ExpressionRef): ExpressionRef
+ fun const(value: Number): ExpressionRef
+ fun not(value: ExpressionRef): ExpressionRef
+ fun and(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun or(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun xor(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun andnot(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun bitselect(left: ExpressionRef, right: ExpressionRef, cond: ExpressionRef): ExpressionRef
+ fun pop(): ExpressionRef
+}
+
+internal external interface `T$15` {
+ fun splat(value: ExpressionRef): ExpressionRef
+ fun extract_lane_s(vec: ExpressionRef, index: ExpressionRef): ExpressionRef
+ fun extract_lane_u(vec: ExpressionRef, index: ExpressionRef): ExpressionRef
+ fun replace_lane(vec: ExpressionRef, index: ExpressionRef, value: ExpressionRef): ExpressionRef
+ fun eq(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun ne(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun lt_s(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun lt_u(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun gt_s(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun gt_u(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun le_s(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun le_u(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun ge_s(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun ge_u(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun neg(value: ExpressionRef): ExpressionRef
+ fun any_true(value: ExpressionRef): ExpressionRef
+ fun all_true(value: ExpressionRef): ExpressionRef
+ fun shl(vec: ExpressionRef, shift: ExpressionRef): ExpressionRef
+ fun shr_s(vec: ExpressionRef, shift: ExpressionRef): ExpressionRef
+ fun shr_u(vec: ExpressionRef, shift: ExpressionRef): ExpressionRef
+ fun add(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun add_saturate_s(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun add_saturate_u(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun sub(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun sub_saturate_s(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun sub_saturate_u(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun mul(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun min_s(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun min_u(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun max_s(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun max_u(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun avgr_u(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun narrow_i16x8_s(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun narrow_i16x8_u(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+}
+
+internal external interface `T$16` {
+ fun splat(value: ExpressionRef): ExpressionRef
+ fun extract_lane_s(vec: ExpressionRef, index: ExpressionRef): ExpressionRef
+ fun extract_lane_u(vec: ExpressionRef, index: ExpressionRef): ExpressionRef
+ fun replace_lane(vec: ExpressionRef, index: ExpressionRef, value: ExpressionRef): ExpressionRef
+ fun eq(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun ne(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun lt_s(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun lt_u(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun gt_s(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun gt_u(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun le_s(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun le_u(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun ge_s(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun ge_u(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun neg(value: ExpressionRef): ExpressionRef
+ fun any_true(value: ExpressionRef): ExpressionRef
+ fun all_true(value: ExpressionRef): ExpressionRef
+ fun shl(vec: ExpressionRef, shift: ExpressionRef): ExpressionRef
+ fun shr_s(vec: ExpressionRef, shift: ExpressionRef): ExpressionRef
+ fun shr_u(vec: ExpressionRef, shift: ExpressionRef): ExpressionRef
+ fun add(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun add_saturate_s(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun add_saturate_u(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun sub(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun sub_saturate_s(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun sub_saturate_u(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun mul(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun min_s(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun min_u(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun max_s(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun max_u(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun avgr_u(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun narrow_i32x4_s(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun narrow_i32x4_u(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun widen_low_i8x16_s(value: ExpressionRef): ExpressionRef
+ fun widen_high_i8x16_s(value: ExpressionRef): ExpressionRef
+ fun widen_low_i8x16_u(value: ExpressionRef): ExpressionRef
+ fun widen_high_i8x16_u(value: ExpressionRef): ExpressionRef
+ fun load8x8_s(offset: Number, align: Number, ptr: ExpressionRef): ExpressionRef
+ fun load8x8_u(offset: Number, align: Number, ptr: ExpressionRef): ExpressionRef
+}
+
+internal external interface `T$17` {
+ fun splat(value: ExpressionRef): ExpressionRef
+ fun extract_lane(vec: ExpressionRef, index: ExpressionRef): ExpressionRef
+ fun replace_lane(vec: ExpressionRef, index: ExpressionRef, value: ExpressionRef): ExpressionRef
+ fun eq(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun ne(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun lt_s(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun lt_u(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun gt_s(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun gt_u(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun le_s(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun le_u(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun ge_s(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun ge_u(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun neg(value: ExpressionRef): ExpressionRef
+ fun any_true(value: ExpressionRef): ExpressionRef
+ fun all_true(value: ExpressionRef): ExpressionRef
+ fun shl(vec: ExpressionRef, shift: ExpressionRef): ExpressionRef
+ fun shr_s(vec: ExpressionRef, shift: ExpressionRef): ExpressionRef
+ fun shr_u(vec: ExpressionRef, shift: ExpressionRef): ExpressionRef
+ fun add(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun sub(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun mul(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun trunc_sat_f32x4_s(value: ExpressionRef): ExpressionRef
+ fun trunc_sat_f32x4_u(value: ExpressionRef): ExpressionRef
+ fun widen_low_i16x8_s(value: ExpressionRef): ExpressionRef
+ fun widen_high_i16x8_s(value: ExpressionRef): ExpressionRef
+ fun widen_low_i16x8_u(value: ExpressionRef): ExpressionRef
+ fun widen_high_i16x8_u(value: ExpressionRef): ExpressionRef
+ fun load16x4_s(offset: Number, align: Number, ptr: ExpressionRef): ExpressionRef
+ fun load16x4_u(offset: Number, align: Number, ptr: ExpressionRef): ExpressionRef
+}
+
+internal external interface `T$18` {
+ fun splat(value: ExpressionRef): ExpressionRef
+ fun extract_lane(vec: ExpressionRef, index: ExpressionRef): ExpressionRef
+ fun replace_lane(vec: ExpressionRef, index: ExpressionRef, value: ExpressionRef): ExpressionRef
+ fun neg(value: ExpressionRef): ExpressionRef
+ fun any_true(value: ExpressionRef): ExpressionRef
+ fun all_true(value: ExpressionRef): ExpressionRef
+ fun shl(vec: ExpressionRef, shift: ExpressionRef): ExpressionRef
+ fun shr_s(vec: ExpressionRef, shift: ExpressionRef): ExpressionRef
+ fun shr_u(vec: ExpressionRef, shift: ExpressionRef): ExpressionRef
+ fun add(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun sub(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun trunc_sat_f64x2_s(value: ExpressionRef): ExpressionRef
+ fun trunc_sat_f64x2_u(value: ExpressionRef): ExpressionRef
+ fun load32x2_s(offset: Number, align: Number, ptr: ExpressionRef): ExpressionRef
+ fun load32x2_u(offset: Number, align: Number, ptr: ExpressionRef): ExpressionRef
+}
+
+internal external interface `T$19` {
+ fun splat(value: ExpressionRef): ExpressionRef
+ fun extract_lane(vec: ExpressionRef, index: ExpressionRef): ExpressionRef
+ fun replace_lane(vec: ExpressionRef, index: ExpressionRef, value: ExpressionRef): ExpressionRef
+ fun eq(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun ne(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun lt(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun gt(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun le(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun ge(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun abs(value: ExpressionRef): ExpressionRef
+ fun neg(value: ExpressionRef): ExpressionRef
+ fun sqrt(value: ExpressionRef): ExpressionRef
+ fun qfma(a: ExpressionRef, b: ExpressionRef, c: ExpressionRef): ExpressionRef
+ fun qfms(a: ExpressionRef, b: ExpressionRef, c: ExpressionRef): ExpressionRef
+ fun add(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun sub(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun mul(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun div(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun min(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun max(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun convert_i32x4_s(value: ExpressionRef): ExpressionRef
+ fun convert_i32x4_u(value: ExpressionRef): ExpressionRef
+}
+
+internal external interface `T$20` {
+ fun shuffle(left: ExpressionRef, right: ExpressionRef, mask: Array): ExpressionRef
+ fun swizzle(left: ExpressionRef, right: ExpressionRef): ExpressionRef
+ fun load_splat(offset: Number, align: Number, ptr: ExpressionRef): ExpressionRef
+}
+
+internal external interface `T$21` {
+ fun load_splat(offset: Number, align: Number, ptr: ExpressionRef): ExpressionRef
+}
+
+internal external interface `T$22` {
+ fun pop(): ExpressionRef
+}
+
+internal external interface `T$23` {
+ fun `null`(): ExpressionRef
+ fun is_null(value: ExpressionRef): ExpressionRef
+ fun func(name: String): ExpressionRef
+}
+
+internal external interface `T$24` {
+ fun notify(ptr: ExpressionRef, notifyCount: ExpressionRef): ExpressionRef
+ fun fence(): ExpressionRef
+}
+
+internal external interface `T$25` {
+ fun make(elements: Array): ExpressionRef
+ fun extract(tuple: ExpressionRef, index: Number): ExpressionRef
+}
+
+internal external interface `T$26` {
+ var imported: Boolean
+ var segments: Array
+}
+
+internal external interface `T$27` {
+ var binary: Uint8Array
+ var sourceMap: String?
+}
+
+internal open external class Module {
+ open var ptr: Number
+ open fun block(label: String, children: Array, resultType: Type = definedExternally): ExpressionRef
+ open fun `if`(
+ condition: ExpressionRef,
+ ifTrue: ExpressionRef,
+ ifFalse: ExpressionRef = definedExternally
+ ): ExpressionRef
+
+ open fun loop(label: String, body: ExpressionRef): ExpressionRef
+ open fun br(
+ label: String,
+ condition: ExpressionRef = definedExternally,
+ value: ExpressionRef = definedExternally
+ ): ExpressionRef
+
+ open fun br_if(
+ label: String,
+ condition: ExpressionRef = definedExternally,
+ value: ExpressionRef = definedExternally
+ ): ExpressionRef
+
+ open fun switch(
+ labels: Array,
+ defaultLabel: String,
+ condition: ExpressionRef,
+ value: ExpressionRef = definedExternally
+ ): ExpressionRef
+
+ open fun call(name: String, operands: Array, returnType: Type): ExpressionRef
+ open fun return_call(name: String, operands: Array, returnType: Type): ExpressionRef
+ open fun call_indirect(
+ target: ExpressionRef,
+ operands: Array,
+ params: Type,
+ results: Type
+ ): ExpressionRef
+
+ open fun return_call_indirect(
+ target: ExpressionRef,
+ operands: Array,
+ params: Type,
+ results: Type
+ ): ExpressionRef
+
+ open var local: `T$2`
+ open var global: `T$3`
+ open var memory: `T$4`
+ open var data: `T$5`
+ open var i32: `T$9`
+ open var i64: `T$11`
+ open var f32: `T$12`
+ open var f64: `T$13`
+ open var v128: `T$14`
+ open var i8x16: `T$15`
+ open var i16x8: `T$16`
+ open var i32x4: `T$17`
+ open var i64x2: `T$18`
+ open var f32x4: `T$19`
+ open var f64x2: `T$19`
+ open var v8x16: `T$20`
+ open var v16x8: `T$21`
+ open var v32x4: `T$21`
+ open var v64x2: `T$21`
+ open var funcref: `T$22`
+ open var anyref: `T$22`
+ open var nullref: `T$22`
+ open var exnref: `T$22`
+ open var ref: `T$23`
+ open var atomic: `T$24`
+ open var tuple: `T$25`
+ open fun `try`(body: ExpressionRef, catchBody: ExpressionRef): ExpressionRef
+ open fun `throw`(event: String, operands: Array): ExpressionRef
+ open fun rethrow(exnref: ExpressionRef): ExpressionRef
+ open fun br_on_exn(label: String, event: String, exnref: ExpressionRef): ExpressionRef
+ open fun push(value: ExpressionRef): ExpressionRef
+ open fun select(
+ condition: ExpressionRef,
+ ifTrue: ExpressionRef,
+ ifFalse: ExpressionRef,
+ type: Type = definedExternally
+ ): ExpressionRef
+
+ open fun drop(value: ExpressionRef): ExpressionRef
+ open fun `return`(value: ExpressionRef = definedExternally): ExpressionRef
+ open fun host(op: Operations, name: String, operands: Array): ExpressionRef
+ open fun nop(): ExpressionRef
+ open fun unreachable(): ExpressionRef
+ open fun addFunction(name: String, params: Type, results: Type, vars: Array, body: ExpressionRef): FunctionRef
+ open fun getFunction(name: String): FunctionRef
+ open fun removeFunction(name: String)
+ open fun getNumFunctions(): Number
+ open fun getFunctionByIndex(index: Number): FunctionRef
+ open fun addGlobal(name: String, type: Type, mutable: Boolean, init: ExpressionRef): GlobalRef
+ open fun getGlobal(name: String): GlobalRef
+ open fun removeGlobal(name: String)
+ open fun addEvent(name: String, attribute: Number, params: Type, results: Type): EventRef
+ open fun getEvent(name: String): EventRef
+ open fun removeEvent(name: String)
+ open fun addFunctionImport(
+ internalName: String,
+ externalModuleName: String,
+ externalBaseName: String,
+ params: Type,
+ results: Type
+ )
+
+ open fun addTableImport(internalName: String, externalModuleName: String, externalBaseName: String)
+ open fun addMemoryImport(internalName: String, externalModuleName: String, externalBaseName: String)
+ open fun addGlobalImport(
+ internalName: String,
+ externalModuleName: String,
+ externalBaseName: String,
+ globalType: Type
+ )
+
+ open fun addEventImport(
+ internalName: String,
+ externalModuleName: String,
+ externalBaseName: String,
+ attribute: Number,
+ params: Type,
+ results: Type
+ )
+
+ open fun addFunctionExport(internalName: String, externalName: String): ExportRef
+ open fun addTableExport(internalName: String, externalName: String): ExportRef
+ open fun addMemoryExport(internalName: String, externalName: String): ExportRef
+ open fun addGlobalExport(internalName: String, externalName: String): ExportRef
+ open fun removeExport(externalName: String)
+ open fun getNumExports(): Number
+ open fun getExportByIndex(index: Number): ExportRef
+ open fun setFunctionTable(
+ initial: Number,
+ maximum: Number,
+ funcNames: Array,
+ offset: ExpressionRef = definedExternally
+ )
+
+ open fun getFunctionTable(): `T$26`
+ open fun setMemory(
+ initial: Number,
+ maximum: Number,
+ exportName: String? = definedExternally,
+ segments: Array? = definedExternally,
+ flags: Array? = definedExternally,
+ shared: Boolean = definedExternally
+ )
+
+ open fun getNumMemorySegments(): Number
+ open fun getMemorySegmentInfoByIndex(index: Number): MemorySegmentInfo
+ open fun setStart(start: FunctionRef)
+ open fun getFeatures(): Features
+ open fun setFeatures(features: Features)
+ open fun addCustomSection(name: String, contents: Uint8Array)
+ open fun emitText(): String
+ open fun emitStackIR(optimize: Boolean = definedExternally): String
+ open fun emitAsmjs(): String
+ open fun validate(): Number
+ open fun optimize()
+ open fun optimizeFunction(func: String)
+ open fun optimizeFunction(func: FunctionRef)
+ open fun runPasses(passes: Array)
+ open fun runPassesOnFunction(func: String, passes: Array)
+ open fun runPassesOnFunction(func: FunctionRef, passes: Array)
+ open fun autoDrop()
+ open fun dispose()
+ open fun emitBinary(): Uint8Array
+ open fun emitBinary(sourceMapUrl: String?): `T$27`
+ open fun interpret()
+ open fun addDebugInfoFileName(filename: String): Number
+ open fun getDebugInfoFileName(index: Number): String?
+ open fun setDebugLocation(
+ func: FunctionRef,
+ expr: ExpressionRef,
+ fileIndex: Number,
+ lineNumber: Number,
+ columnNumber: Number
+ )
+
+ open fun copyExpression(expr: ExpressionRef): ExpressionRef
+}
+
+internal external interface MemorySegment {
+ var offset: ExpressionRef
+ var data: Uint8Array
+ var passive: Boolean?
+ get() = definedExternally
+ set(value) = definedExternally
+}
+
+internal external interface TableElement {
+ var offset: ExpressionRef
+ var names: Array
+}
+
+internal external fun wrapModule(ptr: Number): Module
+
+internal external fun getExpressionId(expression: ExpressionRef): Number
+
+internal external fun getExpressionType(expression: ExpressionRef): Type
+
+internal external fun getExpressionInfo(expression: ExpressionRef): ExpressionInfo
+
+internal external interface MemorySegmentInfo {
+ var offset: ExpressionRef
+ var data: Uint8Array
+ var passive: Boolean
+}
+
+internal external interface ExpressionInfo {
+ var id: ExpressionIds
+ var type: Type
+}
+
+internal external interface BlockInfo : ExpressionInfo {
+ var name: String
+ var children: Array
+}
+
+internal external interface IfInfo : ExpressionInfo {
+ var condition: ExpressionRef
+ var ifTrue: ExpressionRef
+ var ifFalse: ExpressionRef
+}
+
+internal external interface LoopInfo : ExpressionInfo {
+ var name: String
+ var body: ExpressionRef
+}
+
+internal external interface BreakInfo : ExpressionInfo {
+ var name: String
+ var condition: ExpressionRef
+ var value: ExpressionRef
+}
+
+internal external interface SwitchInfo : ExpressionInfo {
+ var names: Array
+ var defaultName: String?
+ var condition: ExpressionRef
+ var value: ExpressionRef
+}
+
+internal external interface CallInfo : ExpressionInfo {
+ var isReturn: Boolean
+ var target: String
+ var operands: Array
+}
+
+internal external interface CallIndirectInfo : ExpressionInfo {
+ var isReturn: Boolean
+ var target: ExpressionRef
+ var operands: Array
+}
+
+internal external interface LocalGetInfo : ExpressionInfo {
+ var index: Number
+}
+
+internal external interface LocalSetInfo : ExpressionInfo {
+ var isTee: Boolean
+ var index: Number
+ var value: ExpressionRef
+}
+
+internal external interface GlobalGetInfo : ExpressionInfo {
+ var name: String
+}
+
+internal external interface GlobalSetInfo : ExpressionInfo {
+ var name: String
+ var value: ExpressionRef
+}
+
+internal external interface LoadInfo : ExpressionInfo {
+ var isAtomic: Boolean
+ var isSigned: Boolean
+ var offset: Number
+ var bytes: Number
+ var align: Number
+ var ptr: ExpressionRef
+}
+
+internal external interface StoreInfo : ExpressionInfo {
+ var isAtomic: Boolean
+ var offset: Number
+ var bytes: Number
+ var align: Number
+ var ptr: ExpressionRef
+ var value: ExpressionRef
+}
+
+internal external interface `T$28` {
+ var low: Number
+ var high: Number
+}
+
+internal external interface ConstInfo : ExpressionInfo {
+ var value: dynamic /* Number | `T$28` */
+ get() = definedExternally
+ set(value) = definedExternally
+}
+
+internal external interface UnaryInfo : ExpressionInfo {
+ var op: Operations
+ var value: ExpressionRef
+}
+
+internal external interface BinaryInfo : ExpressionInfo {
+ var op: Operations
+ var left: ExpressionRef
+ var right: ExpressionRef
+}
+
+internal external interface SelectInfo : ExpressionInfo {
+ var ifTrue: ExpressionRef
+ var ifFalse: ExpressionRef
+ var condition: ExpressionRef
+}
+
+internal external interface DropInfo : ExpressionInfo {
+ var value: ExpressionRef
+}
+
+internal external interface ReturnInfo : ExpressionInfo {
+ var value: ExpressionRef
+}
+
+internal external interface NopInfo : ExpressionInfo
+
+internal external interface UnreachableInfo : ExpressionInfo
+
+internal external interface HostInfo : ExpressionInfo {
+ var op: Operations
+ var nameOperand: String?
+ var operands: Array
+}
+
+internal external interface AtomicRMWInfo : ExpressionInfo {
+ var op: Operations
+ var bytes: Number
+ var offset: Number
+ var ptr: ExpressionRef
+ var value: ExpressionRef
+}
+
+internal external interface AtomicCmpxchgInfo : ExpressionInfo {
+ var bytes: Number
+ var offset: Number
+ var ptr: ExpressionRef
+ var expected: ExpressionRef
+ var replacement: ExpressionRef
+}
+
+internal external interface AtomicWaitInfo : ExpressionInfo {
+ var ptr: ExpressionRef
+ var expected: ExpressionRef
+ var timeout: ExpressionRef
+ var expectedType: Type
+}
+
+internal external interface AtomicNotifyInfo : ExpressionInfo {
+ var ptr: ExpressionRef
+ var notifyCount: ExpressionRef
+}
+
+internal external interface AtomicFenceInfo : ExpressionInfo {
+ var order: Number
+}
+
+internal external interface SIMDExtractInfo : ExpressionInfo {
+ var op: Operations
+ var vec: ExpressionRef
+ var index: ExpressionRef
+}
+
+internal external interface SIMDReplaceInfo : ExpressionInfo {
+ var op: Operations
+ var vec: ExpressionRef
+ var index: ExpressionRef
+ var value: ExpressionRef
+}
+
+internal external interface SIMDShuffleInfo : ExpressionInfo {
+ var left: ExpressionRef
+ var right: ExpressionRef
+ var mask: Array
+}
+
+internal external interface SIMDTernaryInfo : ExpressionInfo {
+ var op: Operations
+ var a: ExpressionRef
+ var b: ExpressionRef
+ var c: ExpressionRef
+}
+
+internal external interface SIMDShiftInfo : ExpressionInfo {
+ var op: Operations
+ var vec: ExpressionRef
+ var shift: ExpressionRef
+}
+
+internal external interface SIMDLoadInfo : ExpressionInfo {
+ var op: Operations
+ var offset: Number
+ var align: Number
+ var ptr: ExpressionRef
+}
+
+internal external interface MemoryInitInfo : ExpressionInfo {
+ var segment: Number
+ var dest: ExpressionRef
+ var offset: ExpressionRef
+ var size: ExpressionRef
+}
+
+internal external interface MemoryDropInfo : ExpressionInfo {
+ var segment: Number
+}
+
+internal external interface MemoryCopyInfo : ExpressionInfo {
+ var dest: ExpressionRef
+ var source: ExpressionRef
+ var size: ExpressionRef
+}
+
+internal external interface MemoryFillInfo : ExpressionInfo {
+ var dest: ExpressionRef
+ var value: ExpressionRef
+ var size: ExpressionRef
+}
+
+internal external interface RefNullInfo : ExpressionInfo
+
+internal external interface RefIsNullInfo : ExpressionInfo {
+ var value: ExpressionRef
+}
+
+internal external interface RefFuncInfo : ExpressionInfo {
+ var func: String
+}
+
+internal external interface TryInfo : ExpressionInfo {
+ var body: ExpressionRef
+ var catchBody: ExpressionRef
+}
+
+internal external interface ThrowInfo : ExpressionInfo {
+ var event: String
+ var operands: Array
+}
+
+internal external interface RethrowInfo : ExpressionInfo {
+ var exnref: ExpressionRef
+}
+
+internal external interface BrOnExnInfo : ExpressionInfo {
+ var name: String
+ var event: String
+ var exnref: ExpressionRef
+}
+
+internal external interface PopInfo : ExpressionInfo
+
+internal external interface PushInfo : ExpressionInfo {
+ var value: ExpressionRef
+}
+
+internal external fun getFunctionInfo(func: FunctionRef): FunctionInfo
+
+internal external interface FunctionInfo {
+ var name: String
+ var module: String?
+ var base: String?
+ var params: Type
+ var results: Type
+ var vars: Array
+ var body: ExpressionRef
+}
+
+internal external fun getGlobalInfo(global: GlobalRef): GlobalInfo
+
+internal external interface GlobalInfo {
+ var name: String
+ var module: String?
+ var base: String?
+ var type: Type
+ var mutable: Boolean
+ var init: ExpressionRef
+}
+
+internal external fun getExportInfo(export_: ExportRef): ExportInfo
+
+internal external interface ExportInfo {
+ var kind: ExternalKinds
+ var name: String
+ var value: String
+}
+
+internal external fun getEventInfo(event: EventRef): EventInfo
+
+internal external interface EventInfo {
+ var name: String
+ var module: String?
+ var base: String?
+ var attribute: Number
+ var params: Type
+ var results: Type
+}
+
+internal external fun getSideEffects(expr: ExpressionRef, features: Features): SideEffects
+
+internal external enum class SideEffects {
+ None,
+ Branches,
+ Calls,
+ ReadsLocal,
+ WritesLocal,
+ ReadsGlobal,
+ WritesGlobal,
+ ReadsMemory,
+ WritesMemory,
+ ImplicitTrap,
+ IsAtomic,
+ Throws,
+ Any
+}
+
+internal external fun emitText(expression: ExpressionRef): String
+
+internal external fun emitText(expression: Module): String
+
+internal external fun readBinary(data: Uint8Array): Module
+
+internal external fun parseText(text: String): Module
+
+internal external fun getOptimizeLevel(): Number
+
+internal external fun setOptimizeLevel(level: Number): Number
+
+internal external fun getShrinkLevel(): Number
+
+internal external fun setShrinkLevel(level: Number): Number
+
+internal external fun getDebugInfo(): Boolean
+
+internal external fun setDebugInfo(on: Boolean)
+
+internal external fun getLowMemoryUnused(): Boolean
+
+internal external fun setLowMemoryUnused(on: Boolean)
+
+internal external fun getPassArgument(key: String): String?
+
+internal external fun setPassArgument(key: String, value: String?)
+
+internal external fun clearPassArguments()
+
+internal external fun getAlwaysInlineMaxSize(): Number
+
+internal external fun setAlwaysInlineMaxSize(size: Number)
+
+internal external fun getFlexibleInlineMaxSize(): Number
+
+internal external fun setFlexibleInlineMaxSize(size: Number)
+
+internal external fun getOneCallerInlineMaxSize(): Number
+
+internal external fun setOneCallerInlineMaxSize(size: Number)
+
+internal external fun exit(status: Number)
+
+internal open external class Relooper(module: Module) {
+ open fun addBlock(expression: ExpressionRef): RelooperBlockRef
+ open fun addBranch(from: RelooperBlockRef, to: RelooperBlockRef, condition: ExpressionRef, code: ExpressionRef)
+ open fun addBlockWithSwitch(code: ExpressionRef, condition: ExpressionRef): RelooperBlockRef
+ open fun addBranchForSwitch(
+ from: RelooperBlockRef,
+ to: RelooperBlockRef,
+ indexes: Array,
+ code: ExpressionRef
+ )
+
+ open fun renderAndDispose(entry: RelooperBlockRef, labelHelper: Number): ExpressionRef
+}
diff --git a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/binaryen/index.binaryen.typealiases.kt b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/binaryen/index.binaryen.typealiases.kt
new file mode 100644
index 000000000..523b13b40
--- /dev/null
+++ b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/binaryen/index.binaryen.typealiases.kt
@@ -0,0 +1,16 @@
+/*
+ * 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.
+ */
+
+@file:Suppress("PackageDirectoryMismatch", "NO_EXPLICIT_VISIBILITY_IN_API_MODE_WARNING", "KDocMissingDocumentation")
+
+package space.kscience.kmath.internal.binaryen
+
+internal typealias Type = Number
+internal typealias ExpressionRef = Number
+internal typealias FunctionRef = Number
+internal typealias GlobalRef = Number
+internal typealias ExportRef = Number
+internal typealias EventRef = Number
+internal typealias RelooperBlockRef = Number
diff --git a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/estree/internal/emitter/emitter.kt b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/emitter/emitter.kt
similarity index 91%
rename from kmath-ast/src/jsMain/kotlin/space/kscience/kmath/estree/internal/emitter/emitter.kt
rename to kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/emitter/emitter.kt
index 7707f53a2..1f7b09af8 100644
--- a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/estree/internal/emitter/emitter.kt
+++ b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/emitter/emitter.kt
@@ -3,7 +3,7 @@
* 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.estree.internal.emitter
+package space.kscience.kmath.internal.emitter
internal open external class Emitter {
constructor(obj: Any)
diff --git a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/estree/internal/estree/estree.extensions.kt b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/estree/estree.extensions.kt
similarity index 97%
rename from kmath-ast/src/jsMain/kotlin/space/kscience/kmath/estree/internal/estree/estree.extensions.kt
rename to kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/estree/estree.extensions.kt
index 9ba11e085..3aa31f921 100644
--- a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/estree/internal/estree/estree.extensions.kt
+++ b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/estree/estree.extensions.kt
@@ -3,7 +3,7 @@
* 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.estree.internal.estree
+package space.kscience.kmath.internal.estree
internal fun Program(sourceType: String, vararg body: dynamic) = object : Program {
override var type = "Program"
diff --git a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/estree/internal/estree/estree.kt b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/estree/estree.kt
similarity index 99%
rename from kmath-ast/src/jsMain/kotlin/space/kscience/kmath/estree/internal/estree/estree.kt
rename to kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/estree/estree.kt
index a0e42db5d..e5254013e 100644
--- a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/estree/internal/estree/estree.kt
+++ b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/estree/estree.kt
@@ -3,7 +3,7 @@
* 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.estree.internal.estree
+package space.kscience.kmath.internal.estree
import kotlin.js.RegExp
diff --git a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/estree/internal/stream/stream.kt b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/stream/stream.kt
similarity index 70%
rename from kmath-ast/src/jsMain/kotlin/space/kscience/kmath/estree/internal/stream/stream.kt
rename to kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/stream/stream.kt
index 4bdeeea0b..52be5530f 100644
--- a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/estree/internal/stream/stream.kt
+++ b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/stream/stream.kt
@@ -3,9 +3,9 @@
* 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.estree.internal.stream
+package space.kscience.kmath.internal.stream
-import space.kscience.kmath.estree.internal.emitter.Emitter
+import space.kscience.kmath.internal.emitter.Emitter
internal open external class Stream : Emitter {
open fun pipe(dest: Any, options: Any): Any
diff --git a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/estree/internal/tsstdlib/lib.es2015.iterable.kt b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/tsstdlib/lib.es2015.iterable.kt
similarity index 94%
rename from kmath-ast/src/jsMain/kotlin/space/kscience/kmath/estree/internal/tsstdlib/lib.es2015.iterable.kt
rename to kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/tsstdlib/lib.es2015.iterable.kt
index a3c721ed4..9c012e3a3 100644
--- a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/estree/internal/tsstdlib/lib.es2015.iterable.kt
+++ b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/tsstdlib/lib.es2015.iterable.kt
@@ -3,7 +3,7 @@
* 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.estree.internal.tsstdlib
+package space.kscience.kmath.internal.tsstdlib
internal external interface IteratorYieldResult {
var done: Boolean?
diff --git a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/estree/internal/tsstdlib/lib.es5.kt b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/tsstdlib/lib.es5.kt
similarity index 88%
rename from kmath-ast/src/jsMain/kotlin/space/kscience/kmath/estree/internal/tsstdlib/lib.es5.kt
rename to kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/tsstdlib/lib.es5.kt
index d2413b3e3..0cd395f2c 100644
--- a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/estree/internal/tsstdlib/lib.es5.kt
+++ b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/tsstdlib/lib.es5.kt
@@ -5,7 +5,7 @@
@file:Suppress("UNUSED_TYPEALIAS_PARAMETER", "DEPRECATION")
-package space.kscience.kmath.estree.internal.tsstdlib
+package space.kscience.kmath.internal.tsstdlib
import kotlin.js.RegExp
@@ -38,6 +38,8 @@ internal external interface RegExpConstructor {
var lastMatch: String
}
+internal typealias Record = Any
+
internal external interface ConcatArray {
var length: Number
@@ -85,3 +87,10 @@ internal external interface ArrayLike {
}
internal typealias Extract = Any
+
+internal external interface PromiseLike {
+ fun then(
+ onfulfilled: ((value: T) -> Any?)? = definedExternally,
+ onrejected: ((reason: Any) -> Any?)? = definedExternally
+ ): PromiseLike
+}
diff --git a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/webassembly/lib.dom.WebAssembly.module_dukat.kt b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/webassembly/lib.dom.WebAssembly.module_dukat.kt
new file mode 100644
index 000000000..3754c3eff
--- /dev/null
+++ b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/webassembly/lib.dom.WebAssembly.module_dukat.kt
@@ -0,0 +1,236 @@
+/*
+ * 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.
+ */
+
+@file:JsQualifier("WebAssembly")
+
+@file:Suppress(
+ "INTERFACE_WITH_SUPERCLASS",
+ "OVERRIDING_FINAL_MEMBER",
+ "RETURN_TYPE_MISMATCH_ON_OVERRIDE",
+ "NO_EXPLICIT_VISIBILITY_IN_API_MODE_WARNING",
+ "ClassName",
+)
+
+package space.kscience.kmath.internal.webassembly
+
+import space.kscience.kmath.internal.tsstdlib.PromiseLike
+import org.khronos.webgl.ArrayBuffer
+import org.khronos.webgl.ArrayBufferView
+import org.khronos.webgl.Uint8Array
+import org.w3c.fetch.Response
+import kotlin.js.Promise
+
+@Suppress("NESTED_CLASS_IN_EXTERNAL_INTERFACE")
+internal external interface CompileError {
+ companion object {
+ var prototype: CompileError
+ }
+}
+
+@Suppress("NESTED_CLASS_IN_EXTERNAL_INTERFACE")
+internal external interface Global {
+ var value: Any
+ fun valueOf(): Any
+
+ companion object {
+ var prototype: Global
+ }
+}
+
+@Suppress("NESTED_CLASS_IN_EXTERNAL_INTERFACE")
+@JsName("Instance")
+internal external interface Instance1 {
+ var exports: Exports
+
+ companion object {
+ var prototype: Instance
+ }
+}
+
+@Suppress("NESTED_CLASS_IN_EXTERNAL_INTERFACE")
+internal external interface LinkError {
+ companion object {
+ var prototype: LinkError
+ }
+}
+
+@Suppress("NESTED_CLASS_IN_EXTERNAL_INTERFACE")
+internal external interface Memory {
+ var buffer: ArrayBuffer
+ fun grow(delta: Number): Number
+
+ companion object {
+ var prototype: Memory
+ }
+}
+
+@Suppress("NESTED_CLASS_IN_EXTERNAL_INTERFACE")
+@JsName("Module")
+internal external interface Module1 {
+ companion object {
+ var prototype: Module
+ fun customSections(moduleObject: Module, sectionName: String): Array
+ fun exports(moduleObject: Module): Array
+ fun imports(moduleObject: Module): Array
+ }
+}
+
+@Suppress("NESTED_CLASS_IN_EXTERNAL_INTERFACE")
+internal external interface RuntimeError {
+ companion object {
+ var prototype: RuntimeError
+ }
+}
+
+@Suppress("NESTED_CLASS_IN_EXTERNAL_INTERFACE")
+internal external interface Table {
+ var length: Number
+ fun get(index: Number): Function<*>?
+ fun grow(delta: Number): Number
+ fun set(index: Number, value: Function<*>?)
+
+ companion object {
+ var prototype: Table
+ }
+}
+
+internal external interface GlobalDescriptor {
+ var mutable: Boolean?
+ get() = definedExternally
+ set(value) = definedExternally
+ var value: String /* "f32" | "f64" | "i32" | "i64" */
+}
+
+internal external interface MemoryDescriptor {
+ var initial: Number
+ var maximum: Number?
+ get() = definedExternally
+ set(value) = definedExternally
+}
+
+internal external interface ModuleExportDescriptor {
+ var kind: String /* "function" | "global" | "memory" | "table" */
+ var name: String
+}
+
+internal external interface ModuleImportDescriptor {
+ var kind: String /* "function" | "global" | "memory" | "table" */
+ var module: String
+ var name: String
+}
+
+internal external interface TableDescriptor {
+ var element: String /* "anyfunc" */
+ var initial: Number
+ var maximum: Number?
+ get() = definedExternally
+ set(value) = definedExternally
+}
+
+internal external interface WebAssemblyInstantiatedSource {
+ var instance: Instance
+ var module: Module
+}
+
+internal external fun compile(bytes: ArrayBufferView): Promise
+
+internal external fun compile(bytes: ArrayBuffer): Promise
+
+internal external fun compileStreaming(source: Response): Promise
+
+internal external fun compileStreaming(source: Promise): Promise
+
+internal external fun instantiate(
+ bytes: ArrayBufferView,
+ importObject: Imports = definedExternally,
+): Promise
+
+internal external fun instantiate(bytes: ArrayBufferView): Promise
+
+internal external fun instantiate(
+ bytes: ArrayBuffer,
+ importObject: Imports = definedExternally,
+): dynamic /* Promise | Promise */
+
+internal external fun instantiate(bytes: ArrayBuffer): dynamic /* Promise | Promise */
+
+internal external fun instantiate(moduleObject: Module, importObject: Imports = definedExternally): Promise
+
+internal external fun instantiate(moduleObject: Module): Promise
+
+internal external fun instantiateStreaming(
+ response: Response,
+ importObject: Imports = definedExternally,
+): Promise
+
+internal external fun instantiateStreaming(response: Response): Promise
+
+internal external fun instantiateStreaming(
+ response: PromiseLike,
+ importObject: Imports = definedExternally,
+): Promise
+
+internal external fun instantiateStreaming(response: PromiseLike): Promise
+
+internal external fun validate(bytes: ArrayBufferView): Boolean
+
+internal external fun validate(bytes: ArrayBuffer): Boolean
+
+internal external interface `T$0` {
+ var name: String
+ var kind: String
+}
+
+internal external interface `T$1` {
+ var module: String
+ var name: String
+ var kind: String
+}
+
+internal open external class Module {
+ constructor(bufferSource: ArrayBuffer)
+ constructor(bufferSource: Uint8Array)
+
+ companion object {
+ fun customSections(module: Module, sectionName: String): Array
+ fun exports(module: Module): Array<`T$0`>
+ fun imports(module: Module): Array<`T$1`>
+ }
+}
+
+@JsName("Instance")
+internal open external class Instance(module: Module, importObject: Any = definedExternally) {
+ open var exports: Any
+}
+
+@JsName("Memory")
+internal open external class Memory1(memoryDescriptor: MemoryDescriptor) {
+ open var buffer: ArrayBuffer
+ open fun grow(numPages: Number): Number
+}
+
+@JsName("Table")
+internal open external class Table1(tableDescriptor: TableDescriptor) {
+ open var length: Number
+ open fun get(index: Number): Function<*>
+ open fun grow(numElements: Number): Number
+ open fun set(index: Number, value: Function<*>)
+}
+
+internal external fun compile(bufferSource: Uint8Array): Promise
+
+internal external interface ResultObject {
+ var module: Module
+ var instance: Instance
+}
+
+internal external fun instantiate(
+ bufferSource: Uint8Array,
+ importObject: Any = definedExternally,
+): Promise
+
+internal external fun instantiate(bufferSource: Uint8Array): Promise
+
+internal external fun validate(bufferSource: Uint8Array): Boolean
diff --git a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/webassembly/nonDeclarations.WebAssembly.kt b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/webassembly/nonDeclarations.WebAssembly.kt
new file mode 100644
index 000000000..c5023c384
--- /dev/null
+++ b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/webassembly/nonDeclarations.WebAssembly.kt
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ */
+
+@file:Suppress(
+ "INTERFACE_WITH_SUPERCLASS",
+ "OVERRIDING_FINAL_MEMBER",
+ "RETURN_TYPE_MISMATCH_ON_OVERRIDE",
+ "CONFLICTING_OVERLOADS",
+ "NO_EXPLICIT_VISIBILITY_IN_API_MODE_WARNING",
+)
+
+package space.kscience.kmath.internal.webassembly
+
+import space.kscience.kmath.internal.tsstdlib.Record
+
+internal typealias Exports = Record | Global | Memory | Table */>
+
+internal typealias ModuleImports = Record | Global | Memory | Table | Number */>
+
+internal typealias Imports = Record
+
+internal typealias CompileError1 = Error
+
+internal typealias LinkError1 = Error
+
+internal typealias RuntimeError1 = Error
diff --git a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/wasm/internal/WasmBuilder.kt b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/wasm/internal/WasmBuilder.kt
new file mode 100644
index 000000000..8fd3c9fb9
--- /dev/null
+++ b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/wasm/internal/WasmBuilder.kt
@@ -0,0 +1,160 @@
+/*
+ * Copyright 2018-2021 KMath contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package space.kscience.kmath.wasm.internal
+
+import space.kscience.kmath.expressions.Expression
+import space.kscience.kmath.expressions.MST
+import space.kscience.kmath.expressions.MST.*
+import space.kscience.kmath.internal.binaryen.*
+import space.kscience.kmath.internal.webassembly.Instance
+import space.kscience.kmath.misc.StringSymbol
+import space.kscience.kmath.operations.*
+import space.kscience.kmath.internal.binaryen.Module as BinaryenModule
+import space.kscience.kmath.internal.webassembly.Module as WasmModule
+
+private val spreader = eval("(obj, args) => obj(...args)")
+
+@Suppress("UnsafeCastFromDynamic")
+internal sealed class WasmBuilder(
+ val binaryenType: Type,
+ val algebra: Algebra,
+ val target: MST,
+) where T : Number {
+ val keys: MutableList = mutableListOf()
+ lateinit var ctx: BinaryenModule
+
+ open fun visitSymbolic(mst: Symbolic): ExpressionRef {
+ try {
+ algebra.bindSymbol(mst.value)
+ } catch (ignored: Throwable) {
+ null
+ }?.let { return visitNumeric(Numeric(it)) }
+
+ var idx = keys.indexOf(mst.value)
+
+ if (idx == -1) {
+ keys += mst.value
+ idx = keys.lastIndex
+ }
+
+ return ctx.local.get(idx, binaryenType)
+ }
+
+ abstract fun visitNumeric(mst: Numeric): ExpressionRef
+
+ open fun visitUnary(mst: Unary): ExpressionRef =
+ error("Unary operation ${mst.operation} not defined in $this")
+
+ open fun visitBinary(mst: Binary): ExpressionRef =
+ error("Binary operation ${mst.operation} not defined in $this")
+
+ open fun createModule(): BinaryenModule = js("new \$module\$binaryen.Module()")
+
+ fun visit(mst: MST): ExpressionRef = when (mst) {
+ is Symbolic -> visitSymbolic(mst)
+ is Numeric -> visitNumeric(mst)
+
+ is Unary -> when {
+ algebra is NumericAlgebra && mst.value is Numeric -> visitNumeric(
+ Numeric(algebra.unaryOperationFunction(mst.operation)(algebra.number((mst.value as Numeric).value))))
+
+ else -> visitUnary(mst)
+ }
+
+ is Binary -> when {
+ algebra is NumericAlgebra && mst.left is Numeric && mst.right is Numeric -> visitNumeric(Numeric(
+ algebra.binaryOperationFunction(mst.operation)
+ .invoke(algebra.number((mst.left as Numeric).value), algebra.number((mst.right as Numeric).value))
+ ))
+
+ else -> visitBinary(mst)
+ }
+ }
+
+ val instance by lazy {
+ val c = WasmModule(with(createModule()) {
+ ctx = this
+ val expr = visit(target)
+
+ addFunction(
+ "executable",
+ createType(Array(keys.size) { binaryenType }),
+ binaryenType,
+ arrayOf(),
+ expr
+ )
+
+ setOptimizeLevel(3)
+ optimizeFunction("executable")
+ addFunctionExport("executable", "executable")
+ val res = emitBinary()
+ dispose()
+ res
+ })
+
+ val i = Instance(c, js("{}") as Any)
+ val symbols = keys.map(::StringSymbol)
+ keys.clear()
+
+ Expression { args ->
+ val params = symbols.map(args::getValue).toTypedArray()
+ spreader(i.exports.asDynamic().executable, params) as T
+ }
+ }
+}
+
+internal class DoubleWasmBuilder(target: MST) : WasmBuilder(f64, DoubleField, target) {
+ override fun createModule(): BinaryenModule = readBinary(f64StandardFunctions)
+
+ override fun visitNumeric(mst: Numeric): ExpressionRef = ctx.f64.const(mst.value)
+
+ override fun visitUnary(mst: Unary): ExpressionRef = when (mst.operation) {
+ GroupOperations.MINUS_OPERATION -> ctx.f64.neg(visit(mst.value))
+ GroupOperations.PLUS_OPERATION -> visit(mst.value)
+ PowerOperations.SQRT_OPERATION -> ctx.f64.sqrt(visit(mst.value))
+ TrigonometricOperations.SIN_OPERATION -> ctx.call("sin", arrayOf(visit(mst.value)), f64)
+ TrigonometricOperations.COS_OPERATION -> ctx.call("cos", arrayOf(visit(mst.value)), f64)
+ TrigonometricOperations.TAN_OPERATION -> ctx.call("tan", arrayOf(visit(mst.value)), f64)
+ TrigonometricOperations.ASIN_OPERATION -> ctx.call("asin", arrayOf(visit(mst.value)), f64)
+ TrigonometricOperations.ACOS_OPERATION -> ctx.call("acos", arrayOf(visit(mst.value)), f64)
+ TrigonometricOperations.ATAN_OPERATION -> ctx.call("atan", arrayOf(visit(mst.value)), f64)
+ ExponentialOperations.SINH_OPERATION -> ctx.call("sinh", arrayOf(visit(mst.value)), f64)
+ ExponentialOperations.COSH_OPERATION -> ctx.call("cosh", arrayOf(visit(mst.value)), f64)
+ ExponentialOperations.TANH_OPERATION -> ctx.call("tanh", arrayOf(visit(mst.value)), f64)
+ ExponentialOperations.ASINH_OPERATION -> ctx.call("asinh", arrayOf(visit(mst.value)), f64)
+ ExponentialOperations.ACOSH_OPERATION -> ctx.call("acosh", arrayOf(visit(mst.value)), f64)
+ ExponentialOperations.ATANH_OPERATION -> ctx.call("atanh", arrayOf(visit(mst.value)), f64)
+ ExponentialOperations.EXP_OPERATION -> ctx.call("exp", arrayOf(visit(mst.value)), f64)
+ ExponentialOperations.LN_OPERATION -> ctx.call("log", arrayOf(visit(mst.value)), f64)
+ else -> super.visitUnary(mst)
+ }
+
+ override fun visitBinary(mst: Binary): ExpressionRef = when (mst.operation) {
+ GroupOperations.PLUS_OPERATION -> ctx.f64.add(visit(mst.left), visit(mst.right))
+ GroupOperations.MINUS_OPERATION -> ctx.f64.sub(visit(mst.left), visit(mst.right))
+ RingOperations.TIMES_OPERATION -> ctx.f64.mul(visit(mst.left), visit(mst.right))
+ FieldOperations.DIV_OPERATION -> ctx.f64.div(visit(mst.left), visit(mst.right))
+ PowerOperations.POW_OPERATION -> ctx.call("pow", arrayOf(visit(mst.left), visit(mst.right)), f64)
+ else -> super.visitBinary(mst)
+ }
+}
+
+internal class IntWasmBuilder(target: MST) : WasmBuilder(i32, IntRing, target) {
+ override fun visitNumeric(mst: Numeric): ExpressionRef = ctx.i32.const(mst.value)
+
+ override fun visitUnary(mst: Unary): ExpressionRef = when (mst.operation) {
+ GroupOperations.MINUS_OPERATION -> ctx.i32.sub(ctx.i32.const(0), visit(mst.value))
+ GroupOperations.PLUS_OPERATION -> visit(mst.value)
+ else -> super.visitUnary(mst)
+ }
+
+ override fun visitBinary(mst: Binary): ExpressionRef = when (mst.operation) {
+ GroupOperations.PLUS_OPERATION -> ctx.i32.add(visit(mst.left), visit(mst.right))
+ GroupOperations.MINUS_OPERATION -> ctx.i32.sub(visit(mst.left), visit(mst.right))
+ RingOperations.TIMES_OPERATION -> ctx.i32.mul(visit(mst.left), visit(mst.right))
+ else -> super.visitBinary(mst)
+ }
+}
diff --git a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/wasm/internal/f64StandardFunctions.kt b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/wasm/internal/f64StandardFunctions.kt
new file mode 100644
index 000000000..21a88b5d0
--- /dev/null
+++ b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/wasm/internal/f64StandardFunctions.kt
@@ -0,0 +1,13 @@
+/*
+ * Copyright 2018-2021 KMath contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package space.kscience.kmath.wasm.internal
+
+import space.kscience.kmath.internal.base64.toUint8Array
+
+internal val f64StandardFunctions by lazy { toUint8Array(B) }
+
+private const val B =
+ "AGFzbQEAAAABMghgAABgAXwBfGACfHwBfGAFf39/f38Bf2ACfH8Bf2ADfHx/AXxgAnx/AXxgA39/fwF/AxsaAAEBAQEBAQIDBAUBAQEBAQEBAgYBAQUBAQcEBQFwAQEBBQMBAAIGFQN/AUGgnwQLfwBBoJ8EC38AQaAfCwclAwZtZW1vcnkCAAtfX2hlYXBfYmFzZQMBCl9fZGF0YV9lbmQDAgrpaxoCAAvPBQMBfgF/AnwCQAJAAkAgAL0iAUIgiKdB/////wdxIgJBgIDA/wNJDQAgAkGAgMCAfGogAadyRQ0BRAAAAAAAAAAAIAAgAKGjDwsCQAJAIAJB/////gNLDQBEGC1EVPsh+T8hAyACQYGAgOMDSQ0BRAdcFDMmppE8IAAgAKIiAyADIAMgAyADIANECff9DeE9Aj+iRIiyAXXg70k/oKJEO49otSiCpL+gokRVRIgOVcHJP6CiRH1v6wMS1tS/oKJEVVVVVVVVxT+goiADIAMgAyADRIKSLrHFuLM/okRZAY0bbAbmv6CiRMiKWZzlKgBAoKJESy2KHCc6A8CgokQAAAAAAADwP6CjIACioSAAoUQYLURU+yH5P6APCyABQn9XDQJEAAAAAAAA8D8gAKFEAAAAAAAA4D+iIgAgAJ8iBL1CgICAgHCDvyIDIAOioSAEIAOgoyAEIAAgACAAIAAgACAARAn3/Q3hPQI/okSIsgF14O9JP6CiRDuPaLUogqS/oKJEVUSIDlXByT+gokR9b+sDEtbUv6CiRFVVVVVVVcU/oKIgACAAIAAgAESCki6xxbizP6JEWQGNG2wG5r+gokTIilmc5SoAQKCiREstihwnOgPAoKJEAAAAAAAA8D+go6KgIAOgIgAgAKAhAwsgAw8LRBgtRFT7IQlARAAAAAAAAAAAIAFCAFMbDwtEGC1EVPsh+T8gAEQAAAAAAADwP6BEAAAAAAAA4D+iIgCfIgMgAyAAIAAgACAAIAAgAEQJ9/0N4T0CP6JEiLIBdeDvST+gokQ7j2i1KIKkv6CiRFVEiA5Vwck/oKJEfW/rAxLW1L+gokRVVVVVVVXFP6CiIAAgACAAIABEgpIuscW4sz+iRFkBjRtsBua/oKJEyIpZnOUqAECgokRLLYocJzoDwKCiRAAAAAAAAPA/oKOiRAdcFDMmppG8oKChIgAgAKALdwEBfwJAIAC9QjSIp0H/D3EiAUH/B0sNACAARAAAAAAAAPC/oCIAIAAgAKIgACAAoKCfoBARDwsCQCABQZgISw0AIAAgAKBEAAAAAAAA8L8gACAAokQAAAAAAADwv6CfIACgo6AQEA8LIAAQEETvOfr+Qi7mP6AL0gQDAX4BfwN8AkACQAJAAkACQCAAvSIBQiCIp0H/////B3EiAkGAgMD/A0kNACACQYCAwIB8aiABp3JFDQFEAAAAAAAAAAAgACAAoaMPCwJAIAJB/////gNLDQAgAkGAgEBqQYCAgPIDTw0CIAAPC0QAAAAAAADwPyAAmaFEAAAAAAAA4D+iIgAgACAAIAAgACAARAn3/Q3hPQI/okSIsgF14O9JP6CiRDuPaLUogqS/oKJEVUSIDlXByT+gokR9b+sDEtbUv6CiRFVVVVVVVcU/oKIgACAAIAAgAESCki6xxbizP6JEWQGNG2wG5r+gokTIilmc5SoAQKCiREstihwnOgPAoKJEAAAAAAAA8D+goyEDIACfIQQgAkGz5rz/A0kNAkQYLURU+yH5PyAEIAQgA6KgIgAgAKBEB1wUMyamkbygoSEADAMLIABEGC1EVPsh+T+iRAAAAAAAAHA4oA8LIAAgAKIiBCAEIAQgBCAEIARECff9DeE9Aj+iRIiyAXXg70k/oKJEO49otSiCpL+gokRVRIgOVcHJP6CiRH1v6wMS1tS/oKJEVVVVVVVVxT+goiAEIAQgBCAERIKSLrHFuLM/okRZAY0bbAbmv6CiRMiKWZzlKgBAoKJESy2KHCc6A8CgokQAAAAAAADwP6CjIACiIACgDwtEGC1EVPsh6T8gBL1CgICAgHCDvyIFIAWgoSAEIASgIAOiRAdcFDMmppE8IAAgBSAFoqEgBCAFoKMiACAAoKGhoUQYLURU+yHpP6AhAAsgAJogACABQgBTGwvbAQQBfwF+AX8BfCMAQRBrIgEkACAAvSICQv///////////wCDvyEAAkACQCACQjSIp0H/D3EiA0GZCEkNACAAEBBE7zn6/kIu5j+gIQAMAQsCQCADQYAISQ0AIAAgAKBEAAAAAAAA8D8gACAAokQAAAAAAADwP6CfIACgo6AQECEADAELAkAgA0HlB0kNACAAIACiIgQgBEQAAAAAAADwP6CfRAAAAAAAAPA/oKMgAKAQESEADAELIAEgAEQAAAAAAABwR6A5AwgLIAFBEGokACAAmiAAIAJCAFMbC6gEBAF/AX4DfwJ8IwBBEGshASAAvSICQj+IpyEDAkACQAJAIAJCIIinQf////8HcSIEQYCAwKAESQ0AIAJC////////////AINCgICAgICAgPj/AFYNAUQYLURU+yH5v0QYLURU+yH5PyADGw8LAkACQCAEQf//7/4DSw0AQX8hBSAEQf////EDSw0BIARB//8/Sw0CIAEgALY4AgwgAA8LIACZIQACQAJAAkAgBEH//8v/A0sNACAEQf//l/8DSw0BIAAgAKBEAAAAAAAA8L+gIABEAAAAAAAAAECgoyEAQQAhBQwDCyAEQf//jYAESw0BIABEAAAAAAAA+L+gIABEAAAAAAAA+D+iRAAAAAAAAPA/oKMhAEECIQUMAgsgAEQAAAAAAADwv6AgAEQAAAAAAADwP6CjIQBBASEFDAELRAAAAAAAAPC/IACjIQBBAyEFCyAAIAAgAKIiBiAGoiIHIAcgByAHIAdEL2xqLES0or+iRJr93lIt3q2/oKJEbZp0r/Kws7+gokRxFiP+xnG8v6CiRMTrmJmZmcm/oKIgBiAHIAcgByAHIAdEEdoi4zqtkD+iROsNdiRLe6k/oKJEUT3QoGYNsT+gokRuIEzFzUW3P6CiRP+DAJIkScI/oKJEDVVVVVVV1T+goqCiIQcgBUF/TA0BIAVBA3QiBEGACGorAwAgByAEQaAIaisDAKEgAKGhIgCaIAAgAxshAAsgAA8LIAAgB6ELtgEEAX8BfgF/AXwjAEEQayIBJAAgAL0iAkL///////////8Ag78hAAJAAkACQCACQjSIp0H/D3EiA0H9B0sNACADQd4HSw0BIAMNAiABIAC2OAIMDAILIABEAAAAAAAA8D8gAKGjIgAgAKAQEUQAAAAAAADgP6IhAAwBCyAAIACgIgQgBCAAokQAAAAAAADwPyAAoaOgEBFEAAAAAAAA4D+iIQALIAFBEGokACAAmiAAIAJCAFMbC5IBAQN8RAAAAAAAAPA/IAAgAKIiAkQAAAAAAADgP6IiA6EiBEQAAAAAAADwPyAEoSADoSACIAIgAiACRJAVyxmgAfo+okR3UcEWbMFWv6CiRExVVVVVVaU/oKIgAiACoiIDIAOiIAIgAkTUOIi+6fqovaJExLG0vZ7uIT6gokStUpyAT36SvqCioKIgACABoqGgoAuEFgYHfwF8Cn8BfAN/AnwjAEGwBGsiBSQAIAIgAkF9akEYbSIGQQAgBkEAShsiB0FobGohCAJAIARBAnRBwAhqKAIAIgkgA0F/aiICakEASA0AIAkgA2ohCiAHIAJrIQIgB0EBaiADa0ECdEHQCGohCyAFQcACaiEGA0ACQAJAIAJBAEgNACALKAIAtyEMDAELRAAAAAAAAAAAIQwLIAYgDDkDACAGQQhqIQYgC0EEaiELIAJBAWohAiAKQX9qIgoNAAsLIAhBaGohDQJAAkAgA0EBSA0AIAVBwAJqIANBA3RqQXhqIQ5BACEKA0BEAAAAAAAAAAAhDCAAIQIgAyELIA4hBgNAIAwgAisDACAGKwMAoqAhDCACQQhqIQIgBkF4aiEGIAtBf2oiCw0ACyAFIApBA3RqIAw5AwAgDkEIaiEOIAogCUghAiAKQQFqIQogAg0ADAILCyAFQQAgCUEAIAlBAEobQQN0QQhqEBkaC0EXIA1rIQ9BGCANayEQIAVB4ANqIAlBAnRqQXxqIREgBUHgA2pBfGohEiAFQXhqIRMgBUEIciEUIAkhBgN/IAUgBkEDdCIVaisDACEMAkAgBkEBSCIWDQAgEyAVaiECIAVB4ANqIQsgBiEKA0ACQAJAIAxEAAAAAAAAcD6iIheZRAAAAAAAAOBBYw0AQYCAgIB4IQ4MAQsgF6ohDgsCQAJAIAwgDrciF0QAAAAAAABwwaKgIgyZRAAAAAAAAOBBYw0AQYCAgIB4IQ4MAQsgDKohDgsgCyAONgIAIAtBBGohCyACKwMAIBegIQwgAkF4aiECIApBf2oiCg0ACwsCQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQCAMIA0QEyIMIAxEAAAAAAAAwD+inEQAAAAAAAAgwKKgIgyZRAAAAAAAAOBBYw0AQYCAgIB4IRggDEGAgICAeLehIQwgDUEBSCIZRQ0BDAILIAwgDKoiGLehIQwgDUEBSCIZDQELIAVB4ANqIAZBAnRqQXxqIgIgAigCACICIAIgEHUiAiAQdGsiCzYCACACIBhqIRggCyAPdSIaQQFIDQIMAQsCQCANRQ0AQQIhGiAMRAAAAAAAAOA/ZkEBc0UNAUEAIRogDEQAAAAAAAAAAGENAwwECyAFQeADaiAGQQJ0akF8aigCAEEXdSIaQQFIDQELAkACQCAWDQBBACEWIAVB4ANqIQIgBiEOA0AgAigCACELQf///wchCgJAAkAgFg0AIAtFDQFBASEWQYCAgAghCgsgAiAKIAtrNgIAIAJBBGohAiAOQX9qIg4NAQwDC0EAIRYgAkEEaiECIA5Bf2oiDg0ADAILC0EAIRYLAkACQAJAIBkNACANQQJGDQEgDUEBRw0AIAVB4ANqIAZBAnRqQXxqIgIgAigCAEH///8DcTYCAAsgGEEBaiEYIBpBAkcNAgwBCyAFQeADaiAGQQJ0akF8aiICIAIoAgBB////AXE2AgAgGEEBaiEYIBpBAkcNAQtEAAAAAAAA8D8gDKEhDEECIRogFkUNACAMRAAAAAAAAPA/IA0QE6EiDEQAAAAAAAAAAGENAQwCCyAMRAAAAAAAAAAAYg0BCwJAIAYgCUwNACASIAZBAnRqIQJBACELIAYhCgNAIAIoAgAgC3IhCyACQXxqIQIgCkF/aiIKIAlKDQALIAsNAgsgESECIAYhDgNAIA5BAWohDiACKAIAIQsgAkF8aiECIAtFDQALIAZBAWohAgJAIANBAUgNACAFQcACaiADIAZqQQN0aiEWA0AgBUHAAmogBiADakEDdGogAiIKIAdqQQJ0QdAIaigCALc5AwBEAAAAAAAAAAAhDCAAIQIgFiEGIAMhCwNAIAwgAisDACAGKwMAoqAhDCACQQhqIQIgBkF4aiEGIAtBf2oiCw0ACyAFIApBA3RqIAw5AwAgFkEIaiEWIApBAWohAiAKIQYgCiAOSA0ADAsLCyAUIBVqQQAgDiACIA4gAkobIAZrQQN0EBkaIAcgBmpBAnRB1AhqIQIgBUHAAmogAyAGakEDdGohCwNAIAsgAigCALc5AwAgAkEEaiECIAtBCGohCyAGQQFqIgYgDkgNAAsgDiEGDAoLAkAgDEEAIA1rEBMiDEQAAAAAAABwQWZBAXNFDQAgDJlEAAAAAAAA4EFjDQJBgICAgHghAgwDCyAGQQJ0IQsgDEQAAAAAAABwPqIiF5lEAAAAAAAA4EFjDQNBgICAgHghAgwECyAFQeADaiAGQQJ0akF8aiECIA0hCANAIAZBf2ohBiAIQWhqIQggAigCACELIAJBfGohAiALRQ0AC0EAIQ4gBkEATg0FDAYLIAyqIQILIA0hCAwCCyAXqiECCyAFQeADaiALaiELAkACQCAMIAK3RAAAAAAAAHDBoqAiDJlEAAAAAAAA4EFjDQBBgICAgHghCgwBCyAMqiEKCyALIAo2AgAgBkEBaiEGCyAFQeADaiAGQQJ0aiACNgIAQQAhDiAGQQBIDQELIAZBAWohCkQAAAAAAADwPyAIEBMhDCAFQeADaiAGQQJ0aiECIAUgBkEDdGohCwNAIAsgDCACKAIAt6I5AwAgAkF8aiECIAtBeGohCyAMRAAAAAAAAHA+oiEMIApBf2oiCiAOSg0ACyAGQQBIDQAgBSAGQQN0aiEOIAYhAgNAIAYgAiIDayEWRAAAAAAAAAAAIQxBACECQQAhCwJAA0AgDCACQaAeaisDACAOIAJqKwMAoqAhDCALIAlODQEgAkEIaiECIAsgFkkhCiALQQFqIQsgCg0ACwsgBUGgAWogFkEDdGogDDkDACAOQXhqIQ4gA0F/aiECIANBAEoNAAsLAkACQAJAAkACQAJAAkACQCAEQX9qQQJJDQAgBEUNASAEQQNHDQdEAAAAAAAAAAAhGwJAIAZBAUgNACAFQaABaiAGQQN0aiILQXhqIQIgCysDACEMIAYhCwNAIAIgAisDACIcIAygIhc5AwAgAkEIaiAMIBwgF6GgOQMAIAJBeGohAiAXIQwgC0F/aiILQQBKDQALIAZBAkgNACAFQaABaiAGQQN0aiILQXhqIQIgCysDACEMIAYhCwNAIAIgAisDACIcIAygIhc5AwAgAkEIaiAMIBwgF6GgOQMAIAJBeGohAiAXIQwgC0F/aiILQQFKDQALIAZBAkgNACAFQaABaiAGQQN0aiECRAAAAAAAAAAAIRsDQCAbIAIrAwCgIRsgAkF4aiECIAZBf2oiBkEBSg0ACwsgBSsDoAEhDCAaRQ0EIAEgDJo5AwAgASAFKwOoAZo5AwggASAbmjkDEAwHCyAGQQBIDQEgBkEBaiELIAVBoAFqIAZBA3RqIQJEAAAAAAAAAAAhDANAIAwgAisDAKAhDCACQXhqIQIgC0F/aiILQQBKDQAMAwsLIAZBAEgNAyAGQQFqIQsgBUGgAWogBkEDdGohAkQAAAAAAAAAACEMA0AgDCACKwMAoCEMIAJBeGohAiALQX9qIgtBAEoNAAwFCwtEAAAAAAAAAAAhDAsgASAMmiAMIBobOQMAIAUrA6ABIAyhIQwCQCAGQQFIDQAgBUGgAWpBCHIhAgNAIAwgAisDAKAhDCACQQhqIQIgBkF/aiIGDQALCyABIAyaIAwgGhs5AwgMAwsgASAMOQMAIAEgBSkDqAE3AwggASAbOQMQDAILRAAAAAAAAAAAIQwLIAEgDJogDCAaGzkDAAsgBUGwBGokACAYQQdxDwsgDiEGDAALC8MKBgF/AX4DfwN8AX8BfCMAQTBrIgIkACAAvSIDQj+IpyEEAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQCADQiCIpyIFQf////8HcSIGQfrUvYAESw0AIAVB//8/cUH7wyRGDQMgBkH8souABEsNASAERQ0GIAEgAEQAAEBU+yH5P6AiAEQxY2IaYbTQPaAiBzkDACABIAAgB6FEMWNiGmG00D2gOQMIIAJBMGokAEF/DwsCQCAGQbuM8YAESw0AIAZBvPvXgARLDQIgBkH8ssuABEYNAyAERQ0KIAEgAEQAADB/fNkSQKAiAETKlJOnkQ7pPaAiBzkDACABIAAgB6FEypSTp5EO6T2gOQMIIAJBMGokAEF9DwsgBkH6w+SJBE0NAiAGQYCAwP8HSQ0DIAEgACAAoSIAOQMAIAEgADkDCCACQTBqJABBAA8LIARFDQUgASAARAAAQFT7IQlAoCIARDFjYhphtOA9oCIHOQMAIAEgACAHoUQxY2IaYbTgPaA5AwggAkEwaiQAQX4PCyAGQfvD5IAERw0CCyABIAAgAESDyMltMF/kP6JEAAAAAAAAOEOgRAAAAAAAADjDoCIHRAAAQFT7Ifm/oqAiCCAHRDFjYhphtNA9oiIJoSIAOQMAIAZBFHYiCiAAvUI0iKdB/w9xa0ERSCEFAkACQAJAIAeZRAAAAAAAAOBBYw0AQYCAgIB4IQYgBUUNAQwCCyAHqiEGIAUNAQsgASAIIAdEAABgGmG00D2iIgChIgsgB0RzcAMuihmjO6IgCCALoSAAoaEiCaEiADkDAAJAIAogAL1CNIinQf8PcWtBMkgNACABIAsgB0QAAAAuihmjO6IiAKEiCCAHRMFJICWag3s5oiALIAihIAChoSIJoSIAOQMADAELIAshCAsgASAIIAChIAmhOQMIIAJBMGokACAGDwsgA0L/////////B4NCgICAgICAgLDBAIS/IgCZRAAAAAAAAOBBYw0DQYCAgIB4IQUMBAsgBEUNBSABIABEAABAVPshGUCgIgBEMWNiGmG08D2gIgc5AwAgASAAIAehRDFjYhphtPA9oDkDCCACQTBqJABBfA8LIAEgAEQAAEBU+yH5v6AiAEQxY2IaYbTQvaAiBzkDACABIAAgB6FEMWNiGmG00L2gOQMIIAJBMGokAEEBDwsgASAARAAAQFT7IQnAoCIARDFjYhphtOC9oCIHOQMAIAEgACAHoUQxY2IaYbTgvaA5AwggAkEwaiQAQQIPCyAAqiEFCyACIAW3Igc5AxACQAJAIAAgB6FEAAAAAAAAcEGiIgCZRAAAAAAAAOBBYw0AQYCAgIB4IQUMAQsgAKohBQsgAiAFtyIHOQMYIAIgACAHoUQAAAAAAABwQaIiADkDICAARAAAAAAAAAAAYg0CIAJBEGpBCHIhBUECIQoDQCAKQX9qIQogBSsDACEAIAVBeGohBSAARAAAAAAAAAAAYQ0ADAQLCyABIABEAAAwf3zZEsCgIgBEypSTp5EO6b2gIgc5AwAgASAAIAehRMqUk6eRDum9oDkDCCACQTBqJABBAw8LIAEgAEQAAEBU+yEZwKAiAEQxY2IaYbTwvaAiBzkDACABIAAgB6FEMWNiGmG08L2gOQMIIAJBMGokAEEEDwtBAiEKCyACQRBqIAIgBkEUdkHqd2ogCkEBakEBEAghBSACKwMAIQACQCAERQ0AIAEgAJo5AwAgASACKwMImjkDCCACQTBqJABBACAFaw8LIAEgADkDACABIAIpAwg3AwggAkEwaiQAIAULmwEBA3wgACAAoiIDIAMgA6KiIANEfNXPWjrZ5T2iROucK4rm5Vq+oKIgAyADRH3+sVfjHcc+okTVYcEZoAEqv6CiRKb4EBEREYE/oKAhBCADIACiIQUCQCACRQ0AIAAgBURJVVVVVVXFP6IgAyABRAAAAAAAAOA/oiAFIASioaIgAaGgoQ8LIAUgAyAEokRJVVVVVVXFv6CiIACgC5ICAgJ/AXwjAEEQayIBJAACQAJAAkAgAL1CIIinQf////8HcSICQfvDpP8DSw0AIAJBncGa8gNLDQEgASAARAAAAAAAAHBHoDkDACABQRBqJABEAAAAAAAA8D8PCyACQYCAwP8HSQ0BIAFBEGokACAAIAChDwsgAEQAAAAAAAAAABAHIQAgAUEQaiQAIAAPCyAAIAEQCSECIAErAwghACABKwMAIQMCQAJAAkAgAkEDcSICQQJGDQAgAkEBRg0BIAINAiADIAAQByEAIAFBEGokACAADwsgAyAAEAchACABQRBqJAAgAJoPCyADIABBARAKIQAgAUEQaiQAIACaDwsgAyAAQQEQCiEAIAFBEGokACAACyQAIABEi90aFWYglsCgEA5EAAAAAAAAwH+iRAAAAAAAAMB/ogvaAQMBfwF+AX8jAEEQayIBJAAgAL1C////////////AIMiAr8hAAJAAkACQCACQiCIpyIDQcHcmP8DSw0AIANB//+/8gNLDQEgASAARAAAAAAAAHBHoDkDCCABQRBqJABEAAAAAAAA8D8PCyADQcHcmIQESw0BIAAQDiEAIAFBEGokACAARAAAAAAAAPA/IACjoEQAAAAAAADgP6IPCyABQRBqJAAgABAPIgAgAKIgAEQAAAAAAADwP6AiACAAoKNEAAAAAAAA8D+gDwsgABAMIQAgAUEQaiQAIAALoAQEAX8BfgJ/A3wjAEEQayIBJAAgAL0iAkI/iKchAwJAAkACQAJAAkACQAJAAkACQAJAIAJCIIinQf////8HcSIEQavGmIQESQ0AIAJC////////////AINCgICAgICAgPj/AFgNASABQRBqJAAgAA8LIARBw9zY/gNJDQEgBEGyxcL/A08NAyADQQFzIANrIQQMBgsgAETvOfr+Qi6GQGRBAXMNASABQRBqJAAgAEQAAAAAAADgf6IPCyAEQYCAwPEDTQ0CQQAhBEQAAAAAAAAAACEFIAAhBgwFCyAARNK8et0rI4bAY0EBcw0AIAFEAAAAAAAAoLYgAKO2OAIMRAAAAAAAAAAAIQcgAERRMC3VEEmHwGMNBQsgAET+gitlRxX3P6IgA0EDdEHgHmorAwCgIgeZRAAAAAAAAOBBYw0BQYCAgIB4IQQMAgsgASAARAAAAAAAAOB/oDkDACABQRBqJAAgAEQAAAAAAADwP6APCyAHqiEECyAAIAS3IgdEAADg/kIu5r+ioCIAIAdEdjx5Ne856j2iIgWhIQYLIAAgBiAGIAYgBqIiByAHIAcgByAHRNCkvnJpN2Y+okTxa9LFQb27vqCiRCzeJa9qVhE/oKJEk72+FmzBZr+gokQ+VVVVVVXFP6CioSIHokQAAAAAAAAAQCAHoaMgBaGgRAAAAAAAAPA/oCEHIARFDQAgByAEEBMhBwsgAUEQaiQAIAcL2QYEAX8BfgJ/BHwjAEEQayEBIAC9IgJCP4inIQMCQAJAAkACQAJAAkACQAJAAkACQAJAAkACQCACQiCIp0H/////B3EiBEH60I2CBEkNACACQv///////////wCDQoCAgICAgID4/wBYDQEgAA8LIARBw9zY/gNJDQEgBEGxxcL/A0sNAiADRQ0GIABEAADg/kIu5j+gIQVBfyEERHY8eTXvOeq9IQYMCgsgA0UNA0QAAAAAAADwvw8LIARB//+/5ANLDQEgBEH//z9LDQMgASAAtjgCDCAADwsgAET+gitlRxX3P6IhBkQAAAAAAADgvyEFIAMNBgwFC0EAIQQMBwsgAETvOfr+Qi6GQGRFDQIgAEQAAAAAAADgf6IPCyAADwsgAEQAAOD+Qi7mv6AhBUEBIQREdjx5Ne856j0hBgwDCyAARP6CK2VHFfc/oiEGC0QAAAAAAADgPyEFCwJAAkAgBiAFoCIFmUQAAAAAAADgQWMNAEGAgICAeCEEDAELIAWqIQQLIAS3IgVEdjx5Ne856j2iIQYgACAFRAAA4P5CLua/oqAhBQsgBSAFIAahIgChIAahIQYLIAAgAEQAAAAAAADgP6IiB6IiBSAFIAUgBSAFIAVELcMJbrf9ir6iRDlS5obKz9A+oKJEt9uqnhnOFL+gokSFVf4ZoAFaP6CiRPQQEREREaG/oKJEAAAAAAAA8D+gIghEAAAAAAAACEAgByAIoqEiB6FEAAAAAAAAGEAgACAHoqGjoiEHAkACQAJAAkACQCAERQ0AIAAgByAGoaIgBqEgBaEhBSAEQQFGDQEgBEF/Rw0CIAAgBaFEAAAAAAAA4D+iRAAAAAAAAOC/oA8LIAAgACAHoiAFoaEPCyAARAAAAAAAANC/Y0EBcw0BIAUgAEQAAAAAAADgP6ChRAAAAAAAAADAog8LIARB/wdqrUI0hr8hBiAEQTlJDQEgACAFoUQAAAAAAADwP6AiACAAoEQAAAAAAADgf6IgACAGoiAEQYAIRhtEAAAAAAAA8L+gDwsgACAFoSIAIACgRAAAAAAAAPA/oA8LRAAAAAAAAPA/Qf8HIARrrUI0hr8iB6EgACAFIAegoSAEQRRIIgQbIAAgBaFEAAAAAAAA8D8gBBugIAaiC6IDAwF+A38CfAJAAkACQAJAAkAgAL0iAUIAUw0AIAFCIIinIgJB//8/TQ0AIAJB//+//wdLDQNBgIDA/wMhA0GBeCEEIAJBgIDA/wNHDQEgAacNAkQAAAAAAAAAAA8LAkAgAUL///////////8Ag0IAUQ0AIAFCf1cNBCAARAAAAAAAAFBDor0iAUIgiKchA0HLdyEEDAILRAAAAAAAAPC/IAAgAKKjDwsgAiEDCyAEIANB4r4laiICQRR2arciBUQAAOD+Qi7mP6IgAkH//z9xQZ7Bmv8Daq1CIIYgAUL/////D4OEv0QAAAAAAADwv6AiACAFRHY8eTXvOeo9oiAAIABEAAAAAAAAAECgoyIFIAAgAEQAAAAAAADgP6KiIgYgBSAFoiIFIAWiIgAgACAARJ/GeNAJmsM/okSveI4dxXHMP6CiRAT6l5mZmdk/oKIgBSAAIAAgAEREUj7fEvHCP6JE3gPLlmRGxz+gokRZkyKUJEnSP6CiRJNVVVVVVeU/oKKgoKKgIAahoKAhAAsgAA8LIAAgAKFEAAAAAAAAAACjC4kEBAF/AX4BfwN8IwBBEGshASAAvSICQiCIpyEDAkACQAJAAkACQCACQgBTDQAgA0H5hOr+A00NACADQf//v/8HTQ0BIAAPCwJAIANBgIDA/3tJDQAgAEQAAAAAAADwv2INA0QAAAAAAADw/w8LAkAgA0EBdEH////JB0sNACADQYCAwP8HcUUNBCAADwtEAAAAAAAAAAAhBCADQcX9yv57Tw0ARAAAAAAAAAAAIQUMAQtEAAAAAAAAAAAhBAJAIABEAAAAAAAA8D+gIgW9IgJCIIinQeK+JWoiAUEUdkGBeGoiA0E1Sg0AIAAgBaFEAAAAAAAA8D+gIAAgBUQAAAAAAADwv6ChIANBAUobIAWjIQQLIAFB//8/cUGewZr/A2qtQiCGIAJC/////w+DhL9EAAAAAAAA8L+gIQAgA7chBQsgBUQAAOD+Qi7mP6IgACAEIAVEdjx5Ne856j2ioCAAIABEAAAAAAAAAECgoyIFIAAgAEQAAAAAAADgP6KiIgYgBSAFoiIEIASiIgUgBSAFRJ/GeNAJmsM/okSveI4dxXHMP6CiRAT6l5mZmdk/oKIgBCAFIAUgBUREUj7fEvHCP6JE3gPLlmRGxz+gokRZkyKUJEnSP6CiRJNVVVVVVeU/oKKgoKKgIAahoKAPCyAAIAChRAAAAAAAAAAAow8LIAEgALY4AgwgAAvHEAYBfAF+A38BfgV/CHxEAAAAAAAA8D8hAgJAIAG9IgNCIIinIgRB/////wdxIgUgA6ciBnJFDQAgAL0iB0IgiKchCAJAIAenIgkNACAIQYCAwP8DRg0BCwJAAkAgCEH/////B3EiCkGAgMD/B0sNACAJQQBHIApBgIDA/wdGcQ0AIAVBgIDA/wdLDQAgBkUNASAFQYCAwP8HRw0BCyAAIAGgDwtBACELAkACQAJAAkAgCEF/Sg0AQQIhCyAFQf///5kESw0AQQAhCyAFQYCAwP8DSQ0AIAVBFHYhDCAFQYCAgIoESQ0BQQIgBkGzCCAMayILdiIMQQFxa0EAIAwgC3QgBkYbIQsLIAZFDQEMAgtBACELIAYNAUECIAVBkwggDGsiBnYiC0EBcWtBACALIAZ0IAVGGyELCwJAAkACQAJAIAVBgIDA/wdHDQAgCkGAgMCAfGogCXJFDQUgCkGAgMD/A0kNASABRAAAAAAAAAAAIARBf0obDwsCQCAFQYCAwP8DRw0AIARBf0wNAyAADwsgBEGAgICABEcNASAAIACiDwtEAAAAAAAAAAAgAZogBEF/ShsPCyAIQQBIDQEgBEGAgID/A0cNASAAnw8LRAAAAAAAAPA/IACjDwsgAJkhAgJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAIAkNACAKRQ0BIApBgICAgARyQYCAwP8HRg0BC0QAAAAAAADwPyENIAhBf0oNAyALQQFGDQEgCw0DIAAgAKEiASABow8LRAAAAAAAAPA/IAKjIAIgBEEASBshAiAIQX9KDQsgCyAKQYCAwIB8anJFDQEgApogAiALQQFGGw8LRAAAAAAAAPC/IQ0gBUGBgICPBE8NAgwDCyACIAKhIgEgAaMPCyAFQYGAgI8ESQ0BCwJAIAVBgYDAnwRJDQAgCkH//7//A0sNAkQAAAAAAADwf0QAAAAAAAAAACAEQQBIGw8LIApB/v+//wNLDQIgDUScdQCIPOQ3fqJEnHUAiDzkN36iIA1EWfP4wh9upQGiRFnz+MIfbqUBoiAEQQBIGw8LQQAhBQJAAkAgCkH//z9LDQAgAkQAAAAAAABAQ6IiAr1CIIinIQpBSyEEDAELQQAhBAsgCkH//z9xIgZBgIDA/wNyIQggCkEUdSAEakGBeGohBCAGQY+xDkkNAyAGQfrsLk8NAkEBIQUMAwtEAAAAAAAA8H9EAAAAAAAAAAAgBEEAShsPCyAKQYGAwP8DSQ0CIA1EnHUAiDzkN36iRJx1AIg85Dd+oiANRFnz+MIfbqUBokRZ8/jCH26lAaIgBEEAShsPCyAIQYCAQGohCCAEQQFqIQQLIAVBA3QiBkGQH2orAwAiDiAIrUIghiACvUL/////D4OEvyIPIAZB8B5qKwMAIhChIhFEAAAAAAAA8D8gECAPoKMiEqIiAr1CgICAgHCDvyIAIAAgAKIiE0QAAAAAAAAIQKAgAiAAoCASIBEgACAIQQF1QYCAgIACciAFQRJ0akGAgCBqrUIghr8iFKKhIAAgDyAUIBChoaKhoiIPoiACIAKiIgAgAKIgACAAIAAgACAARO9ORUoofso/okRl28mTSobNP6CiRAFBHalgdNE/oKJETSaPUVVV1T+gokT/q2/btm3bP6CiRAMzMzMzM+M/oKKgIhCgvUKAgICAcIO/IgCiIhEgDyAAoiACIBAgAEQAAAAAAAAIwKAgE6GhoqAiAqC9QoCAgIBwg78iAEQAAADgCcfuP6IiDyAGQYAfaisDACACIAAgEaGhRP0DOtwJx+4/oiAARPUBWxTgLz6+oqCgIhCgoCAEtyICoL1CgICAgHCDvyIAIAKhIA6hIA+hIQ4MAQsgAkQAAAAAAADwv6AiAEQAAABgRxX3P6IiAiAARETfXfgLrlQ+oiAAIACiRAAAAAAAAOA/IAAgAEQAAAAAAADQv6JEVVVVVVVV1T+goqGiRP6CK2VHFfe/oqAiEKC9QoCAgIBwg78iACACoSEOCyAAIANCgICAgHCDvyIPoiICIBAgDqEgAaIgASAPoSAAoqAiAaAiAL0iA6chBQJAAkACQAJAAkAgA0IgiKciCEGAgMCEBEgNACAIQYCAwPt7aiAFckUNASANRJx1AIg85Dd+okScdQCIPOQ3fqIPCyAIQYD4//8HcUGAmMOEBEkNAiAIQYDovPsDaiAFckUNASANRFnz+MIfbqUBokRZ8/jCH26lAaIPCyABRP6CK2VHFZc8oCAAIAKhZEEBcw0BIA1EnHUAiDzkN36iRJx1AIg85Dd+og8LIAEgACACoWVBAXNFDQELQQAhBQJAIAhB/////wdxIgZBgYCA/wNJDQBBAEGAgMAAIAZBFHZBgnhqdiAIaiIGQf//P3FBgIDAAHJBkwggBkEUdkH/D3EiBGt2IgVrIAUgCEEASBshBSABIAJBgIBAIARBgXhqdSAGca1CIIa/oSICoL0hAwsCQCAFQRR0IANCgICAgHCDvyIARAAAAABDLuY/oiIPIAEgACACoaFE7zn6/kIu5j+iIABEOWyoDGFcIL6ioCICoCIBIAEgASABIAGiIgAgACAAIAAgAETQpL5yaTdmPqJE8WvSxUG9u76gokQs3iWvalYRP6CiRJO9vhZswWa/oKJEPlVVVVVVxT+goqEiAKIgAEQAAAAAAAAAwKCjIAIgASAPoaEiACABIACioKGhRAAAAAAAAPA/oCIBvSIDQiCIp2oiCEH//z9KDQAgDSABIAUQE6IPCyANIAitQiCGIANC/////w+DhL+iDwsgDURZ8/jCH26lAaJEWfP4wh9upQGiDwsgAgu4AQEBfwJAAkACQAJAIAFBgAhIDQAgAEQAAAAAAADgf6IhACABQYF4aiICQYAISA0BIAFBgnBqIgFB/wcgAUH/B0gbIQEgAEQAAAAAAADgf6IhAAwDCyABQYF4Sg0CIABEAAAAAAAAYAOiIQAgAUHJB2oiAkGBeEoNASABQZIPaiIBQYJ4IAFBgnhKGyEBIABEAAAAAAAAYAOiIQAMAgsgAiEBDAELIAIhAQsgACABQf8Haq1CNIa/oguiAgICfwF8IwBBEGsiASQAAkACQAJAIAC9QiCIp0H/////B3EiAkH7w6T/A0sNACACQf//v/IDSw0BIAEgAEQAAAAAAABwOKIgAEQAAAAAAABwR6AgAkGAgMAASRs5AwAgAUEQaiQAIAAPCyACQYCAwP8HSQ0BIAFBEGokACAAIAChDwsgAEQAAAAAAAAAAEEAEAohACABQRBqJAAgAA8LIAAgARAJIQIgASsDCCEAIAErAwAhAwJAAkACQCACQQNxIgJBAkYNACACQQFGDQEgAg0CIAMgAEEBEAohACABQRBqJAAgAA8LIAMgAEEBEAohACABQRBqJAAgAJoPCyADIAAQByEAIAFBEGokACAADwsgAyAAEAchACABQRBqJAAgAJoLrgEDAX4CfAF/RAAAAAAAAOC/RAAAAAAAAOA/IAC9IgFCAFMbIQIgAUL///////////8AgyIBvyEDAkACQAJAIAFCIIinIgRBwdyYhARLDQAgAxAPIQMgBEH//7//A0sNAiAEQYCAwPIDSQ0BIAIgAyADoCADIAOiIANEAAAAAAAA8D+go6GiDwsgAiACoCADEAyiIQALIAAPCyACIAMgAyADRAAAAAAAAPA/oKOgoguwAwMBfgJ/A3wCQAJAIAC9IgNCgICAgID/////AINCgYCAgPCE5fI/VCIEDQBEGC1EVPsh6T8gAJogACADQj+IpyIFG6FEB1wUMyamgTwgAZogASAFG6GgIQBEAAAAAAAAAAAhAQwBCwsgACAAIAAgAKIiBqIiB0RjVVVVVVXVP6IgASAGIAEgByAGIAaiIgggCCAIIAggCERzU2Dby3XzvqJEppI3oIh+FD+gokQBZfLy2ERDP6CiRCgDVskibW0/oKJEN9YGhPRklj+gokR6/hARERHBP6AgBiAIIAggCCAIIAhE1Hq/dHAq+z6iROmn8DIPuBI/oKJEaBCNGvcmMD+gokQVg+D+yNtXP6CiRJOEbunjJoI/oKJE/kGzG7qhqz+goqCioKKgoCIGoCEIAkAgBA0AQQEgAkEBdGu3IgEgACAGIAggCKIgCCABoKOhoCIIIAigoSIImiAIIAUbDwsCQCACRQ0ARAAAAAAAAPC/IAijIgEgCL1CgICAgHCDvyIHIAG9QoCAgIBwg78iCKJEAAAAAAAA8D+gIAYgByAAoaEgCKKgoiAIoCEICyAIC8EBAQJ/IwBBEGsiASQAAkACQAJAIAC9QiCIp0H/////B3EiAkH7w6T/A0sNACACQf////EDSw0BIAEgAEQAAAAAAABwOKIgAEQAAAAAAABwR6AgAkGAgMAASRs5AwAgAUEQaiQAIAAPCyACQYCAwP8HSQ0BIAFBEGokACAAIAChDwsgAEQAAAAAAAAAAEEAEBYhACABQRBqJAAgAA8LIAAgARAJIQIgASsDACABKwMIIAJBAXEQFiEAIAFBEGokACAAC4ACAwF/An4BfyMAQRBrIgEkACAAvSICQv///////////wCDIgO/IQACQAJAAkACQCADQiCIpyIEQeunhv8DSQ0AIARBgYDQgQRJDQFEAAAAAAAAAIAgAKNEAAAAAAAA8D+gIQAMAwsgBEGvscH+A0kNASAAIACgEA8iACAARAAAAAAAAABAoKMhAAwCC0QAAAAAAADwP0QAAAAAAAAAQCAAIACgEA9EAAAAAAAAAECgo6EhAAwBCwJAIARBgIDAAEkNACAARAAAAAAAAADAohAPIgCaIABEAAAAAAAAAECgoyEADAELIAEgALY4AgwLIAFBEGokACAAmiAAIAJCAFMbC/wCAgN/AX4CQCACRQ0AIAAgAToAACAAIAJqIgNBf2ogAToAACACQQNJDQAgACABOgACIAAgAToAASADQX1qIAE6AAAgA0F+aiABOgAAIAJBB0kNACAAIAE6AAMgA0F8aiABOgAAIAJBCUkNACAAQQAgAGtBA3EiBGoiAyABQf8BcUGBgoQIbCIBNgIAIAMgAiAEa0F8cSIEaiICQXxqIAE2AgAgBEEJSQ0AIAMgATYCCCADIAE2AgQgAkF4aiABNgIAIAJBdGogATYCACAEQRlJDQAgAyABNgIQIAMgATYCDCADIAE2AhQgAyABNgIYIAJBaGogATYCACACQWRqIAE2AgAgAkFsaiABNgIAIAJBcGogATYCACAEIANBBHFBGHIiBWsiAkEgSQ0AIAGtIgZCIIYgBoQhBiADIAVqIQEDQCABIAY3AwAgAUEIaiAGNwMAIAFBEGogBjcDACABQRhqIAY3AwAgAUEgaiEBIAJBYGoiAkEfSw0ACwsgAAsLqBcBAEGACAugF0+7YQVnrN0/GC1EVPsh6T+b9oHSC3PvPxgtRFT7Ifk/4mUvIn8rejwHXBQzJqaBPL3L8HqIB3A8B1wUMyamkTwDAAAABAAAAAQAAAAGAAAAg/miAERObgD8KRUA0VcnAN009QBi28AAPJmVAEGQQwBjUf4Au96rALdhxQA6biQA0k1CAEkG4AAJ6i4AHJLRAOsd/gApsRwA6D6nAPU1ggBEuy4AnOmEALQmcABBfl8A1pE5AFODOQCc9DkAi1+EACj5vQD4HzsA3v+XAA+YBQARL+8AClqLAG0fbQDPfjYACcsnAEZPtwCeZj8ALepfALondQDl68cAPXvxAPc5BwCSUooA+2vqAB+xXwAIXY0AMANWAHv8RgDwq2sAILzPADb0mgDjqR0AXmGRAAgb5gCFmWUAoBRfAI1AaACA2P8AJ3NNAAYGMQDKVhUAyahzAHviYABrjMAAGcRHAM1nwwAJ6NwAWYMqAIt2xACmHJYARK/dABlX0QClPgUABQf/ADN+PwDCMugAmE/eALt9MgAmPcMAHmvvAJ/4XgA1HzoAf/LKAPGHHQB8kCEAaiR8ANVu+gAwLXcAFTtDALUUxgDDGZ0ArcTCACxNQQAMAF0Ahn1GAONxLQCbxpoAM2IAALTSfAC0p5cAN1XVANc+9gCjEBgATXb8AGSdKgBw16sAY3z4AHqwVwAXFecAwElWADvW2QCnhDgAJCPLANaKdwBaVCMAAB+5APEKGwAZzt8AnzH/AGYeagCZV2EArPtHAH5/2AAiZbcAMuiJAOa/YADvxM0AbDYJAF0/1AAW3tcAWDveAN6bkgDSIigAKIboAOJYTQDGyjIACOMWAOB9ywAXwFAA8x2nABjgWwAuEzQAgxJiAINIAQD1jlsArbB/AB7p8gBISkMAEGfTAKrd2ACuX0IAamHOAAoopADTmbQABqbyAFx3fwCjwoMAYTyIAIpzeACvjFoAb9e9AC2mYwD0v8sAjYHvACbBZwBVykUAytk2ACio0gDCYY0AEsl3AAQmFAASRpsAxFnEAMjFRABNspEAABfzANRDrQApSeUA/dUQAAC+/AAelMwAcM7uABM+9QDs8YAAs+fDAMf4KACTBZQAwXE+AC4JswALRfMAiBKcAKsgewAutZ8AR5LCAHsyLwAMVW0AcqeQAGvnHwAxy5YAeRZKAEF54gD034kA6JSXAOLmhACZMZcAiO1rAF9fNgC7/Q4ASJq0AGekbABxckIAjV0yAJ8VuAC85QkAjTElAPd0OQAwBRwADQwBAEsIaAAs7lgAR6qQAHTnAgC91iQA932mAG5IcgCfFu8AjpSmALSR9gDRU1EAzwryACCYMwD1S34AsmNoAN0+XwBAXQMAhYl/AFVSKQA3ZMAAbdgQADJIMgBbTHUATnHUAEVUbgALCcEAKvVpABRm1QAnB50AXQRQALQ72wDqdsUAh/kXAElrfQAdJ7oAlmkpAMbMrACtFFQAkOJqAIjZiQAsclAABKS+AHcHlADzMHAAAPwnAOpxqABmwkkAZOA9AJfdgwCjP5cAQ5T9AA2GjAAxQd4AkjmdAN1wjAAXt+cACN87ABU3KwBcgKAAWoCTABARkgAP6NgAbICvANv/SwA4kA8AWRh2AGKlFQBhy7sAx4m5ABBAvQDS8gQASXUnAOu29gDbIrsAChSqAIkmLwBkg3YACTszAA6UGgBROqoAHaPCAK/trgBcJhIAbcJNAC16nADAVpcAAz+DAAnw9gArQIwAbTGZADm0BwAMIBUA2MNbAPWSxADGrUsATsqlAKc3zQDmqTYAq5KUAN1CaAAZY94AdozvAGiLUgD82zcArqGrAN8VMQAArqEADPvaAGRNZgDtBbcAKWUwAFdWvwBH/zoAavm5AHW+8wAok98Aq4AwAGaM9gAEyxUA+iIGANnkHQA9s6QAVxuPADbNCQBOQukAE76kADMjtQDwqhoAT2WoANLBpQALPw8AW3jNACP5dgB7iwQAiRdyAMamUwBvbuIA7+sAAJtKWADE2rcAqma6AHbPzwDRAh0AsfEtAIyZwQDDrXcAhkjaAPddoADGgPQArPAvAN3smgA/XLwA0N5tAJDHHwAq27YAoyU6AACvmgCtU5MAtlcEACkttABLgH4A2genAHaqDgB7WaEAFhIqANy3LQD65f0Aidv+AIm+/QDkdmwABqn8AD6AcACFbhUA/Yf/ACg+BwBhZzMAKhiGAE296gCz568Aj21uAJVnOQAxv1sAhNdIADDfFgDHLUMAJWE1AMlwzgAwy7gAv2z9AKQAogAFbOQAWt2gACFvRwBiEtIAuVyEAHBhSQBrVuAAmVIBAFBVNwAe1bcAM/HEABNuXwBdMOQAhS6pAB2ywwChMjYACLekAOqx1AAW9yEAj2nkACf/dwAMA4AAjUAtAE/NoAAgpZkAs6LTAC9dCgC0+UIAEdrLAH2+0ACb28EAqxe9AMqigQAIalwALlUXACcAVQB/FPAA4QeGABQLZACWQY0Ah77eANr9KgBrJbYAe4k0AAXz/gC5v54AaGpPAEoqqABPxFoALfi8ANdamAD0x5UADU2NACA6pgCkV18AFD+xAIA4lQDMIAEAcd2GAMnetgC/YPUATWURAAEHawCMsKwAssDQAFFVSAAe+w4AlXLDAKMGOwDAQDUABtx7AOBFzABOKfoA1srIAOjzQQB8ZN4Am2TYANm+MQCkl8MAd1jUAGnjxQDw2hMAujo8AEYYRgBVdV8A0r31AG6SxgCsLl0ADkTtABw+QgBhxIcAKf3pAOfW8wAifMoAb5E1AAjgxQD/140AbmriALD9xgCTCMEAfF10AGutsgDNbp0APnJ7AMYRagD3z6kAKXPfALXJugC3AFEA4rINAHS6JADlfWAAdNiKAA0VLACBGAwAfmaUAAEpFgCfenYA/f2+AFZF7wDZfjYA7NkTAIu6uQDEl/wAMagnAPFuwwCUxTYA2KhWALSotQDPzA4AEoktAG9XNAAsVokAmc7jANYguQBrXqoAPiqcABFfzAD9C0oA4fT7AI47bQDihiwA6dSEAPy0qQDv7tEALjXJAC85YQA4IUQAG9nIAIH8CgD7SmoALxzYAFO0hABOmYwAVCLMACpV3ADAxtYACxmWABpwuABplWQAJlpgAD9S7gB/EQ8A9LURAPzL9QA0vC0ANLzuAOhdzADdXmAAZ46bAJIz7wDJF7gAYVibAOFXvABRg8YA2D4QAN1xSAAtHN0ArxihACEsRgBZ89cA2XqYAJ5UwABPhvoAVgb8AOV5rgCJIjYAOK0iAGeT3ABV6KoAgiY4AMrnmwBRDaQAmTOxAKnXDgBpBUgAZbLwAH+IpwCITJcA+dE2ACGSswB7gkoAmM8hAECf3ADcR1UA4XQ6AGfrQgD+nd8AXtRfAHtnpAC6rHoAVfaiACuIIwBBulUAWW4IACEqhgA5R4MAiePmAOWe1ABJ+0AA/1bpABwPygDFWYoAlPorANPBxQAPxc8A21quAEfFhgCFQ2IAIYY7ACx5lAAQYYcAKkx7AIAsGgBDvxIAiCaQAHg8iQCoxOQA5dt7AMQ6wgAm9OoA92eKAA2SvwBloysAPZOxAL18CwCkUdwAJ91jAGnh3QCalBkAqCmVAGjOKAAJ7bQARJ8gAE6YygBwgmMAfnwjAA+5MgCn9Y4AFFbnACHxCAC1nSoAb35NAKUZUQC1+asAgt/WAJbdYQAWNgIAxDqfAIOioQBy7W0AOY16AIK4qQBrMlwARidbAAA07QDSAHcA/PRVAAFZTQDgcYAAAAAAAAAAAAAAAABA+yH5PwAAAAAtRHQ+AAAAgJhG+DwAAABgUcx4OwAAAICDG/A5AAAAQCAlejgAAACAIoLjNgAAAAAd82k1AAAAAAAA4D8AAAAAAADgvwAAAAAAAPA/AAAAAAAA+D8AAAAAAAAAAAbQz0Pr/Uw+AAAAAAAAAAAAAABAA7jiPwDsBwRuYW1lAcUBGgARX193YXNtX2NhbGxfY3RvcnMBBGFjb3MCBWFjb3NoAwRhc2luBAVhc2luaAUEYXRhbgYFYXRhbmgHBV9fY29zCBBfX3JlbV9waW8yX2xhcmdlCQpfX3JlbV9waW8yCgVfX3NpbgsDY29zDAdfX2V4cG8yDQRjb3NoDgNleHAPBWV4cG0xEANsb2cRBWxvZzFwEgNwb3cTBnNjYWxibhQDc2luFQRzaW5oFgVfX3RhbhcDdGFuGAR0YW5oGQZtZW1zZXQCnAYaAAABBQACcDABAmwwAgJsMQMCbDIEAmwzAgIAAnAwAQJsMAMGAAJwMAECbDACAmwxAwJsMgQCbDMFAmw0BAUAAnAwAQJsMAICbDEDAmwyBAJsMwUIAAJwMAECbDACAmwxAwJsMgQCbDMFAmw0BgJsNQcCbDYGBQACcDABAmwwAgJsMQMCbDIEAmwzBwUAAnAwAQJwMQICbDADAmwxBAJsMggdAAJwMAECcDECAnAyAwJwMwQCcDQFAmwwBgJsMQcCbDIIAmwzCQJsNAoCbDULAmw2DAJsNw0CbDgOAmw5DwNsMTAQA2wxMREDbDEyEgNsMTMTA2wxNBQDbDE1FQNsMTYWA2wxNxcDbDE4GANsMTkZA2wyMBoDbDIxGwNsMjIcA2wyMwkMAAJwMAECcDECAmwwAwJsMQQCbDIFAmwzBgJsNAcCbDUIAmw2CQJsNwoCbDgLAmw5CgYAAnAwAQJwMQICcDIDAmwwBAJsMQUCbDILBAACcDABAmwwAgJsMQMCbDIMAQACcDANBAACcDABAmwwAgJsMQMCbDIOCAACcDABAmwwAgJsMQMCbDIEAmwzBQJsNAYCbDUHAmw2DwkAAnAwAQJsMAICbDEDAmwyBAJsMwUCbDQGAmw1BwJsNggCbDcQBwACcDABAmwwAgJsMQMCbDIEAmwzBQJsNAYCbDURBwACcDABAmwwAgJsMQMCbDIEAmwzBQJsNAYCbDUSFQACcDABAnAxAgJsMAMCbDEEAmwyBQJsMwYCbDQHAmw1CAJsNgkCbDcKAmw4CwJsOQwDbDEwDQNsMTEOA2wxMg8DbDEzEANsMTQRA2wxNRIDbDE2EwNsMTcUA2wxOBMDAAJwMAECcDECAmwwFAQAAnAwAQJsMAICbDEDAmwyFQUAAnAwAQJsMAICbDEDAmwyBAJsMxYJAAJwMAECcDECAnAyAwJsMAQCbDEFAmwyBgJsMwcCbDQIAmw1FwMAAnAwAQJsMAICbDEYBQACcDABAmwwAgJsMQMCbDIEAmwzGQcAAnAwAQJwMQICcDIDAmwwBAJsMQUCbDIGAmwz"
diff --git a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/wasm/wasm.kt b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/wasm/wasm.kt
new file mode 100644
index 000000000..394a0567e
--- /dev/null
+++ b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/wasm/wasm.kt
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2018-2021 KMath contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package space.kscience.kmath.wasm
+
+import space.kscience.kmath.estree.compileWith
+import space.kscience.kmath.expressions.Expression
+import space.kscience.kmath.expressions.MST
+import space.kscience.kmath.expressions.invoke
+import space.kscience.kmath.misc.Symbol
+import space.kscience.kmath.misc.UnstableKMathAPI
+import space.kscience.kmath.operations.DoubleField
+import space.kscience.kmath.operations.IntRing
+import space.kscience.kmath.wasm.internal.DoubleWasmBuilder
+import space.kscience.kmath.wasm.internal.IntWasmBuilder
+
+/**
+ * Compiles an [MST] to WASM in the context of reals.
+ *
+ * @author Iaroslav Postovalov
+ */
+@UnstableKMathAPI
+public fun DoubleField.expression(mst: MST): Expression =
+ DoubleWasmBuilder(mst).instance
+
+/**
+ * Compiles an [MST] to WASM in the context of integers.
+ *
+ * @author Iaroslav Postovalov
+ */
+@UnstableKMathAPI
+public fun IntRing.expression(mst: MST): Expression =
+ IntWasmBuilder(mst).instance
+
+/**
+ * Create a compiled expression with given [MST] and given [algebra].
+ *
+ * @author Iaroslav Postovalov
+ */
+@UnstableKMathAPI
+public fun MST.compileToExpression(algebra: IntRing): Expression = compileWith(algebra)
+
+
+/**
+ * Compile given MST to expression and evaluate it against [arguments].
+ *
+ * @author Iaroslav Postovalov
+ */
+@UnstableKMathAPI
+public fun MST.compile(algebra: IntRing, arguments: Map): Int =
+ compileToExpression(algebra).invoke(arguments)
+
+
+/**
+ * Compile given MST to expression and evaluate it against [arguments].
+ *
+ * @author Iaroslav Postovalov
+ */
+@UnstableKMathAPI
+public fun MST.compile(algebra: IntRing, vararg arguments: Pair): Int =
+ compileToExpression(algebra)(*arguments)
+
+/**
+ * Create a compiled expression with given [MST] and given [algebra].
+ *
+ * @author Iaroslav Postovalov
+ */
+@UnstableKMathAPI
+public fun MST.compileToExpression(algebra: DoubleField): Expression = compileWith(algebra)
+
+
+/**
+ * Compile given MST to expression and evaluate it against [arguments].
+ *
+ * @author Iaroslav Postovalov
+ */
+@UnstableKMathAPI
+public fun MST.compile(algebra: DoubleField, arguments: Map): Double =
+ compileToExpression(algebra).invoke(arguments)
+
+
+/**
+ * Compile given MST to expression and evaluate it against [arguments].
+ *
+ * @author Iaroslav Postovalov
+ */
+@UnstableKMathAPI
+public fun MST.compile(algebra: DoubleField, vararg arguments: Pair): Double =
+ compileToExpression(algebra).invoke(*arguments)
diff --git a/kmath-ast/src/jsTest/kotlin/space/kscience/kmath/ast/TestExecutionTime.kt b/kmath-ast/src/jsTest/kotlin/space/kscience/kmath/ast/TestExecutionTime.kt
new file mode 100644
index 000000000..01746ddb6
--- /dev/null
+++ b/kmath-ast/src/jsTest/kotlin/space/kscience/kmath/ast/TestExecutionTime.kt
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2018-2021 KMath contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package space.kscience.kmath.ast
+
+import space.kscience.kmath.expressions.*
+import space.kscience.kmath.misc.symbol
+import space.kscience.kmath.operations.DoubleField
+import space.kscience.kmath.operations.ExtendedField
+import space.kscience.kmath.operations.bindSymbol
+import space.kscience.kmath.operations.invoke
+import kotlin.math.sin
+import kotlin.random.Random
+import kotlin.test.Test
+import kotlin.time.measureTime
+import space.kscience.kmath.estree.compileToExpression as estreeCompileToExpression
+import space.kscience.kmath.wasm.compileToExpression as wasmCompileToExpression
+
+internal class TestExecutionTime {
+ private companion object {
+ private const val times = 1_000_000
+ private val x by symbol
+ private val algebra: ExtendedField = DoubleField
+
+ private val functional = DoubleField.expressionInExtendedField {
+ bindSymbol(x) * const(2.0) + const(2.0) / bindSymbol(x) - const(16.0) / sin(bindSymbol(x))
+ }
+
+ private val node = MstExtendedField {
+ bindSymbol(x) * number(2.0) + number(2.0) / bindSymbol(x) - number(16.0) / sin(bindSymbol(x))
+ }
+
+ private val mst = node.toExpression(DoubleField)
+ private val wasm = node.wasmCompileToExpression(DoubleField)
+ private val estree = node.estreeCompileToExpression(DoubleField)
+
+ // In JavaScript, the expression below is implemented like
+ // _no_name_provided__125.prototype.invoke_178 = function (args) {
+ // var tmp = getValue(args, raw$_get_x__3(this._$x$delegate_2)) * 2.0 + 2.0 / getValue(args, raw$_get_x__3(this._$x$delegate_2));
+ // var tmp0_sin_0_5 = getValue(args, raw$_get_x__3(this._$x$delegate_2));
+ // return tmp - 16.0 / Math.sin(tmp0_sin_0_5);
+ // };
+
+ private val raw = Expression { args ->
+ args.getValue(x) * 2.0 + 2.0 / args.getValue(x) - 16.0 / sin(args.getValue(x))
+ }
+ }
+
+ private fun invokeAndSum(name: String, expr: Expression) {
+ println(name)
+ val rng = Random(0)
+ var sum = 0.0
+ measureTime { repeat(times) { sum += expr(x to rng.nextDouble()) } }.also(::println)
+ }
+
+ @Test
+ fun functionalExpression() = invokeAndSum("functional", functional)
+
+ @Test
+ fun mstExpression() = invokeAndSum("mst", mst)
+
+ @Test
+ fun wasmExpression() = invokeAndSum("wasm", wasm)
+
+ @Test
+ fun estreeExpression() = invokeAndSum("estree", wasm)
+
+ @Test
+ fun rawExpression() = invokeAndSum("raw", raw)
+}
diff --git a/kmath-ast/src/jsTest/kotlin/space/kscience/kmath/ast/utils.kt b/kmath-ast/src/jsTest/kotlin/space/kscience/kmath/ast/utils.kt
new file mode 100644
index 000000000..6b5b1b83d
--- /dev/null
+++ b/kmath-ast/src/jsTest/kotlin/space/kscience/kmath/ast/utils.kt
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2018-2021 KMath contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package space.kscience.kmath.ast
+
+import space.kscience.kmath.expressions.Expression
+import space.kscience.kmath.expressions.MST
+import space.kscience.kmath.misc.Symbol
+import space.kscience.kmath.operations.DoubleField
+import space.kscience.kmath.operations.IntRing
+import space.kscience.kmath.estree.compile as estreeCompile
+import space.kscience.kmath.estree.compileToExpression as estreeCompileToExpression
+import space.kscience.kmath.wasm.compile as wasmCompile
+import space.kscience.kmath.wasm.compileToExpression as wasmCompileToExpression
+
+private object WasmCompilerTestContext : CompilerTestContext {
+ override fun MST.compileToExpression(algebra: IntRing): Expression = wasmCompileToExpression(algebra)
+ override fun MST.compile(algebra: IntRing, arguments: Map): Int = wasmCompile(algebra, arguments)
+ override fun MST.compileToExpression(algebra: DoubleField): Expression = wasmCompileToExpression(algebra)
+
+ override fun MST.compile(algebra: DoubleField, arguments: Map): Double =
+ wasmCompile(algebra, arguments)
+}
+
+private object ESTreeCompilerTestContext : CompilerTestContext {
+ override fun MST.compileToExpression(algebra: IntRing): Expression = estreeCompileToExpression(algebra)
+ override fun MST.compile(algebra: IntRing, arguments: Map): Int = estreeCompile(algebra, arguments)
+ override fun MST.compileToExpression(algebra: DoubleField): Expression = estreeCompileToExpression(algebra)
+
+ override fun MST.compile(algebra: DoubleField, arguments: Map): Double =
+ estreeCompile(algebra, arguments)
+}
+
+internal actual inline fun runCompilerTest(action: CompilerTestContext.() -> Unit) {
+ action(WasmCompilerTestContext)
+ action(ESTreeCompilerTestContext)
+}
diff --git a/kmath-ast/src/jsTest/kotlin/space/kscience/kmath/estree/TestESTreeConsistencyWithInterpreter.kt b/kmath-ast/src/jsTest/kotlin/space/kscience/kmath/estree/TestESTreeConsistencyWithInterpreter.kt
deleted file mode 100644
index 5823518ce..000000000
--- a/kmath-ast/src/jsTest/kotlin/space/kscience/kmath/estree/TestESTreeConsistencyWithInterpreter.kt
+++ /dev/null
@@ -1,94 +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.
- */
-
-package space.kscience.kmath.estree
-
-import space.kscience.kmath.complex.ComplexField
-import space.kscience.kmath.complex.toComplex
-import space.kscience.kmath.expressions.*
-import space.kscience.kmath.misc.Symbol
-import space.kscience.kmath.operations.ByteRing
-import space.kscience.kmath.operations.DoubleField
-import space.kscience.kmath.operations.invoke
-import kotlin.test.Test
-import kotlin.test.assertEquals
-
-internal class TestESTreeConsistencyWithInterpreter {
-
- @Test
- fun mstSpace() {
-
- val mst = MstGroup {
- binaryOperationFunction("+")(
- unaryOperationFunction("+")(
- number(3.toByte()) - (number(2.toByte()) + (scale(
- add(number(1), number(1)),
- 2.0
- ) + number(1.toByte()) * 3.toByte() - number(1.toByte())))
- ),
-
- number(1)
- ) + bindSymbol("x") + zero
- }
-
- assertEquals(
- mst.interpret(MstGroup, Symbol.x to MST.Numeric(2)),
- mst.compile(MstGroup, Symbol.x to MST.Numeric(2))
- )
- }
-
- @Test
- fun byteRing() {
- val mst = MstRing {
- binaryOperationFunction("+")(
- unaryOperationFunction("+")(
- (bindSymbol("x") - (2.toByte() + (scale(
- add(number(1), number(1)),
- 2.0
- ) + 1.toByte()))) * 3.0 - 1.toByte()
- ),
-
- number(1)
- ) * number(2)
- }
-
- assertEquals(
- mst.interpret(ByteRing, Symbol.x to 3.toByte()),
- mst.compile(ByteRing, Symbol.x to 3.toByte())
- )
- }
-
- @Test
- fun realField() {
- val mst = MstField {
- +(3 - 2 + 2 * number(1) + 1.0) + binaryOperationFunction("+")(
- (3.0 - (bindSymbol("x") + (scale(add(number(1.0), number(1.0)), 2.0) + 1.0))) * 3 - 1.0
- + number(1),
- number(1) / 2 + number(2.0) * one
- ) + zero
- }
-
- assertEquals(
- mst.interpret(DoubleField, Symbol.x to 2.0),
- mst.compile(DoubleField, Symbol.x to 2.0)
- )
- }
-
- @Test
- fun complexField() {
- val mst = MstField {
- +(3 - 2 + 2 * number(1) + 1.0) + binaryOperationFunction("+")(
- (3.0 - (bindSymbol("x") + (scale(add(number(1.0), number(1.0)), 2.0) + 1.0))) * 3 - 1.0
- + number(1),
- number(1) / 2 + number(2.0) * one
- ) + zero
- }
-
- assertEquals(
- mst.interpret(ComplexField, Symbol.x to 2.0.toComplex()),
- mst.compile(ComplexField, Symbol.x to 2.0.toComplex())
- )
- }
-}
diff --git a/kmath-ast/src/jsTest/kotlin/space/kscience/kmath/estree/TestESTreeOperationsSupport.kt b/kmath-ast/src/jsTest/kotlin/space/kscience/kmath/estree/TestESTreeOperationsSupport.kt
deleted file mode 100644
index a1bff92d0..000000000
--- a/kmath-ast/src/jsTest/kotlin/space/kscience/kmath/estree/TestESTreeOperationsSupport.kt
+++ /dev/null
@@ -1,47 +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.
- */
-
-package space.kscience.kmath.estree
-
-import space.kscience.kmath.expressions.MstExtendedField
-import space.kscience.kmath.expressions.invoke
-import space.kscience.kmath.operations.DoubleField
-import space.kscience.kmath.operations.invoke
-import kotlin.random.Random
-import kotlin.test.Test
-import kotlin.test.assertEquals
-
-internal class TestESTreeOperationsSupport {
- @Test
- fun testUnaryOperationInvocation() {
- val expression = MstExtendedField { -bindSymbol("x") }.compileToExpression(DoubleField)
- val res = expression("x" to 2.0)
- assertEquals(-2.0, res)
- }
-
- @Test
- fun testBinaryOperationInvocation() {
- val expression = MstExtendedField { -bindSymbol("x") + number(1.0) }.compileToExpression(DoubleField)
- val res = expression("x" to 2.0)
- assertEquals(-1.0, res)
- }
-
- @Test
- fun testConstProductInvocation() {
- val res = MstExtendedField { bindSymbol("x") * 2 }.compileToExpression(DoubleField)("x" to 2.0)
- assertEquals(4.0, res)
- }
-
- @Test
- fun testMultipleCalls() {
- val e =
- MstExtendedField { sin(bindSymbol("x")).pow(4) - 6 * bindSymbol("x") / tanh(bindSymbol("x")) }
- .compileToExpression(DoubleField)
- val r = Random(0)
- var s = 0.0
- repeat(1000000) { s += e("x" to r.nextDouble()) }
- println(s)
- }
-}
diff --git a/kmath-ast/src/jsTest/kotlin/space/kscience/kmath/estree/TestESTreeSpecialization.kt b/kmath-ast/src/jsTest/kotlin/space/kscience/kmath/estree/TestESTreeSpecialization.kt
deleted file mode 100644
index b5ae1ca3f..000000000
--- a/kmath-ast/src/jsTest/kotlin/space/kscience/kmath/estree/TestESTreeSpecialization.kt
+++ /dev/null
@@ -1,69 +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.
- */
-
-package space.kscience.kmath.estree
-
-import space.kscience.kmath.expressions.MstExtendedField
-import space.kscience.kmath.expressions.invoke
-import space.kscience.kmath.operations.DoubleField
-import space.kscience.kmath.operations.invoke
-import kotlin.test.Test
-import kotlin.test.assertEquals
-
-internal class TestESTreeSpecialization {
- @Test
- fun testUnaryPlus() {
- val expr = MstExtendedField { unaryOperationFunction("+")(bindSymbol("x")) }.compileToExpression(DoubleField)
- assertEquals(2.0, expr("x" to 2.0))
- }
-
- @Test
- fun testUnaryMinus() {
- val expr = MstExtendedField { unaryOperationFunction("-")(bindSymbol("x")) }.compileToExpression(DoubleField)
- assertEquals(-2.0, expr("x" to 2.0))
- }
-
- @Test
- fun testAdd() {
- val expr = MstExtendedField {
- binaryOperationFunction("+")(bindSymbol("x"),
- bindSymbol("x"))
- }.compileToExpression(DoubleField)
- assertEquals(4.0, expr("x" to 2.0))
- }
-
- @Test
- fun testSine() {
- val expr = MstExtendedField { unaryOperationFunction("sin")(bindSymbol("x")) }.compileToExpression(DoubleField)
- assertEquals(0.0, expr("x" to 0.0))
- }
-
- @Test
- fun testMinus() {
- val expr = MstExtendedField {
- binaryOperationFunction("-")(bindSymbol("x"),
- bindSymbol("x"))
- }.compileToExpression(DoubleField)
- assertEquals(0.0, expr("x" to 2.0))
- }
-
- @Test
- fun testDivide() {
- val expr = MstExtendedField {
- binaryOperationFunction("/")(bindSymbol("x"),
- bindSymbol("x"))
- }.compileToExpression(DoubleField)
- assertEquals(1.0, expr("x" to 2.0))
- }
-
- @Test
- fun testPower() {
- val expr = MstExtendedField {
- binaryOperationFunction("pow")(bindSymbol("x"), number(2))
- }.compileToExpression(DoubleField)
-
- assertEquals(4.0, expr("x" to 2.0))
- }
-}
diff --git a/kmath-ast/src/jsTest/kotlin/space/kscience/kmath/estree/TestESTreeVariables.kt b/kmath-ast/src/jsTest/kotlin/space/kscience/kmath/estree/TestESTreeVariables.kt
deleted file mode 100644
index 1effe14e1..000000000
--- a/kmath-ast/src/jsTest/kotlin/space/kscience/kmath/estree/TestESTreeVariables.kt
+++ /dev/null
@@ -1,28 +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.
- */
-
-package space.kscience.kmath.estree
-
-import space.kscience.kmath.expressions.MstRing
-import space.kscience.kmath.expressions.invoke
-import space.kscience.kmath.operations.ByteRing
-import space.kscience.kmath.operations.invoke
-import kotlin.test.Test
-import kotlin.test.assertEquals
-import kotlin.test.assertFailsWith
-
-internal class TestESTreeVariables {
- @Test
- fun testVariable() {
- val expr = MstRing{ bindSymbol("x") }.compileToExpression(ByteRing)
- assertEquals(1.toByte(), expr("x" to 1.toByte()))
- }
-
- @Test
- fun testUndefinedVariableFails() {
- val expr = MstRing { bindSymbol("x") }.compileToExpression(ByteRing)
- assertFailsWith { expr() }
- }
-}
diff --git a/kmath-ast/src/jsTest/kotlin/space/kscience/kmath/wasm/TestWasmSpecific.kt b/kmath-ast/src/jsTest/kotlin/space/kscience/kmath/wasm/TestWasmSpecific.kt
new file mode 100644
index 000000000..dd5452d04
--- /dev/null
+++ b/kmath-ast/src/jsTest/kotlin/space/kscience/kmath/wasm/TestWasmSpecific.kt
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2018-2021 KMath contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package space.kscience.kmath.wasm
+
+import space.kscience.kmath.expressions.MstExtendedField
+import space.kscience.kmath.expressions.MstRing
+import space.kscience.kmath.expressions.invoke
+import space.kscience.kmath.misc.symbol
+import space.kscience.kmath.operations.DoubleField
+import space.kscience.kmath.operations.IntRing
+import space.kscience.kmath.operations.bindSymbol
+import space.kscience.kmath.operations.invoke
+import kotlin.test.Test
+import kotlin.test.assertEquals
+
+internal class TestWasmSpecific {
+ @Test
+ fun int() {
+ val res = MstRing { number(100000000) + number(10000000) }.compile(IntRing)
+ assertEquals(110000000, res)
+ }
+
+ @Test
+ fun real() {
+ val res = MstExtendedField { number(100000000) + number(2).pow(10) }.compile(DoubleField)
+ assertEquals(100001024.0, res)
+ }
+
+ @Test
+ fun argsPassing() {
+ val res = MstExtendedField { bindSymbol(y) + bindSymbol(x).pow(10) }.compile(
+ DoubleField,
+ x to 2.0,
+ y to 100000000.0,
+ )
+
+ assertEquals(100001024.0, res)
+ }
+
+ @Test
+ fun powFunction() {
+ val expr = MstExtendedField { bindSymbol(x).pow(1.0 / 6.0) }.compileToExpression(DoubleField)
+ assertEquals(0.9730585187140817, expr(x to 0.8488554755054833))
+ }
+
+ private companion object {
+ private val x by symbol
+ private val y by symbol
+ }
+}
diff --git a/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/asm/internal/AsmBuilder.kt b/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/asm/internal/AsmBuilder.kt
index bdd8f52b6..39ebf049d 100644
--- a/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/asm/internal/AsmBuilder.kt
+++ b/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/asm/internal/AsmBuilder.kt
@@ -342,8 +342,8 @@ internal class AsmBuilder(
val MAP_INTRINSICS_TYPE: Type by lazy { getObjectType("space/kscience/kmath/asm/internal/MapIntrinsics") }
/**
- * ASM Type for [kscience.kmath.expressions.Symbol].
+ * ASM Type for [space.kscience.kmath.misc.Symbol].
*/
- val SYMBOL_TYPE: Type by lazy { getObjectType("space/kscience/kmath/expressions/Symbol") }
+ val SYMBOL_TYPE: Type by lazy { getObjectType("space/kscience/kmath/misc/Symbol") }
}
}
diff --git a/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/asm/internal/codegenUtils.kt b/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/asm/internal/codegenUtils.kt
index 560780f99..cfac59847 100644
--- a/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/asm/internal/codegenUtils.kt
+++ b/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/asm/internal/codegenUtils.kt
@@ -52,7 +52,7 @@ internal inline fun MethodVisitor.instructionAdapter(block: InstructionAdapter.(
*
* @author Iaroslav Postovalov
*/
-internal fun MethodVisitor.label(): Label = Label().also { visitLabel(it) }
+internal fun MethodVisitor.label(): Label = Label().also(::visitLabel)
/**
* Creates a class name for [Expression] subclassed to implement [mst] provided.
diff --git a/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/ast/rendering/multiplatformToString.kt b/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/ast/rendering/multiplatformToString.kt
new file mode 100644
index 000000000..556adbe7d
--- /dev/null
+++ b/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/ast/rendering/multiplatformToString.kt
@@ -0,0 +1,9 @@
+/*
+ * Copyright 2018-2021 KMath contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package space.kscience.kmath.ast.rendering
+
+internal actual fun Double.multiplatformToString(): String = toString()
+internal actual fun Float.multiplatformToString(): String = toString()
diff --git a/kmath-ast/src/jvmTest/kotlin/space/kscience/kmath/asm/TestAsmConsistencyWithInterpreter.kt b/kmath-ast/src/jvmTest/kotlin/space/kscience/kmath/asm/TestAsmConsistencyWithInterpreter.kt
deleted file mode 100644
index 77cfb2241..000000000
--- a/kmath-ast/src/jvmTest/kotlin/space/kscience/kmath/asm/TestAsmConsistencyWithInterpreter.kt
+++ /dev/null
@@ -1,94 +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.
- */
-
-package space.kscience.kmath.asm
-
-import space.kscience.kmath.complex.ComplexField
-import space.kscience.kmath.complex.toComplex
-import space.kscience.kmath.expressions.*
-import space.kscience.kmath.misc.Symbol.Companion.x
-import space.kscience.kmath.operations.ByteRing
-import space.kscience.kmath.operations.DoubleField
-import space.kscience.kmath.operations.invoke
-import kotlin.test.Test
-import kotlin.test.assertEquals
-
-internal class TestAsmConsistencyWithInterpreter {
-
- @Test
- fun mstSpace() {
-
- val mst = MstGroup {
- binaryOperationFunction("+")(
- unaryOperationFunction("+")(
- number(3.toByte()) - (number(2.toByte()) + (scale(
- add(number(1), number(1)),
- 2.0
- ) + number(1.toByte()) * 3.toByte() - number(1.toByte())))
- ),
-
- number(1)
- ) + bindSymbol("x") + zero
- }
-
- assertEquals(
- mst.interpret(MstGroup, x to MST.Numeric(2)),
- mst.compile(MstGroup, x to MST.Numeric(2))
- )
- }
-
- @Test
- fun byteRing() {
- val mst = MstRing {
- binaryOperationFunction("+")(
- unaryOperationFunction("+")(
- (bindSymbol("x") - (2.toByte() + (scale(
- add(number(1), number(1)),
- 2.0
- ) + 1.toByte()))) * 3.0 - 1.toByte()
- ),
-
- number(1)
- ) * number(2)
- }
-
- assertEquals(
- mst.interpret(ByteRing, x to 3.toByte()),
- mst.compile(ByteRing, x to 3.toByte())
- )
- }
-
- @Test
- fun realField() {
- val mst = MstField {
- +(3 - 2 + 2 * number(1) + 1.0) + binaryOperationFunction("+")(
- (3.0 - (bindSymbol("x") + (scale(add(number(1.0), number(1.0)), 2.0) + 1.0))) * 3 - 1.0
- + number(1),
- number(1) / 2 + number(2.0) * one
- ) + zero
- }
-
- assertEquals(
- mst.interpret(DoubleField, x to 2.0),
- mst.compile(DoubleField, x to 2.0)
- )
- }
-
- @Test
- fun complexField() {
- val mst = MstField {
- +(3 - 2 + 2 * number(1) + 1.0) + binaryOperationFunction("+")(
- (3.0 - (bindSymbol("x") + (scale(add(number(1.0), number(1.0)), 2.0) + 1.0))) * 3 - 1.0
- + number(1),
- number(1) / 2 + number(2.0) * one
- ) + zero
- }
-
- assertEquals(
- mst.interpret(ComplexField, x to 2.0.toComplex()),
- mst.compile(ComplexField, x to 2.0.toComplex())
- )
- }
-}
diff --git a/kmath-ast/src/jvmTest/kotlin/space/kscience/kmath/asm/TestAsmOperationsSupport.kt b/kmath-ast/src/jvmTest/kotlin/space/kscience/kmath/asm/TestAsmOperationsSupport.kt
deleted file mode 100644
index 757235fb7..000000000
--- a/kmath-ast/src/jvmTest/kotlin/space/kscience/kmath/asm/TestAsmOperationsSupport.kt
+++ /dev/null
@@ -1,49 +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.
- */
-
-package space.kscience.kmath.asm
-
-import space.kscience.kmath.expressions.MstExtendedField
-import space.kscience.kmath.expressions.MstField
-import space.kscience.kmath.expressions.MstGroup
-import space.kscience.kmath.expressions.invoke
-import space.kscience.kmath.operations.DoubleField
-import space.kscience.kmath.operations.invoke
-import kotlin.random.Random
-import kotlin.test.Test
-import kotlin.test.assertEquals
-
-internal class TestAsmOperationsSupport {
- @Test
- fun testUnaryOperationInvocation() {
- val expression = MstGroup { -bindSymbol("x") }.compileToExpression(DoubleField)
- val res = expression("x" to 2.0)
- assertEquals(-2.0, res)
- }
-
- @Test
- fun testBinaryOperationInvocation() {
- val expression = MstGroup { -bindSymbol("x") + number(1.0) }.compileToExpression(DoubleField)
- val res = expression("x" to 2.0)
- assertEquals(-1.0, res)
- }
-
- @Test
- fun testConstProductInvocation() {
- val res = MstField { bindSymbol("x") * 2 }.compileToExpression(DoubleField)("x" to 2.0)
- assertEquals(4.0, res)
- }
-
- @Test
- fun testMultipleCalls() {
- val e =
- MstExtendedField { sin(bindSymbol("x")).pow(4) - 6 * bindSymbol("x") / tanh(bindSymbol("x")) }
- .compileToExpression(DoubleField)
- val r = Random(0)
- var s = 0.0
- repeat(1000000) { s += e("x" to r.nextDouble()) }
- println(s)
- }
-}
diff --git a/kmath-ast/src/jvmTest/kotlin/space/kscience/kmath/asm/TestAsmSpecialization.kt b/kmath-ast/src/jvmTest/kotlin/space/kscience/kmath/asm/TestAsmSpecialization.kt
deleted file mode 100644
index b09d79515..000000000
--- a/kmath-ast/src/jvmTest/kotlin/space/kscience/kmath/asm/TestAsmSpecialization.kt
+++ /dev/null
@@ -1,69 +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.
- */
-
-package space.kscience.kmath.asm
-
-import space.kscience.kmath.expressions.MstExtendedField
-import space.kscience.kmath.expressions.invoke
-import space.kscience.kmath.operations.DoubleField
-import space.kscience.kmath.operations.invoke
-import kotlin.test.Test
-import kotlin.test.assertEquals
-
-internal class TestAsmSpecialization {
- @Test
- fun testUnaryPlus() {
- val expr = MstExtendedField { unaryOperationFunction("+")(bindSymbol("x")) }.compileToExpression(DoubleField)
- assertEquals(2.0, expr("x" to 2.0))
- }
-
- @Test
- fun testUnaryMinus() {
- val expr = MstExtendedField { unaryOperationFunction("-")(bindSymbol("x")) }.compileToExpression(DoubleField)
- assertEquals(-2.0, expr("x" to 2.0))
- }
-
- @Test
- fun testAdd() {
- val expr = MstExtendedField {
- binaryOperationFunction("+")(bindSymbol("x"),
- bindSymbol("x"))
- }.compileToExpression(DoubleField)
- assertEquals(4.0, expr("x" to 2.0))
- }
-
- @Test
- fun testSine() {
- val expr = MstExtendedField { unaryOperationFunction("sin")(bindSymbol("x")) }.compileToExpression(DoubleField)
- assertEquals(0.0, expr("x" to 0.0))
- }
-
- @Test
- fun testMinus() {
- val expr = MstExtendedField {
- binaryOperationFunction("-")(bindSymbol("x"),
- bindSymbol("x"))
- }.compileToExpression(DoubleField)
- assertEquals(0.0, expr("x" to 2.0))
- }
-
- @Test
- fun testDivide() {
- val expr = MstExtendedField {
- binaryOperationFunction("/")(bindSymbol("x"),
- bindSymbol("x"))
- }.compileToExpression(DoubleField)
- assertEquals(1.0, expr("x" to 2.0))
- }
-
- @Test
- fun testPower() {
- val expr = MstExtendedField {
- binaryOperationFunction("pow")(bindSymbol("x"), number(2))
- }.compileToExpression(DoubleField)
-
- assertEquals(4.0, expr("x" to 2.0))
- }
-}
diff --git a/kmath-ast/src/jvmTest/kotlin/space/kscience/kmath/asm/TestAsmVariables.kt b/kmath-ast/src/jvmTest/kotlin/space/kscience/kmath/asm/TestAsmVariables.kt
deleted file mode 100644
index 740326a59..000000000
--- a/kmath-ast/src/jvmTest/kotlin/space/kscience/kmath/asm/TestAsmVariables.kt
+++ /dev/null
@@ -1,28 +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.
- */
-
-package space.kscience.kmath.asm
-
-import space.kscience.kmath.expressions.MstRing
-import space.kscience.kmath.expressions.invoke
-import space.kscience.kmath.operations.ByteRing
-import space.kscience.kmath.operations.invoke
-import kotlin.test.Test
-import kotlin.test.assertEquals
-import kotlin.test.assertFailsWith
-
-internal class TestAsmVariables {
- @Test
- fun testVariable() {
- val expr = MstRing { bindSymbol("x") }.compileToExpression(ByteRing)
- assertEquals(1.toByte(), expr("x" to 1.toByte()))
- }
-
- @Test
- fun testUndefinedVariableFails() {
- val expr = MstRing { bindSymbol("x") }.compileToExpression(ByteRing)
- assertFailsWith { expr() }
- }
-}
diff --git a/kmath-ast/src/jvmTest/kotlin/space/kscience/kmath/ast/utils.kt b/kmath-ast/src/jvmTest/kotlin/space/kscience/kmath/ast/utils.kt
new file mode 100644
index 000000000..607c5fdd6
--- /dev/null
+++ b/kmath-ast/src/jvmTest/kotlin/space/kscience/kmath/ast/utils.kt
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2018-2021 KMath contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package space.kscience.kmath.ast
+
+import space.kscience.kmath.expressions.Expression
+import space.kscience.kmath.expressions.MST
+import space.kscience.kmath.misc.Symbol
+import space.kscience.kmath.operations.DoubleField
+import space.kscience.kmath.operations.IntRing
+import space.kscience.kmath.asm.compile as asmCompile
+import space.kscience.kmath.asm.compileToExpression as asmCompileToExpression
+
+private object AsmCompilerTestContext : CompilerTestContext {
+ override fun MST.compileToExpression(algebra: IntRing): Expression = asmCompileToExpression(algebra)
+ override fun MST.compile(algebra: IntRing, arguments: Map): Int = asmCompile(algebra, arguments)
+ override fun MST.compileToExpression(algebra: DoubleField): Expression = asmCompileToExpression(algebra)
+
+ override fun MST.compile(algebra: DoubleField, arguments: Map): Double =
+ asmCompile(algebra, arguments)
+}
+
+internal actual inline fun runCompilerTest(action: CompilerTestContext.() -> Unit) = action(AsmCompilerTestContext)
diff --git a/kmath-commons/build.gradle.kts b/kmath-commons/build.gradle.kts
index 570ac2b74..a208c956c 100644
--- a/kmath-commons/build.gradle.kts
+++ b/kmath-commons/build.gradle.kts
@@ -1,12 +1,8 @@
-/*
- * 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.
- */
-
plugins {
kotlin("jvm")
id("ru.mipt.npm.gradle.common")
}
+
description = "Commons math binding for kmath"
dependencies {
diff --git a/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/integration/CMIntegrator.kt b/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/integration/CMIntegrator.kt
index 535c6b39e..92bf86128 100644
--- a/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/integration/CMIntegrator.kt
+++ b/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/integration/CMIntegrator.kt
@@ -28,7 +28,7 @@ public class CMIntegrator(
val integrator = integratorBuilder(integrand)
val maxCalls = integrand.getFeature()?.maxCalls ?: defaultMaxCalls
val remainingCalls = maxCalls - integrand.calls
- val range = integrand.getFeature>()?.range
+ val range = integrand.getFeature()?.range
?: error("Integration range is not provided")
val res = integrator.integrate(remainingCalls, integrand.function, range.start, range.endInclusive)
diff --git a/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/integration/GaussRuleIntegrator.kt b/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/integration/GaussRuleIntegrator.kt
index 071bac315..1c9915563 100644
--- a/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/integration/GaussRuleIntegrator.kt
+++ b/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/integration/GaussRuleIntegrator.kt
@@ -17,7 +17,7 @@ public class GaussRuleIntegrator(
) : UnivariateIntegrator {
override fun integrate(integrand: UnivariateIntegrand): UnivariateIntegrand {
- val range = integrand.getFeature>()?.range
+ val range = integrand.getFeature()?.range
?: error("Integration range is not provided")
val integrator: GaussIntegrator = getIntegrator(range)
//TODO check performance
diff --git a/kmath-commons/src/test/kotlin/space/kscience/kmath/commons/integration/IntegrationTest.kt b/kmath-commons/src/test/kotlin/space/kscience/kmath/commons/integration/IntegrationTest.kt
index 9d475d04d..97dc94d1d 100644
--- a/kmath-commons/src/test/kotlin/space/kscience/kmath/commons/integration/IntegrationTest.kt
+++ b/kmath-commons/src/test/kotlin/space/kscience/kmath/commons/integration/IntegrationTest.kt
@@ -19,16 +19,16 @@ internal class IntegrationTest {
@Test
fun simpson() {
- val res = CMIntegrator.simpson().integrate(0.0..2 * PI, function)
+ val res = CMIntegrator.simpson().integrate(0.0..2 * PI, function = function)
assertTrue { abs(res) < 1e-3 }
}
@Test
fun customSimpson() {
- val res = CMIntegrator.simpson().integrate(0.0..PI, function) {
+ val res = CMIntegrator.simpson().integrate(0.0..PI, {
targetRelativeAccuracy = 1e-4
targetAbsoluteAccuracy = 1e-4
- }
+ }, function)
assertTrue { abs(res - 2) < 1e-3 }
assertTrue { abs(res - 2) > 1e-12 }
}
diff --git a/kmath-complex/README.md b/kmath-complex/README.md
index 3a05c3d6d..ee5ad416f 100644
--- a/kmath-complex/README.md
+++ b/kmath-complex/README.md
@@ -8,29 +8,27 @@ Complex and hypercomplex number systems in KMath.
## Artifact:
-The Maven coordinates of this project are `space.kscience:kmath-complex:0.3.0-dev-6`.
+The Maven coordinates of this project are `space.kscience:kmath-complex:0.3.0-dev-8`.
**Gradle:**
```gradle
repositories {
maven { url 'https://repo.kotlin.link' }
- maven { url 'https://dl.bintray.com/hotkeytlt/maven' }
- maven { url "https://dl.bintray.com/kotlin/kotlin-eap" } // include for builds based on kotlin-eap
+ mavenCentral()
}
dependencies {
- implementation 'space.kscience:kmath-complex:0.3.0-dev-6'
+ implementation 'space.kscience:kmath-complex:0.3.0-dev-8'
}
```
**Gradle Kotlin DSL:**
```kotlin
repositories {
maven("https://repo.kotlin.link")
- maven("https://dl.bintray.com/kotlin/kotlin-eap") // include for builds based on kotlin-eap
- maven("https://dl.bintray.com/hotkeytlt/maven") // required for a
+ mavenCentral()
}
dependencies {
- implementation("space.kscience:kmath-complex:0.3.0-dev-6")
+ implementation("space.kscience:kmath-complex:0.3.0-dev-8")
}
```
diff --git a/kmath-complex/build.gradle.kts b/kmath-complex/build.gradle.kts
index 1c2e8a0a2..ea74df646 100644
--- a/kmath-complex/build.gradle.kts
+++ b/kmath-complex/build.gradle.kts
@@ -1,10 +1,3 @@
-import ru.mipt.npm.gradle.Maturity
-
-/*
- * 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.
- */
-
plugins {
kotlin("multiplatform")
id("ru.mipt.npm.gradle.common")
@@ -21,7 +14,7 @@ kotlin.sourceSets {
readme {
description = "Complex numbers and quaternions."
- maturity = Maturity.PROTOTYPE
+ maturity = ru.mipt.npm.gradle.Maturity.PROTOTYPE
propertyByTemplate("artifact", rootProject.file("docs/templates/ARTIFACT-TEMPLATE.md"))
feature(
diff --git a/kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/Complex.kt b/kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/Complex.kt
index 8d626c17d..a96d046c9 100644
--- a/kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/Complex.kt
+++ b/kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/Complex.kt
@@ -9,7 +9,10 @@ import space.kscience.kmath.memory.MemoryReader
import space.kscience.kmath.memory.MemorySpec
import space.kscience.kmath.memory.MemoryWriter
import space.kscience.kmath.misc.UnstableKMathAPI
-import space.kscience.kmath.operations.*
+import space.kscience.kmath.operations.ExtendedField
+import space.kscience.kmath.operations.Norm
+import space.kscience.kmath.operations.NumbersAddOperations
+import space.kscience.kmath.operations.ScaleOperations
import space.kscience.kmath.structures.Buffer
import space.kscience.kmath.structures.MemoryBuffer
import space.kscience.kmath.structures.MutableBuffer
@@ -180,13 +183,11 @@ public object ComplexField : ExtendedField, Norm, Num
* @property im The imaginary part.
*/
@OptIn(UnstableKMathAPI::class)
-public data class Complex(val re: Double, val im: Double) : FieldElement {
+public data class Complex(val re: Double, val im: Double) {
public constructor(re: Number, im: Number) : this(re.toDouble(), im.toDouble())
public constructor(re: Number) : this(re.toDouble(), 0.0)
- public override val context: ComplexField get() = ComplexField
-
- public override fun toString(): String = "($re + i*$im)"
+ public override fun toString(): String = "($re + i * $im)"
public companion object : MemorySpec {
public override val objectSize: Int
diff --git a/kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/Quaternion.kt b/kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/Quaternion.kt
index 382b5cc05..c59aabdcb 100644
--- a/kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/Quaternion.kt
+++ b/kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/Quaternion.kt
@@ -27,8 +27,10 @@ public val Quaternion.conjugate: Quaternion
*/
public val Quaternion.reciprocal: Quaternion
get() {
- val n = QuaternionField { norm(this@reciprocal) }
- return conjugate / (n * n)
+ QuaternionField {
+ val n = norm(this@reciprocal)
+ return conjugate / (n * n)
+ }
}
/**
@@ -198,7 +200,7 @@ public object QuaternionField : Field, Norm,
@OptIn(UnstableKMathAPI::class)
public data class Quaternion(
val w: Double, val x: Double, val y: Double, val z: Double,
-) : FieldElement {
+) {
public constructor(w: Number, x: Number, y: Number, z: Number) : this(
w.toDouble(),
x.toDouble(),
@@ -219,8 +221,6 @@ public data class Quaternion(
require(!z.isNaN()) { "x-component of quaternion is not-a-number" }
}
- public override val context: QuaternionField get() = QuaternionField
-
/**
* Returns a string representation of this quaternion.
*/
diff --git a/kmath-core/README.md b/kmath-core/README.md
index b83fb13d0..7283a18ce 100644
--- a/kmath-core/README.md
+++ b/kmath-core/README.md
@@ -15,29 +15,27 @@ performance calculations to code generation.
## Artifact:
-The Maven coordinates of this project are `space.kscience:kmath-core:0.3.0-dev-6`.
+The Maven coordinates of this project are `space.kscience:kmath-core:0.3.0-dev-8`.
**Gradle:**
```gradle
repositories {
maven { url 'https://repo.kotlin.link' }
- maven { url 'https://dl.bintray.com/hotkeytlt/maven' }
- maven { url "https://dl.bintray.com/kotlin/kotlin-eap" } // include for builds based on kotlin-eap
+ mavenCentral()
}
dependencies {
- implementation 'space.kscience:kmath-core:0.3.0-dev-6'
+ implementation 'space.kscience:kmath-core:0.3.0-dev-8'
}
```
**Gradle Kotlin DSL:**
```kotlin
repositories {
maven("https://repo.kotlin.link")
- maven("https://dl.bintray.com/kotlin/kotlin-eap") // include for builds based on kotlin-eap
- maven("https://dl.bintray.com/hotkeytlt/maven") // required for a
+ mavenCentral()
}
dependencies {
- implementation("space.kscience:kmath-core:0.3.0-dev-6")
+ implementation("space.kscience:kmath-core:0.3.0-dev-8")
}
```
diff --git a/kmath-core/api/kmath-core.api b/kmath-core/api/kmath-core.api
index 6b300123c..14bc70a2a 100644
--- a/kmath-core/api/kmath-core.api
+++ b/kmath-core/api/kmath-core.api
@@ -45,13 +45,6 @@ public abstract interface class space/kscience/kmath/expressions/ExpressionAlgeb
public abstract fun const (Ljava/lang/Object;)Ljava/lang/Object;
}
-public final class space/kscience/kmath/expressions/ExpressionBuildersKt {
- public static final fun extendedFieldExpression (Lspace/kscience/kmath/operations/ExtendedField;Lkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/expressions/Expression;
- public static final fun fieldExpression (Lspace/kscience/kmath/operations/Field;Lkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/expressions/Expression;
- public static final fun ringExpression (Lspace/kscience/kmath/operations/Ring;Lkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/expressions/Expression;
- public static final fun spaceExpression (Lspace/kscience/kmath/operations/Ring;Lkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/expressions/Expression;
-}
-
public final class space/kscience/kmath/expressions/ExpressionKt {
public static final fun binding (Lspace/kscience/kmath/expressions/ExpressionAlgebra;)Lkotlin/properties/ReadOnlyProperty;
public static final fun callByString (Lspace/kscience/kmath/expressions/Expression;[Lkotlin/Pair;)Ljava/lang/Object;
@@ -272,6 +265,8 @@ public final class space/kscience/kmath/expressions/MstExtendedField : space/ksc
public fun sin (Lspace/kscience/kmath/expressions/MST;)Lspace/kscience/kmath/expressions/MST$Unary;
public synthetic fun sinh (Ljava/lang/Object;)Ljava/lang/Object;
public fun sinh (Lspace/kscience/kmath/expressions/MST;)Lspace/kscience/kmath/expressions/MST$Unary;
+ public synthetic fun sqrt (Ljava/lang/Object;)Ljava/lang/Object;
+ public fun sqrt (Lspace/kscience/kmath/expressions/MST;)Lspace/kscience/kmath/expressions/MST;
public synthetic fun tan (Ljava/lang/Object;)Ljava/lang/Object;
public fun tan (Lspace/kscience/kmath/expressions/MST;)Lspace/kscience/kmath/expressions/MST$Unary;
public synthetic fun tanh (Ljava/lang/Object;)Ljava/lang/Object;
@@ -679,6 +674,9 @@ public final class space/kscience/kmath/misc/CumulativeKt {
public static final fun cumulativeSumOfLong (Lkotlin/sequences/Sequence;)Lkotlin/sequences/Sequence;
}
+public abstract interface annotation class space/kscience/kmath/misc/PerformancePitfall : java/lang/annotation/Annotation {
+}
+
public final class space/kscience/kmath/misc/StringSymbol : space/kscience/kmath/misc/Symbol {
public static final synthetic fun box-impl (Ljava/lang/String;)Lspace/kscience/kmath/misc/StringSymbol;
public static fun constructor-impl (Ljava/lang/String;)Ljava/lang/String;
@@ -705,7 +703,11 @@ public final class space/kscience/kmath/misc/Symbol$Companion {
}
public final class space/kscience/kmath/misc/SymbolKt {
+ public static final fun get (Ljava/util/Map;Ljava/lang/String;)Ljava/lang/Object;
+ public static final fun get (Ljava/util/Map;Lspace/kscience/kmath/misc/Symbol;)Ljava/lang/Object;
public static final fun getSymbol ()Lkotlin/properties/ReadOnlyProperty;
+ public static final fun set (Ljava/util/Map;Ljava/lang/String;Ljava/lang/Object;)V
+ public static final fun set (Ljava/util/Map;Lspace/kscience/kmath/misc/Symbol;Ljava/lang/Object;)V
}
public abstract interface annotation class space/kscience/kmath/misc/UnstableKMathAPI : java/lang/annotation/Annotation {
@@ -748,7 +750,7 @@ public final class space/kscience/kmath/nd/BufferAlgebraNDKt {
public static final fun ring (Lspace/kscience/kmath/nd/AlgebraND$Companion;Lspace/kscience/kmath/operations/Ring;Lkotlin/jvm/functions/Function2;[I)Lspace/kscience/kmath/nd/BufferedRingND;
}
-public final class space/kscience/kmath/nd/BufferND : space/kscience/kmath/nd/StructureND {
+public class space/kscience/kmath/nd/BufferND : space/kscience/kmath/nd/StructureND {
public fun (Lspace/kscience/kmath/nd/Strides;Lspace/kscience/kmath/structures/Buffer;)V
public fun elements ()Lkotlin/sequences/Sequence;
public fun get ([I)Ljava/lang/Object;
@@ -789,10 +791,9 @@ public final class space/kscience/kmath/nd/DefaultStrides : space/kscience/kmath
public fun equals (Ljava/lang/Object;)Z
public fun getLinearSize ()I
public fun getShape ()[I
- public fun getStrides ()Ljava/util/List;
+ public fun getStrides ()[I
public fun hashCode ()I
public fun index (I)[I
- public fun offset ([I)I
}
public final class space/kscience/kmath/nd/DefaultStrides$Companion {
@@ -876,6 +877,22 @@ public abstract interface class space/kscience/kmath/nd/GroupND : space/kscience
public final class space/kscience/kmath/nd/GroupND$Companion {
}
+public final class space/kscience/kmath/nd/MutableBufferND : space/kscience/kmath/nd/BufferND, space/kscience/kmath/nd/MutableStructureND {
+ public fun (Lspace/kscience/kmath/nd/Strides;Lspace/kscience/kmath/structures/MutableBuffer;)V
+ public final fun getMutableBuffer ()Lspace/kscience/kmath/structures/MutableBuffer;
+ public fun set ([ILjava/lang/Object;)V
+}
+
+public abstract interface class space/kscience/kmath/nd/MutableStructure1D : space/kscience/kmath/nd/MutableStructureND, space/kscience/kmath/nd/Structure1D, space/kscience/kmath/structures/MutableBuffer {
+ public fun set ([ILjava/lang/Object;)V
+}
+
+public abstract interface class space/kscience/kmath/nd/MutableStructure2D : space/kscience/kmath/nd/MutableStructureND, space/kscience/kmath/nd/Structure2D {
+ public fun getColumns ()Ljava/util/List;
+ public fun getRows ()Ljava/util/List;
+ public abstract fun set (IILjava/lang/Object;)V
+}
+
public abstract interface class space/kscience/kmath/nd/MutableStructureND : space/kscience/kmath/nd/StructureND {
public abstract fun set ([ILjava/lang/Object;)V
}
@@ -915,10 +932,10 @@ public final class space/kscience/kmath/nd/ShortRingNDKt {
public abstract interface class space/kscience/kmath/nd/Strides {
public abstract fun getLinearSize ()I
public abstract fun getShape ()[I
- public abstract fun getStrides ()Ljava/util/List;
+ public abstract fun getStrides ()[I
public abstract fun index (I)[I
public fun indices ()Lkotlin/sequences/Sequence;
- public abstract fun offset ([I)I
+ public fun offset ([I)I
}
public abstract interface class space/kscience/kmath/nd/Structure1D : space/kscience/kmath/nd/StructureND, space/kscience/kmath/structures/Buffer {
@@ -932,6 +949,7 @@ public final class space/kscience/kmath/nd/Structure1D$Companion {
}
public final class space/kscience/kmath/nd/Structure1DKt {
+ public static final fun as1D (Lspace/kscience/kmath/nd/MutableStructureND;)Lspace/kscience/kmath/nd/MutableStructure1D;
public static final fun as1D (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/Structure1D;
public static final fun asND (Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/nd/Structure1D;
}
@@ -952,6 +970,7 @@ public final class space/kscience/kmath/nd/Structure2D$Companion {
}
public final class space/kscience/kmath/nd/Structure2DKt {
+ public static final fun as2D (Lspace/kscience/kmath/nd/MutableStructureND;)Lspace/kscience/kmath/nd/MutableStructure2D;
public static final fun as2D (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/Structure2D;
}
@@ -991,14 +1010,7 @@ public abstract interface class space/kscience/kmath/operations/Algebra {
public fun unaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function1;
}
-public abstract interface class space/kscience/kmath/operations/AlgebraElement {
- public abstract fun getContext ()Lspace/kscience/kmath/operations/Algebra;
-}
-
public final class space/kscience/kmath/operations/AlgebraElementsKt {
- public static final fun div (Lspace/kscience/kmath/operations/AlgebraElement;Lspace/kscience/kmath/operations/AlgebraElement;)Lspace/kscience/kmath/operations/AlgebraElement;
- public static final fun plus (Lspace/kscience/kmath/operations/AlgebraElement;Lspace/kscience/kmath/operations/AlgebraElement;)Lspace/kscience/kmath/operations/AlgebraElement;
- public static final fun times (Lspace/kscience/kmath/operations/AlgebraElement;Lspace/kscience/kmath/operations/AlgebraElement;)Lspace/kscience/kmath/operations/AlgebraElement;
}
public final class space/kscience/kmath/operations/AlgebraExtensionsKt {
@@ -1209,7 +1221,6 @@ public abstract interface class space/kscience/kmath/operations/ExtendedField :
public fun acosh (Ljava/lang/Object;)Ljava/lang/Object;
public fun asinh (Ljava/lang/Object;)Ljava/lang/Object;
public fun atanh (Ljava/lang/Object;)Ljava/lang/Object;
- public fun bindSymbol (Ljava/lang/String;)Ljava/lang/Object;
public fun cosh (Ljava/lang/Object;)Ljava/lang/Object;
public fun rightSideNumberOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2;
public fun sinh (Ljava/lang/Object;)Ljava/lang/Object;
diff --git a/kmath-core/build.gradle.kts b/kmath-core/build.gradle.kts
index df70aa40b..92a5f419d 100644
--- a/kmath-core/build.gradle.kts
+++ b/kmath-core/build.gradle.kts
@@ -1,10 +1,3 @@
-/*
- * 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.
- */
-
-import ru.mipt.npm.gradle.Maturity
-
plugins {
kotlin("multiplatform")
id("ru.mipt.npm.gradle.common")
@@ -21,7 +14,7 @@ kotlin.sourceSets {
readme {
description = "Core classes, algebra definitions, basic linear algebra"
- maturity = Maturity.DEVELOPMENT
+ maturity = ru.mipt.npm.gradle.Maturity.DEVELOPMENT
propertyByTemplate("artifact", rootProject.file("docs/templates/ARTIFACT-TEMPLATE.md"))
feature(
diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/data/ColumnarData.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/data/ColumnarData.kt
index abbb46583..febf615a8 100644
--- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/data/ColumnarData.kt
+++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/data/ColumnarData.kt
@@ -5,6 +5,7 @@
package space.kscience.kmath.data
+import space.kscience.kmath.misc.PerformancePitfall
import space.kscience.kmath.misc.Symbol
import space.kscience.kmath.misc.UnstableKMathAPI
import space.kscience.kmath.nd.Structure2D
@@ -25,6 +26,7 @@ public interface ColumnarData {
* A zero-copy method to represent a [Structure2D] as a two-column x-y data.
* There could more than two columns in the structure.
*/
+@OptIn(PerformancePitfall::class)
@UnstableKMathAPI
public fun Structure2D.asColumnarData(mapping: Map): ColumnarData {
require(shape[1] >= mapping.maxOf { it.value }) { "Column index out of bounds" }
diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/data/XYColumnarData.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/data/XYColumnarData.kt
index 663908e90..56bb59826 100644
--- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/data/XYColumnarData.kt
+++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/data/XYColumnarData.kt
@@ -5,6 +5,7 @@
package space.kscience.kmath.data
+import space.kscience.kmath.misc.PerformancePitfall
import space.kscience.kmath.misc.Symbol
import space.kscience.kmath.misc.UnstableKMathAPI
import space.kscience.kmath.nd.Structure2D
@@ -49,6 +50,7 @@ public fun XYColumnarData(x: Buffer, y: Buffer): XYColum
* A zero-copy method to represent a [Structure2D] as a two-column x-y data.
* There could more than two columns in the structure.
*/
+@OptIn(PerformancePitfall::class)
@UnstableKMathAPI
public fun Structure2D.asXYData(xIndex: Int = 0, yIndex: Int = 1): XYColumnarData {
require(shape[1] >= max(xIndex, yIndex)) { "Column index out of bounds" }
diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/MstAlgebra.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/MstAlgebra.kt
index 32a7efc1e..53124b777 100644
--- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/MstAlgebra.kt
+++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/MstAlgebra.kt
@@ -135,6 +135,7 @@ public object MstExtendedField : ExtendedField, NumericAlgebra {
public override fun acosh(arg: MST): MST.Unary = unaryOperationFunction(ExponentialOperations.ACOSH_OPERATION)(arg)
public override fun atanh(arg: MST): MST.Unary = unaryOperationFunction(ExponentialOperations.ATANH_OPERATION)(arg)
public override fun add(a: MST, b: MST): MST.Binary = MstField.add(a, b)
+ public override fun sqrt(arg: MST): MST = unaryOperationFunction(PowerOperations.SQRT_OPERATION)(arg)
public override fun scale(a: MST, value: Double): MST =
binaryOperation(GroupOperations.PLUS_OPERATION, a, number(value))
diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/SymbolIndexer.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/SymbolIndexer.kt
index 886008983..738156975 100644
--- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/SymbolIndexer.kt
+++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/SymbolIndexer.kt
@@ -33,12 +33,12 @@ public interface SymbolIndexer {
public operator fun DoubleArray.get(symbol: Symbol): Double {
require(size == symbols.size) { "The input array size for indexer should be ${symbols.size} but $size found" }
- return get(this@SymbolIndexer.indexOf(symbol))
+ return get(indexOf(symbol))
}
public operator fun Point.get(symbol: Symbol): T {
require(size == symbols.size) { "The input buffer size for indexer should be ${symbols.size} but $size found" }
- return get(this@SymbolIndexer.indexOf(symbol))
+ return get(indexOf(symbol))
}
public fun DoubleArray.toMap(): Map {
diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/expressionBuilders.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/expressionBuilders.kt
deleted file mode 100644
index 142194070..000000000
--- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/expressionBuilders.kt
+++ /dev/null
@@ -1,45 +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.
- */
-
-package space.kscience.kmath.expressions
-
-import space.kscience.kmath.operations.ExtendedField
-import space.kscience.kmath.operations.Field
-import space.kscience.kmath.operations.Ring
-import kotlin.contracts.InvocationKind
-import kotlin.contracts.contract
-
-
-/**
- * Creates a functional expression with this [Ring].
- */
-public inline fun Ring.spaceExpression(block: FunctionalExpressionGroup>.() -> Expression): Expression {
- contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }
- return FunctionalExpressionGroup(this).block()
-}
-
-/**
- * Creates a functional expression with this [Ring].
- */
-public inline fun Ring.ringExpression(block: FunctionalExpressionRing>.() -> Expression): Expression {
- contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }
- return FunctionalExpressionRing(this).block()
-}
-
-/**
- * Creates a functional expression with this [Field].
- */
-public inline fun Field.fieldExpression(block: FunctionalExpressionField>.() -> Expression): Expression {
- contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }
- return FunctionalExpressionField(this).block()
-}
-
-/**
- * Creates a functional expression with this [ExtendedField].
- */
-public inline fun ExtendedField.extendedFieldExpression(block: FunctionalExpressionExtendedField>.() -> Expression): Expression {
- contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }
- return FunctionalExpressionExtendedField(this).block()
-}
diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/BufferedLinearSpace.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/BufferedLinearSpace.kt
index 62d2408e3..9b4451a62 100644
--- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/BufferedLinearSpace.kt
+++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/BufferedLinearSpace.kt
@@ -5,6 +5,7 @@
package space.kscience.kmath.linear
+import space.kscience.kmath.misc.PerformancePitfall
import space.kscience.kmath.nd.*
import space.kscience.kmath.operations.Ring
import space.kscience.kmath.operations.invoke
@@ -50,6 +51,7 @@ public class BufferedLinearSpace>(
this
}
+ @OptIn(PerformancePitfall::class)
override fun Matrix.dot(other: Matrix): Matrix {
require(colNum == other.rowNum) { "Matrix dot operation dimension mismatch: ($rowNum, $colNum) x (${other.rowNum}, ${other.colNum})" }
return elementAlgebra {
@@ -67,6 +69,7 @@ public class BufferedLinearSpace>(
}
}
+ @OptIn(PerformancePitfall::class)
override fun Matrix.dot(vector: Point): Point {
require(colNum == vector.size) { "Matrix dot vector operation dimension mismatch: ($rowNum, $colNum) x (${vector.size})" }
return elementAlgebra {
diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LinearSpace.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LinearSpace.kt
index 0798e8763..ec073ac48 100644
--- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LinearSpace.kt
+++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LinearSpace.kt
@@ -19,6 +19,7 @@ import kotlin.reflect.KClass
* @param T the type of items.
*/
public typealias Matrix = Structure2D
+public typealias MutableMatrix = MutableStructure2D
/**
* Alias or using [Buffer] as a point/vector in a many-dimensional space.
diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/misc/Symbol.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/misc/Symbol.kt
index 737acc025..b9fb6879a 100644
--- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/misc/Symbol.kt
+++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/misc/Symbol.kt
@@ -32,10 +32,33 @@ public value class StringSymbol(override val identity: String) : Symbol {
override fun toString(): String = identity
}
-
/**
* A delegate to create a symbol with a string identity in this scope
*/
public val symbol: ReadOnlyProperty = ReadOnlyProperty { _, property ->
StringSymbol(property.name)
}
+
+/**
+ * Ger a value from a [String]-keyed map by a [Symbol]
+ */
+public operator fun Map.get(symbol: Symbol): T? = get(symbol.identity)
+
+/**
+ * Set a value of [String]-keyed map by a [Symbol]
+ */
+public operator fun MutableMap.set(symbol: Symbol, value: T){
+ set(symbol.identity, value)
+}
+
+/**
+ * Get a value from a [Symbol]-keyed map by a [String]
+ */
+public operator fun Map.get(string: String): T? = get(StringSymbol(string))
+
+/**
+ * Set a value of [String]-keyed map by a [Symbol]
+ */
+public operator fun MutableMap.set(string: String, value: T){
+ set(StringSymbol(string), value)
+}
\ No newline at end of file
diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/misc/annotations.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/misc/annotations.kt
index 206e4e000..18718de97 100644
--- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/misc/annotations.kt
+++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/misc/annotations.kt
@@ -5,5 +5,25 @@
package space.kscience.kmath.misc
+/**
+ * Marks declarations that are still experimental in the KMath APIs, which means that the design of the corresponding
+ * declarations has open issues which may (or may not) lead to their changes in the future. Roughly speaking, there is
+ * a chance that those declarations will be deprecated in the near future or the semantics of their behavior may change
+ * in some way that may break some code.
+ */
+@MustBeDocumented
+@Retention(value = AnnotationRetention.BINARY)
@RequiresOptIn("This API is unstable and could change in future", RequiresOptIn.Level.WARNING)
public annotation class UnstableKMathAPI
+
+/**
+ * Marks API which could cause performance problems. The code, marked by this API is not necessary slow, but could cause
+ * slow-down in some cases. Refer to the documentation and benchmark it to be sure.
+ */
+@MustBeDocumented
+@Retention(value = AnnotationRetention.BINARY)
+@RequiresOptIn(
+ "Refer to the documentation to use this API in performance-critical code",
+ RequiresOptIn.Level.WARNING
+)
+public annotation class PerformancePitfall
diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/BufferND.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/BufferND.kt
index 23d961a7e..425808aeb 100644
--- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/BufferND.kt
+++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/BufferND.kt
@@ -5,8 +5,11 @@
package space.kscience.kmath.nd
+import space.kscience.kmath.misc.PerformancePitfall
import space.kscience.kmath.structures.Buffer
import space.kscience.kmath.structures.BufferFactory
+import space.kscience.kmath.structures.MutableBuffer
+import space.kscience.kmath.structures.MutableBufferFactory
/**
* Represents [StructureND] over [Buffer].
@@ -15,7 +18,7 @@ import space.kscience.kmath.structures.BufferFactory
* @param strides The strides to access elements of [Buffer] by linear indices.
* @param buffer The underlying buffer.
*/
-public class BufferND(
+public open class BufferND(
public val strides: Strides,
public val buffer: Buffer,
) : StructureND {
@@ -30,6 +33,7 @@ public class BufferND(
override val shape: IntArray get() = strides.shape
+ @PerformancePitfall
override fun elements(): Sequence> = strides.indices().map {
it to this[it]
}
@@ -50,4 +54,35 @@ public inline fun StructureND.mapToBuffer(
val strides = DefaultStrides(shape)
BufferND(strides, factory.invoke(strides.linearSize) { transform(get(strides.index(it))) })
}
+}
+
+/**
+ * Represents [MutableStructureND] over [MutableBuffer].
+ *
+ * @param T the type of items.
+ * @param strides The strides to access elements of [MutableBuffer] by linear indices.
+ * @param mutableBuffer The underlying buffer.
+ */
+public class MutableBufferND(
+ strides: Strides,
+ public val mutableBuffer: MutableBuffer,
+) : MutableStructureND, BufferND(strides, mutableBuffer) {
+ override fun set(index: IntArray, value: T) {
+ mutableBuffer[strides.offset(index)] = value
+ }
+}
+
+/**
+ * Transform structure to a new structure using provided [MutableBufferFactory] and optimizing if argument is [MutableBufferND]
+ */
+public inline fun MutableStructureND