merge dev
This commit is contained in:
commit
b7cc4e4b1b
6
.github/workflows/build.yml
vendored
6
.github/workflows/build.yml
vendored
@ -13,9 +13,11 @@ jobs:
|
|||||||
- name: Checkout the repo
|
- name: Checkout the repo
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
- name: Set up JDK 11
|
- name: Set up JDK 11
|
||||||
uses: actions/setup-java@v1
|
uses: DeLaGuardo/setup-graalvm@4.0
|
||||||
with:
|
with:
|
||||||
java-version: 11
|
graalvm: 21.1.0
|
||||||
|
java: java11
|
||||||
|
arch: amd64
|
||||||
- name: Add msys to path
|
- name: Add msys to path
|
||||||
if: matrix.os == 'windows-latest'
|
if: matrix.os == 'windows-latest'
|
||||||
run: SETX PATH "%PATH%;C:\msys64\mingw64\bin"
|
run: SETX PATH "%PATH%;C:\msys64\mingw64\bin"
|
||||||
|
10
.github/workflows/pages.yml
vendored
10
.github/workflows/pages.yml
vendored
@ -12,9 +12,11 @@ jobs:
|
|||||||
- name: Checkout the repo
|
- name: Checkout the repo
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
- name: Set up JDK 11
|
- name: Set up JDK 11
|
||||||
uses: actions/setup-java@v1
|
uses: DeLaGuardo/setup-graalvm@4.0
|
||||||
with:
|
with:
|
||||||
java-version: 11
|
graalvm: 21.1.0
|
||||||
|
java: java11
|
||||||
|
arch: amd64
|
||||||
- name: Cache gradle
|
- name: Cache gradle
|
||||||
uses: actions/cache@v2
|
uses: actions/cache@v2
|
||||||
with:
|
with:
|
||||||
@ -30,9 +32,7 @@ jobs:
|
|||||||
restore-keys: |
|
restore-keys: |
|
||||||
${{ runner.os }}-gradle-
|
${{ runner.os }}-gradle-
|
||||||
- name: Build
|
- name: Build
|
||||||
run: |
|
run: ./gradlew dokkaHtmlMultiModule --no-daemon --no-parallel --stacktrace
|
||||||
./gradlew dokkaHtmlMultiModule --no-daemon --no-parallel --stacktrace
|
|
||||||
mv build/dokka/htmlMultiModule/-modules.html build/dokka/htmlMultiModule/index.html
|
|
||||||
- name: Deploy to GitHub Pages
|
- name: Deploy to GitHub Pages
|
||||||
uses: JamesIves/github-pages-deploy-action@4.1.0
|
uses: JamesIves/github-pages-deploy-action@4.1.0
|
||||||
with:
|
with:
|
||||||
|
6
.github/workflows/publish.yml
vendored
6
.github/workflows/publish.yml
vendored
@ -18,9 +18,11 @@ jobs:
|
|||||||
- name: Checkout the repo
|
- name: Checkout the repo
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
- name: Set up JDK 11
|
- name: Set up JDK 11
|
||||||
uses: actions/setup-java@v1
|
uses: DeLaGuardo/setup-graalvm@4.0
|
||||||
with:
|
with:
|
||||||
java-version: 11
|
graalvm: 21.1.0
|
||||||
|
java: java11
|
||||||
|
arch: amd64
|
||||||
- name: Add msys to path
|
- name: Add msys to path
|
||||||
if: matrix.os == 'windows-latest'
|
if: matrix.os == 'windows-latest'
|
||||||
run: SETX PATH "%PATH%;C:\msys64\mingw64\bin"
|
run: SETX PATH "%PATH%;C:\msys64\mingw64\bin"
|
||||||
|
@ -10,7 +10,8 @@
|
|||||||
- Blocking chains and Statistics
|
- Blocking chains and Statistics
|
||||||
- Multiplatform integration
|
- Multiplatform integration
|
||||||
- Integration for any Field element
|
- Integration for any Field element
|
||||||
- Extendend operations for ND4J fields
|
- Extended operations for ND4J fields
|
||||||
|
- Jupyter Notebook integration module (kmath-jupyter)
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
- Exponential operations merged with hyperbolic functions
|
- Exponential operations merged with hyperbolic functions
|
||||||
@ -24,6 +25,7 @@
|
|||||||
- Redesign MST. Remove MSTExpression.
|
- Redesign MST. Remove MSTExpression.
|
||||||
- Move MST to core
|
- Move MST to core
|
||||||
- Separated benchmarks and examples
|
- Separated benchmarks and examples
|
||||||
|
- Rewritten EJML module without ejml-simple
|
||||||
|
|
||||||
### Deprecated
|
### Deprecated
|
||||||
|
|
||||||
|
14
README.md
14
README.md
@ -91,7 +91,7 @@ KMath is a modular library. Different modules provide different features with di
|
|||||||
* ### [kmath-ast](kmath-ast)
|
* ### [kmath-ast](kmath-ast)
|
||||||
>
|
>
|
||||||
>
|
>
|
||||||
> **Maturity**: PROTOTYPE
|
> **Maturity**: EXPERIMENTAL
|
||||||
>
|
>
|
||||||
> **Features:**
|
> **Features:**
|
||||||
> - [expression-language](kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/parser.kt) : Expression language and its parser
|
> - [expression-language](kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/parser.kt) : Expression language and its parser
|
||||||
@ -154,9 +154,9 @@ performance calculations to code generation.
|
|||||||
> **Maturity**: PROTOTYPE
|
> **Maturity**: PROTOTYPE
|
||||||
>
|
>
|
||||||
> **Features:**
|
> **Features:**
|
||||||
> - [ejml-vector](kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/EjmlVector.kt) : The Point 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) : The Matrix implementation using SimpleMatrix.
|
> - [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) : The LinearSpace implementation using SimpleMatrix.
|
> - [ejml-linear-space](kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/EjmlLinearSpace.kt) : LinearSpace implementations.
|
||||||
|
|
||||||
<hr/>
|
<hr/>
|
||||||
|
|
||||||
@ -200,6 +200,12 @@ One can still use generic algebras though.
|
|||||||
> **Maturity**: PROTOTYPE
|
> **Maturity**: PROTOTYPE
|
||||||
<hr/>
|
<hr/>
|
||||||
|
|
||||||
|
* ### [kmath-jupyter](kmath-jupyter)
|
||||||
|
>
|
||||||
|
>
|
||||||
|
> **Maturity**: PROTOTYPE
|
||||||
|
<hr/>
|
||||||
|
|
||||||
* ### [kmath-kotlingrad](kmath-kotlingrad)
|
* ### [kmath-kotlingrad](kmath-kotlingrad)
|
||||||
>
|
>
|
||||||
>
|
>
|
||||||
|
@ -9,14 +9,10 @@ sourceSets.register("benchmarks")
|
|||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
jcenter()
|
|
||||||
maven("https://repo.kotlin.link")
|
maven("https://repo.kotlin.link")
|
||||||
maven("https://clojars.org/repo")
|
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("https://jitpack.io")
|
||||||
maven {
|
maven("http://logicrunch.research.it.uu.se/maven") {
|
||||||
setUrl("http://logicrunch.research.it.uu.se/maven/")
|
|
||||||
isAllowInsecureProtocol = true
|
isAllowInsecureProtocol = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ import kotlinx.benchmark.Blackhole
|
|||||||
import kotlinx.benchmark.Scope
|
import kotlinx.benchmark.Scope
|
||||||
import kotlinx.benchmark.State
|
import kotlinx.benchmark.State
|
||||||
import space.kscience.kmath.commons.linear.CMLinearSpace
|
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.LinearSpace
|
||||||
import space.kscience.kmath.linear.invoke
|
import space.kscience.kmath.linear.invoke
|
||||||
import space.kscience.kmath.operations.DoubleField
|
import space.kscience.kmath.operations.DoubleField
|
||||||
@ -29,8 +29,8 @@ internal class DotBenchmark {
|
|||||||
val cmMatrix1 = CMLinearSpace { matrix1.toCM() }
|
val cmMatrix1 = CMLinearSpace { matrix1.toCM() }
|
||||||
val cmMatrix2 = CMLinearSpace { matrix2.toCM() }
|
val cmMatrix2 = CMLinearSpace { matrix2.toCM() }
|
||||||
|
|
||||||
val ejmlMatrix1 = EjmlLinearSpace { matrix1.toEjml() }
|
val ejmlMatrix1 = EjmlLinearSpaceDDRM { matrix1.toEjml() }
|
||||||
val ejmlMatrix2 = EjmlLinearSpace { matrix2.toEjml() }
|
val ejmlMatrix2 = EjmlLinearSpaceDDRM { matrix2.toEjml() }
|
||||||
}
|
}
|
||||||
|
|
||||||
@Benchmark
|
@Benchmark
|
||||||
@ -42,14 +42,14 @@ internal class DotBenchmark {
|
|||||||
|
|
||||||
@Benchmark
|
@Benchmark
|
||||||
fun ejmlDot(blackhole: Blackhole) {
|
fun ejmlDot(blackhole: Blackhole) {
|
||||||
EjmlLinearSpace {
|
EjmlLinearSpaceDDRM {
|
||||||
blackhole.consume(ejmlMatrix1 dot ejmlMatrix2)
|
blackhole.consume(ejmlMatrix1 dot ejmlMatrix2)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Benchmark
|
@Benchmark
|
||||||
fun ejmlDotWithConversion(blackhole: Blackhole) {
|
fun ejmlDotWithConversion(blackhole: Blackhole) {
|
||||||
EjmlLinearSpace {
|
EjmlLinearSpaceDDRM {
|
||||||
blackhole.consume(matrix1 dot matrix2)
|
blackhole.consume(matrix1 dot matrix2)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,25 +11,26 @@ import kotlinx.benchmark.Scope
|
|||||||
import kotlinx.benchmark.State
|
import kotlinx.benchmark.State
|
||||||
import space.kscience.kmath.commons.linear.CMLinearSpace
|
import space.kscience.kmath.commons.linear.CMLinearSpace
|
||||||
import space.kscience.kmath.commons.linear.inverse
|
import space.kscience.kmath.commons.linear.inverse
|
||||||
import space.kscience.kmath.ejml.EjmlLinearSpace
|
import space.kscience.kmath.ejml.EjmlLinearSpaceDDRM
|
||||||
import space.kscience.kmath.ejml.inverse
|
import space.kscience.kmath.linear.InverseMatrixFeature
|
||||||
import space.kscience.kmath.linear.LinearSpace
|
import space.kscience.kmath.linear.LinearSpace
|
||||||
import space.kscience.kmath.linear.inverseWithLup
|
import space.kscience.kmath.linear.inverseWithLup
|
||||||
import space.kscience.kmath.linear.invoke
|
import space.kscience.kmath.linear.invoke
|
||||||
|
import space.kscience.kmath.nd.getFeature
|
||||||
import kotlin.random.Random
|
import kotlin.random.Random
|
||||||
|
|
||||||
@State(Scope.Benchmark)
|
@State(Scope.Benchmark)
|
||||||
internal class MatrixInverseBenchmark {
|
internal class MatrixInverseBenchmark {
|
||||||
companion object {
|
private companion object {
|
||||||
val random = Random(1224)
|
private val random = Random(1224)
|
||||||
const val dim = 100
|
private const val dim = 100
|
||||||
|
|
||||||
private val space = LinearSpace.real
|
private val space = LinearSpace.real
|
||||||
|
|
||||||
//creating invertible matrix
|
//creating invertible matrix
|
||||||
val u = space.buildMatrix(dim, dim) { i, j -> if (i <= j) random.nextDouble() else 0.0 }
|
private 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 }
|
private val l = space.buildMatrix(dim, dim) { i, j -> if (i >= j) random.nextDouble() else 0.0 }
|
||||||
val matrix = space { l dot u }
|
private val matrix = space { l dot u }
|
||||||
}
|
}
|
||||||
|
|
||||||
@Benchmark
|
@Benchmark
|
||||||
@ -46,8 +47,8 @@ internal class MatrixInverseBenchmark {
|
|||||||
|
|
||||||
@Benchmark
|
@Benchmark
|
||||||
fun ejmlInverse(blackhole: Blackhole) {
|
fun ejmlInverse(blackhole: Blackhole) {
|
||||||
with(EjmlLinearSpace) {
|
with(EjmlLinearSpaceDDRM) {
|
||||||
blackhole.consume(inverse(matrix))
|
blackhole.consume(matrix.getFeature<InverseMatrixFeature<Double>>()?.inverse)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,16 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id("ru.mipt.npm.gradle.project")
|
id("ru.mipt.npm.gradle.project")
|
||||||
|
kotlin("jupyter.api") apply false
|
||||||
}
|
}
|
||||||
|
|
||||||
allprojects {
|
allprojects {
|
||||||
repositories {
|
repositories {
|
||||||
jcenter()
|
|
||||||
maven("https://clojars.org/repo")
|
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("https://jitpack.io")
|
||||||
maven("http://logicrunch.research.it.uu.se/maven/") {
|
maven("http://logicrunch.research.it.uu.se/maven") {
|
||||||
isAllowInsecureProtocol = true
|
isAllowInsecureProtocol = true
|
||||||
}
|
}
|
||||||
|
maven("https://maven.pkg.jetbrains.space/public/p/kotlinx-html/maven")
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -23,22 +22,16 @@ subprojects {
|
|||||||
if (name.startsWith("kmath")) apply<MavenPublishPlugin>()
|
if (name.startsWith("kmath")) apply<MavenPublishPlugin>()
|
||||||
|
|
||||||
afterEvaluate {
|
afterEvaluate {
|
||||||
tasks.withType<org.jetbrains.dokka.gradle.DokkaTask> {
|
tasks.withType<org.jetbrains.dokka.gradle.DokkaTaskPartial> {
|
||||||
dokkaSourceSets.all {
|
dependsOn(tasks.getByName("assemble"))
|
||||||
val readmeFile = File(this@subprojects.projectDir, "./README.md")
|
|
||||||
if (readmeFile.exists())
|
|
||||||
includes.setFrom(includes + readmeFile.absolutePath)
|
|
||||||
|
|
||||||
arrayOf(
|
dokkaSourceSets.all {
|
||||||
"http://ejml.org/javadoc/",
|
val readmeFile = File(this@subprojects.projectDir, "README.md")
|
||||||
"https://commons.apache.org/proper/commons-math/javadocs/api-3.6.1/",
|
if (readmeFile.exists()) includes.setFrom(includes + readmeFile.absolutePath)
|
||||||
"https://deeplearning4j.org/api/latest/"
|
externalDocumentationLink("http://ejml.org/javadoc/")
|
||||||
).map { java.net.URL("${it}package-list") to java.net.URL(it) }.forEach { (a, b) ->
|
externalDocumentationLink("https://commons.apache.org/proper/commons-math/javadocs/api-3.6.1/")
|
||||||
externalDocumentationLink {
|
externalDocumentationLink("https://deeplearning4j.org/api/latest/")
|
||||||
packageListUrl.set(a)
|
externalDocumentationLink("https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/")
|
||||||
url.set(b)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
6
docs/templates/ARTIFACT-TEMPLATE.md
vendored
6
docs/templates/ARTIFACT-TEMPLATE.md
vendored
@ -6,8 +6,7 @@ The Maven coordinates of this project are `${group}:${name}:${version}`.
|
|||||||
```gradle
|
```gradle
|
||||||
repositories {
|
repositories {
|
||||||
maven { url 'https://repo.kotlin.link' }
|
maven { url 'https://repo.kotlin.link' }
|
||||||
maven { url 'https://dl.bintray.com/hotkeytlt/maven' }
|
mavenCentral()
|
||||||
maven { url "https://dl.bintray.com/kotlin/kotlin-eap" } // include for builds based on kotlin-eap
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
@ -18,8 +17,7 @@ dependencies {
|
|||||||
```kotlin
|
```kotlin
|
||||||
repositories {
|
repositories {
|
||||||
maven("https://repo.kotlin.link")
|
maven("https://repo.kotlin.link")
|
||||||
maven("https://dl.bintray.com/kotlin/kotlin-eap") // include for builds based on kotlin-eap
|
mavenCentral()
|
||||||
maven("https://dl.bintray.com/hotkeytlt/maven") // required for a
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
@ -4,14 +4,11 @@ plugins {
|
|||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
jcenter()
|
|
||||||
maven("https://repo.kotlin.link")
|
maven("https://repo.kotlin.link")
|
||||||
maven("https://clojars.org/repo")
|
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("https://jitpack.io")
|
||||||
maven{
|
maven("https://maven.pkg.jetbrains.space/kotlin/p/kotlin/kotlin-js-wrappers")
|
||||||
setUrl("http://logicrunch.research.it.uu.se/maven/")
|
maven("http://logicrunch.research.it.uu.se/maven") {
|
||||||
isAllowInsecureProtocol = true
|
isAllowInsecureProtocol = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# Module kmath-ast
|
# Module kmath-ast
|
||||||
|
|
||||||
Abstract syntax tree expression representation and related optimizations.
|
Performance and visualization extensions to MST API.
|
||||||
|
|
||||||
- [expression-language](src/commonMain/kotlin/space/kscience/kmath/ast/parser.kt) : Expression language and its parser
|
- [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-jvm-codegen](src/jvmMain/kotlin/space/kscience/kmath/asm/asm.kt) : Dynamic MST to JVM bytecode compiler
|
||||||
@ -16,8 +16,7 @@ The Maven coordinates of this project are `space.kscience:kmath-ast:0.3.0-dev-7`
|
|||||||
```gradle
|
```gradle
|
||||||
repositories {
|
repositories {
|
||||||
maven { url 'https://repo.kotlin.link' }
|
maven { url 'https://repo.kotlin.link' }
|
||||||
maven { url 'https://dl.bintray.com/hotkeytlt/maven' }
|
mavenCentral()
|
||||||
maven { url "https://dl.bintray.com/kotlin/kotlin-eap" } // include for builds based on kotlin-eap
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
@ -28,8 +27,7 @@ dependencies {
|
|||||||
```kotlin
|
```kotlin
|
||||||
repositories {
|
repositories {
|
||||||
maven("https://repo.kotlin.link")
|
maven("https://repo.kotlin.link")
|
||||||
maven("https://dl.bintray.com/kotlin/kotlin-eap") // include for builds based on kotlin-eap
|
mavenCentral()
|
||||||
maven("https://dl.bintray.com/hotkeytlt/maven") // required for a
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
@ -41,12 +39,16 @@ dependencies {
|
|||||||
|
|
||||||
### On JVM
|
### On JVM
|
||||||
|
|
||||||
`kmath-ast` JVM module supports runtime code generation to eliminate overhead of tree traversal. Code generator builds
|
`kmath-ast` JVM module supports runtime code generation to eliminate overhead of tree traversal. Code generator builds a
|
||||||
a special implementation of `Expression<T>` with implemented `invoke` function.
|
special implementation of `Expression<T>` with implemented `invoke` function.
|
||||||
|
|
||||||
For example, the following builder:
|
For example, the following builder:
|
||||||
|
|
||||||
```kotlin
|
```kotlin
|
||||||
|
import space.kscience.kmath.expressions.*
|
||||||
|
import space.kscience.kmath.operations.*
|
||||||
|
import space.kscience.kmath.asm.*
|
||||||
|
|
||||||
MstField { bindSymbol("x") + 2 }.compileToExpression(DoubleField)
|
MstField { bindSymbol("x") + 2 }.compileToExpression(DoubleField)
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -56,6 +58,7 @@ MstField { bindSymbol("x") + 2 }.compileToExpression(DoubleField)
|
|||||||
package space.kscience.kmath.asm.generated;
|
package space.kscience.kmath.asm.generated;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import kotlin.jvm.functions.Function2;
|
import kotlin.jvm.functions.Function2;
|
||||||
import space.kscience.kmath.asm.internal.MapIntrinsics;
|
import space.kscience.kmath.asm.internal.MapIntrinsics;
|
||||||
import space.kscience.kmath.expressions.Expression;
|
import space.kscience.kmath.expressions.Expression;
|
||||||
@ -65,7 +68,7 @@ public final class AsmCompiledExpression_45045_0 implements Expression<Double> {
|
|||||||
private final Object[] constants;
|
private final Object[] constants;
|
||||||
|
|
||||||
public final Double invoke(Map<Symbol, ? extends Double> arguments) {
|
public final Double invoke(Map<Symbol, ? extends Double> 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) {
|
public AsmCompiledExpression_45045_0(Object[] constants) {
|
||||||
@ -77,8 +80,8 @@ public final class AsmCompiledExpression_45045_0 implements Expression<Double> {
|
|||||||
|
|
||||||
#### Known issues
|
#### Known issues
|
||||||
|
|
||||||
- The same classes may be generated and loaded twice, so it is recommended to cache compiled expressions to avoid
|
- The same classes may be generated and loaded twice, so it is recommended to cache compiled expressions to avoid class
|
||||||
class loading overhead.
|
loading overhead.
|
||||||
- This API is not supported by non-dynamic JVM implementations (like TeaVM and GraalVM) because of using class loaders.
|
- This API is not supported by non-dynamic JVM implementations (like TeaVM and GraalVM) because of using class loaders.
|
||||||
|
|
||||||
### On JS
|
### On JS
|
||||||
@ -86,6 +89,10 @@ public final class AsmCompiledExpression_45045_0 implements Expression<Double> {
|
|||||||
A similar feature is also available on JS.
|
A similar feature is also available on JS.
|
||||||
|
|
||||||
```kotlin
|
```kotlin
|
||||||
|
import space.kscience.kmath.expressions.*
|
||||||
|
import space.kscience.kmath.operations.*
|
||||||
|
import space.kscience.kmath.estree.*
|
||||||
|
|
||||||
MstField { bindSymbol("x") + 2 }.compileToExpression(DoubleField)
|
MstField { bindSymbol("x") + 2 }.compileToExpression(DoubleField)
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -93,13 +100,16 @@ The code above returns expression implemented with such a JS function:
|
|||||||
|
|
||||||
```js
|
```js
|
||||||
var executable = function (constants, arguments) {
|
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.
|
JS also supports very experimental expression optimization with [WebAssembly](https://webassembly.org/) IR generation.
|
||||||
|
Currently, only expressions inside `DoubleField` and `IntRing` are supported.
|
||||||
|
|
||||||
```kotlin
|
```kotlin
|
||||||
|
import space.kscience.kmath.expressions.*
|
||||||
|
import space.kscience.kmath.operations.*
|
||||||
import space.kscience.kmath.wasm.*
|
import space.kscience.kmath.wasm.*
|
||||||
|
|
||||||
MstField { bindSymbol("x") + 2 }.compileToExpression(DoubleField)
|
MstField { bindSymbol("x") + 2 }.compileToExpression(DoubleField)
|
||||||
@ -130,7 +140,9 @@ Example usage:
|
|||||||
```kotlin
|
```kotlin
|
||||||
import space.kscience.kmath.ast.*
|
import space.kscience.kmath.ast.*
|
||||||
import space.kscience.kmath.ast.rendering.*
|
import space.kscience.kmath.ast.rendering.*
|
||||||
|
import space.kscience.kmath.misc.*
|
||||||
|
|
||||||
|
@OptIn(UnstableKMathAPI::class)
|
||||||
public fun main() {
|
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)".parseMath()
|
||||||
val syntax = FeaturedMathRendererWithPostProcess.Default.render(mst)
|
val syntax = FeaturedMathRendererWithPostProcess.Default.render(mst)
|
||||||
@ -146,13 +158,68 @@ 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})
|
||||||
|
|
||||||
Result MathML (embedding MathML is not allowed by GitHub Markdown):
|
Result MathML (embedding MathML is not allowed by GitHub Markdown):
|
||||||
|
|
||||||
|
<details>
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<mrow><msup><mrow><mi>e</mi></mrow><mrow><msqrt><mi>x</mi></msqrt></mrow></msup><mo>-</mo><mfrac><mrow><mfrac><mrow><msup><mrow><mo>sin</mo></mrow><mrow><mo>-</mo><mn>1</mn></mrow></msup><mspace width="0.167em"></mspace><mfenced open="(" close=")" separators=""><mn>2</mn><mspace width="0.167em"></mspace><mi>x</mi></mfenced></mrow><mrow><mn>2</mn><mo>×</mo><msup><mrow><mn>10</mn></mrow><mrow><mn>10</mn></mrow></msup><mo>+</mo><msup><mrow><mi>x</mi></mrow><mrow><mn>3</mn></mrow></msup></mrow></mfrac></mrow><mrow><mo>-</mo><mn>12</mn></mrow></mfrac></mrow>
|
<math xmlns="https://www.w3.org/1998/Math/MathML">
|
||||||
|
<mrow>
|
||||||
|
<mo>exp</mo>
|
||||||
|
<mspace width="0.167em"></mspace>
|
||||||
|
<mfenced open="(" close=")" separators="">
|
||||||
|
<msqrt>
|
||||||
|
<mi>x</mi>
|
||||||
|
</msqrt>
|
||||||
|
</mfenced>
|
||||||
|
<mo>-</mo>
|
||||||
|
<mfrac>
|
||||||
|
<mrow>
|
||||||
|
<mfrac>
|
||||||
|
<mrow>
|
||||||
|
<mo>arcsin</mo>
|
||||||
|
<mspace width="0.167em"></mspace>
|
||||||
|
<mfenced open="(" close=")" separators="">
|
||||||
|
<mn>2</mn>
|
||||||
|
<mspace width="0.167em"></mspace>
|
||||||
|
<mi>x</mi>
|
||||||
|
</mfenced>
|
||||||
|
</mrow>
|
||||||
|
<mrow>
|
||||||
|
<mn>2</mn>
|
||||||
|
<mo>×</mo>
|
||||||
|
<msup>
|
||||||
|
<mrow>
|
||||||
|
<mn>10</mn>
|
||||||
|
</mrow>
|
||||||
|
<mrow>
|
||||||
|
<mn>10</mn>
|
||||||
|
</mrow>
|
||||||
|
</msup>
|
||||||
|
<mo>+</mo>
|
||||||
|
<msup>
|
||||||
|
<mrow>
|
||||||
|
<mi>x</mi>
|
||||||
|
</mrow>
|
||||||
|
<mrow>
|
||||||
|
<mn>3</mn>
|
||||||
|
</mrow>
|
||||||
|
</msup>
|
||||||
|
</mrow>
|
||||||
|
</mfrac>
|
||||||
|
</mrow>
|
||||||
|
<mrow>
|
||||||
|
<mo>-</mo>
|
||||||
|
<mn>12</mn>
|
||||||
|
</mrow>
|
||||||
|
</mfrac>
|
||||||
|
</mrow>
|
||||||
|
</math>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
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).
|
(see API reference).
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# Module kmath-ast
|
# Module kmath-ast
|
||||||
|
|
||||||
Abstract syntax tree expression representation and related optimizations.
|
Performance and visualization extensions to MST API.
|
||||||
|
|
||||||
${features}
|
${features}
|
||||||
|
|
||||||
@ -10,12 +10,16 @@ ${artifact}
|
|||||||
|
|
||||||
### On JVM
|
### On JVM
|
||||||
|
|
||||||
`kmath-ast` JVM module supports runtime code generation to eliminate overhead of tree traversal. Code generator builds
|
`kmath-ast` JVM module supports runtime code generation to eliminate overhead of tree traversal. Code generator builds a
|
||||||
a special implementation of `Expression<T>` with implemented `invoke` function.
|
special implementation of `Expression<T>` with implemented `invoke` function.
|
||||||
|
|
||||||
For example, the following builder:
|
For example, the following builder:
|
||||||
|
|
||||||
```kotlin
|
```kotlin
|
||||||
|
import space.kscience.kmath.expressions.*
|
||||||
|
import space.kscience.kmath.operations.*
|
||||||
|
import space.kscience.kmath.asm.*
|
||||||
|
|
||||||
MstField { bindSymbol("x") + 2 }.compileToExpression(DoubleField)
|
MstField { bindSymbol("x") + 2 }.compileToExpression(DoubleField)
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -25,6 +29,7 @@ MstField { bindSymbol("x") + 2 }.compileToExpression(DoubleField)
|
|||||||
package space.kscience.kmath.asm.generated;
|
package space.kscience.kmath.asm.generated;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import kotlin.jvm.functions.Function2;
|
import kotlin.jvm.functions.Function2;
|
||||||
import space.kscience.kmath.asm.internal.MapIntrinsics;
|
import space.kscience.kmath.asm.internal.MapIntrinsics;
|
||||||
import space.kscience.kmath.expressions.Expression;
|
import space.kscience.kmath.expressions.Expression;
|
||||||
@ -34,7 +39,7 @@ public final class AsmCompiledExpression_45045_0 implements Expression<Double> {
|
|||||||
private final Object[] constants;
|
private final Object[] constants;
|
||||||
|
|
||||||
public final Double invoke(Map<Symbol, ? extends Double> arguments) {
|
public final Double invoke(Map<Symbol, ? extends Double> 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) {
|
public AsmCompiledExpression_45045_0(Object[] constants) {
|
||||||
@ -46,8 +51,8 @@ public final class AsmCompiledExpression_45045_0 implements Expression<Double> {
|
|||||||
|
|
||||||
#### Known issues
|
#### Known issues
|
||||||
|
|
||||||
- The same classes may be generated and loaded twice, so it is recommended to cache compiled expressions to avoid
|
- The same classes may be generated and loaded twice, so it is recommended to cache compiled expressions to avoid class
|
||||||
class loading overhead.
|
loading overhead.
|
||||||
- This API is not supported by non-dynamic JVM implementations (like TeaVM and GraalVM) because of using class loaders.
|
- This API is not supported by non-dynamic JVM implementations (like TeaVM and GraalVM) because of using class loaders.
|
||||||
|
|
||||||
### On JS
|
### On JS
|
||||||
@ -55,6 +60,10 @@ public final class AsmCompiledExpression_45045_0 implements Expression<Double> {
|
|||||||
A similar feature is also available on JS.
|
A similar feature is also available on JS.
|
||||||
|
|
||||||
```kotlin
|
```kotlin
|
||||||
|
import space.kscience.kmath.expressions.*
|
||||||
|
import space.kscience.kmath.operations.*
|
||||||
|
import space.kscience.kmath.estree.*
|
||||||
|
|
||||||
MstField { bindSymbol("x") + 2 }.compileToExpression(DoubleField)
|
MstField { bindSymbol("x") + 2 }.compileToExpression(DoubleField)
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -62,13 +71,16 @@ The code above returns expression implemented with such a JS function:
|
|||||||
|
|
||||||
```js
|
```js
|
||||||
var executable = function (constants, arguments) {
|
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.
|
JS also supports very experimental expression optimization with [WebAssembly](https://webassembly.org/) IR generation.
|
||||||
|
Currently, only expressions inside `DoubleField` and `IntRing` are supported.
|
||||||
|
|
||||||
```kotlin
|
```kotlin
|
||||||
|
import space.kscience.kmath.expressions.*
|
||||||
|
import space.kscience.kmath.operations.*
|
||||||
import space.kscience.kmath.wasm.*
|
import space.kscience.kmath.wasm.*
|
||||||
|
|
||||||
MstField { bindSymbol("x") + 2 }.compileToExpression(DoubleField)
|
MstField { bindSymbol("x") + 2 }.compileToExpression(DoubleField)
|
||||||
@ -99,9 +111,11 @@ Example usage:
|
|||||||
```kotlin
|
```kotlin
|
||||||
import space.kscience.kmath.ast.*
|
import space.kscience.kmath.ast.*
|
||||||
import space.kscience.kmath.ast.rendering.*
|
import space.kscience.kmath.ast.rendering.*
|
||||||
|
import space.kscience.kmath.misc.*
|
||||||
|
|
||||||
|
@OptIn(UnstableKMathAPI::class)
|
||||||
public fun main() {
|
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 syntax = FeaturedMathRendererWithPostProcess.Default.render(mst)
|
||||||
val latex = LatexSyntaxRenderer.renderWithStringBuilder(syntax)
|
val latex = LatexSyntaxRenderer.renderWithStringBuilder(syntax)
|
||||||
println("LaTeX:")
|
println("LaTeX:")
|
||||||
@ -115,13 +129,78 @@ 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):
|
||||||
|
|
||||||
|
<details>
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<mrow><msup><mrow><mi>e</mi></mrow><mrow><msqrt><mi>x</mi></msqrt></mrow></msup><mo>-</mo><mfrac><mrow><mfrac><mrow><msup><mrow><mo>sin</mo></mrow><mrow><mo>-</mo><mn>1</mn></mrow></msup><mspace width="0.167em"></mspace><mfenced open="(" close=")" separators=""><mn>2</mn><mspace width="0.167em"></mspace><mi>x</mi></mfenced></mrow><mrow><mn>2</mn><mo>×</mo><msup><mrow><mn>10</mn></mrow><mrow><mn>10</mn></mrow></msup><mo>+</mo><msup><mrow><mi>x</mi></mrow><mrow><mn>3</mn></mrow></msup></mrow></mfrac></mrow><mrow><mo>-</mo><mn>12</mn></mrow></mfrac></mrow>
|
<math xmlns="https://www.w3.org/1998/Math/MathML">
|
||||||
|
<mrow>
|
||||||
|
<mo>exp</mo>
|
||||||
|
<mspace width="0.167em"></mspace>
|
||||||
|
<mfenced open="(" close=")" separators="">
|
||||||
|
<msqrt>
|
||||||
|
<mi>x</mi>
|
||||||
|
</msqrt>
|
||||||
|
</mfenced>
|
||||||
|
<mo>-</mo>
|
||||||
|
<mfrac>
|
||||||
|
<mrow>
|
||||||
|
<mfrac>
|
||||||
|
<mrow>
|
||||||
|
<mo>arcsin</mo>
|
||||||
|
<mspace width="0.167em"></mspace>
|
||||||
|
<mfenced open="(" close=")" separators="">
|
||||||
|
<mn>2</mn>
|
||||||
|
<mspace width="0.167em"></mspace>
|
||||||
|
<mi>x</mi>
|
||||||
|
</mfenced>
|
||||||
|
</mrow>
|
||||||
|
<mrow>
|
||||||
|
<mn>2</mn>
|
||||||
|
<mo>×</mo>
|
||||||
|
<msup>
|
||||||
|
<mrow>
|
||||||
|
<mn>10</mn>
|
||||||
|
</mrow>
|
||||||
|
<mrow>
|
||||||
|
<mn>10</mn>
|
||||||
|
</mrow>
|
||||||
|
</msup>
|
||||||
|
<mo>+</mo>
|
||||||
|
<msup>
|
||||||
|
<mrow>
|
||||||
|
<mi>x</mi>
|
||||||
|
</mrow>
|
||||||
|
<mrow>
|
||||||
|
<mn>3</mn>
|
||||||
|
</mrow>
|
||||||
|
</msup>
|
||||||
|
</mrow>
|
||||||
|
</mfrac>
|
||||||
|
</mrow>
|
||||||
|
<mrow>
|
||||||
|
<mn>12</mn>
|
||||||
|
</mrow>
|
||||||
|
</mfrac>
|
||||||
|
<mo>+</mo>
|
||||||
|
<msup>
|
||||||
|
<mrow>
|
||||||
|
<mi>x</mi>
|
||||||
|
</mrow>
|
||||||
|
<mrow>
|
||||||
|
<mn>2</mn>
|
||||||
|
<mo>/</mo>
|
||||||
|
<mn>3</mn>
|
||||||
|
</mrow>
|
||||||
|
</msup>
|
||||||
|
</mrow>
|
||||||
|
</math>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
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).
|
(see API reference).
|
||||||
|
@ -118,7 +118,11 @@ public object LatexSyntaxRenderer : SyntaxRenderer {
|
|||||||
render(node.right)
|
render(node.right)
|
||||||
}
|
}
|
||||||
|
|
||||||
is FractionSyntax -> {
|
is FractionSyntax -> if (node.infix) {
|
||||||
|
render(node.left)
|
||||||
|
append('/')
|
||||||
|
render(node.right)
|
||||||
|
} else {
|
||||||
append("\\frac{")
|
append("\\frac{")
|
||||||
render(node.left)
|
render(node.left)
|
||||||
append("}{")
|
append("}{")
|
||||||
|
@ -18,11 +18,14 @@ import space.kscience.kmath.misc.UnstableKMathAPI
|
|||||||
public object MathMLSyntaxRenderer : SyntaxRenderer {
|
public object MathMLSyntaxRenderer : SyntaxRenderer {
|
||||||
public override fun render(node: MathSyntax, output: Appendable) {
|
public override fun render(node: MathSyntax, output: Appendable) {
|
||||||
output.append("<math xmlns=\"https://www.w3.org/1998/Math/MathML\"><mrow>")
|
output.append("<math xmlns=\"https://www.w3.org/1998/Math/MathML\"><mrow>")
|
||||||
render0(node, output)
|
renderPart(node, output)
|
||||||
output.append("</mrow></math>")
|
output.append("</mrow></math>")
|
||||||
}
|
}
|
||||||
|
|
||||||
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<String, String>, block: () -> Unit = {}) {
|
fun tag(tagName: String, vararg attr: Pair<String, String>, block: () -> Unit = {}) {
|
||||||
append('<')
|
append('<')
|
||||||
append(tagName)
|
append(tagName)
|
||||||
@ -47,7 +50,7 @@ public object MathMLSyntaxRenderer : SyntaxRenderer {
|
|||||||
append('>')
|
append('>')
|
||||||
}
|
}
|
||||||
|
|
||||||
fun render(syntax: MathSyntax) = render0(syntax, output)
|
fun render(syntax: MathSyntax) = renderPart(syntax, output)
|
||||||
|
|
||||||
when (node) {
|
when (node) {
|
||||||
is NumberSyntax -> tag("mn") { append(node.string) }
|
is NumberSyntax -> tag("mn") { append(node.string) }
|
||||||
@ -130,14 +133,13 @@ public object MathMLSyntaxRenderer : SyntaxRenderer {
|
|||||||
render(node.right)
|
render(node.right)
|
||||||
}
|
}
|
||||||
|
|
||||||
is FractionSyntax -> tag("mfrac") {
|
is FractionSyntax -> if (node.infix) {
|
||||||
tag("mrow") {
|
render(node.left)
|
||||||
render(node.left)
|
tag("mo") { append('/') }
|
||||||
}
|
render(node.right)
|
||||||
|
} else tag("mfrac") {
|
||||||
tag("mrow") {
|
tag("mrow") { render(node.left) }
|
||||||
render(node.right)
|
tag("mrow") { render(node.right) }
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
is RadicalWithIndexSyntax -> tag("mroot") {
|
is RadicalWithIndexSyntax -> tag("mroot") {
|
||||||
|
@ -89,6 +89,7 @@ public open class FeaturedMathRendererWithPostProcess(
|
|||||||
SquareRoot.Default,
|
SquareRoot.Default,
|
||||||
Exponent.Default,
|
Exponent.Default,
|
||||||
InverseTrigonometricOperations.Default,
|
InverseTrigonometricOperations.Default,
|
||||||
|
InverseHyperbolicOperations.Default,
|
||||||
|
|
||||||
// Fallback option for unknown operations - printing them as operator
|
// Fallback option for unknown operations - printing them as operator
|
||||||
BinaryOperator.Default,
|
BinaryOperator.Default,
|
||||||
@ -105,6 +106,7 @@ public open class FeaturedMathRendererWithPostProcess(
|
|||||||
),
|
),
|
||||||
listOf(
|
listOf(
|
||||||
BetterExponent,
|
BetterExponent,
|
||||||
|
BetterFraction,
|
||||||
SimplifyParentheses.Default,
|
SimplifyParentheses.Default,
|
||||||
BetterMultiplication,
|
BetterMultiplication,
|
||||||
),
|
),
|
||||||
|
@ -102,7 +102,7 @@ public data class SymbolSyntax(public var string: String) : TerminalSyntax()
|
|||||||
public data class OperatorNameSyntax(public var name: String) : TerminalSyntax()
|
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.
|
* @property kind The kind of symbol.
|
||||||
* @author Iaroslav Postovalov
|
* @author Iaroslav Postovalov
|
||||||
@ -143,7 +143,7 @@ public data class OperandSyntax(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents unary, prefix operator syntax (like f x).
|
* Represents unary, prefix operator syntax (like *f(x)*).
|
||||||
*
|
*
|
||||||
* @property prefix The prefix.
|
* @property prefix The prefix.
|
||||||
* @author Iaroslav Postovalov
|
* @author Iaroslav Postovalov
|
||||||
@ -160,7 +160,7 @@ public data class UnaryOperatorSyntax(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents prefix, unary plus operator.
|
* Represents prefix, unary plus operator (*+x*).
|
||||||
*
|
*
|
||||||
* @author Iaroslav Postovalov
|
* @author Iaroslav Postovalov
|
||||||
*/
|
*/
|
||||||
@ -175,7 +175,7 @@ public data class UnaryPlusSyntax(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents prefix, unary minus operator.
|
* Represents prefix, unary minus operator (*-x*).
|
||||||
*
|
*
|
||||||
* @author Iaroslav Postovalov
|
* @author Iaroslav Postovalov
|
||||||
*/
|
*/
|
||||||
@ -190,7 +190,7 @@ public data class UnaryMinusSyntax(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents radical with a node inside it.
|
* Represents radical with a node inside it (*√x*).
|
||||||
*
|
*
|
||||||
* @property operand The radicand.
|
* @property operand The radicand.
|
||||||
* @author Iaroslav Postovalov
|
* @author Iaroslav Postovalov
|
||||||
@ -225,7 +225,7 @@ public data class ExponentSyntax(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a syntax node with superscript (usually, for exponentiation).
|
* Represents a syntax node with superscript (*x<sup>2</sup>*).
|
||||||
*
|
*
|
||||||
* @property left The node.
|
* @property left The node.
|
||||||
* @property right The superscript.
|
* @property right The superscript.
|
||||||
@ -244,7 +244,7 @@ public data class SuperscriptSyntax(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a syntax node with subscript.
|
* Represents a syntax node with subscript (*x<sub>i</sup>*).
|
||||||
*
|
*
|
||||||
* @property left The node.
|
* @property left The node.
|
||||||
* @property right The subscript.
|
* @property right The subscript.
|
||||||
@ -263,7 +263,7 @@ 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.
|
* @property prefix The prefix.
|
||||||
* @author Iaroslav Postovalov
|
* @author Iaroslav Postovalov
|
||||||
@ -282,7 +282,7 @@ public data class BinaryOperatorSyntax(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents binary, infix addition.
|
* Represents binary, infix addition (*42 + 42*).
|
||||||
*
|
*
|
||||||
* @param left The augend.
|
* @param left The augend.
|
||||||
* @param right The addend.
|
* @param right The addend.
|
||||||
@ -301,7 +301,7 @@ public data class BinaryPlusSyntax(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents binary, infix subtraction.
|
* Represents binary, infix subtraction (*42 - 42*).
|
||||||
*
|
*
|
||||||
* @param left The minuend.
|
* @param left The minuend.
|
||||||
* @param right The subtrahend.
|
* @param right The subtrahend.
|
||||||
@ -324,13 +324,15 @@ public data class BinaryMinusSyntax(
|
|||||||
*
|
*
|
||||||
* @property left The numerator.
|
* @property left The numerator.
|
||||||
* @property right The denominator.
|
* @property right The denominator.
|
||||||
|
* @property infix Whether infix (*1 / 2*) or normal (*½*) fraction should be made.
|
||||||
* @author Iaroslav Postovalov
|
* @author Iaroslav Postovalov
|
||||||
*/
|
*/
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
public data class FractionSyntax(
|
public data class FractionSyntax(
|
||||||
public override val operation: String,
|
public override val operation: String,
|
||||||
public override val left: MathSyntax,
|
public override val left: OperandSyntax,
|
||||||
public override val right: MathSyntax,
|
public override val right: OperandSyntax,
|
||||||
|
public var infix: Boolean,
|
||||||
) : BinarySyntax() {
|
) : BinarySyntax() {
|
||||||
init {
|
init {
|
||||||
left.parent = this
|
left.parent = this
|
||||||
@ -339,7 +341,7 @@ public data class FractionSyntax(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents radical syntax with index.
|
* Represents radical syntax with index (*<sup>3</sup>√x*).
|
||||||
*
|
*
|
||||||
* @property left The index.
|
* @property left The index.
|
||||||
* @property right The radicand.
|
* @property right The radicand.
|
||||||
@ -358,11 +360,11 @@ 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 left The multiplicand.
|
||||||
* @property right The multiplier.
|
* @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
|
* @author Iaroslav Postovalov
|
||||||
*/
|
*/
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
|
@ -54,6 +54,7 @@ else
|
|||||||
* *('-'? (DIGIT+ ('.' DIGIT+)? ('E' '-'? DIGIT+)? | 'Infinity')) | 'NaN'*.
|
* *('-'? (DIGIT+ ('.' DIGIT+)? ('E' '-'? DIGIT+)? | 'Infinity')) | 'NaN'*.
|
||||||
*
|
*
|
||||||
* @property types The suitable types.
|
* @property types The suitable types.
|
||||||
|
* @author Iaroslav Postovalov
|
||||||
*/
|
*/
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
public class PrettyPrintFloats(public val types: Set<KClass<out Number>>) : RenderFeature {
|
public class PrettyPrintFloats(public val types: Set<KClass<out Number>>) : RenderFeature {
|
||||||
@ -113,6 +114,7 @@ public class PrettyPrintFloats(public val types: Set<KClass<out Number>>) : Rend
|
|||||||
* Special printing for numeric types which are printed in form of *'-'? DIGIT+*.
|
* Special printing for numeric types which are printed in form of *'-'? DIGIT+*.
|
||||||
*
|
*
|
||||||
* @property types The suitable types.
|
* @property types The suitable types.
|
||||||
|
* @author Iaroslav Postovalov
|
||||||
*/
|
*/
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
public class PrettyPrintIntegers(public val types: Set<KClass<out Number>>) : RenderFeature {
|
public class PrettyPrintIntegers(public val types: Set<KClass<out Number>>) : RenderFeature {
|
||||||
@ -135,6 +137,7 @@ public class PrettyPrintIntegers(public val types: Set<KClass<out Number>>) : Re
|
|||||||
* Special printing for symbols meaning Pi.
|
* Special printing for symbols meaning Pi.
|
||||||
*
|
*
|
||||||
* @property symbols The allowed symbols.
|
* @property symbols The allowed symbols.
|
||||||
|
* @author Iaroslav Postovalov
|
||||||
*/
|
*/
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
public class PrettyPrintPi(public val symbols: Set<String>) : RenderFeature {
|
public class PrettyPrintPi(public val symbols: Set<String>) : RenderFeature {
|
||||||
@ -157,6 +160,7 @@ public class PrettyPrintPi(public val symbols: Set<String>) : RenderFeature {
|
|||||||
* not [MST.Unary].
|
* not [MST.Unary].
|
||||||
*
|
*
|
||||||
* @param operations the allowed operations. If `null`, any operation is accepted.
|
* @param operations the allowed operations. If `null`, any operation is accepted.
|
||||||
|
* @author Iaroslav Postovalov
|
||||||
*/
|
*/
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
public abstract class Unary(public val operations: Collection<String>?) : RenderFeature {
|
public abstract class Unary(public val operations: Collection<String>?) : RenderFeature {
|
||||||
@ -177,6 +181,7 @@ public abstract class Unary(public val operations: Collection<String>?) : Render
|
|||||||
* not [MST.Binary].
|
* not [MST.Binary].
|
||||||
*
|
*
|
||||||
* @property operations the allowed operations. If `null`, any operation is accepted.
|
* @property operations the allowed operations. If `null`, any operation is accepted.
|
||||||
|
* @author Iaroslav Postovalov
|
||||||
*/
|
*/
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
public abstract class Binary(public val operations: Collection<String>?) : RenderFeature {
|
public abstract class Binary(public val operations: Collection<String>?) : RenderFeature {
|
||||||
@ -193,6 +198,8 @@ public abstract class Binary(public val operations: Collection<String>?) : Rende
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles binary nodes by producing [BinaryPlusSyntax].
|
* Handles binary nodes by producing [BinaryPlusSyntax].
|
||||||
|
*
|
||||||
|
* @author Iaroslav Postovalov
|
||||||
*/
|
*/
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
public class BinaryPlus(operations: Collection<String>?) : Binary(operations) {
|
public class BinaryPlus(operations: Collection<String>?) : Binary(operations) {
|
||||||
@ -213,6 +220,8 @@ public class BinaryPlus(operations: Collection<String>?) : Binary(operations) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles binary nodes by producing [BinaryMinusSyntax].
|
* Handles binary nodes by producing [BinaryMinusSyntax].
|
||||||
|
*
|
||||||
|
* @author Iaroslav Postovalov
|
||||||
*/
|
*/
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
public class BinaryMinus(operations: Collection<String>?) : Binary(operations) {
|
public class BinaryMinus(operations: Collection<String>?) : Binary(operations) {
|
||||||
@ -233,6 +242,8 @@ public class BinaryMinus(operations: Collection<String>?) : Binary(operations) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles unary nodes by producing [UnaryPlusSyntax].
|
* Handles unary nodes by producing [UnaryPlusSyntax].
|
||||||
|
*
|
||||||
|
* @author Iaroslav Postovalov
|
||||||
*/
|
*/
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
public class UnaryPlus(operations: Collection<String>?) : Unary(operations) {
|
public class UnaryPlus(operations: Collection<String>?) : Unary(operations) {
|
||||||
@ -251,6 +262,8 @@ public class UnaryPlus(operations: Collection<String>?) : Unary(operations) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles binary nodes by producing [UnaryMinusSyntax].
|
* Handles binary nodes by producing [UnaryMinusSyntax].
|
||||||
|
*
|
||||||
|
* @author Iaroslav Postovalov
|
||||||
*/
|
*/
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
public class UnaryMinus(operations: Collection<String>?) : Unary(operations) {
|
public class UnaryMinus(operations: Collection<String>?) : Unary(operations) {
|
||||||
@ -269,13 +282,16 @@ public class UnaryMinus(operations: Collection<String>?) : Unary(operations) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles binary nodes by producing [FractionSyntax].
|
* Handles binary nodes by producing [FractionSyntax].
|
||||||
|
*
|
||||||
|
* @author Iaroslav Postovalov
|
||||||
*/
|
*/
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
public class Fraction(operations: Collection<String>?) : Binary(operations) {
|
public class Fraction(operations: Collection<String>?) : Binary(operations) {
|
||||||
public override fun renderBinary(parent: FeaturedMathRenderer, node: MST.Binary): FractionSyntax = FractionSyntax(
|
public override fun renderBinary(parent: FeaturedMathRenderer, node: MST.Binary): FractionSyntax = FractionSyntax(
|
||||||
operation = node.operation,
|
operation = node.operation,
|
||||||
left = parent.render(node.left),
|
left = OperandSyntax(operand = parent.render(node.left), parentheses = true),
|
||||||
right = parent.render(node.right),
|
right = OperandSyntax(operand = parent.render(node.right), parentheses = true),
|
||||||
|
infix = true,
|
||||||
)
|
)
|
||||||
|
|
||||||
public companion object {
|
public companion object {
|
||||||
@ -288,6 +304,8 @@ public class Fraction(operations: Collection<String>?) : Binary(operations) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles binary nodes by producing [BinaryOperatorSyntax].
|
* Handles binary nodes by producing [BinaryOperatorSyntax].
|
||||||
|
*
|
||||||
|
* @author Iaroslav Postovalov
|
||||||
*/
|
*/
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
public class BinaryOperator(operations: Collection<String>?) : Binary(operations) {
|
public class BinaryOperator(operations: Collection<String>?) : Binary(operations) {
|
||||||
@ -309,6 +327,8 @@ public class BinaryOperator(operations: Collection<String>?) : Binary(operations
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles unary nodes by producing [UnaryOperatorSyntax].
|
* Handles unary nodes by producing [UnaryOperatorSyntax].
|
||||||
|
*
|
||||||
|
* @author Iaroslav Postovalov
|
||||||
*/
|
*/
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
public class UnaryOperator(operations: Collection<String>?) : Unary(operations) {
|
public class UnaryOperator(operations: Collection<String>?) : Unary(operations) {
|
||||||
@ -329,6 +349,8 @@ public class UnaryOperator(operations: Collection<String>?) : Unary(operations)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles binary nodes by producing [SuperscriptSyntax].
|
* Handles binary nodes by producing [SuperscriptSyntax].
|
||||||
|
*
|
||||||
|
* @author Iaroslav Postovalov
|
||||||
*/
|
*/
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
public class Power(operations: Collection<String>?) : Binary(operations) {
|
public class Power(operations: Collection<String>?) : Binary(operations) {
|
||||||
@ -365,6 +387,8 @@ public class SquareRoot(operations: Collection<String>?) : Unary(operations) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles unary nodes by producing [ExponentSyntax].
|
* Handles unary nodes by producing [ExponentSyntax].
|
||||||
|
*
|
||||||
|
* @author Iaroslav Postovalov
|
||||||
*/
|
*/
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
public class Exponent(operations: Collection<String>?) : Unary(operations) {
|
public class Exponent(operations: Collection<String>?) : Unary(operations) {
|
||||||
@ -384,6 +408,8 @@ public class Exponent(operations: Collection<String>?) : Unary(operations) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles binary nodes by producing [MultiplicationSyntax].
|
* Handles binary nodes by producing [MultiplicationSyntax].
|
||||||
|
*
|
||||||
|
* @author Iaroslav Postovalov
|
||||||
*/
|
*/
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
public class Multiplication(operations: Collection<String>?) : Binary(operations) {
|
public class Multiplication(operations: Collection<String>?) : Binary(operations) {
|
||||||
@ -404,36 +430,52 @@ public class Multiplication(operations: Collection<String>?) : Binary(operations
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles binary nodes by producing inverse [UnaryOperatorSyntax] (like *sin<sup>-1</sup>*) with removing the `a`
|
* Handles binary nodes by producing inverse [UnaryOperatorSyntax] with *arc* prefix instead of *a*.
|
||||||
* prefix of operation ID.
|
*
|
||||||
|
* @author Iaroslav Postovalov
|
||||||
*/
|
*/
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
public class InverseTrigonometricOperations(operations: Collection<String>?) : Unary(operations) {
|
public class InverseTrigonometricOperations(operations: Collection<String>?) : Unary(operations) {
|
||||||
public override fun renderUnary(parent: FeaturedMathRenderer, node: MST.Unary): UnaryOperatorSyntax =
|
public override fun renderUnary(parent: FeaturedMathRenderer, node: MST.Unary): UnaryOperatorSyntax =
|
||||||
UnaryOperatorSyntax(
|
UnaryOperatorSyntax(
|
||||||
operation = node.operation,
|
operation = node.operation,
|
||||||
prefix = SuperscriptSyntax(
|
prefix = OperatorNameSyntax(name = node.operation.replaceFirst("a", "arc")),
|
||||||
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),
|
operand = OperandSyntax(operand = parent.render(node.value), parentheses = true),
|
||||||
)
|
)
|
||||||
|
|
||||||
public companion object {
|
public companion object {
|
||||||
/**
|
/**
|
||||||
* The default instance configured with [TrigonometricOperations.ACOS_OPERATION],
|
* The default instance configured with [TrigonometricOperations.ACOS_OPERATION],
|
||||||
* [TrigonometricOperations.ASIN_OPERATION], [TrigonometricOperations.ATAN_OPERATION],
|
* [TrigonometricOperations.ASIN_OPERATION], [TrigonometricOperations.ATAN_OPERATION].
|
||||||
* [ExponentialOperations.ACOSH_OPERATION], [ExponentialOperations.ASINH_OPERATION], and
|
|
||||||
* [ExponentialOperations.ATANH_OPERATION].
|
|
||||||
*/
|
*/
|
||||||
public val Default: InverseTrigonometricOperations = InverseTrigonometricOperations(setOf(
|
public val Default: InverseTrigonometricOperations = InverseTrigonometricOperations(setOf(
|
||||||
TrigonometricOperations.ACOS_OPERATION,
|
TrigonometricOperations.ACOS_OPERATION,
|
||||||
TrigonometricOperations.ASIN_OPERATION,
|
TrigonometricOperations.ASIN_OPERATION,
|
||||||
TrigonometricOperations.ATAN_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<String>?) : 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.ACOSH_OPERATION,
|
||||||
ExponentialOperations.ASINH_OPERATION,
|
ExponentialOperations.ASINH_OPERATION,
|
||||||
ExponentialOperations.ATANH_OPERATION,
|
ExponentialOperations.ATANH_OPERATION,
|
||||||
|
@ -83,6 +83,75 @@ public object BetterMultiplication : FeaturedMathRendererWithPostProcess.PostPro
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
* Applies [ExponentSyntax.useOperatorForm] to [ExponentSyntax] when the operand contains a fraction, a
|
||||||
@ -102,7 +171,7 @@ public object BetterExponent : FeaturedMathRendererWithPostProcess.PostProcessSt
|
|||||||
is UnaryOperatorSyntax -> perform0(node.prefix) || perform0(node.operand)
|
is UnaryOperatorSyntax -> perform0(node.prefix) || perform0(node.operand)
|
||||||
is UnaryPlusSyntax -> perform0(node.operand)
|
is UnaryPlusSyntax -> perform0(node.operand)
|
||||||
is UnaryMinusSyntax -> perform0(node.operand)
|
is UnaryMinusSyntax -> perform0(node.operand)
|
||||||
is RadicalSyntax -> perform0(node.operand)
|
is RadicalSyntax -> true
|
||||||
|
|
||||||
is ExponentSyntax -> {
|
is ExponentSyntax -> {
|
||||||
val r = perform0(node.operand)
|
val r = perform0(node.operand)
|
||||||
@ -116,7 +185,7 @@ public object BetterExponent : FeaturedMathRendererWithPostProcess.PostProcessSt
|
|||||||
is BinaryPlusSyntax -> perform0(node.left) || perform0(node.right)
|
is BinaryPlusSyntax -> perform0(node.left) || perform0(node.right)
|
||||||
is BinaryMinusSyntax -> perform0(node.left) || perform0(node.right)
|
is BinaryMinusSyntax -> perform0(node.left) || perform0(node.right)
|
||||||
is FractionSyntax -> true
|
is FractionSyntax -> true
|
||||||
is RadicalWithIndexSyntax -> perform0(node.left) || perform0(node.right)
|
is RadicalWithIndexSyntax -> true
|
||||||
is MultiplicationSyntax -> perform0(node.left) || perform0(node.right)
|
is MultiplicationSyntax -> perform0(node.left) || perform0(node.right)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -163,8 +232,11 @@ public class SimplifyParentheses(public val precedenceFunction: (MathSyntax) ->
|
|||||||
val isInsideExpOperator =
|
val isInsideExpOperator =
|
||||||
node.parent is ExponentSyntax && (node.parent as ExponentSyntax).useOperatorForm
|
node.parent is ExponentSyntax && (node.parent as ExponentSyntax).useOperatorForm
|
||||||
|
|
||||||
|
val isOnOrUnderNormalFraction = node.parent is FractionSyntax && !((node.parent as FractionSyntax).infix)
|
||||||
|
|
||||||
node.parentheses = !isRightOfSuperscript
|
node.parentheses = !isRightOfSuperscript
|
||||||
&& (needParenthesesByPrecedence || node.parent is UnaryOperatorSyntax || isInsideExpOperator)
|
&& (needParenthesesByPrecedence || node.parent is UnaryOperatorSyntax || isInsideExpOperator)
|
||||||
|
&& !isOnOrUnderNormalFraction
|
||||||
|
|
||||||
perform(node.operand)
|
perform(node.operand)
|
||||||
}
|
}
|
||||||
|
@ -3,12 +3,12 @@
|
|||||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package space.kscience.kmath.wasm
|
package space.kscience.kmath.ast
|
||||||
|
|
||||||
import space.kscience.kmath.expressions.MstField
|
import space.kscience.kmath.expressions.MstField
|
||||||
import space.kscience.kmath.expressions.MstRing
|
import space.kscience.kmath.expressions.MstRing
|
||||||
import space.kscience.kmath.expressions.interpret
|
import space.kscience.kmath.expressions.interpret
|
||||||
import space.kscience.kmath.misc.symbol
|
import space.kscience.kmath.misc.Symbol.Companion.x
|
||||||
import space.kscience.kmath.operations.DoubleField
|
import space.kscience.kmath.operations.DoubleField
|
||||||
import space.kscience.kmath.operations.IntRing
|
import space.kscience.kmath.operations.IntRing
|
||||||
import space.kscience.kmath.operations.bindSymbol
|
import space.kscience.kmath.operations.bindSymbol
|
||||||
@ -16,45 +16,41 @@ import space.kscience.kmath.operations.invoke
|
|||||||
import kotlin.test.Test
|
import kotlin.test.Test
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
internal class TestWasmConsistencyWithInterpreter {
|
internal class TestCompilerConsistencyWithInterpreter {
|
||||||
@Test
|
@Test
|
||||||
fun intRing() {
|
fun intRing() = runCompilerTest {
|
||||||
val mst = MstRing {
|
val mst = MstRing {
|
||||||
binaryOperationFunction("+")(
|
binaryOperationFunction("+")(
|
||||||
unaryOperationFunction("+")(
|
unaryOperationFunction("+")(
|
||||||
(bindSymbol(x) - (2.toByte() + (scale(
|
(bindSymbol(x) - (2.toByte() + (scale(
|
||||||
add(number(1), number(1)),
|
add(number(1), number(1)),
|
||||||
2.0
|
2.0,
|
||||||
) + 1.toByte()))) * 3.0 - 1.toByte()
|
) + 1.toByte()))) * 3.0 - 1.toByte()
|
||||||
),
|
),
|
||||||
|
|
||||||
number(1)
|
number(1),
|
||||||
) * number(2)
|
) * number(2)
|
||||||
}
|
}
|
||||||
|
|
||||||
assertEquals(
|
assertEquals(
|
||||||
mst.interpret(IntRing, x to 3),
|
mst.interpret(IntRing, x to 3),
|
||||||
mst.compile(IntRing, x to 3)
|
mst.compile(IntRing, x to 3),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun doubleField() {
|
fun doubleField() = runCompilerTest {
|
||||||
val mst = MstField {
|
val mst = MstField {
|
||||||
+(3 - 2 + 2 * number(1) + 1.0) + binaryOperationFunction("+")(
|
+(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
|
(3.0 - (bindSymbol(x) + (scale(add(number(1.0), number(1.0)), 2.0) + 1.0))) * 3 - 1.0
|
||||||
+ number(1),
|
+ number(1),
|
||||||
number(1) / 2 + number(2.0) * one
|
number(1) / 2 + number(2.0) * one,
|
||||||
) + zero
|
) + zero
|
||||||
}
|
}
|
||||||
|
|
||||||
assertEquals(
|
assertEquals(
|
||||||
mst.interpret(DoubleField, x to 2.0),
|
mst.interpret(DoubleField, x to 2.0),
|
||||||
mst.compile(DoubleField, x to 2.0)
|
mst.compile(DoubleField, x to 2.0),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private companion object {
|
|
||||||
private val x by symbol
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -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))
|
||||||
|
}
|
||||||
|
}
|
@ -3,11 +3,11 @@
|
|||||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package space.kscience.kmath.wasm
|
package space.kscience.kmath.ast
|
||||||
|
|
||||||
import space.kscience.kmath.expressions.MstRing
|
import space.kscience.kmath.expressions.MstRing
|
||||||
import space.kscience.kmath.expressions.invoke
|
import space.kscience.kmath.expressions.invoke
|
||||||
import space.kscience.kmath.misc.symbol
|
import space.kscience.kmath.misc.Symbol.Companion.x
|
||||||
import space.kscience.kmath.operations.IntRing
|
import space.kscience.kmath.operations.IntRing
|
||||||
import space.kscience.kmath.operations.bindSymbol
|
import space.kscience.kmath.operations.bindSymbol
|
||||||
import space.kscience.kmath.operations.invoke
|
import space.kscience.kmath.operations.invoke
|
||||||
@ -15,20 +15,16 @@ import kotlin.test.Test
|
|||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
import kotlin.test.assertFailsWith
|
import kotlin.test.assertFailsWith
|
||||||
|
|
||||||
internal class TestWasmVariables {
|
internal class TestCompilerVariables {
|
||||||
@Test
|
@Test
|
||||||
fun testVariable() {
|
fun testVariable() = runCompilerTest {
|
||||||
val expr = MstRing { bindSymbol(x) }.compileToExpression(IntRing)
|
val expr = MstRing { bindSymbol(x) }.compileToExpression(IntRing)
|
||||||
assertEquals(1, expr(x to 1))
|
assertEquals(1, expr(x to 1))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testUndefinedVariableFails() {
|
fun testUndefinedVariableFails() = runCompilerTest {
|
||||||
val expr = MstRing { bindSymbol(x) }.compileToExpression(IntRing)
|
val expr = MstRing { bindSymbol(x) }.compileToExpression(IntRing)
|
||||||
assertFailsWith<NoSuchElementException> { expr() }
|
assertFailsWith<NoSuchElementException> { expr() }
|
||||||
}
|
}
|
||||||
|
|
||||||
private companion object {
|
|
||||||
private val x by symbol
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -13,7 +13,7 @@ import space.kscience.kmath.operations.DoubleField
|
|||||||
import kotlin.test.Test
|
import kotlin.test.Test
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
internal class ParserTest {
|
internal class TestParser {
|
||||||
@Test
|
@Test
|
||||||
fun evaluateParsedMst() {
|
fun evaluateParsedMst() {
|
||||||
val mst = "2+2*(2+2)".parseMath()
|
val mst = "2+2*(2+2)".parseMath()
|
@ -10,7 +10,7 @@ import space.kscience.kmath.operations.DoubleField
|
|||||||
import kotlin.test.Test
|
import kotlin.test.Test
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
internal class ParserPrecedenceTest {
|
internal class TestParserPrecedence {
|
||||||
@Test
|
@Test
|
||||||
fun test1(): Unit = assertEquals(6.0, f.evaluate("2*2+2".parseMath()))
|
fun test1(): Unit = assertEquals(6.0, f.evaluate("2*2+2".parseMath()))
|
||||||
|
|
@ -99,13 +99,17 @@ internal class TestFeatures {
|
|||||||
fun multiplication() = testLatex("x*1", "x\\times1")
|
fun multiplication() = testLatex("x*1", "x\\times1")
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun inverseTrigonometry() {
|
fun inverseTrigonometric() {
|
||||||
testLatex("asin(x)", "\\operatorname{sin}^{-1}\\,\\left(x\\right)")
|
testLatex("asin(x)", "\\operatorname{arcsin}\\,\\left(x\\right)")
|
||||||
testLatex("asinh(x)", "\\operatorname{sinh}^{-1}\\,\\left(x\\right)")
|
testLatex("acos(x)", "\\operatorname{arccos}\\,\\left(x\\right)")
|
||||||
testLatex("acos(x)", "\\operatorname{cos}^{-1}\\,\\left(x\\right)")
|
testLatex("atan(x)", "\\operatorname{arctan}\\,\\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)")
|
@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
|
// @Test
|
||||||
|
@ -37,4 +37,10 @@ internal class TestStages {
|
|||||||
testLatex("exp(x/2)", "\\operatorname{exp}\\,\\left(\\frac{x}{2}\\right)")
|
testLatex("exp(x/2)", "\\operatorname{exp}\\,\\left(\\frac{x}{2}\\right)")
|
||||||
testLatex("exp(x^2)", "\\operatorname{exp}\\,\\left(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}")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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<Int>
|
||||||
|
fun MST.compile(algebra: IntRing, arguments: Map<Symbol, Int>): Int
|
||||||
|
fun MST.compile(algebra: IntRing, vararg arguments: Pair<Symbol, Int>): Int = compile(algebra, mapOf(*arguments))
|
||||||
|
fun MST.compileToExpression(algebra: DoubleField): Expression<Double>
|
||||||
|
fun MST.compile(algebra: DoubleField, arguments: Map<Symbol, Double>): Double
|
||||||
|
|
||||||
|
fun MST.compile(algebra: DoubleField, vararg arguments: Pair<Symbol, Double>): Double =
|
||||||
|
compile(algebra, mapOf(*arguments))
|
||||||
|
}
|
||||||
|
|
||||||
|
internal expect inline fun runCompilerTest(action: CompilerTestContext.() -> Unit)
|
@ -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<Int> = wasmCompileToExpression(algebra)
|
||||||
|
override fun MST.compile(algebra: IntRing, arguments: Map<Symbol, Int>): Int = wasmCompile(algebra, arguments)
|
||||||
|
override fun MST.compileToExpression(algebra: DoubleField): Expression<Double> = wasmCompileToExpression(algebra)
|
||||||
|
|
||||||
|
override fun MST.compile(algebra: DoubleField, arguments: Map<Symbol, Double>): Double =
|
||||||
|
wasmCompile(algebra, arguments)
|
||||||
|
}
|
||||||
|
|
||||||
|
private object ESTreeCompilerTestContext : CompilerTestContext {
|
||||||
|
override fun MST.compileToExpression(algebra: IntRing): Expression<Int> = estreeCompileToExpression(algebra)
|
||||||
|
override fun MST.compile(algebra: IntRing, arguments: Map<Symbol, Int>): Int = estreeCompile(algebra, arguments)
|
||||||
|
override fun MST.compileToExpression(algebra: DoubleField): Expression<Double> = estreeCompileToExpression(algebra)
|
||||||
|
|
||||||
|
override fun MST.compile(algebra: DoubleField, arguments: Map<Symbol, Double>): Double =
|
||||||
|
estreeCompile(algebra, arguments)
|
||||||
|
}
|
||||||
|
|
||||||
|
internal actual inline fun runCompilerTest(action: CompilerTestContext.() -> Unit) {
|
||||||
|
action(WasmCompilerTestContext)
|
||||||
|
action(ESTreeCompilerTestContext)
|
||||||
|
}
|
@ -1,97 +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.bindSymbol
|
|
||||||
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, 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 doubleField() {
|
|
||||||
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()),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private companion object {
|
|
||||||
private val x by symbol
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,42 +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.MstField
|
|
||||||
import space.kscience.kmath.expressions.MstGroup
|
|
||||||
import space.kscience.kmath.expressions.invoke
|
|
||||||
import space.kscience.kmath.misc.symbol
|
|
||||||
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 TestESTreeOperationsSupport {
|
|
||||||
@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)
|
|
||||||
}
|
|
||||||
|
|
||||||
private companion object {
|
|
||||||
private val x by symbol
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,76 +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.misc.symbol
|
|
||||||
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 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 testSubtract() {
|
|
||||||
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))
|
|
||||||
}
|
|
||||||
|
|
||||||
private companion object {
|
|
||||||
private val x by symbol
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,34 +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.misc.symbol
|
|
||||||
import space.kscience.kmath.operations.ByteRing
|
|
||||||
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 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<NoSuchElementException> { expr() }
|
|
||||||
}
|
|
||||||
|
|
||||||
private companion object {
|
|
||||||
private val x by symbol
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,42 +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.wasm
|
|
||||||
|
|
||||||
import space.kscience.kmath.expressions.MstField
|
|
||||||
import space.kscience.kmath.expressions.MstGroup
|
|
||||||
import space.kscience.kmath.expressions.invoke
|
|
||||||
import space.kscience.kmath.misc.symbol
|
|
||||||
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 TestWasmOperationsSupport {
|
|
||||||
@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)
|
|
||||||
}
|
|
||||||
|
|
||||||
private companion object {
|
|
||||||
private val x by symbol
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,76 +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.wasm
|
|
||||||
|
|
||||||
import space.kscience.kmath.expressions.MstExtendedField
|
|
||||||
import space.kscience.kmath.expressions.invoke
|
|
||||||
import space.kscience.kmath.misc.symbol
|
|
||||||
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 TestWasmSpecialization {
|
|
||||||
@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 testSubtract() {
|
|
||||||
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))
|
|
||||||
}
|
|
||||||
|
|
||||||
private companion object {
|
|
||||||
private val x by symbol
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,97 +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
|
|
||||||
import space.kscience.kmath.operations.ByteRing
|
|
||||||
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 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 doubleField() {
|
|
||||||
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())
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private companion object {
|
|
||||||
private val x by symbol
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,42 +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.MstField
|
|
||||||
import space.kscience.kmath.expressions.MstGroup
|
|
||||||
import space.kscience.kmath.expressions.invoke
|
|
||||||
import space.kscience.kmath.misc.symbol
|
|
||||||
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 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)
|
|
||||||
}
|
|
||||||
|
|
||||||
private companion object {
|
|
||||||
private val x by symbol
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,76 +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.misc.symbol
|
|
||||||
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 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 testSubtract() {
|
|
||||||
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))
|
|
||||||
}
|
|
||||||
|
|
||||||
private companion object {
|
|
||||||
private val x by symbol
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,34 +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.misc.symbol
|
|
||||||
import space.kscience.kmath.operations.ByteRing
|
|
||||||
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 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<NoSuchElementException> { expr() }
|
|
||||||
}
|
|
||||||
|
|
||||||
private companion object {
|
|
||||||
private val x by symbol
|
|
||||||
}
|
|
||||||
}
|
|
@ -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<Int> = asmCompileToExpression(algebra)
|
||||||
|
override fun MST.compile(algebra: IntRing, arguments: Map<Symbol, Int>): Int = asmCompile(algebra, arguments)
|
||||||
|
override fun MST.compileToExpression(algebra: DoubleField): Expression<Double> = asmCompileToExpression(algebra)
|
||||||
|
|
||||||
|
override fun MST.compile(algebra: DoubleField, arguments: Map<Symbol, Double>): Double =
|
||||||
|
asmCompile(algebra, arguments)
|
||||||
|
}
|
||||||
|
|
||||||
|
internal actual inline fun runCompilerTest(action: CompilerTestContext.() -> Unit) = action(AsmCompilerTestContext)
|
@ -14,8 +14,7 @@ The Maven coordinates of this project are `space.kscience:kmath-complex:0.3.0-de
|
|||||||
```gradle
|
```gradle
|
||||||
repositories {
|
repositories {
|
||||||
maven { url 'https://repo.kotlin.link' }
|
maven { url 'https://repo.kotlin.link' }
|
||||||
maven { url 'https://dl.bintray.com/hotkeytlt/maven' }
|
mavenCentral()
|
||||||
maven { url "https://dl.bintray.com/kotlin/kotlin-eap" } // include for builds based on kotlin-eap
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
@ -26,8 +25,7 @@ dependencies {
|
|||||||
```kotlin
|
```kotlin
|
||||||
repositories {
|
repositories {
|
||||||
maven("https://repo.kotlin.link")
|
maven("https://repo.kotlin.link")
|
||||||
maven("https://dl.bintray.com/kotlin/kotlin-eap") // include for builds based on kotlin-eap
|
mavenCentral()
|
||||||
maven("https://dl.bintray.com/hotkeytlt/maven") // required for a
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
@ -21,8 +21,7 @@ The Maven coordinates of this project are `space.kscience:kmath-core:0.3.0-dev-7
|
|||||||
```gradle
|
```gradle
|
||||||
repositories {
|
repositories {
|
||||||
maven { url 'https://repo.kotlin.link' }
|
maven { url 'https://repo.kotlin.link' }
|
||||||
maven { url 'https://dl.bintray.com/hotkeytlt/maven' }
|
mavenCentral()
|
||||||
maven { url "https://dl.bintray.com/kotlin/kotlin-eap" } // include for builds based on kotlin-eap
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
@ -33,8 +32,7 @@ dependencies {
|
|||||||
```kotlin
|
```kotlin
|
||||||
repositories {
|
repositories {
|
||||||
maven("https://repo.kotlin.link")
|
maven("https://repo.kotlin.link")
|
||||||
maven("https://dl.bintray.com/kotlin/kotlin-eap") // include for builds based on kotlin-eap
|
mavenCentral()
|
||||||
maven("https://dl.bintray.com/hotkeytlt/maven") // required for a
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
@ -272,6 +272,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 fun sin (Lspace/kscience/kmath/expressions/MST;)Lspace/kscience/kmath/expressions/MST$Unary;
|
||||||
public synthetic fun sinh (Ljava/lang/Object;)Ljava/lang/Object;
|
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 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 synthetic fun tan (Ljava/lang/Object;)Ljava/lang/Object;
|
||||||
public fun tan (Lspace/kscience/kmath/expressions/MST;)Lspace/kscience/kmath/expressions/MST$Unary;
|
public fun tan (Lspace/kscience/kmath/expressions/MST;)Lspace/kscience/kmath/expressions/MST$Unary;
|
||||||
public synthetic fun tanh (Ljava/lang/Object;)Ljava/lang/Object;
|
public synthetic fun tanh (Ljava/lang/Object;)Ljava/lang/Object;
|
||||||
@ -1008,14 +1010,7 @@ public abstract interface class space/kscience/kmath/operations/Algebra {
|
|||||||
public fun unaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function1;
|
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 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 {
|
public final class space/kscience/kmath/operations/AlgebraExtensionsKt {
|
||||||
|
@ -135,6 +135,7 @@ public object MstExtendedField : ExtendedField<MST>, NumericAlgebra<MST> {
|
|||||||
public override fun acosh(arg: MST): MST.Unary = unaryOperationFunction(ExponentialOperations.ACOSH_OPERATION)(arg)
|
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 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 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 =
|
public override fun scale(a: MST, value: Double): MST =
|
||||||
binaryOperation(GroupOperations.PLUS_OPERATION, a, number(value))
|
binaryOperation(GroupOperations.PLUS_OPERATION, a, number(value))
|
||||||
|
@ -13,6 +13,8 @@ import space.kscience.kmath.misc.UnstableKMathAPI
|
|||||||
* @param C the type of mathematical context for this element.
|
* @param C the type of mathematical context for this element.
|
||||||
* @param T the type wrapped by this wrapper.
|
* @param T the type wrapped by this wrapper.
|
||||||
*/
|
*/
|
||||||
|
@UnstableKMathAPI
|
||||||
|
@Deprecated("AlgebraElements are considered odd and will be removed in future releases.")
|
||||||
public interface AlgebraElement<T, C : Algebra<T>> {
|
public interface AlgebraElement<T, C : Algebra<T>> {
|
||||||
/**
|
/**
|
||||||
* The context this element belongs to.
|
* The context this element belongs to.
|
||||||
@ -45,6 +47,7 @@ public interface AlgebraElement<T, C : Algebra<T>> {
|
|||||||
* @return the difference.
|
* @return the difference.
|
||||||
*/
|
*/
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
|
@Deprecated("AlgebraElements are considered odd and will be removed in future releases.")
|
||||||
public operator fun <T : AlgebraElement<T, S>, S : NumbersAddOperations<T>> T.minus(b: T): T =
|
public operator fun <T : AlgebraElement<T, S>, S : NumbersAddOperations<T>> T.minus(b: T): T =
|
||||||
context.add(this, context.run { -b })
|
context.add(this, context.run { -b })
|
||||||
|
|
||||||
@ -55,6 +58,8 @@ public operator fun <T : AlgebraElement<T, S>, S : NumbersAddOperations<T>> T.mi
|
|||||||
* @param b the addend.
|
* @param b the addend.
|
||||||
* @return the sum.
|
* @return the sum.
|
||||||
*/
|
*/
|
||||||
|
@UnstableKMathAPI
|
||||||
|
@Deprecated("AlgebraElements are considered odd and will be removed in future releases.")
|
||||||
public operator fun <T : AlgebraElement<T, S>, S : Ring<T>> T.plus(b: T): T =
|
public operator fun <T : AlgebraElement<T, S>, S : Ring<T>> T.plus(b: T): T =
|
||||||
context.add(this, b)
|
context.add(this, b)
|
||||||
|
|
||||||
@ -71,6 +76,8 @@ public operator fun <T : AlgebraElement<T, S>, S : Ring<T>> T.plus(b: T): T =
|
|||||||
* @param b the multiplier.
|
* @param b the multiplier.
|
||||||
* @return the product.
|
* @return the product.
|
||||||
*/
|
*/
|
||||||
|
@UnstableKMathAPI
|
||||||
|
@Deprecated("AlgebraElements are considered odd and will be removed in future releases.")
|
||||||
public operator fun <T : AlgebraElement<T, R>, R : Ring<T>> T.times(b: T): T =
|
public operator fun <T : AlgebraElement<T, R>, R : Ring<T>> T.times(b: T): T =
|
||||||
context.multiply(this, b)
|
context.multiply(this, b)
|
||||||
|
|
||||||
@ -81,6 +88,8 @@ public operator fun <T : AlgebraElement<T, R>, R : Ring<T>> T.times(b: T): T =
|
|||||||
* @param b the divisor.
|
* @param b the divisor.
|
||||||
* @return the quotient.
|
* @return the quotient.
|
||||||
*/
|
*/
|
||||||
|
@UnstableKMathAPI
|
||||||
|
@Deprecated("AlgebraElements are considered odd and will be removed in future releases.")
|
||||||
public operator fun <T : AlgebraElement<T, F>, F : Field<T>> T.div(b: T): T =
|
public operator fun <T : AlgebraElement<T, F>, F : Field<T>> T.div(b: T): T =
|
||||||
context.divide(this, b)
|
context.divide(this, b)
|
||||||
|
|
||||||
@ -93,6 +102,7 @@ public operator fun <T : AlgebraElement<T, F>, F : Field<T>> T.div(b: T): T =
|
|||||||
* @param S the type of space.
|
* @param S the type of space.
|
||||||
*/
|
*/
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
|
@Deprecated("AlgebraElements are considered odd and will be removed in future releases.")
|
||||||
public interface GroupElement<T : GroupElement<T, S>, S : Group<T>> : AlgebraElement<T, S>
|
public interface GroupElement<T : GroupElement<T, S>, S : Group<T>> : AlgebraElement<T, S>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -103,6 +113,7 @@ public interface GroupElement<T : GroupElement<T, S>, S : Group<T>> : AlgebraEle
|
|||||||
* @param R the type of ring.
|
* @param R the type of ring.
|
||||||
*/
|
*/
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
|
@Deprecated("AlgebraElements are considered odd and will be removed in future releases.")
|
||||||
public interface RingElement<T : RingElement<T, R>, R : Ring<T>> : GroupElement<T, R>
|
public interface RingElement<T : RingElement<T, R>, R : Ring<T>> : GroupElement<T, R>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -113,4 +124,5 @@ public interface RingElement<T : RingElement<T, R>, R : Ring<T>> : GroupElement<
|
|||||||
* @param F the type of field.
|
* @param F the type of field.
|
||||||
*/
|
*/
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
public interface FieldElement<T : FieldElement<T, F>, F : Field<T>> : RingElement<T, F>
|
@Deprecated("AlgebraElements are considered odd and will be removed in future releases.")
|
||||||
|
public interface FieldElement<T : FieldElement<T, F>, F : Field<T>> : RingElement<T, F>
|
||||||
|
@ -80,36 +80,42 @@ public interface TrigonometricOperations<T> : Algebra<T> {
|
|||||||
* Computes the sine of [arg].
|
* Computes the sine of [arg].
|
||||||
*/
|
*/
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
|
@Deprecated("AlgebraElements are considered odd and will be removed in future releases.")
|
||||||
public fun <T : AlgebraElement<T, out TrigonometricOperations<T>>> sin(arg: T): T = arg.context.sin(arg)
|
public fun <T : AlgebraElement<T, out TrigonometricOperations<T>>> sin(arg: T): T = arg.context.sin(arg)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Computes the cosine of [arg].
|
* Computes the cosine of [arg].
|
||||||
*/
|
*/
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
|
@Deprecated("AlgebraElements are considered odd and will be removed in future releases.")
|
||||||
public fun <T : AlgebraElement<T, out TrigonometricOperations<T>>> cos(arg: T): T = arg.context.cos(arg)
|
public fun <T : AlgebraElement<T, out TrigonometricOperations<T>>> cos(arg: T): T = arg.context.cos(arg)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Computes the tangent of [arg].
|
* Computes the tangent of [arg].
|
||||||
*/
|
*/
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
|
@Deprecated("AlgebraElements are considered odd and will be removed in future releases.")
|
||||||
public fun <T : AlgebraElement<T, out TrigonometricOperations<T>>> tan(arg: T): T = arg.context.tan(arg)
|
public fun <T : AlgebraElement<T, out TrigonometricOperations<T>>> tan(arg: T): T = arg.context.tan(arg)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Computes the inverse sine of [arg].
|
* Computes the inverse sine of [arg].
|
||||||
*/
|
*/
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
|
@Deprecated("AlgebraElements are considered odd and will be removed in future releases.")
|
||||||
public fun <T : AlgebraElement<T, out TrigonometricOperations<T>>> asin(arg: T): T = arg.context.asin(arg)
|
public fun <T : AlgebraElement<T, out TrigonometricOperations<T>>> asin(arg: T): T = arg.context.asin(arg)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Computes the inverse cosine of [arg].
|
* Computes the inverse cosine of [arg].
|
||||||
*/
|
*/
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
|
@Deprecated("AlgebraElements are considered odd and will be removed in future releases.")
|
||||||
public fun <T : AlgebraElement<T, out TrigonometricOperations<T>>> acos(arg: T): T = arg.context.acos(arg)
|
public fun <T : AlgebraElement<T, out TrigonometricOperations<T>>> acos(arg: T): T = arg.context.acos(arg)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Computes the inverse tangent of [arg].
|
* Computes the inverse tangent of [arg].
|
||||||
*/
|
*/
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
|
@Deprecated("AlgebraElements are considered odd and will be removed in future releases.")
|
||||||
public fun <T : AlgebraElement<T, out TrigonometricOperations<T>>> atan(arg: T): T = arg.context.atan(arg)
|
public fun <T : AlgebraElement<T, out TrigonometricOperations<T>>> atan(arg: T): T = arg.context.atan(arg)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -154,18 +160,21 @@ public interface PowerOperations<T> : Algebra<T> {
|
|||||||
* @return the base raised to the power.
|
* @return the base raised to the power.
|
||||||
*/
|
*/
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
|
@Deprecated("AlgebraElements are considered odd and will be removed in future releases.")
|
||||||
public infix fun <T : AlgebraElement<T, out PowerOperations<T>>> T.pow(power: Double): T = context.power(this, power)
|
public infix fun <T : AlgebraElement<T, out PowerOperations<T>>> T.pow(power: Double): T = context.power(this, power)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Computes the square root of the value [arg].
|
* Computes the square root of the value [arg].
|
||||||
*/
|
*/
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
|
@Deprecated("AlgebraElements are considered odd and will be removed in future releases.")
|
||||||
public fun <T : AlgebraElement<T, out PowerOperations<T>>> sqrt(arg: T): T = arg pow 0.5
|
public fun <T : AlgebraElement<T, out PowerOperations<T>>> sqrt(arg: T): T = arg pow 0.5
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Computes the square of the value [arg].
|
* Computes the square of the value [arg].
|
||||||
*/
|
*/
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
|
@Deprecated("AlgebraElements are considered odd and will be removed in future releases.")
|
||||||
public fun <T : AlgebraElement<T, out PowerOperations<T>>> sqr(arg: T): T = arg pow 2.0
|
public fun <T : AlgebraElement<T, out PowerOperations<T>>> sqr(arg: T): T = arg pow 2.0
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -261,12 +270,14 @@ public interface ExponentialOperations<T> : Algebra<T> {
|
|||||||
* The identifier of exponential function.
|
* The identifier of exponential function.
|
||||||
*/
|
*/
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
|
@Deprecated("AlgebraElements are considered odd and will be removed in future releases.")
|
||||||
public fun <T : AlgebraElement<T, out ExponentialOperations<T>>> exp(arg: T): T = arg.context.exp(arg)
|
public fun <T : AlgebraElement<T, out ExponentialOperations<T>>> exp(arg: T): T = arg.context.exp(arg)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The identifier of natural logarithm.
|
* The identifier of natural logarithm.
|
||||||
*/
|
*/
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
|
@Deprecated("AlgebraElements are considered odd and will be removed in future releases.")
|
||||||
public fun <T : AlgebraElement<T, out ExponentialOperations<T>>> ln(arg: T): T = arg.context.ln(arg)
|
public fun <T : AlgebraElement<T, out ExponentialOperations<T>>> ln(arg: T): T = arg.context.ln(arg)
|
||||||
|
|
||||||
|
|
||||||
@ -280,30 +291,35 @@ public fun <T : AlgebraElement<T, out ExponentialOperations<T>>> sinh(arg: T): T
|
|||||||
* Computes the hyperbolic cosine of [arg].
|
* Computes the hyperbolic cosine of [arg].
|
||||||
*/
|
*/
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
|
@Deprecated("AlgebraElements are considered odd and will be removed in future releases.")
|
||||||
public fun <T : AlgebraElement<T, out ExponentialOperations<T>>> cosh(arg: T): T = arg.context.cosh(arg)
|
public fun <T : AlgebraElement<T, out ExponentialOperations<T>>> cosh(arg: T): T = arg.context.cosh(arg)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Computes the hyperbolic tangent of [arg].
|
* Computes the hyperbolic tangent of [arg].
|
||||||
*/
|
*/
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
|
@Deprecated("AlgebraElements are considered odd and will be removed in future releases.")
|
||||||
public fun <T : AlgebraElement<T, out ExponentialOperations<T>>> tanh(arg: T): T = arg.context.tanh(arg)
|
public fun <T : AlgebraElement<T, out ExponentialOperations<T>>> tanh(arg: T): T = arg.context.tanh(arg)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Computes the inverse hyperbolic sine of [arg].
|
* Computes the inverse hyperbolic sine of [arg].
|
||||||
*/
|
*/
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
|
@Deprecated("AlgebraElements are considered odd and will be removed in future releases.")
|
||||||
public fun <T : AlgebraElement<T, out ExponentialOperations<T>>> asinh(arg: T): T = arg.context.asinh(arg)
|
public fun <T : AlgebraElement<T, out ExponentialOperations<T>>> asinh(arg: T): T = arg.context.asinh(arg)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Computes the inverse hyperbolic cosine of [arg].
|
* Computes the inverse hyperbolic cosine of [arg].
|
||||||
*/
|
*/
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
|
@Deprecated("AlgebraElements are considered odd and will be removed in future releases.")
|
||||||
public fun <T : AlgebraElement<T, out ExponentialOperations<T>>> acosh(arg: T): T = arg.context.acosh(arg)
|
public fun <T : AlgebraElement<T, out ExponentialOperations<T>>> acosh(arg: T): T = arg.context.acosh(arg)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Computes the inverse hyperbolic tangent of [arg].
|
* Computes the inverse hyperbolic tangent of [arg].
|
||||||
*/
|
*/
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
|
@Deprecated("AlgebraElements are considered odd and will be removed in future releases.")
|
||||||
public fun <T : AlgebraElement<T, out ExponentialOperations<T>>> atanh(arg: T): T = arg.context.atanh(arg)
|
public fun <T : AlgebraElement<T, out ExponentialOperations<T>>> atanh(arg: T): T = arg.context.atanh(arg)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
EJML based linear algebra implementation.
|
EJML based linear algebra implementation.
|
||||||
|
|
||||||
- [ejml-vector](src/main/kotlin/space/kscience/kmath/ejml/EjmlVector.kt) : The Point implementation using SimpleMatrix.
|
- [ejml-vector](src/main/kotlin/space/kscience/kmath/ejml/EjmlVector.kt) : Point implementations.
|
||||||
- [ejml-matrix](src/main/kotlin/space/kscience/kmath/ejml/EjmlMatrix.kt) : The Matrix implementation using SimpleMatrix.
|
- [ejml-matrix](src/main/kotlin/space/kscience/kmath/ejml/EjmlMatrix.kt) : Matrix implementation.
|
||||||
- [ejml-linear-space](src/main/kotlin/space/kscience/kmath/ejml/EjmlLinearSpace.kt) : The LinearSpace implementation using SimpleMatrix.
|
- [ejml-linear-space](src/main/kotlin/space/kscience/kmath/ejml/EjmlLinearSpace.kt) : LinearSpace implementations.
|
||||||
|
|
||||||
|
|
||||||
## Artifact:
|
## Artifact:
|
||||||
@ -15,8 +15,7 @@ The Maven coordinates of this project are `space.kscience:kmath-ejml:0.3.0-dev-7
|
|||||||
```gradle
|
```gradle
|
||||||
repositories {
|
repositories {
|
||||||
maven { url 'https://repo.kotlin.link' }
|
maven { url 'https://repo.kotlin.link' }
|
||||||
maven { url 'https://dl.bintray.com/hotkeytlt/maven' }
|
mavenCentral()
|
||||||
maven { url "https://dl.bintray.com/kotlin/kotlin-eap" } // include for builds based on kotlin-eap
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
@ -27,8 +26,7 @@ dependencies {
|
|||||||
```kotlin
|
```kotlin
|
||||||
repositories {
|
repositories {
|
||||||
maven("https://repo.kotlin.link")
|
maven("https://repo.kotlin.link")
|
||||||
maven("https://dl.bintray.com/kotlin/kotlin-eap") // include for builds based on kotlin-eap
|
mavenCentral()
|
||||||
maven("https://dl.bintray.com/hotkeytlt/maven") // required for a
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
@ -4,7 +4,7 @@ plugins {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
api("org.ejml:ejml-simple:0.40")
|
api("org.ejml:ejml-ddense:0.40")
|
||||||
api(project(":kmath-core"))
|
api(project(":kmath-core"))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -14,19 +14,19 @@ readme {
|
|||||||
|
|
||||||
feature(
|
feature(
|
||||||
id = "ejml-vector",
|
id = "ejml-vector",
|
||||||
description = "The Point implementation using SimpleMatrix.",
|
description = "Point implementations.",
|
||||||
ref = "src/main/kotlin/space/kscience/kmath/ejml/EjmlVector.kt"
|
ref = "src/main/kotlin/space/kscience/kmath/ejml/EjmlVector.kt"
|
||||||
)
|
)
|
||||||
|
|
||||||
feature(
|
feature(
|
||||||
id = "ejml-matrix",
|
id = "ejml-matrix",
|
||||||
description = "The Matrix implementation using SimpleMatrix.",
|
description = "Matrix implementation.",
|
||||||
ref = "src/main/kotlin/space/kscience/kmath/ejml/EjmlMatrix.kt"
|
ref = "src/main/kotlin/space/kscience/kmath/ejml/EjmlMatrix.kt"
|
||||||
)
|
)
|
||||||
|
|
||||||
feature(
|
feature(
|
||||||
id = "ejml-linear-space",
|
id = "ejml-linear-space",
|
||||||
description = "The LinearSpace implementation using SimpleMatrix.",
|
description = "LinearSpace implementations.",
|
||||||
ref = "src/main/kotlin/space/kscience/kmath/ejml/EjmlLinearSpace.kt"
|
ref = "src/main/kotlin/space/kscience/kmath/ejml/EjmlLinearSpace.kt"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -5,45 +5,71 @@
|
|||||||
|
|
||||||
package space.kscience.kmath.ejml
|
package space.kscience.kmath.ejml
|
||||||
|
|
||||||
|
import org.ejml.data.DMatrix
|
||||||
|
import org.ejml.data.DMatrixD1
|
||||||
|
import org.ejml.data.DMatrixRMaj
|
||||||
|
import org.ejml.dense.row.CommonOps_DDRM
|
||||||
import org.ejml.dense.row.factory.DecompositionFactory_DDRM
|
import org.ejml.dense.row.factory.DecompositionFactory_DDRM
|
||||||
import org.ejml.simple.SimpleMatrix
|
|
||||||
import space.kscience.kmath.linear.*
|
import space.kscience.kmath.linear.*
|
||||||
import space.kscience.kmath.misc.UnstableKMathAPI
|
import space.kscience.kmath.misc.UnstableKMathAPI
|
||||||
import space.kscience.kmath.nd.StructureFeature
|
import space.kscience.kmath.nd.StructureFeature
|
||||||
import space.kscience.kmath.nd.getFeature
|
|
||||||
import space.kscience.kmath.operations.DoubleField
|
import space.kscience.kmath.operations.DoubleField
|
||||||
|
import space.kscience.kmath.operations.Ring
|
||||||
import space.kscience.kmath.structures.DoubleBuffer
|
import space.kscience.kmath.structures.DoubleBuffer
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
import kotlin.reflect.cast
|
import kotlin.reflect.cast
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents context of basic operations operating with [EjmlMatrix].
|
* [LinearSpace] implementation specialized for a certain EJML type.
|
||||||
|
*
|
||||||
|
* @param T the type of items in the matrices.
|
||||||
|
* @param A the element context type.
|
||||||
|
* @param M the EJML matrix type.
|
||||||
|
* @author Iaroslav Postovalov
|
||||||
|
*/
|
||||||
|
public abstract class EjmlLinearSpace<T : Any, out A : Ring<T>, M : org.ejml.data.Matrix> : LinearSpace<T, A> {
|
||||||
|
/**
|
||||||
|
* Converts this matrix to EJML one.
|
||||||
|
*/
|
||||||
|
public abstract fun Matrix<T>.toEjml(): EjmlMatrix<T, M>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts this vector to EJML one.
|
||||||
|
*/
|
||||||
|
public abstract fun Point<T>.toEjml(): EjmlVector<T, M>
|
||||||
|
|
||||||
|
public abstract override fun buildMatrix(
|
||||||
|
rows: Int,
|
||||||
|
columns: Int,
|
||||||
|
initializer: A.(i: Int, j: Int) -> T,
|
||||||
|
): EjmlMatrix<T, M>
|
||||||
|
|
||||||
|
public abstract override fun buildVector(size: Int, initializer: A.(Int) -> T): EjmlVector<T, M>
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* [EjmlLinearSpace] implementation based on [CommonOps_DDRM], [DecompositionFactory_DDRM] operations and
|
||||||
|
* [DMatrixRMaj] matrices.
|
||||||
*
|
*
|
||||||
* @author Iaroslav Postovalov
|
* @author Iaroslav Postovalov
|
||||||
* @author Alexander Nozik
|
|
||||||
*/
|
*/
|
||||||
public object EjmlLinearSpace : LinearSpace<Double, DoubleField> {
|
public object EjmlLinearSpaceDDRM : EjmlLinearSpace<Double, DoubleField, DMatrixRMaj>() {
|
||||||
/**
|
/**
|
||||||
* The [DoubleField] reference.
|
* The [DoubleField] reference.
|
||||||
*/
|
*/
|
||||||
public override val elementAlgebra: DoubleField get() = DoubleField
|
public override val elementAlgebra: DoubleField get() = DoubleField
|
||||||
|
|
||||||
/**
|
@Suppress("UNCHECKED_CAST")
|
||||||
* Converts this matrix to EJML one.
|
public override fun Matrix<Double>.toEjml(): EjmlDoubleMatrix<DMatrixRMaj> = when {
|
||||||
*/
|
this is EjmlDoubleMatrix<*> && origin is DMatrixRMaj -> this as EjmlDoubleMatrix<DMatrixRMaj>
|
||||||
@OptIn(UnstableKMathAPI::class)
|
|
||||||
public fun Matrix<Double>.toEjml(): EjmlMatrix = when (val matrix = origin) {
|
|
||||||
is EjmlMatrix -> matrix
|
|
||||||
else -> buildMatrix(rowNum, colNum) { i, j -> get(i, j) }
|
else -> buildMatrix(rowNum, colNum) { i, j -> get(i, j) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Suppress("UNCHECKED_CAST")
|
||||||
* Converts this vector to EJML one.
|
public override fun Point<Double>.toEjml(): EjmlDoubleVector<DMatrixRMaj> = when {
|
||||||
*/
|
this is EjmlDoubleVector<*> && origin is DMatrixRMaj -> this as EjmlDoubleVector<DMatrixRMaj>
|
||||||
public fun Point<Double>.toEjml(): EjmlVector = when (this) {
|
else -> EjmlDoubleVector(DMatrixRMaj(size, 1).also {
|
||||||
is EjmlVector -> this
|
(0 until it.numRows).forEach { row -> it[row, 0] = get(row) }
|
||||||
else -> EjmlVector(SimpleMatrix(size, 1).also {
|
|
||||||
(0 until it.numRows()).forEach { row -> it[row, 0] = get(row) }
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,159 +77,178 @@ public object EjmlLinearSpace : LinearSpace<Double, DoubleField> {
|
|||||||
rows: Int,
|
rows: Int,
|
||||||
columns: Int,
|
columns: Int,
|
||||||
initializer: DoubleField.(i: Int, j: Int) -> Double,
|
initializer: DoubleField.(i: Int, j: Int) -> Double,
|
||||||
): EjmlMatrix = EjmlMatrix(SimpleMatrix(rows, columns).also {
|
): EjmlDoubleMatrix<DMatrixRMaj> = EjmlDoubleMatrix(DMatrixRMaj(rows, columns).also {
|
||||||
(0 until rows).forEach { row ->
|
(0 until rows).forEach { row ->
|
||||||
(0 until columns).forEach { col -> it[row, col] = DoubleField.initializer(row, col) }
|
(0 until columns).forEach { col -> it[row, col] = elementAlgebra.initializer(row, col) }
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
public override fun buildVector(size: Int, initializer: DoubleField.(Int) -> Double): Point<Double> =
|
public override fun buildVector(
|
||||||
EjmlVector(SimpleMatrix(size, 1).also {
|
size: Int,
|
||||||
(0 until it.numRows()).forEach { row -> it[row, 0] = DoubleField.initializer(row) }
|
initializer: DoubleField.(Int) -> Double,
|
||||||
})
|
): EjmlDoubleVector<DMatrixRMaj> = EjmlDoubleVector(DMatrixRMaj(size, 1).also {
|
||||||
|
(0 until it.numRows).forEach { row -> it[row, 0] = elementAlgebra.initializer(row) }
|
||||||
|
})
|
||||||
|
|
||||||
private fun SimpleMatrix.wrapMatrix() = EjmlMatrix(this)
|
private fun <T : DMatrix> T.wrapMatrix() = EjmlDoubleMatrix(this)
|
||||||
private fun SimpleMatrix.wrapVector() = EjmlVector(this)
|
private fun <T : DMatrixD1> T.wrapVector() = EjmlDoubleVector(this)
|
||||||
|
|
||||||
public override fun Matrix<Double>.unaryMinus(): Matrix<Double> = this * (-1.0)
|
public override fun Matrix<Double>.unaryMinus(): Matrix<Double> = this * (-1.0)
|
||||||
|
|
||||||
public override fun Matrix<Double>.dot(other: Matrix<Double>): EjmlMatrix =
|
public override fun Matrix<Double>.dot(other: Matrix<Double>): EjmlDoubleMatrix<DMatrixRMaj> {
|
||||||
EjmlMatrix(toEjml().origin.mult(other.toEjml().origin))
|
val out = DMatrixRMaj(1, 1)
|
||||||
|
CommonOps_DDRM.mult(toEjml().origin, other.toEjml().origin, out)
|
||||||
|
return out.wrapMatrix()
|
||||||
|
}
|
||||||
|
|
||||||
public override fun Matrix<Double>.dot(vector: Point<Double>): EjmlVector =
|
public override fun Matrix<Double>.dot(vector: Point<Double>): EjmlDoubleVector<DMatrixRMaj> {
|
||||||
EjmlVector(toEjml().origin.mult(vector.toEjml().origin))
|
val out = DMatrixRMaj(1, 1)
|
||||||
|
CommonOps_DDRM.mult(toEjml().origin, vector.toEjml().origin, out)
|
||||||
|
return out.wrapVector()
|
||||||
|
}
|
||||||
|
|
||||||
public override operator fun Matrix<Double>.minus(other: Matrix<Double>): EjmlMatrix =
|
public override operator fun Matrix<Double>.minus(other: Matrix<Double>): EjmlDoubleMatrix<DMatrixRMaj> {
|
||||||
(toEjml().origin - other.toEjml().origin).wrapMatrix()
|
val out = DMatrixRMaj(1, 1)
|
||||||
|
CommonOps_DDRM.subtract(toEjml().origin, other.toEjml().origin, out)
|
||||||
|
return out.wrapMatrix()
|
||||||
|
}
|
||||||
|
|
||||||
public override operator fun Matrix<Double>.times(value: Double): EjmlMatrix =
|
public override operator fun Matrix<Double>.times(value: Double): EjmlDoubleMatrix<DMatrixRMaj> {
|
||||||
toEjml().origin.scale(value).wrapMatrix()
|
val res = this.toEjml().origin.copy()
|
||||||
|
CommonOps_DDRM.scale(value, res)
|
||||||
|
return res.wrapMatrix()
|
||||||
|
}
|
||||||
|
|
||||||
public override fun Point<Double>.unaryMinus(): EjmlVector =
|
public override fun Point<Double>.unaryMinus(): EjmlDoubleVector<DMatrixRMaj> {
|
||||||
toEjml().origin.negative().wrapVector()
|
val out = toEjml().origin.copy()
|
||||||
|
CommonOps_DDRM.changeSign(out)
|
||||||
|
return out.wrapVector()
|
||||||
|
}
|
||||||
|
|
||||||
public override fun Matrix<Double>.plus(other: Matrix<Double>): EjmlMatrix =
|
public override fun Matrix<Double>.plus(other: Matrix<Double>): EjmlDoubleMatrix<DMatrixRMaj> {
|
||||||
(toEjml().origin + other.toEjml().origin).wrapMatrix()
|
val out = DMatrixRMaj(1, 1)
|
||||||
|
CommonOps_DDRM.add(toEjml().origin, other.toEjml().origin, out)
|
||||||
|
return out.wrapMatrix()
|
||||||
|
}
|
||||||
|
|
||||||
public override fun Point<Double>.plus(other: Point<Double>): EjmlVector =
|
public override fun Point<Double>.plus(other: Point<Double>): EjmlDoubleVector<DMatrixRMaj> {
|
||||||
(toEjml().origin + other.toEjml().origin).wrapVector()
|
val out = DMatrixRMaj(1, 1)
|
||||||
|
CommonOps_DDRM.add(toEjml().origin, other.toEjml().origin, out)
|
||||||
|
return out.wrapVector()
|
||||||
|
}
|
||||||
|
|
||||||
public override fun Point<Double>.minus(other: Point<Double>): EjmlVector =
|
public override fun Point<Double>.minus(other: Point<Double>): EjmlDoubleVector<DMatrixRMaj> {
|
||||||
(toEjml().origin - other.toEjml().origin).wrapVector()
|
val out = DMatrixRMaj(1, 1)
|
||||||
|
CommonOps_DDRM.subtract(toEjml().origin, other.toEjml().origin, out)
|
||||||
|
return out.wrapVector()
|
||||||
|
}
|
||||||
|
|
||||||
public override fun Double.times(m: Matrix<Double>): EjmlMatrix =
|
public override fun Double.times(m: Matrix<Double>): EjmlDoubleMatrix<DMatrixRMaj> = m * this
|
||||||
m.toEjml().origin.scale(this).wrapMatrix()
|
|
||||||
|
|
||||||
public override fun Point<Double>.times(value: Double): EjmlVector =
|
public override fun Point<Double>.times(value: Double): EjmlDoubleVector<DMatrixRMaj> {
|
||||||
toEjml().origin.scale(value).wrapVector()
|
val res = this.toEjml().origin.copy()
|
||||||
|
CommonOps_DDRM.scale(value, res)
|
||||||
|
return res.wrapVector()
|
||||||
|
}
|
||||||
|
|
||||||
public override fun Double.times(v: Point<Double>): EjmlVector =
|
public override fun Double.times(v: Point<Double>): EjmlDoubleVector<DMatrixRMaj> = v * this
|
||||||
v.toEjml().origin.scale(this).wrapVector()
|
|
||||||
|
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
public override fun <F : StructureFeature> getFeature(structure: Matrix<Double>, type: KClass<out F>): F? {
|
public override fun <F : StructureFeature> getFeature(structure: Matrix<Double>, type: KClass<out F>): F? {
|
||||||
//Return the feature if it is intrinsic to the structure
|
// Return the feature if it is intrinsic to the structure
|
||||||
structure.getFeature(type)?.let { return it }
|
structure.getFeature(type)?.let { return it }
|
||||||
|
|
||||||
val origin = structure.toEjml().origin
|
val origin = structure.toEjml().origin
|
||||||
|
|
||||||
return when (type) {
|
return when (type) {
|
||||||
InverseMatrixFeature::class -> object : InverseMatrixFeature<Double> {
|
InverseMatrixFeature::class -> object : InverseMatrixFeature<Double> {
|
||||||
override val inverse: Matrix<Double> by lazy { EjmlMatrix(origin.invert()) }
|
override val inverse: Matrix<Double> by lazy {
|
||||||
|
val res = origin.copy()
|
||||||
|
CommonOps_DDRM.invert(res)
|
||||||
|
EjmlDoubleMatrix(res)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DeterminantFeature::class -> object : DeterminantFeature<Double> {
|
DeterminantFeature::class -> object : DeterminantFeature<Double> {
|
||||||
override val determinant: Double by lazy(origin::determinant)
|
override val determinant: Double by lazy { CommonOps_DDRM.det(DMatrixRMaj(origin)) }
|
||||||
}
|
}
|
||||||
|
|
||||||
SingularValueDecompositionFeature::class -> object : SingularValueDecompositionFeature<Double> {
|
SingularValueDecompositionFeature::class -> object : SingularValueDecompositionFeature<Double> {
|
||||||
private val svd by lazy {
|
private val svd by lazy {
|
||||||
DecompositionFactory_DDRM.svd(origin.numRows(), origin.numCols(), true, true, false)
|
DecompositionFactory_DDRM.svd(origin.numRows, origin.numCols, true, true, false)
|
||||||
.apply { decompose(origin.ddrm.copy()) }
|
.apply { decompose(origin.copy()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override val u: Matrix<Double> by lazy { EjmlMatrix(SimpleMatrix(svd.getU(null, false))) }
|
override val u: Matrix<Double> by lazy { EjmlDoubleMatrix(svd.getU(null, false)) }
|
||||||
override val s: Matrix<Double> by lazy { EjmlMatrix(SimpleMatrix(svd.getW(null))) }
|
override val s: Matrix<Double> by lazy { EjmlDoubleMatrix(svd.getW(null)) }
|
||||||
override val v: Matrix<Double> by lazy { EjmlMatrix(SimpleMatrix(svd.getV(null, false))) }
|
override val v: Matrix<Double> by lazy { EjmlDoubleMatrix(svd.getV(null, false)) }
|
||||||
override val singularValues: Point<Double> by lazy { DoubleBuffer(svd.singularValues) }
|
override val singularValues: Point<Double> by lazy { DoubleBuffer(svd.singularValues) }
|
||||||
}
|
}
|
||||||
|
|
||||||
QRDecompositionFeature::class -> object : QRDecompositionFeature<Double> {
|
QRDecompositionFeature::class -> object : QRDecompositionFeature<Double> {
|
||||||
private val qr by lazy {
|
private val qr by lazy {
|
||||||
DecompositionFactory_DDRM.qr().apply { decompose(origin.ddrm.copy()) }
|
DecompositionFactory_DDRM.qr().apply { decompose(origin.copy()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override val q: Matrix<Double> by lazy {
|
override val q: Matrix<Double> by lazy {
|
||||||
EjmlMatrix(SimpleMatrix(qr.getQ(null, false))) + OrthogonalFeature
|
EjmlDoubleMatrix(qr.getQ(null, false)) + OrthogonalFeature
|
||||||
}
|
}
|
||||||
|
|
||||||
override val r: Matrix<Double> by lazy { EjmlMatrix(SimpleMatrix(qr.getR(null, false))) + UFeature }
|
override val r: Matrix<Double> by lazy { EjmlDoubleMatrix(qr.getR(null, false)) + UFeature }
|
||||||
}
|
}
|
||||||
|
|
||||||
CholeskyDecompositionFeature::class -> object : CholeskyDecompositionFeature<Double> {
|
CholeskyDecompositionFeature::class -> object : CholeskyDecompositionFeature<Double> {
|
||||||
override val l: Matrix<Double> by lazy {
|
override val l: Matrix<Double> by lazy {
|
||||||
val cholesky =
|
val cholesky =
|
||||||
DecompositionFactory_DDRM.chol(structure.rowNum, true).apply { decompose(origin.ddrm.copy()) }
|
DecompositionFactory_DDRM.chol(structure.rowNum, true).apply { decompose(origin.copy()) }
|
||||||
|
|
||||||
EjmlMatrix(SimpleMatrix(cholesky.getT(null))) + LFeature
|
EjmlDoubleMatrix(cholesky.getT(null)) + LFeature
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LupDecompositionFeature::class -> object : LupDecompositionFeature<Double> {
|
LupDecompositionFeature::class -> object : LupDecompositionFeature<Double> {
|
||||||
private val lup by lazy {
|
private val lup by lazy {
|
||||||
DecompositionFactory_DDRM.lu(origin.numRows(), origin.numCols())
|
DecompositionFactory_DDRM.lu(origin.numRows, origin.numCols).apply { decompose(origin.copy()) }
|
||||||
.apply { decompose(origin.ddrm.copy()) }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override val l: Matrix<Double> by lazy {
|
override val l: Matrix<Double> by lazy {
|
||||||
EjmlMatrix(SimpleMatrix(lup.getLower(null))) + LFeature
|
EjmlDoubleMatrix(lup.getLower(null)) + LFeature
|
||||||
}
|
}
|
||||||
|
|
||||||
override val u: Matrix<Double> by lazy {
|
override val u: Matrix<Double> by lazy {
|
||||||
EjmlMatrix(SimpleMatrix(lup.getUpper(null))) + UFeature
|
EjmlDoubleMatrix(lup.getUpper(null)) + UFeature
|
||||||
}
|
}
|
||||||
|
|
||||||
override val p: Matrix<Double> by lazy { EjmlMatrix(SimpleMatrix(lup.getRowPivot(null))) }
|
override val p: Matrix<Double> by lazy { EjmlDoubleMatrix(lup.getRowPivot(null)) }
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> null
|
else -> null
|
||||||
}?.let(type::cast)
|
}?.let(type::cast)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Solves for *x* in the following equation: *x = [a] <sup>-1</sup> · [b]*.
|
||||||
|
*
|
||||||
|
* @param a the base matrix.
|
||||||
|
* @param b n by p matrix.
|
||||||
|
* @return the solution for 'x' that is n by p.
|
||||||
|
*/
|
||||||
|
public fun solve(a: Matrix<Double>, b: Matrix<Double>): EjmlDoubleMatrix<DMatrixRMaj> {
|
||||||
|
val res = DMatrixRMaj(1, 1)
|
||||||
|
CommonOps_DDRM.solve(DMatrixRMaj(a.toEjml().origin), DMatrixRMaj(b.toEjml().origin), res)
|
||||||
|
return EjmlDoubleMatrix(res)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Solves for *x* in the following equation: *x = [a] <sup>-1</sup> · [b]*.
|
||||||
|
*
|
||||||
|
* @param a the base matrix.
|
||||||
|
* @param b n by p vector.
|
||||||
|
* @return the solution for 'x' that is n by p.
|
||||||
|
*/
|
||||||
|
public fun solve(a: Matrix<Double>, b: Point<Double>): EjmlDoubleVector<DMatrixRMaj> {
|
||||||
|
val res = DMatrixRMaj(1, 1)
|
||||||
|
CommonOps_DDRM.solve(DMatrixRMaj(a.toEjml().origin), DMatrixRMaj(b.toEjml().origin), res)
|
||||||
|
return EjmlDoubleVector(res)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Solves for *x* in the following equation: *x = [a] <sup>-1</sup> · [b]*.
|
|
||||||
*
|
|
||||||
* @param a the base matrix.
|
|
||||||
* @param b n by p matrix.
|
|
||||||
* @return the solution for 'x' that is n by p.
|
|
||||||
* @author Iaroslav Postovalov
|
|
||||||
*/
|
|
||||||
public fun EjmlLinearSpace.solve(a: Matrix<Double>, b: Matrix<Double>): EjmlMatrix =
|
|
||||||
EjmlMatrix(a.toEjml().origin.solve(b.toEjml().origin))
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Solves for *x* in the following equation: *x = [a] <sup>-1</sup> · [b]*.
|
|
||||||
*
|
|
||||||
* @param a the base matrix.
|
|
||||||
* @param b n by p vector.
|
|
||||||
* @return the solution for 'x' that is n by p.
|
|
||||||
* @author Iaroslav Postovalov
|
|
||||||
*/
|
|
||||||
public fun EjmlLinearSpace.solve(a: Matrix<Double>, b: Point<Double>): EjmlVector =
|
|
||||||
EjmlVector(a.toEjml().origin.solve(b.toEjml().origin))
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Inverts this matrix.
|
|
||||||
*
|
|
||||||
* @author Alexander Nozik
|
|
||||||
*/
|
|
||||||
@OptIn(UnstableKMathAPI::class)
|
|
||||||
public fun EjmlMatrix.inverted(): EjmlMatrix = getFeature<InverseMatrixFeature<Double>>()!!.inverse as EjmlMatrix
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Inverts the given matrix.
|
|
||||||
*
|
|
||||||
* @author Alexander Nozik
|
|
||||||
*/
|
|
||||||
public fun EjmlLinearSpace.inverse(matrix: Matrix<Double>): Matrix<Double> = matrix.toEjml().inverted()
|
|
@ -5,18 +5,28 @@
|
|||||||
|
|
||||||
package space.kscience.kmath.ejml
|
package space.kscience.kmath.ejml
|
||||||
|
|
||||||
import org.ejml.simple.SimpleMatrix
|
import org.ejml.data.DMatrix
|
||||||
import space.kscience.kmath.linear.Matrix
|
import org.ejml.data.Matrix
|
||||||
|
import space.kscience.kmath.nd.Structure2D
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The matrix implementation over EJML [SimpleMatrix].
|
* [space.kscience.kmath.linear.Matrix] implementation based on EJML [Matrix].
|
||||||
*
|
*
|
||||||
* @property origin the underlying [SimpleMatrix].
|
* @param T the type of elements contained in the buffer.
|
||||||
|
* @param M the type of EJML matrix.
|
||||||
|
* @property origin The underlying EJML matrix.
|
||||||
* @author Iaroslav Postovalov
|
* @author Iaroslav Postovalov
|
||||||
*/
|
*/
|
||||||
public class EjmlMatrix(public val origin: SimpleMatrix) : Matrix<Double> {
|
public abstract class EjmlMatrix<T, out M : Matrix>(public open val origin: M) : Structure2D<T> {
|
||||||
public override val rowNum: Int get() = origin.numRows()
|
public override val rowNum: Int get() = origin.numRows
|
||||||
public override val colNum: Int get() = origin.numCols()
|
public override val colNum: Int get() = origin.numCols
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* [EjmlMatrix] specialization for [Double].
|
||||||
|
*
|
||||||
|
* @author Iaroslav Postovalov
|
||||||
|
*/
|
||||||
|
public class EjmlDoubleMatrix<out M : DMatrix>(public override val origin: M) : EjmlMatrix<Double, M>(origin) {
|
||||||
public override operator fun get(i: Int, j: Int): Double = origin[i, j]
|
public override operator fun get(i: Int, j: Int): Double = origin[i, j]
|
||||||
}
|
}
|
||||||
|
@ -5,35 +5,41 @@
|
|||||||
|
|
||||||
package space.kscience.kmath.ejml
|
package space.kscience.kmath.ejml
|
||||||
|
|
||||||
import org.ejml.simple.SimpleMatrix
|
import org.ejml.data.DMatrixD1
|
||||||
|
import org.ejml.data.Matrix
|
||||||
import space.kscience.kmath.linear.Point
|
import space.kscience.kmath.linear.Point
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents point over EJML [SimpleMatrix].
|
* [Point] implementation based on EJML [Matrix].
|
||||||
*
|
*
|
||||||
* @property origin the underlying [SimpleMatrix].
|
* @param T the type of elements contained in the buffer.
|
||||||
|
* @param M the type of EJML matrix.
|
||||||
|
* @property origin The underlying matrix.
|
||||||
* @author Iaroslav Postovalov
|
* @author Iaroslav Postovalov
|
||||||
*/
|
*/
|
||||||
public class EjmlVector internal constructor(public val origin: SimpleMatrix) : Point<Double> {
|
public abstract class EjmlVector<out T, out M : Matrix>(public open val origin: M) : Point<T> {
|
||||||
public override val size: Int
|
public override val size: Int
|
||||||
get() = origin.numRows()
|
get() = origin.numRows
|
||||||
|
|
||||||
init {
|
public override operator fun iterator(): Iterator<T> = object : Iterator<T> {
|
||||||
require(origin.numCols() == 1) { "Only single column matrices are allowed" }
|
|
||||||
}
|
|
||||||
|
|
||||||
public override operator fun get(index: Int): Double = origin[index]
|
|
||||||
|
|
||||||
public override operator fun iterator(): Iterator<Double> = object : Iterator<Double> {
|
|
||||||
private var cursor: Int = 0
|
private var cursor: Int = 0
|
||||||
|
|
||||||
override fun next(): Double {
|
override fun next(): T {
|
||||||
cursor += 1
|
cursor += 1
|
||||||
return origin[cursor - 1]
|
return this@EjmlVector[cursor - 1]
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun hasNext(): Boolean = cursor < origin.numCols() * origin.numRows()
|
override fun hasNext(): Boolean = cursor < origin.numCols * origin.numRows
|
||||||
}
|
}
|
||||||
|
|
||||||
public override fun toString(): String = "EjmlVector(origin=$origin)"
|
public override fun toString(): String = "EjmlVector(origin=$origin)"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* [EjmlVector] specialization for [Double].
|
||||||
|
*
|
||||||
|
* @author Iaroslav Postovalov
|
||||||
|
*/
|
||||||
|
public class EjmlDoubleVector<out M : DMatrixD1>(public override val origin: M) : EjmlVector<Double, M>(origin) {
|
||||||
|
public override operator fun get(index: Int): Double = origin[index]
|
||||||
|
}
|
||||||
|
@ -5,12 +5,15 @@
|
|||||||
|
|
||||||
package space.kscience.kmath.ejml
|
package space.kscience.kmath.ejml
|
||||||
|
|
||||||
|
import org.ejml.data.DMatrixRMaj
|
||||||
|
import org.ejml.dense.row.CommonOps_DDRM
|
||||||
|
import org.ejml.dense.row.RandomMatrices_DDRM
|
||||||
import org.ejml.dense.row.factory.DecompositionFactory_DDRM
|
import org.ejml.dense.row.factory.DecompositionFactory_DDRM
|
||||||
import org.ejml.simple.SimpleMatrix
|
import space.kscience.kmath.linear.DeterminantFeature
|
||||||
import space.kscience.kmath.linear.*
|
import space.kscience.kmath.linear.LupDecompositionFeature
|
||||||
|
import space.kscience.kmath.linear.getFeature
|
||||||
import space.kscience.kmath.misc.UnstableKMathAPI
|
import space.kscience.kmath.misc.UnstableKMathAPI
|
||||||
import space.kscience.kmath.nd.StructureND
|
import space.kscience.kmath.nd.StructureND
|
||||||
import space.kscience.kmath.nd.getFeature
|
|
||||||
import kotlin.random.Random
|
import kotlin.random.Random
|
||||||
import kotlin.random.asJavaRandom
|
import kotlin.random.asJavaRandom
|
||||||
import kotlin.test.*
|
import kotlin.test.*
|
||||||
@ -22,65 +25,59 @@ fun <T : Any> assertMatrixEquals(expected: StructureND<T>, actual: StructureND<T
|
|||||||
internal class EjmlMatrixTest {
|
internal class EjmlMatrixTest {
|
||||||
private val random = Random(0)
|
private val random = Random(0)
|
||||||
|
|
||||||
private val randomMatrix: SimpleMatrix
|
private val randomMatrix: DMatrixRMaj
|
||||||
get() {
|
get() {
|
||||||
val s = random.nextInt(2, 100)
|
val s = random.nextInt(2, 100)
|
||||||
return SimpleMatrix.random_DDRM(s, s, 0.0, 10.0, random.asJavaRandom())
|
val d = DMatrixRMaj(s, s)
|
||||||
|
RandomMatrices_DDRM.fillUniform(d, random.asJavaRandom())
|
||||||
|
return d
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun rowNum() {
|
fun rowNum() {
|
||||||
val m = randomMatrix
|
val m = randomMatrix
|
||||||
assertEquals(m.numRows(), EjmlMatrix(m).rowNum)
|
assertEquals(m.numRows, EjmlDoubleMatrix(m).rowNum)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun colNum() {
|
fun colNum() {
|
||||||
val m = randomMatrix
|
val m = randomMatrix
|
||||||
assertEquals(m.numCols(), EjmlMatrix(m).rowNum)
|
assertEquals(m.numCols, EjmlDoubleMatrix(m).rowNum)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun shape() {
|
fun shape() {
|
||||||
val m = randomMatrix
|
val m = randomMatrix
|
||||||
val w = EjmlMatrix(m)
|
val w = EjmlDoubleMatrix(m)
|
||||||
assertEquals(listOf(m.numRows(), m.numCols()), w.shape.toList())
|
assertContentEquals(intArrayOf(m.numRows, m.numCols), w.shape)
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(UnstableKMathAPI::class)
|
@OptIn(UnstableKMathAPI::class)
|
||||||
@Test
|
@Test
|
||||||
fun features() {
|
fun features() {
|
||||||
val m = randomMatrix
|
val m = randomMatrix
|
||||||
val w = EjmlMatrix(m)
|
val w = EjmlDoubleMatrix(m)
|
||||||
val det: DeterminantFeature<Double> = EjmlLinearSpace.getFeature(w) ?: fail()
|
val det: DeterminantFeature<Double> = EjmlLinearSpaceDDRM.getFeature(w) ?: fail()
|
||||||
assertEquals(m.determinant(), det.determinant)
|
assertEquals(CommonOps_DDRM.det(m), det.determinant)
|
||||||
val lup: LupDecompositionFeature<Double> = EjmlLinearSpace.getFeature(w) ?: fail()
|
val lup: LupDecompositionFeature<Double> = EjmlLinearSpaceDDRM.getFeature(w) ?: fail()
|
||||||
|
|
||||||
val ludecompositionF64 = DecompositionFactory_DDRM.lu(m.numRows(), m.numCols())
|
val ludecompositionF64 = DecompositionFactory_DDRM.lu(m.numRows, m.numCols)
|
||||||
.also { it.decompose(m.ddrm.copy()) }
|
.also { it.decompose(m.copy()) }
|
||||||
|
|
||||||
assertMatrixEquals(EjmlMatrix(SimpleMatrix(ludecompositionF64.getLower(null))), lup.l)
|
assertMatrixEquals(EjmlDoubleMatrix(ludecompositionF64.getLower(null)), lup.l)
|
||||||
assertMatrixEquals(EjmlMatrix(SimpleMatrix(ludecompositionF64.getUpper(null))), lup.u)
|
assertMatrixEquals(EjmlDoubleMatrix(ludecompositionF64.getUpper(null)), lup.u)
|
||||||
assertMatrixEquals(EjmlMatrix(SimpleMatrix(ludecompositionF64.getRowPivot(null))), lup.p)
|
assertMatrixEquals(EjmlDoubleMatrix(ludecompositionF64.getRowPivot(null)), lup.p)
|
||||||
}
|
|
||||||
|
|
||||||
private object SomeFeature : MatrixFeature {}
|
|
||||||
|
|
||||||
@OptIn(UnstableKMathAPI::class)
|
|
||||||
@Test
|
|
||||||
fun suggestFeature() {
|
|
||||||
assertNotNull((EjmlMatrix(randomMatrix) + SomeFeature).getFeature<SomeFeature>())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun get() {
|
fun get() {
|
||||||
val m = randomMatrix
|
val m = randomMatrix
|
||||||
assertEquals(m[0, 0], EjmlMatrix(m)[0, 0])
|
assertEquals(m[0, 0], EjmlDoubleMatrix(m)[0, 0])
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun origin() {
|
fun origin() {
|
||||||
val m = randomMatrix
|
val m = randomMatrix
|
||||||
assertSame(m, EjmlMatrix(m).origin)
|
assertSame(m, EjmlDoubleMatrix(m).origin)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,8 @@
|
|||||||
|
|
||||||
package space.kscience.kmath.ejml
|
package space.kscience.kmath.ejml
|
||||||
|
|
||||||
import org.ejml.simple.SimpleMatrix
|
import org.ejml.data.DMatrixRMaj
|
||||||
|
import org.ejml.dense.row.RandomMatrices_DDRM
|
||||||
import kotlin.random.Random
|
import kotlin.random.Random
|
||||||
import kotlin.random.asJavaRandom
|
import kotlin.random.asJavaRandom
|
||||||
import kotlin.test.Test
|
import kotlin.test.Test
|
||||||
@ -15,30 +16,34 @@ import kotlin.test.assertSame
|
|||||||
internal class EjmlVectorTest {
|
internal class EjmlVectorTest {
|
||||||
private val random = Random(0)
|
private val random = Random(0)
|
||||||
|
|
||||||
private val randomMatrix: SimpleMatrix
|
private val randomMatrix: DMatrixRMaj
|
||||||
get() = SimpleMatrix.random_DDRM(random.nextInt(2, 100), 1, 0.0, 10.0, random.asJavaRandom())
|
get() {
|
||||||
|
val d = DMatrixRMaj(random.nextInt(2, 100), 1)
|
||||||
|
RandomMatrices_DDRM.fillUniform(d, random.asJavaRandom())
|
||||||
|
return d
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun size() {
|
fun size() {
|
||||||
val m = randomMatrix
|
val m = randomMatrix
|
||||||
val w = EjmlVector(m)
|
val w = EjmlDoubleVector(m)
|
||||||
assertEquals(m.numRows(), w.size)
|
assertEquals(m.numRows, w.size)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun get() {
|
fun get() {
|
||||||
val m = randomMatrix
|
val m = randomMatrix
|
||||||
val w = EjmlVector(m)
|
val w = EjmlDoubleVector(m)
|
||||||
assertEquals(m[0, 0], w[0])
|
assertEquals(m[0, 0], w[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun iterator() {
|
fun iterator() {
|
||||||
val m = randomMatrix
|
val m = randomMatrix
|
||||||
val w = EjmlVector(m)
|
val w = EjmlDoubleVector(m)
|
||||||
|
|
||||||
assertEquals(
|
assertEquals(
|
||||||
m.iterator(true, 0, 0, m.numRows() - 1, 0).asSequence().toList(),
|
m.iterator(true, 0, 0, m.numRows - 1, 0).asSequence().toList(),
|
||||||
w.iterator().asSequence().toList()
|
w.iterator().asSequence().toList()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -46,7 +51,7 @@ internal class EjmlVectorTest {
|
|||||||
@Test
|
@Test
|
||||||
fun origin() {
|
fun origin() {
|
||||||
val m = randomMatrix
|
val m = randomMatrix
|
||||||
val w = EjmlVector(m)
|
val w = EjmlDoubleVector(m)
|
||||||
assertSame(m, w.origin)
|
assertSame(m, w.origin)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,8 +15,7 @@ The Maven coordinates of this project are `space.kscience:kmath-for-real:0.3.0-d
|
|||||||
```gradle
|
```gradle
|
||||||
repositories {
|
repositories {
|
||||||
maven { url 'https://repo.kotlin.link' }
|
maven { url 'https://repo.kotlin.link' }
|
||||||
maven { url 'https://dl.bintray.com/hotkeytlt/maven' }
|
mavenCentral()
|
||||||
maven { url "https://dl.bintray.com/kotlin/kotlin-eap" } // include for builds based on kotlin-eap
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
@ -27,8 +26,7 @@ dependencies {
|
|||||||
```kotlin
|
```kotlin
|
||||||
repositories {
|
repositories {
|
||||||
maven("https://repo.kotlin.link")
|
maven("https://repo.kotlin.link")
|
||||||
maven("https://dl.bintray.com/kotlin/kotlin-eap") // include for builds based on kotlin-eap
|
mavenCentral()
|
||||||
maven("https://dl.bintray.com/hotkeytlt/maven") // required for a
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
@ -17,8 +17,7 @@ The Maven coordinates of this project are `space.kscience:kmath-functions:0.3.0-
|
|||||||
```gradle
|
```gradle
|
||||||
repositories {
|
repositories {
|
||||||
maven { url 'https://repo.kotlin.link' }
|
maven { url 'https://repo.kotlin.link' }
|
||||||
maven { url 'https://dl.bintray.com/hotkeytlt/maven' }
|
mavenCentral()
|
||||||
maven { url "https://dl.bintray.com/kotlin/kotlin-eap" } // include for builds based on kotlin-eap
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
@ -29,8 +28,7 @@ dependencies {
|
|||||||
```kotlin
|
```kotlin
|
||||||
repositories {
|
repositories {
|
||||||
maven("https://repo.kotlin.link")
|
maven("https://repo.kotlin.link")
|
||||||
maven("https://dl.bintray.com/kotlin/kotlin-eap") // include for builds based on kotlin-eap
|
mavenCentral()
|
||||||
maven("https://dl.bintray.com/hotkeytlt/maven") // required for a
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
19
kmath-jupyter/build.gradle.kts
Normal file
19
kmath-jupyter/build.gradle.kts
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
plugins {
|
||||||
|
id("ru.mipt.npm.gradle.jvm")
|
||||||
|
kotlin("jupyter.api")
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
api(project(":kmath-ast"))
|
||||||
|
api(project(":kmath-complex"))
|
||||||
|
api(project(":kmath-for-real"))
|
||||||
|
implementation("org.jetbrains.kotlinx:kotlinx-html-jvm:0.7.3")
|
||||||
|
}
|
||||||
|
|
||||||
|
readme {
|
||||||
|
maturity = ru.mipt.npm.gradle.Maturity.PROTOTYPE
|
||||||
|
}
|
||||||
|
|
||||||
|
kotlin.sourceSets.all {
|
||||||
|
languageSettings.useExperimentalAnnotation("space.kscience.kmath.misc.UnstableKMathAPI")
|
||||||
|
}
|
@ -0,0 +1,120 @@
|
|||||||
|
package space.kscience.kmath.jupyter
|
||||||
|
|
||||||
|
import kotlinx.html.Unsafe
|
||||||
|
import kotlinx.html.div
|
||||||
|
import kotlinx.html.stream.createHTML
|
||||||
|
import kotlinx.html.unsafe
|
||||||
|
import org.jetbrains.kotlinx.jupyter.api.DisplayResult
|
||||||
|
import org.jetbrains.kotlinx.jupyter.api.HTML
|
||||||
|
import org.jetbrains.kotlinx.jupyter.api.annotations.JupyterLibrary
|
||||||
|
import org.jetbrains.kotlinx.jupyter.api.libraries.JupyterIntegration
|
||||||
|
import space.kscience.kmath.expressions.MST
|
||||||
|
import space.kscience.kmath.ast.rendering.FeaturedMathRendererWithPostProcess
|
||||||
|
import space.kscience.kmath.ast.rendering.MathMLSyntaxRenderer
|
||||||
|
import space.kscience.kmath.ast.rendering.renderWithStringBuilder
|
||||||
|
import space.kscience.kmath.complex.Complex
|
||||||
|
import space.kscience.kmath.nd.Structure2D
|
||||||
|
import space.kscience.kmath.operations.GroupOperations
|
||||||
|
import space.kscience.kmath.operations.RingOperations
|
||||||
|
import space.kscience.kmath.structures.Buffer
|
||||||
|
import space.kscience.kmath.structures.asSequence
|
||||||
|
|
||||||
|
@JupyterLibrary
|
||||||
|
internal class KMathJupyter : JupyterIntegration() {
|
||||||
|
private val mathRender = FeaturedMathRendererWithPostProcess.Default
|
||||||
|
private val syntaxRender = MathMLSyntaxRenderer
|
||||||
|
|
||||||
|
override fun Builder.onLoaded() {
|
||||||
|
import(
|
||||||
|
"space.kscience.kmath.ast.*",
|
||||||
|
"space.kscience.kmath.ast.rendering.*",
|
||||||
|
"space.kscience.kmath.operations.*",
|
||||||
|
"space.kscience.kmath.expressions.*",
|
||||||
|
"space.kscience.kmath.misc.*",
|
||||||
|
"space.kscience.kmath.real.*",
|
||||||
|
)
|
||||||
|
|
||||||
|
fun MST.toDisplayResult(): DisplayResult = HTML(createHTML().div {
|
||||||
|
unsafe {
|
||||||
|
+syntaxRender.renderWithStringBuilder(mathRender.render(this@toDisplayResult))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
render<MST> { it.toDisplayResult() }
|
||||||
|
render<Number> { MST.Numeric(it).toDisplayResult() }
|
||||||
|
|
||||||
|
fun Unsafe.appendCellValue(it: Any?) {
|
||||||
|
when (it) {
|
||||||
|
is Number -> {
|
||||||
|
val s = StringBuilder()
|
||||||
|
syntaxRender.renderPart(mathRender.render(MST.Numeric(it)), s)
|
||||||
|
+s.toString()
|
||||||
|
}
|
||||||
|
is MST -> {
|
||||||
|
val s = StringBuilder()
|
||||||
|
syntaxRender.renderPart(mathRender.render(it), s)
|
||||||
|
+s.toString()
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
+"<ms>"
|
||||||
|
+it.toString()
|
||||||
|
+"</ms>"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
render<Structure2D<*>> { structure ->
|
||||||
|
HTML(createHTML().div {
|
||||||
|
unsafe {
|
||||||
|
+"<math xmlns=\"https://www.w3.org/1998/Math/MathML\">"
|
||||||
|
+"<mrow>"
|
||||||
|
+"<mfenced open=\"[\" close=\"]\" separators=\"\">"
|
||||||
|
+"<mtable>"
|
||||||
|
structure.rows.forEach { row ->
|
||||||
|
+"<mtr>"
|
||||||
|
row.asSequence().forEach {
|
||||||
|
+"<mtd>"
|
||||||
|
appendCellValue(it)
|
||||||
|
+"</mtd>"
|
||||||
|
}
|
||||||
|
+"</mtr>"
|
||||||
|
}
|
||||||
|
+"</mtable>"
|
||||||
|
+"</mfenced>"
|
||||||
|
+"</mrow>"
|
||||||
|
+"</math>"
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
render<Buffer<*>> { buffer ->
|
||||||
|
HTML(createHTML().div {
|
||||||
|
unsafe {
|
||||||
|
+"<math xmlns=\"https://www.w3.org/1998/Math/MathML\">"
|
||||||
|
+"<mrow>"
|
||||||
|
+"<mfenced open=\"[\" close=\"]\" separators=\"\">"
|
||||||
|
+"<mtable>"
|
||||||
|
buffer.asSequence().forEach {
|
||||||
|
+"<mtr>"
|
||||||
|
+"<mtd>"
|
||||||
|
appendCellValue(it)
|
||||||
|
+"</mtd>"
|
||||||
|
+"</mtr>"
|
||||||
|
}
|
||||||
|
+"</mtable>"
|
||||||
|
+"</mfenced>"
|
||||||
|
+"</mrow>"
|
||||||
|
+"</math>"
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
render<Complex> {
|
||||||
|
MST.Binary(
|
||||||
|
operation = GroupOperations.PLUS_OPERATION,
|
||||||
|
left = MST.Numeric(it.re),
|
||||||
|
right = MST.Binary(RingOperations.TIMES_OPERATION, MST.Numeric(it.im), MST.Symbolic("i")),
|
||||||
|
).toDisplayResult()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -4,8 +4,8 @@ plugins {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation("com.github.breandan:kaliningraph:0.1.4")
|
api("com.github.breandan:kaliningraph:0.1.4")
|
||||||
implementation("com.github.breandan:kotlingrad:0.4.0")
|
api("com.github.breandan:kotlingrad:0.4.5")
|
||||||
api(project(":kmath-ast"))
|
api(project(":kmath-ast"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,8 +15,7 @@ The Maven coordinates of this project are `space.kscience:kmath-nd4j:0.3.0-dev-7
|
|||||||
```gradle
|
```gradle
|
||||||
repositories {
|
repositories {
|
||||||
maven { url 'https://repo.kotlin.link' }
|
maven { url 'https://repo.kotlin.link' }
|
||||||
maven { url 'https://dl.bintray.com/hotkeytlt/maven' }
|
mavenCentral()
|
||||||
maven { url "https://dl.bintray.com/kotlin/kotlin-eap" } // include for builds based on kotlin-eap
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
@ -27,8 +26,7 @@ dependencies {
|
|||||||
```kotlin
|
```kotlin
|
||||||
repositories {
|
repositories {
|
||||||
maven("https://repo.kotlin.link")
|
maven("https://repo.kotlin.link")
|
||||||
maven("https://dl.bintray.com/kotlin/kotlin-eap") // include for builds based on kotlin-eap
|
mavenCentral()
|
||||||
maven("https://dl.bintray.com/hotkeytlt/maven") // required for a
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
@ -26,11 +26,6 @@ public open class BufferedTensor<T>(
|
|||||||
override fun elements(): Sequence<Pair<IntArray, T>> = linearStructure.indices().map {
|
override fun elements(): Sequence<Pair<IntArray, T>> = linearStructure.indices().map {
|
||||||
it to this[it]
|
it to this[it]
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun equals(other: Any?): Boolean = false
|
|
||||||
|
|
||||||
override fun hashCode(): Int = 0
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class IntTensor internal constructor(
|
public class IntTensor internal constructor(
|
||||||
|
@ -7,9 +7,9 @@ description = "Binding for https://github.com/JetBrains-Research/viktor"
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
api(project(":kmath-core"))
|
api(project(":kmath-core"))
|
||||||
api("org.jetbrains.bio:viktor:1.0.1")
|
api("org.jetbrains.bio:viktor:1.1.0")
|
||||||
}
|
}
|
||||||
|
|
||||||
readme {
|
readme {
|
||||||
maturity = ru.mipt.npm.gradle.Maturity.DEVELOPMENT
|
maturity = ru.mipt.npm.gradle.Maturity.DEVELOPMENT
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,9 @@ pluginManagement {
|
|||||||
id("ru.mipt.npm.gradle.project") version toolsVersion
|
id("ru.mipt.npm.gradle.project") version toolsVersion
|
||||||
id("ru.mipt.npm.gradle.mpp") version toolsVersion
|
id("ru.mipt.npm.gradle.mpp") version toolsVersion
|
||||||
id("ru.mipt.npm.gradle.jvm") version toolsVersion
|
id("ru.mipt.npm.gradle.jvm") version toolsVersion
|
||||||
|
kotlin("jupyter.api") version "0.9.0.12"
|
||||||
|
kotlin("jvm") version kotlinVersion
|
||||||
|
kotlin("plugin.allopen") version kotlinVersion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -40,6 +43,7 @@ include(
|
|||||||
":kmath-ejml",
|
":kmath-ejml",
|
||||||
":kmath-kotlingrad",
|
":kmath-kotlingrad",
|
||||||
":kmath-tensors",
|
":kmath-tensors",
|
||||||
|
":kmath-jupyter",
|
||||||
":examples",
|
":examples",
|
||||||
":benchmarks"
|
":benchmarks"
|
||||||
)
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user