merge dev

This commit is contained in:
Roland Grinis 2021-05-06 07:45:53 +01:00
commit b7cc4e4b1b
61 changed files with 1010 additions and 990 deletions

View File

@ -13,9 +13,11 @@ jobs:
- name: Checkout the repo
uses: actions/checkout@v2
- name: Set up JDK 11
uses: actions/setup-java@v1
uses: DeLaGuardo/setup-graalvm@4.0
with:
java-version: 11
graalvm: 21.1.0
java: java11
arch: amd64
- name: Add msys to path
if: matrix.os == 'windows-latest'
run: SETX PATH "%PATH%;C:\msys64\mingw64\bin"

View File

@ -12,9 +12,11 @@ jobs:
- name: Checkout the repo
uses: actions/checkout@v2
- name: Set up JDK 11
uses: actions/setup-java@v1
uses: DeLaGuardo/setup-graalvm@4.0
with:
java-version: 11
graalvm: 21.1.0
java: java11
arch: amd64
- name: Cache gradle
uses: actions/cache@v2
with:
@ -30,9 +32,7 @@ jobs:
restore-keys: |
${{ runner.os }}-gradle-
- name: Build
run: |
./gradlew dokkaHtmlMultiModule --no-daemon --no-parallel --stacktrace
mv build/dokka/htmlMultiModule/-modules.html build/dokka/htmlMultiModule/index.html
run: ./gradlew dokkaHtmlMultiModule --no-daemon --no-parallel --stacktrace
- name: Deploy to GitHub Pages
uses: JamesIves/github-pages-deploy-action@4.1.0
with:

View File

@ -18,9 +18,11 @@ jobs:
- name: Checkout the repo
uses: actions/checkout@v2
- name: Set up JDK 11
uses: actions/setup-java@v1
uses: DeLaGuardo/setup-graalvm@4.0
with:
java-version: 11
graalvm: 21.1.0
java: java11
arch: amd64
- name: Add msys to path
if: matrix.os == 'windows-latest'
run: SETX PATH "%PATH%;C:\msys64\mingw64\bin"

View File

@ -10,7 +10,8 @@
- Blocking chains and Statistics
- Multiplatform integration
- Integration for any Field element
- Extendend operations for ND4J fields
- Extended operations for ND4J fields
- Jupyter Notebook integration module (kmath-jupyter)
### Changed
- Exponential operations merged with hyperbolic functions
@ -24,6 +25,7 @@
- Redesign MST. Remove MSTExpression.
- Move MST to core
- Separated benchmarks and examples
- Rewritten EJML module without ejml-simple
### Deprecated

View File

@ -91,7 +91,7 @@ KMath is a modular library. Different modules provide different features with di
* ### [kmath-ast](kmath-ast)
>
>
> **Maturity**: PROTOTYPE
> **Maturity**: EXPERIMENTAL
>
> **Features:**
> - [expression-language](kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/parser.kt) : Expression language and its parser
@ -154,9 +154,9 @@ performance calculations to code generation.
> **Maturity**: PROTOTYPE
>
> **Features:**
> - [ejml-vector](kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/EjmlVector.kt) : The Point implementation using SimpleMatrix.
> - [ejml-matrix](kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/EjmlMatrix.kt) : The Matrix implementation using SimpleMatrix.
> - [ejml-linear-space](kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/EjmlLinearSpace.kt) : The LinearSpace implementation using SimpleMatrix.
> - [ejml-vector](kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/EjmlVector.kt) : Point implementations.
> - [ejml-matrix](kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/EjmlMatrix.kt) : Matrix implementation.
> - [ejml-linear-space](kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/EjmlLinearSpace.kt) : LinearSpace implementations.
<hr/>
@ -200,6 +200,12 @@ One can still use generic algebras though.
> **Maturity**: PROTOTYPE
<hr/>
* ### [kmath-jupyter](kmath-jupyter)
>
>
> **Maturity**: PROTOTYPE
<hr/>
* ### [kmath-kotlingrad](kmath-kotlingrad)
>
>

View File

@ -9,14 +9,10 @@ sourceSets.register("benchmarks")
repositories {
mavenCentral()
jcenter()
maven("https://repo.kotlin.link")
maven("https://clojars.org/repo")
maven("https://dl.bintray.com/egor-bogomolov/astminer/")
maven("https://dl.bintray.com/hotkeytlt/maven")
maven("https://jitpack.io")
maven {
setUrl("http://logicrunch.research.it.uu.se/maven/")
maven("http://logicrunch.research.it.uu.se/maven") {
isAllowInsecureProtocol = true
}
}

View File

@ -10,7 +10,7 @@ import kotlinx.benchmark.Blackhole
import kotlinx.benchmark.Scope
import kotlinx.benchmark.State
import space.kscience.kmath.commons.linear.CMLinearSpace
import space.kscience.kmath.ejml.EjmlLinearSpace
import space.kscience.kmath.ejml.EjmlLinearSpaceDDRM
import space.kscience.kmath.linear.LinearSpace
import space.kscience.kmath.linear.invoke
import space.kscience.kmath.operations.DoubleField
@ -29,8 +29,8 @@ internal class DotBenchmark {
val cmMatrix1 = CMLinearSpace { matrix1.toCM() }
val cmMatrix2 = CMLinearSpace { matrix2.toCM() }
val ejmlMatrix1 = EjmlLinearSpace { matrix1.toEjml() }
val ejmlMatrix2 = EjmlLinearSpace { matrix2.toEjml() }
val ejmlMatrix1 = EjmlLinearSpaceDDRM { matrix1.toEjml() }
val ejmlMatrix2 = EjmlLinearSpaceDDRM { matrix2.toEjml() }
}
@Benchmark
@ -42,14 +42,14 @@ internal class DotBenchmark {
@Benchmark
fun ejmlDot(blackhole: Blackhole) {
EjmlLinearSpace {
EjmlLinearSpaceDDRM {
blackhole.consume(ejmlMatrix1 dot ejmlMatrix2)
}
}
@Benchmark
fun ejmlDotWithConversion(blackhole: Blackhole) {
EjmlLinearSpace {
EjmlLinearSpaceDDRM {
blackhole.consume(matrix1 dot matrix2)
}
}

View File

@ -11,25 +11,26 @@ import kotlinx.benchmark.Scope
import kotlinx.benchmark.State
import space.kscience.kmath.commons.linear.CMLinearSpace
import space.kscience.kmath.commons.linear.inverse
import space.kscience.kmath.ejml.EjmlLinearSpace
import space.kscience.kmath.ejml.inverse
import space.kscience.kmath.ejml.EjmlLinearSpaceDDRM
import space.kscience.kmath.linear.InverseMatrixFeature
import space.kscience.kmath.linear.LinearSpace
import space.kscience.kmath.linear.inverseWithLup
import space.kscience.kmath.linear.invoke
import space.kscience.kmath.nd.getFeature
import kotlin.random.Random
@State(Scope.Benchmark)
internal class MatrixInverseBenchmark {
companion object {
val random = Random(1224)
const val dim = 100
private companion object {
private val random = Random(1224)
private const val dim = 100
private val space = LinearSpace.real
//creating invertible matrix
val u = space.buildMatrix(dim, dim) { i, j -> if (i <= j) random.nextDouble() else 0.0 }
val l = space.buildMatrix(dim, dim) { i, j -> if (i >= j) random.nextDouble() else 0.0 }
val matrix = space { l dot u }
private val u = space.buildMatrix(dim, dim) { i, j -> if (i <= j) random.nextDouble() else 0.0 }
private val l = space.buildMatrix(dim, dim) { i, j -> if (i >= j) random.nextDouble() else 0.0 }
private val matrix = space { l dot u }
}
@Benchmark
@ -46,8 +47,8 @@ internal class MatrixInverseBenchmark {
@Benchmark
fun ejmlInverse(blackhole: Blackhole) {
with(EjmlLinearSpace) {
blackhole.consume(inverse(matrix))
with(EjmlLinearSpaceDDRM) {
blackhole.consume(matrix.getFeature<InverseMatrixFeature<Double>>()?.inverse)
}
}
}

View File

@ -1,17 +1,16 @@
plugins {
id("ru.mipt.npm.gradle.project")
kotlin("jupyter.api") apply false
}
allprojects {
repositories {
jcenter()
maven("https://clojars.org/repo")
maven("https://dl.bintray.com/egor-bogomolov/astminer/")
maven("https://dl.bintray.com/hotkeytlt/maven")
maven("https://jitpack.io")
maven("http://logicrunch.research.it.uu.se/maven/") {
maven("http://logicrunch.research.it.uu.se/maven") {
isAllowInsecureProtocol = true
}
maven("https://maven.pkg.jetbrains.space/public/p/kotlinx-html/maven")
mavenCentral()
}
@ -23,22 +22,16 @@ subprojects {
if (name.startsWith("kmath")) apply<MavenPublishPlugin>()
afterEvaluate {
tasks.withType<org.jetbrains.dokka.gradle.DokkaTask> {
dokkaSourceSets.all {
val readmeFile = File(this@subprojects.projectDir, "./README.md")
if (readmeFile.exists())
includes.setFrom(includes + readmeFile.absolutePath)
tasks.withType<org.jetbrains.dokka.gradle.DokkaTaskPartial> {
dependsOn(tasks.getByName("assemble"))
arrayOf(
"http://ejml.org/javadoc/",
"https://commons.apache.org/proper/commons-math/javadocs/api-3.6.1/",
"https://deeplearning4j.org/api/latest/"
).map { java.net.URL("${it}package-list") to java.net.URL(it) }.forEach { (a, b) ->
externalDocumentationLink {
packageListUrl.set(a)
url.set(b)
}
}
dokkaSourceSets.all {
val readmeFile = File(this@subprojects.projectDir, "README.md")
if (readmeFile.exists()) includes.setFrom(includes + readmeFile.absolutePath)
externalDocumentationLink("http://ejml.org/javadoc/")
externalDocumentationLink("https://commons.apache.org/proper/commons-math/javadocs/api-3.6.1/")
externalDocumentationLink("https://deeplearning4j.org/api/latest/")
externalDocumentationLink("https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/")
}
}
}

View File

@ -6,8 +6,7 @@ The Maven coordinates of this project are `${group}:${name}:${version}`.
```gradle
repositories {
maven { url 'https://repo.kotlin.link' }
maven { url 'https://dl.bintray.com/hotkeytlt/maven' }
maven { url "https://dl.bintray.com/kotlin/kotlin-eap" } // include for builds based on kotlin-eap
mavenCentral()
}
dependencies {
@ -18,8 +17,7 @@ dependencies {
```kotlin
repositories {
maven("https://repo.kotlin.link")
maven("https://dl.bintray.com/kotlin/kotlin-eap") // include for builds based on kotlin-eap
maven("https://dl.bintray.com/hotkeytlt/maven") // required for a
mavenCentral()
}
dependencies {

View File

@ -4,14 +4,11 @@ plugins {
repositories {
mavenCentral()
jcenter()
maven("https://repo.kotlin.link")
maven("https://clojars.org/repo")
maven("https://dl.bintray.com/egor-bogomolov/astminer/")
maven("https://dl.bintray.com/hotkeytlt/maven")
maven("https://jitpack.io")
maven{
setUrl("http://logicrunch.research.it.uu.se/maven/")
maven("https://maven.pkg.jetbrains.space/kotlin/p/kotlin/kotlin-js-wrappers")
maven("http://logicrunch.research.it.uu.se/maven") {
isAllowInsecureProtocol = true
}
}

View File

@ -1,6 +1,6 @@
# 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
- [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
repositories {
maven { url 'https://repo.kotlin.link' }
maven { url 'https://dl.bintray.com/hotkeytlt/maven' }
maven { url "https://dl.bintray.com/kotlin/kotlin-eap" } // include for builds based on kotlin-eap
mavenCentral()
}
dependencies {
@ -28,8 +27,7 @@ dependencies {
```kotlin
repositories {
maven("https://repo.kotlin.link")
maven("https://dl.bintray.com/kotlin/kotlin-eap") // include for builds based on kotlin-eap
maven("https://dl.bintray.com/hotkeytlt/maven") // required for a
mavenCentral()
}
dependencies {
@ -41,12 +39,16 @@ dependencies {
### On JVM
`kmath-ast` JVM module supports runtime code generation to eliminate overhead of tree traversal. Code generator builds
a special implementation of `Expression<T>` with implemented `invoke` function.
`kmath-ast` JVM module supports runtime code generation to eliminate overhead of tree traversal. Code generator builds a
special implementation of `Expression<T>` with implemented `invoke` function.
For example, the following builder:
```kotlin
import space.kscience.kmath.expressions.*
import space.kscience.kmath.operations.*
import space.kscience.kmath.asm.*
MstField { bindSymbol("x") + 2 }.compileToExpression(DoubleField)
```
@ -56,6 +58,7 @@ MstField { bindSymbol("x") + 2 }.compileToExpression(DoubleField)
package space.kscience.kmath.asm.generated;
import java.util.Map;
import kotlin.jvm.functions.Function2;
import space.kscience.kmath.asm.internal.MapIntrinsics;
import space.kscience.kmath.expressions.Expression;
@ -65,7 +68,7 @@ public final class AsmCompiledExpression_45045_0 implements Expression<Double> {
private final Object[] constants;
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) {
@ -77,8 +80,8 @@ public final class AsmCompiledExpression_45045_0 implements Expression<Double> {
#### Known issues
- The same classes may be generated and loaded twice, so it is recommended to cache compiled expressions to avoid
class loading overhead.
- The same classes may be generated and loaded twice, so it is recommended to cache compiled expressions to avoid class
loading overhead.
- This API is not supported by non-dynamic JVM implementations (like TeaVM and GraalVM) because of using class loaders.
### On JS
@ -86,6 +89,10 @@ public final class AsmCompiledExpression_45045_0 implements Expression<Double> {
A similar feature is also available on JS.
```kotlin
import space.kscience.kmath.expressions.*
import space.kscience.kmath.operations.*
import space.kscience.kmath.estree.*
MstField { bindSymbol("x") + 2 }.compileToExpression(DoubleField)
```
@ -93,13 +100,16 @@ The code above returns expression implemented with such a JS function:
```js
var executable = function (constants, arguments) {
return constants[1](constants[0](arguments, "x"), 2);
return constants[1](constants[0](arguments, "x"), 2);
};
```
JS also supports very experimental expression optimization with [WebAssembly](https://webassembly.org/) IR generation. Currently, only expressions inside `DoubleField` and `IntRing` are supported.
JS also supports very experimental expression optimization with [WebAssembly](https://webassembly.org/) IR generation.
Currently, only expressions inside `DoubleField` and `IntRing` are supported.
```kotlin
import space.kscience.kmath.expressions.*
import space.kscience.kmath.operations.*
import space.kscience.kmath.wasm.*
MstField { bindSymbol("x") + 2 }.compileToExpression(DoubleField)
@ -130,7 +140,9 @@ Example usage:
```kotlin
import space.kscience.kmath.ast.*
import space.kscience.kmath.ast.rendering.*
import space.kscience.kmath.misc.*
@OptIn(UnstableKMathAPI::class)
public fun main() {
val mst = "exp(sqrt(x))-asin(2*x)/(2e10+x^3)/(-12)".parseMath()
val syntax = FeaturedMathRendererWithPostProcess.Default.render(mst)
@ -146,13 +158,68 @@ public fun main() {
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):
<details>
```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>&times;</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>&times;</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
(see API reference).

View File

@ -1,6 +1,6 @@
# Module kmath-ast
Abstract syntax tree expression representation and related optimizations.
Performance and visualization extensions to MST API.
${features}
@ -10,12 +10,16 @@ ${artifact}
### On JVM
`kmath-ast` JVM module supports runtime code generation to eliminate overhead of tree traversal. Code generator builds
a special implementation of `Expression<T>` with implemented `invoke` function.
`kmath-ast` JVM module supports runtime code generation to eliminate overhead of tree traversal. Code generator builds a
special implementation of `Expression<T>` with implemented `invoke` function.
For example, the following builder:
```kotlin
import space.kscience.kmath.expressions.*
import space.kscience.kmath.operations.*
import space.kscience.kmath.asm.*
MstField { bindSymbol("x") + 2 }.compileToExpression(DoubleField)
```
@ -25,6 +29,7 @@ MstField { bindSymbol("x") + 2 }.compileToExpression(DoubleField)
package space.kscience.kmath.asm.generated;
import java.util.Map;
import kotlin.jvm.functions.Function2;
import space.kscience.kmath.asm.internal.MapIntrinsics;
import space.kscience.kmath.expressions.Expression;
@ -34,7 +39,7 @@ public final class AsmCompiledExpression_45045_0 implements Expression<Double> {
private final Object[] constants;
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) {
@ -46,8 +51,8 @@ public final class AsmCompiledExpression_45045_0 implements Expression<Double> {
#### Known issues
- The same classes may be generated and loaded twice, so it is recommended to cache compiled expressions to avoid
class loading overhead.
- The same classes may be generated and loaded twice, so it is recommended to cache compiled expressions to avoid class
loading overhead.
- This API is not supported by non-dynamic JVM implementations (like TeaVM and GraalVM) because of using class loaders.
### On JS
@ -55,6 +60,10 @@ public final class AsmCompiledExpression_45045_0 implements Expression<Double> {
A similar feature is also available on JS.
```kotlin
import space.kscience.kmath.expressions.*
import space.kscience.kmath.operations.*
import space.kscience.kmath.estree.*
MstField { bindSymbol("x") + 2 }.compileToExpression(DoubleField)
```
@ -62,13 +71,16 @@ The code above returns expression implemented with such a JS function:
```js
var executable = function (constants, arguments) {
return constants[1](constants[0](arguments, "x"), 2);
return constants[1](constants[0](arguments, "x"), 2);
};
```
JS also supports very experimental expression optimization with [WebAssembly](https://webassembly.org/) IR generation. Currently, only expressions inside `DoubleField` and `IntRing` are supported.
JS also supports very experimental expression optimization with [WebAssembly](https://webassembly.org/) IR generation.
Currently, only expressions inside `DoubleField` and `IntRing` are supported.
```kotlin
import space.kscience.kmath.expressions.*
import space.kscience.kmath.operations.*
import space.kscience.kmath.wasm.*
MstField { bindSymbol("x") + 2 }.compileToExpression(DoubleField)
@ -99,9 +111,11 @@ Example usage:
```kotlin
import space.kscience.kmath.ast.*
import space.kscience.kmath.ast.rendering.*
import space.kscience.kmath.misc.*
@OptIn(UnstableKMathAPI::class)
public fun main() {
val mst = "exp(sqrt(x))-asin(2*x)/(2e10+x^3)/(-12)".parseMath()
val mst = "exp(sqrt(x))-asin(2*x)/(2e10+x^3)/(12)+x^(2/3)".parseMath()
val syntax = FeaturedMathRendererWithPostProcess.Default.render(mst)
val latex = LatexSyntaxRenderer.renderWithStringBuilder(syntax)
println("LaTeX:")
@ -115,13 +129,78 @@ public fun main() {
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
<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>&times;</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>&times;</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
(see API reference).

View File

@ -118,7 +118,11 @@ public object LatexSyntaxRenderer : SyntaxRenderer {
render(node.right)
}
is FractionSyntax -> {
is FractionSyntax -> if (node.infix) {
render(node.left)
append('/')
render(node.right)
} else {
append("\\frac{")
render(node.left)
append("}{")

View File

@ -18,11 +18,14 @@ import space.kscience.kmath.misc.UnstableKMathAPI
public object MathMLSyntaxRenderer : SyntaxRenderer {
public override fun render(node: MathSyntax, output: Appendable) {
output.append("<math xmlns=\"https://www.w3.org/1998/Math/MathML\"><mrow>")
render0(node, output)
renderPart(node, output)
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 = {}) {
append('<')
append(tagName)
@ -47,7 +50,7 @@ public object MathMLSyntaxRenderer : SyntaxRenderer {
append('>')
}
fun render(syntax: MathSyntax) = render0(syntax, output)
fun render(syntax: MathSyntax) = renderPart(syntax, output)
when (node) {
is NumberSyntax -> tag("mn") { append(node.string) }
@ -130,14 +133,13 @@ public object MathMLSyntaxRenderer : SyntaxRenderer {
render(node.right)
}
is FractionSyntax -> tag("mfrac") {
tag("mrow") {
render(node.left)
}
tag("mrow") {
render(node.right)
}
is FractionSyntax -> if (node.infix) {
render(node.left)
tag("mo") { append('/') }
render(node.right)
} else tag("mfrac") {
tag("mrow") { render(node.left) }
tag("mrow") { render(node.right) }
}
is RadicalWithIndexSyntax -> tag("mroot") {

View File

@ -89,6 +89,7 @@ public open class FeaturedMathRendererWithPostProcess(
SquareRoot.Default,
Exponent.Default,
InverseTrigonometricOperations.Default,
InverseHyperbolicOperations.Default,
// Fallback option for unknown operations - printing them as operator
BinaryOperator.Default,
@ -105,6 +106,7 @@ public open class FeaturedMathRendererWithPostProcess(
),
listOf(
BetterExponent,
BetterFraction,
SimplifyParentheses.Default,
BetterMultiplication,
),

View File

@ -102,7 +102,7 @@ public data class SymbolSyntax(public var string: 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., *&infin;*).
*
* @property kind The kind of symbol.
* @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.
* @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
*/
@ -175,7 +175,7 @@ public data class UnaryPlusSyntax(
}
/**
* Represents prefix, unary minus operator.
* Represents prefix, unary minus operator (*-x*).
*
* @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 (*&radic;x*).
*
* @property operand The radicand.
* @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 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 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.
* @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 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 right The subtrahend.
@ -324,13 +324,15 @@ public data class BinaryMinusSyntax(
*
* @property left The numerator.
* @property right The denominator.
* @property infix Whether infix (*1 / 2*) or normal (*&frac12;*) fraction should be made.
* @author Iaroslav Postovalov
*/
@UnstableKMathAPI
public data class FractionSyntax(
public override val operation: String,
public override val left: MathSyntax,
public override val right: MathSyntax,
public override val left: OperandSyntax,
public override val right: OperandSyntax,
public var infix: Boolean,
) : BinarySyntax() {
init {
left.parent = this
@ -339,7 +341,7 @@ public data class FractionSyntax(
}
/**
* Represents radical syntax with index.
* Represents radical syntax with index (*<sup>3</sup>&radic;x*).
*
* @property left The index.
* @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&times;2).
* Represents binary, infix multiplication in the form of coefficient (*2 x*) or with operator (*x &times; 2*).
*
* @property left The multiplicand.
* @property right The multiplier.
* @property times whether the times (&times;) symbol should be used.
* @property times Whether the times (&times;) symbol should be used.
* @author Iaroslav Postovalov
*/
@UnstableKMathAPI

View File

@ -54,6 +54,7 @@ else
* *('-'? (DIGIT+ ('.' DIGIT+)? ('E' '-'? DIGIT+)? | 'Infinity')) | 'NaN'*.
*
* @property types The suitable types.
* @author Iaroslav Postovalov
*/
@UnstableKMathAPI
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+*.
*
* @property types The suitable types.
* @author Iaroslav Postovalov
*/
@UnstableKMathAPI
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.
*
* @property symbols The allowed symbols.
* @author Iaroslav Postovalov
*/
@UnstableKMathAPI
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].
*
* @param operations the allowed operations. If `null`, any operation is accepted.
* @author Iaroslav Postovalov
*/
@UnstableKMathAPI
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].
*
* @property operations the allowed operations. If `null`, any operation is accepted.
* @author Iaroslav Postovalov
*/
@UnstableKMathAPI
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].
*
* @author Iaroslav Postovalov
*/
@UnstableKMathAPI
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].
*
* @author Iaroslav Postovalov
*/
@UnstableKMathAPI
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].
*
* @author Iaroslav Postovalov
*/
@UnstableKMathAPI
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].
*
* @author Iaroslav Postovalov
*/
@UnstableKMathAPI
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].
*
* @author Iaroslav Postovalov
*/
@UnstableKMathAPI
public class Fraction(operations: Collection<String>?) : Binary(operations) {
public override fun renderBinary(parent: FeaturedMathRenderer, node: MST.Binary): FractionSyntax = FractionSyntax(
operation = node.operation,
left = parent.render(node.left),
right = parent.render(node.right),
left = OperandSyntax(operand = parent.render(node.left), parentheses = true),
right = OperandSyntax(operand = parent.render(node.right), parentheses = true),
infix = true,
)
public companion object {
@ -288,6 +304,8 @@ public class Fraction(operations: Collection<String>?) : Binary(operations) {
/**
* Handles binary nodes by producing [BinaryOperatorSyntax].
*
* @author Iaroslav Postovalov
*/
@UnstableKMathAPI
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].
*
* @author Iaroslav Postovalov
*/
@UnstableKMathAPI
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].
*
* @author Iaroslav Postovalov
*/
@UnstableKMathAPI
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].
*
* @author Iaroslav Postovalov
*/
@UnstableKMathAPI
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].
*
* @author Iaroslav Postovalov
*/
@UnstableKMathAPI
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`
* prefix of operation ID.
* Handles binary nodes by producing inverse [UnaryOperatorSyntax] with *arc* prefix instead of *a*.
*
* @author Iaroslav Postovalov
*/
@UnstableKMathAPI
public class InverseTrigonometricOperations(operations: Collection<String>?) : Unary(operations) {
public override fun renderUnary(parent: FeaturedMathRenderer, node: MST.Unary): UnaryOperatorSyntax =
UnaryOperatorSyntax(
operation = node.operation,
prefix = SuperscriptSyntax(
operation = PowerOperations.POW_OPERATION,
left = OperatorNameSyntax(name = node.operation.removePrefix("a")),
right = UnaryMinusSyntax(
operation = GroupOperations.MINUS_OPERATION,
operand = OperandSyntax(operand = NumberSyntax(string = "1"), parentheses = true),
),
),
prefix = OperatorNameSyntax(name = node.operation.replaceFirst("a", "arc")),
operand = OperandSyntax(operand = parent.render(node.value), parentheses = true),
)
public companion object {
/**
* The default instance configured with [TrigonometricOperations.ACOS_OPERATION],
* [TrigonometricOperations.ASIN_OPERATION], [TrigonometricOperations.ATAN_OPERATION],
* [ExponentialOperations.ACOSH_OPERATION], [ExponentialOperations.ASINH_OPERATION], and
* [ExponentialOperations.ATANH_OPERATION].
* [TrigonometricOperations.ASIN_OPERATION], [TrigonometricOperations.ATAN_OPERATION].
*/
public val Default: InverseTrigonometricOperations = InverseTrigonometricOperations(setOf(
TrigonometricOperations.ACOS_OPERATION,
TrigonometricOperations.ASIN_OPERATION,
TrigonometricOperations.ATAN_OPERATION,
))
}
}
/**
* Handles binary nodes by producing inverse [UnaryOperatorSyntax] with *ar* prefix instead of *a*.
*
* @author Iaroslav Postovalov
*/
@UnstableKMathAPI
public class InverseHyperbolicOperations(operations: Collection<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.ASINH_OPERATION,
ExponentialOperations.ATANH_OPERATION,

View File

@ -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
@ -102,7 +171,7 @@ public object BetterExponent : FeaturedMathRendererWithPostProcess.PostProcessSt
is UnaryOperatorSyntax -> perform0(node.prefix) || perform0(node.operand)
is UnaryPlusSyntax -> perform0(node.operand)
is UnaryMinusSyntax -> perform0(node.operand)
is RadicalSyntax -> perform0(node.operand)
is RadicalSyntax -> true
is ExponentSyntax -> {
val r = perform0(node.operand)
@ -116,7 +185,7 @@ public object BetterExponent : FeaturedMathRendererWithPostProcess.PostProcessSt
is BinaryPlusSyntax -> perform0(node.left) || perform0(node.right)
is BinaryMinusSyntax -> perform0(node.left) || perform0(node.right)
is FractionSyntax -> true
is RadicalWithIndexSyntax -> perform0(node.left) || perform0(node.right)
is RadicalWithIndexSyntax -> true
is MultiplicationSyntax -> perform0(node.left) || perform0(node.right)
}
}
@ -163,8 +232,11 @@ public class SimplifyParentheses(public val precedenceFunction: (MathSyntax) ->
val isInsideExpOperator =
node.parent is ExponentSyntax && (node.parent as ExponentSyntax).useOperatorForm
val isOnOrUnderNormalFraction = node.parent is FractionSyntax && !((node.parent as FractionSyntax).infix)
node.parentheses = !isRightOfSuperscript
&& (needParenthesesByPrecedence || node.parent is UnaryOperatorSyntax || isInsideExpOperator)
&& !isOnOrUnderNormalFraction
perform(node.operand)
}

View File

@ -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.
*/
package space.kscience.kmath.wasm
package space.kscience.kmath.ast
import space.kscience.kmath.expressions.MstField
import space.kscience.kmath.expressions.MstRing
import space.kscience.kmath.expressions.interpret
import space.kscience.kmath.misc.symbol
import space.kscience.kmath.misc.Symbol.Companion.x
import space.kscience.kmath.operations.DoubleField
import space.kscience.kmath.operations.IntRing
import space.kscience.kmath.operations.bindSymbol
@ -16,45 +16,41 @@ import space.kscience.kmath.operations.invoke
import kotlin.test.Test
import kotlin.test.assertEquals
internal class TestWasmConsistencyWithInterpreter {
internal class TestCompilerConsistencyWithInterpreter {
@Test
fun intRing() {
fun intRing() = runCompilerTest {
val mst = MstRing {
binaryOperationFunction("+")(
unaryOperationFunction("+")(
(bindSymbol(x) - (2.toByte() + (scale(
add(number(1), number(1)),
2.0
2.0,
) + 1.toByte()))) * 3.0 - 1.toByte()
),
number(1)
number(1),
) * number(2)
}
assertEquals(
mst.interpret(IntRing, x to 3),
mst.compile(IntRing, x to 3)
mst.compile(IntRing, x to 3),
)
}
@Test
fun doubleField() {
fun doubleField() = runCompilerTest {
val mst = MstField {
+(3 - 2 + 2 * number(1) + 1.0) + binaryOperationFunction("+")(
(3.0 - (bindSymbol(x) + (scale(add(number(1.0), number(1.0)), 2.0) + 1.0))) * 3 - 1.0
+ number(1),
number(1) / 2 + number(2.0) * one
number(1) / 2 + number(2.0) * one,
) + zero
}
assertEquals(
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
}
}

View File

@ -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))
}
}

View File

@ -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.
*/
package space.kscience.kmath.wasm
package space.kscience.kmath.ast
import space.kscience.kmath.expressions.MstRing
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.bindSymbol
import space.kscience.kmath.operations.invoke
@ -15,20 +15,16 @@ import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertFailsWith
internal class TestWasmVariables {
internal class TestCompilerVariables {
@Test
fun testVariable() {
fun testVariable() = runCompilerTest {
val expr = MstRing { bindSymbol(x) }.compileToExpression(IntRing)
assertEquals(1, expr(x to 1))
}
@Test
fun testUndefinedVariableFails() {
fun testUndefinedVariableFails() = runCompilerTest {
val expr = MstRing { bindSymbol(x) }.compileToExpression(IntRing)
assertFailsWith<NoSuchElementException> { expr() }
}
private companion object {
private val x by symbol
}
}

View File

@ -13,7 +13,7 @@ import space.kscience.kmath.operations.DoubleField
import kotlin.test.Test
import kotlin.test.assertEquals
internal class ParserTest {
internal class TestParser {
@Test
fun evaluateParsedMst() {
val mst = "2+2*(2+2)".parseMath()

View File

@ -10,7 +10,7 @@ import space.kscience.kmath.operations.DoubleField
import kotlin.test.Test
import kotlin.test.assertEquals
internal class ParserPrecedenceTest {
internal class TestParserPrecedence {
@Test
fun test1(): Unit = assertEquals(6.0, f.evaluate("2*2+2".parseMath()))

View File

@ -99,13 +99,17 @@ internal class TestFeatures {
fun multiplication() = testLatex("x*1", "x\\times1")
@Test
fun inverseTrigonometry() {
testLatex("asin(x)", "\\operatorname{sin}^{-1}\\,\\left(x\\right)")
testLatex("asinh(x)", "\\operatorname{sinh}^{-1}\\,\\left(x\\right)")
testLatex("acos(x)", "\\operatorname{cos}^{-1}\\,\\left(x\\right)")
testLatex("acosh(x)", "\\operatorname{cosh}^{-1}\\,\\left(x\\right)")
testLatex("atan(x)", "\\operatorname{tan}^{-1}\\,\\left(x\\right)")
testLatex("atanh(x)", "\\operatorname{tanh}^{-1}\\,\\left(x\\right)")
fun inverseTrigonometric() {
testLatex("asin(x)", "\\operatorname{arcsin}\\,\\left(x\\right)")
testLatex("acos(x)", "\\operatorname{arccos}\\,\\left(x\\right)")
testLatex("atan(x)", "\\operatorname{arctan}\\,\\left(x\\right)")
}
@Test
fun inverseHyperbolic() {
testLatex("asinh(x)", "\\operatorname{arsinh}\\,\\left(x\\right)")
testLatex("acosh(x)", "\\operatorname{arcosh}\\,\\left(x\\right)")
testLatex("atanh(x)", "\\operatorname{artanh}\\,\\left(x\\right)")
}
// @Test

View File

@ -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(x^{2}\\right)")
}
@Test
fun fraction() {
testLatex("x/y", "\\frac{x}{y}")
testLatex("x^(x/y)", "x^{x/y}")
}
}

View File

@ -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)

View File

@ -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)
}

View File

@ -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
}
}

View File

@ -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
}
}

View File

@ -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
}
}

View File

@ -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
}
}

View File

@ -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
}
}

View File

@ -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
}
}

View File

@ -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
}
}

View File

@ -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
}
}

View File

@ -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
}
}

View File

@ -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
}
}

View File

@ -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)

View File

@ -14,8 +14,7 @@ The Maven coordinates of this project are `space.kscience:kmath-complex:0.3.0-de
```gradle
repositories {
maven { url 'https://repo.kotlin.link' }
maven { url 'https://dl.bintray.com/hotkeytlt/maven' }
maven { url "https://dl.bintray.com/kotlin/kotlin-eap" } // include for builds based on kotlin-eap
mavenCentral()
}
dependencies {
@ -26,8 +25,7 @@ dependencies {
```kotlin
repositories {
maven("https://repo.kotlin.link")
maven("https://dl.bintray.com/kotlin/kotlin-eap") // include for builds based on kotlin-eap
maven("https://dl.bintray.com/hotkeytlt/maven") // required for a
mavenCentral()
}
dependencies {

View File

@ -21,8 +21,7 @@ The Maven coordinates of this project are `space.kscience:kmath-core:0.3.0-dev-7
```gradle
repositories {
maven { url 'https://repo.kotlin.link' }
maven { url 'https://dl.bintray.com/hotkeytlt/maven' }
maven { url "https://dl.bintray.com/kotlin/kotlin-eap" } // include for builds based on kotlin-eap
mavenCentral()
}
dependencies {
@ -33,8 +32,7 @@ dependencies {
```kotlin
repositories {
maven("https://repo.kotlin.link")
maven("https://dl.bintray.com/kotlin/kotlin-eap") // include for builds based on kotlin-eap
maven("https://dl.bintray.com/hotkeytlt/maven") // required for a
mavenCentral()
}
dependencies {

View File

@ -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 synthetic fun sinh (Ljava/lang/Object;)Ljava/lang/Object;
public fun sinh (Lspace/kscience/kmath/expressions/MST;)Lspace/kscience/kmath/expressions/MST$Unary;
public synthetic fun sqrt (Ljava/lang/Object;)Ljava/lang/Object;
public fun sqrt (Lspace/kscience/kmath/expressions/MST;)Lspace/kscience/kmath/expressions/MST;
public synthetic fun tan (Ljava/lang/Object;)Ljava/lang/Object;
public fun tan (Lspace/kscience/kmath/expressions/MST;)Lspace/kscience/kmath/expressions/MST$Unary;
public synthetic fun tanh (Ljava/lang/Object;)Ljava/lang/Object;
@ -1008,14 +1010,7 @@ public abstract interface class space/kscience/kmath/operations/Algebra {
public fun unaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function1;
}
public abstract interface class space/kscience/kmath/operations/AlgebraElement {
public abstract fun getContext ()Lspace/kscience/kmath/operations/Algebra;
}
public final class space/kscience/kmath/operations/AlgebraElementsKt {
public static final fun div (Lspace/kscience/kmath/operations/AlgebraElement;Lspace/kscience/kmath/operations/AlgebraElement;)Lspace/kscience/kmath/operations/AlgebraElement;
public static final fun plus (Lspace/kscience/kmath/operations/AlgebraElement;Lspace/kscience/kmath/operations/AlgebraElement;)Lspace/kscience/kmath/operations/AlgebraElement;
public static final fun times (Lspace/kscience/kmath/operations/AlgebraElement;Lspace/kscience/kmath/operations/AlgebraElement;)Lspace/kscience/kmath/operations/AlgebraElement;
}
public final class space/kscience/kmath/operations/AlgebraExtensionsKt {

View File

@ -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 atanh(arg: MST): MST.Unary = unaryOperationFunction(ExponentialOperations.ATANH_OPERATION)(arg)
public override fun add(a: MST, b: MST): MST.Binary = MstField.add(a, b)
public override fun sqrt(arg: MST): MST = unaryOperationFunction(PowerOperations.SQRT_OPERATION)(arg)
public override fun scale(a: MST, value: Double): MST =
binaryOperation(GroupOperations.PLUS_OPERATION, a, number(value))

View File

@ -13,6 +13,8 @@ import space.kscience.kmath.misc.UnstableKMathAPI
* @param C the type of mathematical context for this element.
* @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>> {
/**
* The context this element belongs to.
@ -45,6 +47,7 @@ public interface AlgebraElement<T, C : Algebra<T>> {
* @return the difference.
*/
@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 =
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.
* @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 =
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.
* @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 =
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.
* @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 =
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.
*/
@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>
/**
@ -103,6 +113,7 @@ public interface GroupElement<T : GroupElement<T, S>, S : Group<T>> : AlgebraEle
* @param R the type of ring.
*/
@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>
/**
@ -113,4 +124,5 @@ public interface RingElement<T : RingElement<T, R>, R : Ring<T>> : GroupElement<
* @param F the type of field.
*/
@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>

View File

@ -80,36 +80,42 @@ public interface TrigonometricOperations<T> : Algebra<T> {
* Computes the sine of [arg].
*/
@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)
/**
* Computes the cosine of [arg].
*/
@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)
/**
* Computes the tangent of [arg].
*/
@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)
/**
* Computes the inverse sine of [arg].
*/
@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)
/**
* Computes the inverse cosine of [arg].
*/
@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)
/**
* Computes the inverse tangent of [arg].
*/
@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)
/**
@ -154,18 +160,21 @@ public interface PowerOperations<T> : Algebra<T> {
* @return the base raised to the power.
*/
@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)
/**
* Computes the square root of the value [arg].
*/
@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
/**
* Computes the square of the value [arg].
*/
@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
/**
@ -261,12 +270,14 @@ public interface ExponentialOperations<T> : Algebra<T> {
* The identifier of exponential function.
*/
@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)
/**
* The identifier of natural logarithm.
*/
@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)
@ -280,30 +291,35 @@ public fun <T : AlgebraElement<T, out ExponentialOperations<T>>> sinh(arg: T): T
* Computes the hyperbolic cosine of [arg].
*/
@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)
/**
* Computes the hyperbolic tangent of [arg].
*/
@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)
/**
* Computes the inverse hyperbolic sine of [arg].
*/
@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)
/**
* Computes the inverse hyperbolic cosine of [arg].
*/
@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)
/**
* Computes the inverse hyperbolic tangent of [arg].
*/
@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)
/**

View File

@ -2,9 +2,9 @@
EJML based linear algebra implementation.
- [ejml-vector](src/main/kotlin/space/kscience/kmath/ejml/EjmlVector.kt) : The Point implementation using SimpleMatrix.
- [ejml-matrix](src/main/kotlin/space/kscience/kmath/ejml/EjmlMatrix.kt) : The Matrix implementation using SimpleMatrix.
- [ejml-linear-space](src/main/kotlin/space/kscience/kmath/ejml/EjmlLinearSpace.kt) : The LinearSpace 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) : Matrix implementation.
- [ejml-linear-space](src/main/kotlin/space/kscience/kmath/ejml/EjmlLinearSpace.kt) : LinearSpace implementations.
## Artifact:
@ -15,8 +15,7 @@ The Maven coordinates of this project are `space.kscience:kmath-ejml:0.3.0-dev-7
```gradle
repositories {
maven { url 'https://repo.kotlin.link' }
maven { url 'https://dl.bintray.com/hotkeytlt/maven' }
maven { url "https://dl.bintray.com/kotlin/kotlin-eap" } // include for builds based on kotlin-eap
mavenCentral()
}
dependencies {
@ -27,8 +26,7 @@ dependencies {
```kotlin
repositories {
maven("https://repo.kotlin.link")
maven("https://dl.bintray.com/kotlin/kotlin-eap") // include for builds based on kotlin-eap
maven("https://dl.bintray.com/hotkeytlt/maven") // required for a
mavenCentral()
}
dependencies {

View File

@ -4,7 +4,7 @@ plugins {
}
dependencies {
api("org.ejml:ejml-simple:0.40")
api("org.ejml:ejml-ddense:0.40")
api(project(":kmath-core"))
}
@ -14,19 +14,19 @@ readme {
feature(
id = "ejml-vector",
description = "The Point implementation using SimpleMatrix.",
description = "Point implementations.",
ref = "src/main/kotlin/space/kscience/kmath/ejml/EjmlVector.kt"
)
feature(
id = "ejml-matrix",
description = "The Matrix implementation using SimpleMatrix.",
description = "Matrix implementation.",
ref = "src/main/kotlin/space/kscience/kmath/ejml/EjmlMatrix.kt"
)
feature(
id = "ejml-linear-space",
description = "The LinearSpace implementation using SimpleMatrix.",
description = "LinearSpace implementations.",
ref = "src/main/kotlin/space/kscience/kmath/ejml/EjmlLinearSpace.kt"
)
}

View File

@ -5,45 +5,71 @@
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.simple.SimpleMatrix
import space.kscience.kmath.linear.*
import space.kscience.kmath.misc.UnstableKMathAPI
import space.kscience.kmath.nd.StructureFeature
import space.kscience.kmath.nd.getFeature
import space.kscience.kmath.operations.DoubleField
import space.kscience.kmath.operations.Ring
import space.kscience.kmath.structures.DoubleBuffer
import kotlin.reflect.KClass
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 Alexander Nozik
*/
public object EjmlLinearSpace : LinearSpace<Double, DoubleField> {
public object EjmlLinearSpaceDDRM : EjmlLinearSpace<Double, DoubleField, DMatrixRMaj>() {
/**
* The [DoubleField] reference.
*/
public override val elementAlgebra: DoubleField get() = DoubleField
/**
* Converts this matrix to EJML one.
*/
@OptIn(UnstableKMathAPI::class)
public fun Matrix<Double>.toEjml(): EjmlMatrix = when (val matrix = origin) {
is EjmlMatrix -> matrix
@Suppress("UNCHECKED_CAST")
public override fun Matrix<Double>.toEjml(): EjmlDoubleMatrix<DMatrixRMaj> = when {
this is EjmlDoubleMatrix<*> && origin is DMatrixRMaj -> this as EjmlDoubleMatrix<DMatrixRMaj>
else -> buildMatrix(rowNum, colNum) { i, j -> get(i, j) }
}
/**
* Converts this vector to EJML one.
*/
public fun Point<Double>.toEjml(): EjmlVector = when (this) {
is EjmlVector -> this
else -> EjmlVector(SimpleMatrix(size, 1).also {
(0 until it.numRows()).forEach { row -> it[row, 0] = get(row) }
@Suppress("UNCHECKED_CAST")
public override fun Point<Double>.toEjml(): EjmlDoubleVector<DMatrixRMaj> = when {
this is EjmlDoubleVector<*> && origin is DMatrixRMaj -> this as EjmlDoubleVector<DMatrixRMaj>
else -> EjmlDoubleVector(DMatrixRMaj(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,
columns: Int,
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 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> =
EjmlVector(SimpleMatrix(size, 1).also {
(0 until it.numRows()).forEach { row -> it[row, 0] = DoubleField.initializer(row) }
})
public override fun buildVector(
size: Int,
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 SimpleMatrix.wrapVector() = EjmlVector(this)
private fun <T : DMatrix> T.wrapMatrix() = EjmlDoubleMatrix(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>.dot(other: Matrix<Double>): EjmlMatrix =
EjmlMatrix(toEjml().origin.mult(other.toEjml().origin))
public override fun Matrix<Double>.dot(other: Matrix<Double>): EjmlDoubleMatrix<DMatrixRMaj> {
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 =
EjmlVector(toEjml().origin.mult(vector.toEjml().origin))
public override fun Matrix<Double>.dot(vector: Point<Double>): EjmlDoubleVector<DMatrixRMaj> {
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 =
(toEjml().origin - other.toEjml().origin).wrapMatrix()
public override operator fun Matrix<Double>.minus(other: Matrix<Double>): EjmlDoubleMatrix<DMatrixRMaj> {
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 =
toEjml().origin.scale(value).wrapMatrix()
public override operator fun Matrix<Double>.times(value: Double): EjmlDoubleMatrix<DMatrixRMaj> {
val res = this.toEjml().origin.copy()
CommonOps_DDRM.scale(value, res)
return res.wrapMatrix()
}
public override fun Point<Double>.unaryMinus(): EjmlVector =
toEjml().origin.negative().wrapVector()
public override fun Point<Double>.unaryMinus(): EjmlDoubleVector<DMatrixRMaj> {
val out = toEjml().origin.copy()
CommonOps_DDRM.changeSign(out)
return out.wrapVector()
}
public override fun Matrix<Double>.plus(other: Matrix<Double>): EjmlMatrix =
(toEjml().origin + other.toEjml().origin).wrapMatrix()
public override fun Matrix<Double>.plus(other: Matrix<Double>): EjmlDoubleMatrix<DMatrixRMaj> {
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 =
(toEjml().origin + other.toEjml().origin).wrapVector()
public override fun Point<Double>.plus(other: Point<Double>): EjmlDoubleVector<DMatrixRMaj> {
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 =
(toEjml().origin - other.toEjml().origin).wrapVector()
public override fun Point<Double>.minus(other: Point<Double>): EjmlDoubleVector<DMatrixRMaj> {
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 =
m.toEjml().origin.scale(this).wrapMatrix()
public override fun Double.times(m: Matrix<Double>): EjmlDoubleMatrix<DMatrixRMaj> = m * this
public override fun Point<Double>.times(value: Double): EjmlVector =
toEjml().origin.scale(value).wrapVector()
public override fun Point<Double>.times(value: Double): EjmlDoubleVector<DMatrixRMaj> {
val res = this.toEjml().origin.copy()
CommonOps_DDRM.scale(value, res)
return res.wrapVector()
}
public override fun Double.times(v: Point<Double>): EjmlVector =
v.toEjml().origin.scale(this).wrapVector()
public override fun Double.times(v: Point<Double>): EjmlDoubleVector<DMatrixRMaj> = v * this
@UnstableKMathAPI
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 }
val origin = structure.toEjml().origin
return when (type) {
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> {
override val determinant: Double by lazy(origin::determinant)
override val determinant: Double by lazy { CommonOps_DDRM.det(DMatrixRMaj(origin)) }
}
SingularValueDecompositionFeature::class -> object : SingularValueDecompositionFeature<Double> {
private val svd by lazy {
DecompositionFactory_DDRM.svd(origin.numRows(), origin.numCols(), true, true, false)
.apply { decompose(origin.ddrm.copy()) }
DecompositionFactory_DDRM.svd(origin.numRows, origin.numCols, true, true, false)
.apply { decompose(origin.copy()) }
}
override val u: Matrix<Double> by lazy { EjmlMatrix(SimpleMatrix(svd.getU(null, false))) }
override val s: Matrix<Double> by lazy { EjmlMatrix(SimpleMatrix(svd.getW(null))) }
override val v: Matrix<Double> by lazy { EjmlMatrix(SimpleMatrix(svd.getV(null, false))) }
override val u: Matrix<Double> by lazy { EjmlDoubleMatrix(svd.getU(null, false)) }
override val s: Matrix<Double> by lazy { EjmlDoubleMatrix(svd.getW(null)) }
override val v: Matrix<Double> by lazy { EjmlDoubleMatrix(svd.getV(null, false)) }
override val singularValues: Point<Double> by lazy { DoubleBuffer(svd.singularValues) }
}
QRDecompositionFeature::class -> object : QRDecompositionFeature<Double> {
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 {
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> {
override val l: Matrix<Double> by lazy {
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> {
private val lup by lazy {
DecompositionFactory_DDRM.lu(origin.numRows(), origin.numCols())
.apply { decompose(origin.ddrm.copy()) }
DecompositionFactory_DDRM.lu(origin.numRows, origin.numCols).apply { decompose(origin.copy()) }
}
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 {
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
}?.let(type::cast)
}
/**
* Solves for *x* in the following equation: *x = [a] <sup>-1</sup> &middot; [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> &middot; [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> &middot; [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> &middot; [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()

View File

@ -5,18 +5,28 @@
package space.kscience.kmath.ejml
import org.ejml.simple.SimpleMatrix
import space.kscience.kmath.linear.Matrix
import org.ejml.data.DMatrix
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
*/
public class EjmlMatrix(public val origin: SimpleMatrix) : Matrix<Double> {
public override val rowNum: Int get() = origin.numRows()
public override val colNum: Int get() = origin.numCols()
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 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]
}

View File

@ -5,35 +5,41 @@
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
/**
* 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
*/
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
get() = origin.numRows()
get() = origin.numRows
init {
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> {
public override operator fun iterator(): Iterator<T> = object : Iterator<T> {
private var cursor: Int = 0
override fun next(): Double {
override fun next(): T {
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)"
}
/**
* [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]
}

View File

@ -5,12 +5,15 @@
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.simple.SimpleMatrix
import space.kscience.kmath.linear.*
import space.kscience.kmath.linear.DeterminantFeature
import space.kscience.kmath.linear.LupDecompositionFeature
import space.kscience.kmath.linear.getFeature
import space.kscience.kmath.misc.UnstableKMathAPI
import space.kscience.kmath.nd.StructureND
import space.kscience.kmath.nd.getFeature
import kotlin.random.Random
import kotlin.random.asJavaRandom
import kotlin.test.*
@ -22,65 +25,59 @@ fun <T : Any> assertMatrixEquals(expected: StructureND<T>, actual: StructureND<T
internal class EjmlMatrixTest {
private val random = Random(0)
private val randomMatrix: SimpleMatrix
private val randomMatrix: DMatrixRMaj
get() {
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
fun rowNum() {
val m = randomMatrix
assertEquals(m.numRows(), EjmlMatrix(m).rowNum)
assertEquals(m.numRows, EjmlDoubleMatrix(m).rowNum)
}
@Test
fun colNum() {
val m = randomMatrix
assertEquals(m.numCols(), EjmlMatrix(m).rowNum)
assertEquals(m.numCols, EjmlDoubleMatrix(m).rowNum)
}
@Test
fun shape() {
val m = randomMatrix
val w = EjmlMatrix(m)
assertEquals(listOf(m.numRows(), m.numCols()), w.shape.toList())
val w = EjmlDoubleMatrix(m)
assertContentEquals(intArrayOf(m.numRows, m.numCols), w.shape)
}
@OptIn(UnstableKMathAPI::class)
@Test
fun features() {
val m = randomMatrix
val w = EjmlMatrix(m)
val det: DeterminantFeature<Double> = EjmlLinearSpace.getFeature(w) ?: fail()
assertEquals(m.determinant(), det.determinant)
val lup: LupDecompositionFeature<Double> = EjmlLinearSpace.getFeature(w) ?: fail()
val w = EjmlDoubleMatrix(m)
val det: DeterminantFeature<Double> = EjmlLinearSpaceDDRM.getFeature(w) ?: fail()
assertEquals(CommonOps_DDRM.det(m), det.determinant)
val lup: LupDecompositionFeature<Double> = EjmlLinearSpaceDDRM.getFeature(w) ?: fail()
val ludecompositionF64 = DecompositionFactory_DDRM.lu(m.numRows(), m.numCols())
.also { it.decompose(m.ddrm.copy()) }
val ludecompositionF64 = DecompositionFactory_DDRM.lu(m.numRows, m.numCols)
.also { it.decompose(m.copy()) }
assertMatrixEquals(EjmlMatrix(SimpleMatrix(ludecompositionF64.getLower(null))), lup.l)
assertMatrixEquals(EjmlMatrix(SimpleMatrix(ludecompositionF64.getUpper(null))), lup.u)
assertMatrixEquals(EjmlMatrix(SimpleMatrix(ludecompositionF64.getRowPivot(null))), lup.p)
}
private object SomeFeature : MatrixFeature {}
@OptIn(UnstableKMathAPI::class)
@Test
fun suggestFeature() {
assertNotNull((EjmlMatrix(randomMatrix) + SomeFeature).getFeature<SomeFeature>())
assertMatrixEquals(EjmlDoubleMatrix(ludecompositionF64.getLower(null)), lup.l)
assertMatrixEquals(EjmlDoubleMatrix(ludecompositionF64.getUpper(null)), lup.u)
assertMatrixEquals(EjmlDoubleMatrix(ludecompositionF64.getRowPivot(null)), lup.p)
}
@Test
fun get() {
val m = randomMatrix
assertEquals(m[0, 0], EjmlMatrix(m)[0, 0])
assertEquals(m[0, 0], EjmlDoubleMatrix(m)[0, 0])
}
@Test
fun origin() {
val m = randomMatrix
assertSame(m, EjmlMatrix(m).origin)
assertSame(m, EjmlDoubleMatrix(m).origin)
}
}

View File

@ -5,7 +5,8 @@
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.asJavaRandom
import kotlin.test.Test
@ -15,30 +16,34 @@ import kotlin.test.assertSame
internal class EjmlVectorTest {
private val random = Random(0)
private val randomMatrix: SimpleMatrix
get() = SimpleMatrix.random_DDRM(random.nextInt(2, 100), 1, 0.0, 10.0, random.asJavaRandom())
private val randomMatrix: DMatrixRMaj
get() {
val d = DMatrixRMaj(random.nextInt(2, 100), 1)
RandomMatrices_DDRM.fillUniform(d, random.asJavaRandom())
return d
}
@Test
fun size() {
val m = randomMatrix
val w = EjmlVector(m)
assertEquals(m.numRows(), w.size)
val w = EjmlDoubleVector(m)
assertEquals(m.numRows, w.size)
}
@Test
fun get() {
val m = randomMatrix
val w = EjmlVector(m)
val w = EjmlDoubleVector(m)
assertEquals(m[0, 0], w[0])
}
@Test
fun iterator() {
val m = randomMatrix
val w = EjmlVector(m)
val w = EjmlDoubleVector(m)
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()
)
}
@ -46,7 +51,7 @@ internal class EjmlVectorTest {
@Test
fun origin() {
val m = randomMatrix
val w = EjmlVector(m)
val w = EjmlDoubleVector(m)
assertSame(m, w.origin)
}
}

View File

@ -15,8 +15,7 @@ The Maven coordinates of this project are `space.kscience:kmath-for-real:0.3.0-d
```gradle
repositories {
maven { url 'https://repo.kotlin.link' }
maven { url 'https://dl.bintray.com/hotkeytlt/maven' }
maven { url "https://dl.bintray.com/kotlin/kotlin-eap" } // include for builds based on kotlin-eap
mavenCentral()
}
dependencies {
@ -27,8 +26,7 @@ dependencies {
```kotlin
repositories {
maven("https://repo.kotlin.link")
maven("https://dl.bintray.com/kotlin/kotlin-eap") // include for builds based on kotlin-eap
maven("https://dl.bintray.com/hotkeytlt/maven") // required for a
mavenCentral()
}
dependencies {

View File

@ -17,8 +17,7 @@ The Maven coordinates of this project are `space.kscience:kmath-functions:0.3.0-
```gradle
repositories {
maven { url 'https://repo.kotlin.link' }
maven { url 'https://dl.bintray.com/hotkeytlt/maven' }
maven { url "https://dl.bintray.com/kotlin/kotlin-eap" } // include for builds based on kotlin-eap
mavenCentral()
}
dependencies {
@ -29,8 +28,7 @@ dependencies {
```kotlin
repositories {
maven("https://repo.kotlin.link")
maven("https://dl.bintray.com/kotlin/kotlin-eap") // include for builds based on kotlin-eap
maven("https://dl.bintray.com/hotkeytlt/maven") // required for a
mavenCentral()
}
dependencies {

View 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")
}

View File

@ -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()
}
}
}

View File

@ -4,8 +4,8 @@ plugins {
}
dependencies {
implementation("com.github.breandan:kaliningraph:0.1.4")
implementation("com.github.breandan:kotlingrad:0.4.0")
api("com.github.breandan:kaliningraph:0.1.4")
api("com.github.breandan:kotlingrad:0.4.5")
api(project(":kmath-ast"))
}

View File

@ -15,8 +15,7 @@ The Maven coordinates of this project are `space.kscience:kmath-nd4j:0.3.0-dev-7
```gradle
repositories {
maven { url 'https://repo.kotlin.link' }
maven { url 'https://dl.bintray.com/hotkeytlt/maven' }
maven { url "https://dl.bintray.com/kotlin/kotlin-eap" } // include for builds based on kotlin-eap
mavenCentral()
}
dependencies {
@ -27,8 +26,7 @@ dependencies {
```kotlin
repositories {
maven("https://repo.kotlin.link")
maven("https://dl.bintray.com/kotlin/kotlin-eap") // include for builds based on kotlin-eap
maven("https://dl.bintray.com/hotkeytlt/maven") // required for a
mavenCentral()
}
dependencies {

View File

@ -26,11 +26,6 @@ public open class BufferedTensor<T>(
override fun elements(): Sequence<Pair<IntArray, T>> = linearStructure.indices().map {
it to this[it]
}
override fun equals(other: Any?): Boolean = false
override fun hashCode(): Int = 0
}
public class IntTensor internal constructor(

View File

@ -7,9 +7,9 @@ description = "Binding for https://github.com/JetBrains-Research/viktor"
dependencies {
api(project(":kmath-core"))
api("org.jetbrains.bio:viktor:1.0.1")
api("org.jetbrains.bio:viktor:1.1.0")
}
readme {
maturity = ru.mipt.npm.gradle.Maturity.DEVELOPMENT
}
}

View File

@ -17,6 +17,9 @@ pluginManagement {
id("ru.mipt.npm.gradle.project") version toolsVersion
id("ru.mipt.npm.gradle.mpp") 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-kotlingrad",
":kmath-tensors",
":kmath-jupyter",
":examples",
":benchmarks"
)