MST rendering: support infix division, use arcsin instead sin^-1 form for inverse trigonometric functions #311
14
README.md
14
README.md
@ -91,7 +91,7 @@ KMath is a modular library. Different modules provide different features with di
|
|||||||
* ### [kmath-ast](kmath-ast)
|
* ### [kmath-ast](kmath-ast)
|
||||||
>
|
>
|
||||||
>
|
>
|
||||||
> **Maturity**: PROTOTYPE
|
> **Maturity**: EXPERIMENTAL
|
||||||
>
|
>
|
||||||
> **Features:**
|
> **Features:**
|
||||||
> - [expression-language](kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/parser.kt) : Expression language and its parser
|
> - [expression-language](kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/parser.kt) : Expression language and its parser
|
||||||
@ -154,9 +154,9 @@ performance calculations to code generation.
|
|||||||
> **Maturity**: PROTOTYPE
|
> **Maturity**: PROTOTYPE
|
||||||
>
|
>
|
||||||
> **Features:**
|
> **Features:**
|
||||||
> - [ejml-vector](kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/EjmlVector.kt) : The Point implementation using SimpleMatrix.
|
> - [ejml-vector](kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/EjmlVector.kt) : Point implementations.
|
||||||
> - [ejml-matrix](kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/EjmlMatrix.kt) : The Matrix implementation using SimpleMatrix.
|
> - [ejml-matrix](kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/EjmlMatrix.kt) : Matrix implementation.
|
||||||
> - [ejml-linear-space](kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/EjmlLinearSpace.kt) : The LinearSpace implementation using SimpleMatrix.
|
> - [ejml-linear-space](kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/EjmlLinearSpace.kt) : LinearSpace implementations.
|
||||||
|
|
||||||
<hr/>
|
<hr/>
|
||||||
|
|
||||||
@ -200,6 +200,12 @@ One can still use generic algebras though.
|
|||||||
> **Maturity**: PROTOTYPE
|
> **Maturity**: PROTOTYPE
|
||||||
<hr/>
|
<hr/>
|
||||||
|
|
||||||
|
* ### [kmath-jupyter](kmath-jupyter)
|
||||||
|
>
|
||||||
|
>
|
||||||
|
> **Maturity**: PROTOTYPE
|
||||||
|
<hr/>
|
||||||
|
|
||||||
* ### [kmath-kotlingrad](kmath-kotlingrad)
|
* ### [kmath-kotlingrad](kmath-kotlingrad)
|
||||||
>
|
>
|
||||||
>
|
>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# Module kmath-ast
|
# Module kmath-ast
|
||||||
|
|
||||||
Abstract syntax tree expression representation and related optimizations.
|
Performance and visualization extensions to MST API.
|
||||||
|
|
||||||
- [expression-language](src/commonMain/kotlin/space/kscience/kmath/ast/parser.kt) : Expression language and its parser
|
- [expression-language](src/commonMain/kotlin/space/kscience/kmath/ast/parser.kt) : Expression language and its parser
|
||||||
- [mst-jvm-codegen](src/jvmMain/kotlin/space/kscience/kmath/asm/asm.kt) : Dynamic MST to JVM bytecode compiler
|
- [mst-jvm-codegen](src/jvmMain/kotlin/space/kscience/kmath/asm/asm.kt) : Dynamic MST to JVM bytecode compiler
|
||||||
@ -39,12 +39,16 @@ dependencies {
|
|||||||
|
|
||||||
### On JVM
|
### On JVM
|
||||||
|
|
||||||
`kmath-ast` JVM module supports runtime code generation to eliminate overhead of tree traversal. Code generator builds
|
`kmath-ast` JVM module supports runtime code generation to eliminate overhead of tree traversal. Code generator builds a
|
||||||
a special implementation of `Expression<T>` with implemented `invoke` function.
|
special implementation of `Expression<T>` with implemented `invoke` function.
|
||||||
|
|
||||||
For example, the following builder:
|
For example, the following builder:
|
||||||
|
|
||||||
```kotlin
|
```kotlin
|
||||||
|
import space.kscience.kmath.expressions.*
|
||||||
|
import space.kscience.kmath.operations.*
|
||||||
|
import space.kscience.kmath.asm.*
|
||||||
|
|
||||||
MstField { bindSymbol("x") + 2 }.compileToExpression(DoubleField)
|
MstField { bindSymbol("x") + 2 }.compileToExpression(DoubleField)
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -54,6 +58,7 @@ MstField { bindSymbol("x") + 2 }.compileToExpression(DoubleField)
|
|||||||
package space.kscience.kmath.asm.generated;
|
package space.kscience.kmath.asm.generated;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import kotlin.jvm.functions.Function2;
|
import kotlin.jvm.functions.Function2;
|
||||||
import space.kscience.kmath.asm.internal.MapIntrinsics;
|
import space.kscience.kmath.asm.internal.MapIntrinsics;
|
||||||
import space.kscience.kmath.expressions.Expression;
|
import space.kscience.kmath.expressions.Expression;
|
||||||
@ -63,7 +68,7 @@ public final class AsmCompiledExpression_45045_0 implements Expression<Double> {
|
|||||||
private final Object[] constants;
|
private final Object[] constants;
|
||||||
|
|
||||||
public final Double invoke(Map<Symbol, ? extends Double> arguments) {
|
public final Double invoke(Map<Symbol, ? extends Double> arguments) {
|
||||||
return (Double)((Function2)this.constants[0]).invoke((Double)MapIntrinsics.getOrFail(arguments, "x"), 2);
|
return (Double) ((Function2) this.constants[0]).invoke((Double) MapIntrinsics.getOrFail(arguments, "x"), 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
public AsmCompiledExpression_45045_0(Object[] constants) {
|
public AsmCompiledExpression_45045_0(Object[] constants) {
|
||||||
@ -75,8 +80,8 @@ public final class AsmCompiledExpression_45045_0 implements Expression<Double> {
|
|||||||
|
|
||||||
#### Known issues
|
#### Known issues
|
||||||
|
|
||||||
- The same classes may be generated and loaded twice, so it is recommended to cache compiled expressions to avoid
|
- The same classes may be generated and loaded twice, so it is recommended to cache compiled expressions to avoid class
|
||||||
class loading overhead.
|
loading overhead.
|
||||||
- This API is not supported by non-dynamic JVM implementations (like TeaVM and GraalVM) because of using class loaders.
|
- This API is not supported by non-dynamic JVM implementations (like TeaVM and GraalVM) because of using class loaders.
|
||||||
|
|
||||||
### On JS
|
### On JS
|
||||||
@ -84,6 +89,10 @@ public final class AsmCompiledExpression_45045_0 implements Expression<Double> {
|
|||||||
A similar feature is also available on JS.
|
A similar feature is also available on JS.
|
||||||
|
|
||||||
```kotlin
|
```kotlin
|
||||||
|
import space.kscience.kmath.expressions.*
|
||||||
|
import space.kscience.kmath.operations.*
|
||||||
|
import space.kscience.kmath.estree.*
|
||||||
|
|
||||||
MstField { bindSymbol("x") + 2 }.compileToExpression(DoubleField)
|
MstField { bindSymbol("x") + 2 }.compileToExpression(DoubleField)
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -91,13 +100,16 @@ The code above returns expression implemented with such a JS function:
|
|||||||
|
|
||||||
```js
|
```js
|
||||||
var executable = function (constants, arguments) {
|
var executable = function (constants, arguments) {
|
||||||
return constants[1](constants[0](arguments, "x"), 2);
|
return constants[1](constants[0](arguments, "x"), 2);
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
JS also supports very experimental expression optimization with [WebAssembly](https://webassembly.org/) IR generation. Currently, only expressions inside `DoubleField` and `IntRing` are supported.
|
JS also supports very experimental expression optimization with [WebAssembly](https://webassembly.org/) IR generation.
|
||||||
|
Currently, only expressions inside `DoubleField` and `IntRing` are supported.
|
||||||
|
|
||||||
```kotlin
|
```kotlin
|
||||||
|
import space.kscience.kmath.expressions.*
|
||||||
|
import space.kscience.kmath.operations.*
|
||||||
import space.kscience.kmath.wasm.*
|
import space.kscience.kmath.wasm.*
|
||||||
|
|
||||||
MstField { bindSymbol("x") + 2 }.compileToExpression(DoubleField)
|
MstField { bindSymbol("x") + 2 }.compileToExpression(DoubleField)
|
||||||
@ -128,7 +140,9 @@ Example usage:
|
|||||||
```kotlin
|
```kotlin
|
||||||
import space.kscience.kmath.ast.*
|
import space.kscience.kmath.ast.*
|
||||||
import space.kscience.kmath.ast.rendering.*
|
import space.kscience.kmath.ast.rendering.*
|
||||||
|
import space.kscience.kmath.misc.*
|
||||||
|
|
||||||
|
@OptIn(UnstableKMathAPI::class)
|
||||||
public fun main() {
|
public fun main() {
|
||||||
val mst = "exp(sqrt(x))-asin(2*x)/(2e10+x^3)/(-12)".parseMath()
|
val mst = "exp(sqrt(x))-asin(2*x)/(2e10+x^3)/(-12)".parseMath()
|
||||||
val syntax = FeaturedMathRendererWithPostProcess.Default.render(mst)
|
val syntax = FeaturedMathRendererWithPostProcess.Default.render(mst)
|
||||||
@ -144,13 +158,68 @@ public fun main() {
|
|||||||
|
|
||||||
Result LaTeX:
|
Result LaTeX:
|
||||||
|
|
||||||
![](http://chart.googleapis.com/chart?cht=tx&chl=e%5E%7B%5Csqrt%7Bx%7D%7D-%5Cfrac%7B%5Cfrac%7B%5Coperatorname%7Bsin%7D%5E%7B-1%7D%5C,%5Cleft(2%5C,x%5Cright)%7D%7B2%5Ctimes10%5E%7B10%7D%2Bx%5E%7B3%7D%7D%7D%7B-12%7D)
|
![](https://latex.codecogs.com/gif.latex?%5Coperatorname{exp}%5C,%5Cleft(%5Csqrt{x}%5Cright)-%5Cfrac{%5Cfrac{%5Coperatorname{arcsin}%5C,%5Cleft(2%5C,x%5Cright)}{2%5Ctimes10^{10}%2Bx^{3}}}{-12})
|
||||||
|
|
||||||
Result MathML (embedding MathML is not allowed by GitHub Markdown):
|
Result MathML (embedding MathML is not allowed by GitHub Markdown):
|
||||||
|
|
||||||
|
<details>
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<mrow><msup><mrow><mi>e</mi></mrow><mrow><msqrt><mi>x</mi></msqrt></mrow></msup><mo>-</mo><mfrac><mrow><mfrac><mrow><msup><mrow><mo>sin</mo></mrow><mrow><mo>-</mo><mn>1</mn></mrow></msup><mspace width="0.167em"></mspace><mfenced open="(" close=")" separators=""><mn>2</mn><mspace width="0.167em"></mspace><mi>x</mi></mfenced></mrow><mrow><mn>2</mn><mo>×</mo><msup><mrow><mn>10</mn></mrow><mrow><mn>10</mn></mrow></msup><mo>+</mo><msup><mrow><mi>x</mi></mrow><mrow><mn>3</mn></mrow></msup></mrow></mfrac></mrow><mrow><mo>-</mo><mn>12</mn></mrow></mfrac></mrow>
|
<math xmlns="https://www.w3.org/1998/Math/MathML">
|
||||||
|
<mrow>
|
||||||
|
<mo>exp</mo>
|
||||||
|
<mspace width="0.167em"></mspace>
|
||||||
|
<mfenced open="(" close=")" separators="">
|
||||||
|
<msqrt>
|
||||||
|
<mi>x</mi>
|
||||||
|
</msqrt>
|
||||||
|
</mfenced>
|
||||||
|
<mo>-</mo>
|
||||||
|
<mfrac>
|
||||||
|
<mrow>
|
||||||
|
<mfrac>
|
||||||
|
<mrow>
|
||||||
|
<mo>arcsin</mo>
|
||||||
|
<mspace width="0.167em"></mspace>
|
||||||
|
<mfenced open="(" close=")" separators="">
|
||||||
|
<mn>2</mn>
|
||||||
|
<mspace width="0.167em"></mspace>
|
||||||
|
<mi>x</mi>
|
||||||
|
</mfenced>
|
||||||
|
</mrow>
|
||||||
|
<mrow>
|
||||||
|
<mn>2</mn>
|
||||||
|
<mo>×</mo>
|
||||||
|
<msup>
|
||||||
|
<mrow>
|
||||||
|
<mn>10</mn>
|
||||||
|
</mrow>
|
||||||
|
<mrow>
|
||||||
|
<mn>10</mn>
|
||||||
|
</mrow>
|
||||||
|
</msup>
|
||||||
|
<mo>+</mo>
|
||||||
|
<msup>
|
||||||
|
<mrow>
|
||||||
|
<mi>x</mi>
|
||||||
|
</mrow>
|
||||||
|
<mrow>
|
||||||
|
<mn>3</mn>
|
||||||
|
</mrow>
|
||||||
|
</msup>
|
||||||
|
</mrow>
|
||||||
|
</mfrac>
|
||||||
|
</mrow>
|
||||||
|
<mrow>
|
||||||
|
<mo>-</mo>
|
||||||
|
<mn>12</mn>
|
||||||
|
</mrow>
|
||||||
|
</mfrac>
|
||||||
|
</mrow>
|
||||||
|
</math>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
It is also possible to create custom algorithms of render, and even add support of other markup languages
|
It is also possible to create custom algorithms of render, and even add support of other markup languages
|
||||||
(see API reference).
|
(see API reference).
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# Module kmath-ast
|
# Module kmath-ast
|
||||||
|
|
||||||
Abstract syntax tree expression representation and related optimizations.
|
Performance and visualization extensions to MST API.
|
||||||
|
|
||||||
${features}
|
${features}
|
||||||
|
|
||||||
@ -10,12 +10,16 @@ ${artifact}
|
|||||||
|
|
||||||
### On JVM
|
### On JVM
|
||||||
|
|
||||||
`kmath-ast` JVM module supports runtime code generation to eliminate overhead of tree traversal. Code generator builds
|
`kmath-ast` JVM module supports runtime code generation to eliminate overhead of tree traversal. Code generator builds a
|
||||||
a special implementation of `Expression<T>` with implemented `invoke` function.
|
special implementation of `Expression<T>` with implemented `invoke` function.
|
||||||
|
|
||||||
For example, the following builder:
|
For example, the following builder:
|
||||||
|
|
||||||
```kotlin
|
```kotlin
|
||||||
|
import space.kscience.kmath.expressions.*
|
||||||
|
import space.kscience.kmath.operations.*
|
||||||
|
import space.kscience.kmath.asm.*
|
||||||
|
|
||||||
MstField { bindSymbol("x") + 2 }.compileToExpression(DoubleField)
|
MstField { bindSymbol("x") + 2 }.compileToExpression(DoubleField)
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -25,6 +29,7 @@ MstField { bindSymbol("x") + 2 }.compileToExpression(DoubleField)
|
|||||||
package space.kscience.kmath.asm.generated;
|
package space.kscience.kmath.asm.generated;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import kotlin.jvm.functions.Function2;
|
import kotlin.jvm.functions.Function2;
|
||||||
import space.kscience.kmath.asm.internal.MapIntrinsics;
|
import space.kscience.kmath.asm.internal.MapIntrinsics;
|
||||||
import space.kscience.kmath.expressions.Expression;
|
import space.kscience.kmath.expressions.Expression;
|
||||||
@ -34,7 +39,7 @@ public final class AsmCompiledExpression_45045_0 implements Expression<Double> {
|
|||||||
private final Object[] constants;
|
private final Object[] constants;
|
||||||
|
|
||||||
public final Double invoke(Map<Symbol, ? extends Double> arguments) {
|
public final Double invoke(Map<Symbol, ? extends Double> arguments) {
|
||||||
return (Double)((Function2)this.constants[0]).invoke((Double)MapIntrinsics.getOrFail(arguments, "x"), 2);
|
return (Double) ((Function2) this.constants[0]).invoke((Double) MapIntrinsics.getOrFail(arguments, "x"), 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
public AsmCompiledExpression_45045_0(Object[] constants) {
|
public AsmCompiledExpression_45045_0(Object[] constants) {
|
||||||
@ -46,8 +51,8 @@ public final class AsmCompiledExpression_45045_0 implements Expression<Double> {
|
|||||||
|
|
||||||
#### Known issues
|
#### Known issues
|
||||||
|
|
||||||
- The same classes may be generated and loaded twice, so it is recommended to cache compiled expressions to avoid
|
- The same classes may be generated and loaded twice, so it is recommended to cache compiled expressions to avoid class
|
||||||
class loading overhead.
|
loading overhead.
|
||||||
- This API is not supported by non-dynamic JVM implementations (like TeaVM and GraalVM) because of using class loaders.
|
- This API is not supported by non-dynamic JVM implementations (like TeaVM and GraalVM) because of using class loaders.
|
||||||
|
|
||||||
### On JS
|
### On JS
|
||||||
@ -55,6 +60,10 @@ public final class AsmCompiledExpression_45045_0 implements Expression<Double> {
|
|||||||
A similar feature is also available on JS.
|
A similar feature is also available on JS.
|
||||||
|
|
||||||
```kotlin
|
```kotlin
|
||||||
|
import space.kscience.kmath.expressions.*
|
||||||
|
import space.kscience.kmath.operations.*
|
||||||
|
import space.kscience.kmath.estree.*
|
||||||
|
|
||||||
MstField { bindSymbol("x") + 2 }.compileToExpression(DoubleField)
|
MstField { bindSymbol("x") + 2 }.compileToExpression(DoubleField)
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -62,13 +71,16 @@ The code above returns expression implemented with such a JS function:
|
|||||||
|
|
||||||
```js
|
```js
|
||||||
var executable = function (constants, arguments) {
|
var executable = function (constants, arguments) {
|
||||||
return constants[1](constants[0](arguments, "x"), 2);
|
return constants[1](constants[0](arguments, "x"), 2);
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
JS also supports very experimental expression optimization with [WebAssembly](https://webassembly.org/) IR generation. Currently, only expressions inside `DoubleField` and `IntRing` are supported.
|
JS also supports very experimental expression optimization with [WebAssembly](https://webassembly.org/) IR generation.
|
||||||
|
Currently, only expressions inside `DoubleField` and `IntRing` are supported.
|
||||||
|
|
||||||
```kotlin
|
```kotlin
|
||||||
|
import space.kscience.kmath.expressions.*
|
||||||
|
import space.kscience.kmath.operations.*
|
||||||
import space.kscience.kmath.wasm.*
|
import space.kscience.kmath.wasm.*
|
||||||
|
|
||||||
MstField { bindSymbol("x") + 2 }.compileToExpression(DoubleField)
|
MstField { bindSymbol("x") + 2 }.compileToExpression(DoubleField)
|
||||||
@ -99,9 +111,11 @@ Example usage:
|
|||||||
```kotlin
|
```kotlin
|
||||||
import space.kscience.kmath.ast.*
|
import space.kscience.kmath.ast.*
|
||||||
import space.kscience.kmath.ast.rendering.*
|
import space.kscience.kmath.ast.rendering.*
|
||||||
|
import space.kscience.kmath.misc.*
|
||||||
|
|
||||||
|
@OptIn(UnstableKMathAPI::class)
|
||||||
public fun main() {
|
public fun main() {
|
||||||
val mst = "exp(sqrt(x))-asin(2*x)/(2e10+x^3)/(-12)".parseMath()
|
val mst = "exp(sqrt(x))-asin(2*x)/(2e10+x^3)/(12)+x^(2/3)".parseMath()
|
||||||
val syntax = FeaturedMathRendererWithPostProcess.Default.render(mst)
|
val syntax = FeaturedMathRendererWithPostProcess.Default.render(mst)
|
||||||
val latex = LatexSyntaxRenderer.renderWithStringBuilder(syntax)
|
val latex = LatexSyntaxRenderer.renderWithStringBuilder(syntax)
|
||||||
println("LaTeX:")
|
println("LaTeX:")
|
||||||
@ -115,13 +129,78 @@ public fun main() {
|
|||||||
|
|
||||||
Result LaTeX:
|
Result LaTeX:
|
||||||
|
|
||||||
![](http://chart.googleapis.com/chart?cht=tx&chl=e%5E%7B%5Csqrt%7Bx%7D%7D-%5Cfrac%7B%5Cfrac%7B%5Coperatorname%7Bsin%7D%5E%7B-1%7D%5C,%5Cleft(2%5C,x%5Cright)%7D%7B2%5Ctimes10%5E%7B10%7D%2Bx%5E%7B3%7D%7D%7D%7B-12%7D)
|
![](https://latex.codecogs.com/gif.latex?%5Coperatorname{exp}%5C,%5Cleft(%5Csqrt{x}%5Cright)-%5Cfrac{%5Cfrac{%5Coperatorname{arcsin}%5C,%5Cleft(2%5C,x%5Cright)}{2%5Ctimes10^{10}%2Bx^{3}}}{12}+x^{2/3})
|
||||||
|
|
||||||
Result MathML (embedding MathML is not allowed by GitHub Markdown):
|
Result MathML (can be used with MathJax or other renderers):
|
||||||
|
|
||||||
|
<details>
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<mrow><msup><mrow><mi>e</mi></mrow><mrow><msqrt><mi>x</mi></msqrt></mrow></msup><mo>-</mo><mfrac><mrow><mfrac><mrow><msup><mrow><mo>sin</mo></mrow><mrow><mo>-</mo><mn>1</mn></mrow></msup><mspace width="0.167em"></mspace><mfenced open="(" close=")" separators=""><mn>2</mn><mspace width="0.167em"></mspace><mi>x</mi></mfenced></mrow><mrow><mn>2</mn><mo>×</mo><msup><mrow><mn>10</mn></mrow><mrow><mn>10</mn></mrow></msup><mo>+</mo><msup><mrow><mi>x</mi></mrow><mrow><mn>3</mn></mrow></msup></mrow></mfrac></mrow><mrow><mo>-</mo><mn>12</mn></mrow></mfrac></mrow>
|
<math xmlns="https://www.w3.org/1998/Math/MathML">
|
||||||
|
<mrow>
|
||||||
|
<mo>exp</mo>
|
||||||
|
<mspace width="0.167em"></mspace>
|
||||||
|
<mfenced open="(" close=")" separators="">
|
||||||
|
<msqrt>
|
||||||
|
<mi>x</mi>
|
||||||
|
</msqrt>
|
||||||
|
</mfenced>
|
||||||
|
<mo>-</mo>
|
||||||
|
<mfrac>
|
||||||
|
<mrow>
|
||||||
|
<mfrac>
|
||||||
|
<mrow>
|
||||||
|
<mo>arcsin</mo>
|
||||||
|
<mspace width="0.167em"></mspace>
|
||||||
|
<mfenced open="(" close=")" separators="">
|
||||||
|
<mn>2</mn>
|
||||||
|
<mspace width="0.167em"></mspace>
|
||||||
|
<mi>x</mi>
|
||||||
|
</mfenced>
|
||||||
|
</mrow>
|
||||||
|
<mrow>
|
||||||
|
<mn>2</mn>
|
||||||
|
<mo>×</mo>
|
||||||
|
<msup>
|
||||||
|
<mrow>
|
||||||
|
<mn>10</mn>
|
||||||
|
</mrow>
|
||||||
|
<mrow>
|
||||||
|
<mn>10</mn>
|
||||||
|
</mrow>
|
||||||
|
</msup>
|
||||||
|
<mo>+</mo>
|
||||||
|
<msup>
|
||||||
|
<mrow>
|
||||||
|
<mi>x</mi>
|
||||||
|
</mrow>
|
||||||
|
<mrow>
|
||||||
|
<mn>3</mn>
|
||||||
|
</mrow>
|
||||||
|
</msup>
|
||||||
|
</mrow>
|
||||||
|
</mfrac>
|
||||||
|
</mrow>
|
||||||
|
<mrow>
|
||||||
|
<mn>12</mn>
|
||||||
|
</mrow>
|
||||||
|
</mfrac>
|
||||||
|
<mo>+</mo>
|
||||||
|
<msup>
|
||||||
|
<mrow>
|
||||||
|
<mi>x</mi>
|
||||||
|
</mrow>
|
||||||
|
<mrow>
|
||||||
|
<mn>2</mn>
|
||||||
|
<mo>/</mo>
|
||||||
|
<mn>3</mn>
|
||||||
|
</mrow>
|
||||||
|
</msup>
|
||||||
|
</mrow>
|
||||||
|
</math>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
It is also possible to create custom algorithms of render, and even add support of other markup languages
|
It is also possible to create custom algorithms of render, and even add support of other markup languages
|
||||||
(see API reference).
|
(see API reference).
|
||||||
|
@ -118,7 +118,11 @@ public object LatexSyntaxRenderer : SyntaxRenderer {
|
|||||||
render(node.right)
|
render(node.right)
|
||||||
}
|
}
|
||||||
|
|
||||||
is FractionSyntax -> {
|
is FractionSyntax -> if (node.infix) {
|
||||||
|
render(node.left)
|
||||||
|
append('/')
|
||||||
|
render(node.right)
|
||||||
|
} else {
|
||||||
append("\\frac{")
|
append("\\frac{")
|
||||||
render(node.left)
|
render(node.left)
|
||||||
append("}{")
|
append("}{")
|
||||||
|
@ -133,14 +133,13 @@ public object MathMLSyntaxRenderer : SyntaxRenderer {
|
|||||||
render(node.right)
|
render(node.right)
|
||||||
}
|
}
|
||||||
|
|
||||||
is FractionSyntax -> tag("mfrac") {
|
is FractionSyntax -> if (node.infix) {
|
||||||
tag("mrow") {
|
render(node.left)
|
||||||
render(node.left)
|
tag("mo") { append('/') }
|
||||||
}
|
render(node.right)
|
||||||
|
} else tag("mfrac") {
|
||||||
tag("mrow") {
|
tag("mrow") { render(node.left) }
|
||||||
render(node.right)
|
tag("mrow") { render(node.right) }
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
is RadicalWithIndexSyntax -> tag("mroot") {
|
is RadicalWithIndexSyntax -> tag("mroot") {
|
||||||
|
@ -89,6 +89,7 @@ public open class FeaturedMathRendererWithPostProcess(
|
|||||||
SquareRoot.Default,
|
SquareRoot.Default,
|
||||||
Exponent.Default,
|
Exponent.Default,
|
||||||
InverseTrigonometricOperations.Default,
|
InverseTrigonometricOperations.Default,
|
||||||
|
InverseHyperbolicOperations.Default,
|
||||||
|
|
||||||
// Fallback option for unknown operations - printing them as operator
|
// Fallback option for unknown operations - printing them as operator
|
||||||
BinaryOperator.Default,
|
BinaryOperator.Default,
|
||||||
@ -105,6 +106,7 @@ public open class FeaturedMathRendererWithPostProcess(
|
|||||||
),
|
),
|
||||||
listOf(
|
listOf(
|
||||||
BetterExponent,
|
BetterExponent,
|
||||||
|
BetterFraction,
|
||||||
SimplifyParentheses.Default,
|
SimplifyParentheses.Default,
|
||||||
BetterMultiplication,
|
BetterMultiplication,
|
||||||
),
|
),
|
||||||
|
@ -102,7 +102,7 @@ public data class SymbolSyntax(public var string: String) : TerminalSyntax()
|
|||||||
public data class OperatorNameSyntax(public var name: String) : TerminalSyntax()
|
public data class OperatorNameSyntax(public var name: String) : TerminalSyntax()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a usage of special symbols.
|
* Represents a usage of special symbols (e.g., *∞*).
|
||||||
*
|
*
|
||||||
* @property kind The kind of symbol.
|
* @property kind The kind of symbol.
|
||||||
* @author Iaroslav Postovalov
|
* @author Iaroslav Postovalov
|
||||||
@ -143,7 +143,7 @@ public data class OperandSyntax(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents unary, prefix operator syntax (like f x).
|
* Represents unary, prefix operator syntax (like *f(x)*).
|
||||||
*
|
*
|
||||||
* @property prefix The prefix.
|
* @property prefix The prefix.
|
||||||
* @author Iaroslav Postovalov
|
* @author Iaroslav Postovalov
|
||||||
@ -160,7 +160,7 @@ public data class UnaryOperatorSyntax(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents prefix, unary plus operator.
|
* Represents prefix, unary plus operator (*+x*).
|
||||||
*
|
*
|
||||||
* @author Iaroslav Postovalov
|
* @author Iaroslav Postovalov
|
||||||
*/
|
*/
|
||||||
@ -175,7 +175,7 @@ public data class UnaryPlusSyntax(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents prefix, unary minus operator.
|
* Represents prefix, unary minus operator (*-x*).
|
||||||
*
|
*
|
||||||
* @author Iaroslav Postovalov
|
* @author Iaroslav Postovalov
|
||||||
*/
|
*/
|
||||||
@ -190,7 +190,7 @@ public data class UnaryMinusSyntax(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents radical with a node inside it.
|
* Represents radical with a node inside it (*√x*).
|
||||||
*
|
*
|
||||||
* @property operand The radicand.
|
* @property operand The radicand.
|
||||||
* @author Iaroslav Postovalov
|
* @author Iaroslav Postovalov
|
||||||
@ -225,7 +225,7 @@ public data class ExponentSyntax(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a syntax node with superscript (usually, for exponentiation).
|
* Represents a syntax node with superscript (*x<sup>2</sup>*).
|
||||||
*
|
*
|
||||||
* @property left The node.
|
* @property left The node.
|
||||||
* @property right The superscript.
|
* @property right The superscript.
|
||||||
@ -244,7 +244,7 @@ public data class SuperscriptSyntax(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a syntax node with subscript.
|
* Represents a syntax node with subscript (*x<sub>i</sup>*).
|
||||||
*
|
*
|
||||||
* @property left The node.
|
* @property left The node.
|
||||||
* @property right The subscript.
|
* @property right The subscript.
|
||||||
@ -263,7 +263,7 @@ public data class SubscriptSyntax(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents binary, prefix operator syntax (like f(a, b)).
|
* Represents binary, prefix operator syntax (like *f(a, b)*).
|
||||||
*
|
*
|
||||||
* @property prefix The prefix.
|
* @property prefix The prefix.
|
||||||
* @author Iaroslav Postovalov
|
* @author Iaroslav Postovalov
|
||||||
@ -282,7 +282,7 @@ public data class BinaryOperatorSyntax(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents binary, infix addition.
|
* Represents binary, infix addition (*42 + 42*).
|
||||||
*
|
*
|
||||||
* @param left The augend.
|
* @param left The augend.
|
||||||
* @param right The addend.
|
* @param right The addend.
|
||||||
@ -301,7 +301,7 @@ public data class BinaryPlusSyntax(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents binary, infix subtraction.
|
* Represents binary, infix subtraction (*42 - 42*).
|
||||||
*
|
*
|
||||||
* @param left The minuend.
|
* @param left The minuend.
|
||||||
* @param right The subtrahend.
|
* @param right The subtrahend.
|
||||||
@ -324,13 +324,15 @@ public data class BinaryMinusSyntax(
|
|||||||
*
|
*
|
||||||
* @property left The numerator.
|
* @property left The numerator.
|
||||||
* @property right The denominator.
|
* @property right The denominator.
|
||||||
|
* @property infix Whether infix (*1 / 2*) or normal (*½*) fraction should be made.
|
||||||
* @author Iaroslav Postovalov
|
* @author Iaroslav Postovalov
|
||||||
*/
|
*/
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
public data class FractionSyntax(
|
public data class FractionSyntax(
|
||||||
public override val operation: String,
|
public override val operation: String,
|
||||||
public override val left: MathSyntax,
|
public override val left: OperandSyntax,
|
||||||
public override val right: MathSyntax,
|
public override val right: OperandSyntax,
|
||||||
|
public var infix: Boolean,
|
||||||
) : BinarySyntax() {
|
) : BinarySyntax() {
|
||||||
init {
|
init {
|
||||||
left.parent = this
|
left.parent = this
|
||||||
@ -339,7 +341,7 @@ public data class FractionSyntax(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents radical syntax with index.
|
* Represents radical syntax with index (*<sup>3</sup>√x*).
|
||||||
*
|
*
|
||||||
* @property left The index.
|
* @property left The index.
|
||||||
* @property right The radicand.
|
* @property right The radicand.
|
||||||
@ -358,11 +360,11 @@ public data class RadicalWithIndexSyntax(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents binary, infix multiplication in the form of coefficient (2 x) or with operator (x×2).
|
* Represents binary, infix multiplication in the form of coefficient (*2 x*) or with operator (*x × 2*).
|
||||||
*
|
*
|
||||||
* @property left The multiplicand.
|
* @property left The multiplicand.
|
||||||
* @property right The multiplier.
|
* @property right The multiplier.
|
||||||
* @property times whether the times (×) symbol should be used.
|
* @property times Whether the times (×) symbol should be used.
|
||||||
* @author Iaroslav Postovalov
|
* @author Iaroslav Postovalov
|
||||||
*/
|
*/
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
|
@ -54,6 +54,7 @@ else
|
|||||||
* *('-'? (DIGIT+ ('.' DIGIT+)? ('E' '-'? DIGIT+)? | 'Infinity')) | 'NaN'*.
|
* *('-'? (DIGIT+ ('.' DIGIT+)? ('E' '-'? DIGIT+)? | 'Infinity')) | 'NaN'*.
|
||||||
*
|
*
|
||||||
* @property types The suitable types.
|
* @property types The suitable types.
|
||||||
|
* @author Iaroslav Postovalov
|
||||||
*/
|
*/
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
public class PrettyPrintFloats(public val types: Set<KClass<out Number>>) : RenderFeature {
|
public class PrettyPrintFloats(public val types: Set<KClass<out Number>>) : RenderFeature {
|
||||||
@ -113,6 +114,7 @@ public class PrettyPrintFloats(public val types: Set<KClass<out Number>>) : Rend
|
|||||||
* Special printing for numeric types which are printed in form of *'-'? DIGIT+*.
|
* Special printing for numeric types which are printed in form of *'-'? DIGIT+*.
|
||||||
*
|
*
|
||||||
* @property types The suitable types.
|
* @property types The suitable types.
|
||||||
|
* @author Iaroslav Postovalov
|
||||||
*/
|
*/
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
public class PrettyPrintIntegers(public val types: Set<KClass<out Number>>) : RenderFeature {
|
public class PrettyPrintIntegers(public val types: Set<KClass<out Number>>) : RenderFeature {
|
||||||
@ -135,6 +137,7 @@ public class PrettyPrintIntegers(public val types: Set<KClass<out Number>>) : Re
|
|||||||
* Special printing for symbols meaning Pi.
|
* Special printing for symbols meaning Pi.
|
||||||
*
|
*
|
||||||
* @property symbols The allowed symbols.
|
* @property symbols The allowed symbols.
|
||||||
|
* @author Iaroslav Postovalov
|
||||||
*/
|
*/
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
public class PrettyPrintPi(public val symbols: Set<String>) : RenderFeature {
|
public class PrettyPrintPi(public val symbols: Set<String>) : RenderFeature {
|
||||||
@ -157,6 +160,7 @@ public class PrettyPrintPi(public val symbols: Set<String>) : RenderFeature {
|
|||||||
* not [MST.Unary].
|
* not [MST.Unary].
|
||||||
*
|
*
|
||||||
* @param operations the allowed operations. If `null`, any operation is accepted.
|
* @param operations the allowed operations. If `null`, any operation is accepted.
|
||||||
|
* @author Iaroslav Postovalov
|
||||||
*/
|
*/
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
public abstract class Unary(public val operations: Collection<String>?) : RenderFeature {
|
public abstract class Unary(public val operations: Collection<String>?) : RenderFeature {
|
||||||
@ -177,6 +181,7 @@ public abstract class Unary(public val operations: Collection<String>?) : Render
|
|||||||
* not [MST.Binary].
|
* not [MST.Binary].
|
||||||
*
|
*
|
||||||
* @property operations the allowed operations. If `null`, any operation is accepted.
|
* @property operations the allowed operations. If `null`, any operation is accepted.
|
||||||
|
* @author Iaroslav Postovalov
|
||||||
*/
|
*/
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
public abstract class Binary(public val operations: Collection<String>?) : RenderFeature {
|
public abstract class Binary(public val operations: Collection<String>?) : RenderFeature {
|
||||||
@ -193,6 +198,8 @@ public abstract class Binary(public val operations: Collection<String>?) : Rende
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles binary nodes by producing [BinaryPlusSyntax].
|
* Handles binary nodes by producing [BinaryPlusSyntax].
|
||||||
|
*
|
||||||
|
* @author Iaroslav Postovalov
|
||||||
*/
|
*/
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
public class BinaryPlus(operations: Collection<String>?) : Binary(operations) {
|
public class BinaryPlus(operations: Collection<String>?) : Binary(operations) {
|
||||||
@ -213,6 +220,8 @@ public class BinaryPlus(operations: Collection<String>?) : Binary(operations) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles binary nodes by producing [BinaryMinusSyntax].
|
* Handles binary nodes by producing [BinaryMinusSyntax].
|
||||||
|
*
|
||||||
|
* @author Iaroslav Postovalov
|
||||||
*/
|
*/
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
public class BinaryMinus(operations: Collection<String>?) : Binary(operations) {
|
public class BinaryMinus(operations: Collection<String>?) : Binary(operations) {
|
||||||
@ -233,6 +242,8 @@ public class BinaryMinus(operations: Collection<String>?) : Binary(operations) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles unary nodes by producing [UnaryPlusSyntax].
|
* Handles unary nodes by producing [UnaryPlusSyntax].
|
||||||
|
*
|
||||||
|
* @author Iaroslav Postovalov
|
||||||
*/
|
*/
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
public class UnaryPlus(operations: Collection<String>?) : Unary(operations) {
|
public class UnaryPlus(operations: Collection<String>?) : Unary(operations) {
|
||||||
@ -251,6 +262,8 @@ public class UnaryPlus(operations: Collection<String>?) : Unary(operations) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles binary nodes by producing [UnaryMinusSyntax].
|
* Handles binary nodes by producing [UnaryMinusSyntax].
|
||||||
|
*
|
||||||
|
* @author Iaroslav Postovalov
|
||||||
*/
|
*/
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
public class UnaryMinus(operations: Collection<String>?) : Unary(operations) {
|
public class UnaryMinus(operations: Collection<String>?) : Unary(operations) {
|
||||||
@ -269,13 +282,16 @@ public class UnaryMinus(operations: Collection<String>?) : Unary(operations) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles binary nodes by producing [FractionSyntax].
|
* Handles binary nodes by producing [FractionSyntax].
|
||||||
|
*
|
||||||
|
* @author Iaroslav Postovalov
|
||||||
*/
|
*/
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
public class Fraction(operations: Collection<String>?) : Binary(operations) {
|
public class Fraction(operations: Collection<String>?) : Binary(operations) {
|
||||||
public override fun renderBinary(parent: FeaturedMathRenderer, node: MST.Binary): FractionSyntax = FractionSyntax(
|
public override fun renderBinary(parent: FeaturedMathRenderer, node: MST.Binary): FractionSyntax = FractionSyntax(
|
||||||
operation = node.operation,
|
operation = node.operation,
|
||||||
left = parent.render(node.left),
|
left = OperandSyntax(operand = parent.render(node.left), parentheses = true),
|
||||||
right = parent.render(node.right),
|
right = OperandSyntax(operand = parent.render(node.right), parentheses = true),
|
||||||
|
infix = true,
|
||||||
)
|
)
|
||||||
|
|
||||||
public companion object {
|
public companion object {
|
||||||
@ -288,6 +304,8 @@ public class Fraction(operations: Collection<String>?) : Binary(operations) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles binary nodes by producing [BinaryOperatorSyntax].
|
* Handles binary nodes by producing [BinaryOperatorSyntax].
|
||||||
|
*
|
||||||
|
* @author Iaroslav Postovalov
|
||||||
*/
|
*/
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
public class BinaryOperator(operations: Collection<String>?) : Binary(operations) {
|
public class BinaryOperator(operations: Collection<String>?) : Binary(operations) {
|
||||||
@ -309,6 +327,8 @@ public class BinaryOperator(operations: Collection<String>?) : Binary(operations
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles unary nodes by producing [UnaryOperatorSyntax].
|
* Handles unary nodes by producing [UnaryOperatorSyntax].
|
||||||
|
*
|
||||||
|
* @author Iaroslav Postovalov
|
||||||
*/
|
*/
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
public class UnaryOperator(operations: Collection<String>?) : Unary(operations) {
|
public class UnaryOperator(operations: Collection<String>?) : Unary(operations) {
|
||||||
@ -329,6 +349,8 @@ public class UnaryOperator(operations: Collection<String>?) : Unary(operations)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles binary nodes by producing [SuperscriptSyntax].
|
* Handles binary nodes by producing [SuperscriptSyntax].
|
||||||
|
*
|
||||||
|
* @author Iaroslav Postovalov
|
||||||
*/
|
*/
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
public class Power(operations: Collection<String>?) : Binary(operations) {
|
public class Power(operations: Collection<String>?) : Binary(operations) {
|
||||||
@ -365,6 +387,8 @@ public class SquareRoot(operations: Collection<String>?) : Unary(operations) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles unary nodes by producing [ExponentSyntax].
|
* Handles unary nodes by producing [ExponentSyntax].
|
||||||
|
*
|
||||||
|
* @author Iaroslav Postovalov
|
||||||
*/
|
*/
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
public class Exponent(operations: Collection<String>?) : Unary(operations) {
|
public class Exponent(operations: Collection<String>?) : Unary(operations) {
|
||||||
@ -384,6 +408,8 @@ public class Exponent(operations: Collection<String>?) : Unary(operations) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles binary nodes by producing [MultiplicationSyntax].
|
* Handles binary nodes by producing [MultiplicationSyntax].
|
||||||
|
*
|
||||||
|
* @author Iaroslav Postovalov
|
||||||
*/
|
*/
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
public class Multiplication(operations: Collection<String>?) : Binary(operations) {
|
public class Multiplication(operations: Collection<String>?) : Binary(operations) {
|
||||||
@ -404,36 +430,52 @@ public class Multiplication(operations: Collection<String>?) : Binary(operations
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles binary nodes by producing inverse [UnaryOperatorSyntax] (like *sin<sup>-1</sup>*) with removing the `a`
|
* Handles binary nodes by producing inverse [UnaryOperatorSyntax] with *arc* prefix instead of *a*.
|
||||||
* prefix of operation ID.
|
*
|
||||||
|
* @author Iaroslav Postovalov
|
||||||
*/
|
*/
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
public class InverseTrigonometricOperations(operations: Collection<String>?) : Unary(operations) {
|
public class InverseTrigonometricOperations(operations: Collection<String>?) : Unary(operations) {
|
||||||
public override fun renderUnary(parent: FeaturedMathRenderer, node: MST.Unary): UnaryOperatorSyntax =
|
public override fun renderUnary(parent: FeaturedMathRenderer, node: MST.Unary): UnaryOperatorSyntax =
|
||||||
UnaryOperatorSyntax(
|
UnaryOperatorSyntax(
|
||||||
operation = node.operation,
|
operation = node.operation,
|
||||||
prefix = SuperscriptSyntax(
|
prefix = OperatorNameSyntax(name = node.operation.replaceFirst("a", "arc")),
|
||||||
operation = PowerOperations.POW_OPERATION,
|
|
||||||
left = OperatorNameSyntax(name = node.operation.removePrefix("a")),
|
|
||||||
right = UnaryMinusSyntax(
|
|
||||||
operation = GroupOperations.MINUS_OPERATION,
|
|
||||||
operand = OperandSyntax(operand = NumberSyntax(string = "1"), parentheses = true),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
operand = OperandSyntax(operand = parent.render(node.value), parentheses = true),
|
operand = OperandSyntax(operand = parent.render(node.value), parentheses = true),
|
||||||
)
|
)
|
||||||
|
|
||||||
public companion object {
|
public companion object {
|
||||||
/**
|
/**
|
||||||
* The default instance configured with [TrigonometricOperations.ACOS_OPERATION],
|
* The default instance configured with [TrigonometricOperations.ACOS_OPERATION],
|
||||||
* [TrigonometricOperations.ASIN_OPERATION], [TrigonometricOperations.ATAN_OPERATION],
|
* [TrigonometricOperations.ASIN_OPERATION], [TrigonometricOperations.ATAN_OPERATION].
|
||||||
* [ExponentialOperations.ACOSH_OPERATION], [ExponentialOperations.ASINH_OPERATION], and
|
|
||||||
* [ExponentialOperations.ATANH_OPERATION].
|
|
||||||
*/
|
*/
|
||||||
public val Default: InverseTrigonometricOperations = InverseTrigonometricOperations(setOf(
|
public val Default: InverseTrigonometricOperations = InverseTrigonometricOperations(setOf(
|
||||||
TrigonometricOperations.ACOS_OPERATION,
|
TrigonometricOperations.ACOS_OPERATION,
|
||||||
TrigonometricOperations.ASIN_OPERATION,
|
TrigonometricOperations.ASIN_OPERATION,
|
||||||
TrigonometricOperations.ATAN_OPERATION,
|
TrigonometricOperations.ATAN_OPERATION,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles binary nodes by producing inverse [UnaryOperatorSyntax] with *ar* prefix instead of *a*.
|
||||||
|
*
|
||||||
|
* @author Iaroslav Postovalov
|
||||||
|
*/
|
||||||
|
@UnstableKMathAPI
|
||||||
|
public class InverseHyperbolicOperations(operations: Collection<String>?) : Unary(operations) {
|
||||||
|
public override fun renderUnary(parent: FeaturedMathRenderer, node: MST.Unary): UnaryOperatorSyntax =
|
||||||
|
UnaryOperatorSyntax(
|
||||||
|
operation = node.operation,
|
||||||
|
prefix = OperatorNameSyntax(name = node.operation.replaceFirst("a", "ar")),
|
||||||
|
operand = OperandSyntax(operand = parent.render(node.value), parentheses = true),
|
||||||
|
)
|
||||||
|
|
||||||
|
public companion object {
|
||||||
|
/**
|
||||||
|
* The default instance configured with [ExponentialOperations.ACOSH_OPERATION],
|
||||||
|
* [ExponentialOperations.ASINH_OPERATION], and [ExponentialOperations.ATANH_OPERATION].
|
||||||
|
*/
|
||||||
|
public val Default: InverseHyperbolicOperations = InverseHyperbolicOperations(setOf(
|
||||||
ExponentialOperations.ACOSH_OPERATION,
|
ExponentialOperations.ACOSH_OPERATION,
|
||||||
ExponentialOperations.ASINH_OPERATION,
|
ExponentialOperations.ASINH_OPERATION,
|
||||||
ExponentialOperations.ATANH_OPERATION,
|
ExponentialOperations.ATANH_OPERATION,
|
||||||
|
@ -83,6 +83,75 @@ public object BetterMultiplication : FeaturedMathRendererWithPostProcess.PostPro
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Chooses [FractionSyntax.infix] depending on the context.
|
||||||
|
*
|
||||||
|
* @author Iaroslav Postovalov
|
||||||
|
*/
|
||||||
|
@UnstableKMathAPI
|
||||||
|
public object BetterFraction : FeaturedMathRendererWithPostProcess.PostProcessStage {
|
||||||
|
private fun perform0(node: MathSyntax, infix: Boolean = false): Unit = when (node) {
|
||||||
|
is NumberSyntax -> Unit
|
||||||
|
is SymbolSyntax -> Unit
|
||||||
|
is OperatorNameSyntax -> Unit
|
||||||
|
is SpecialSymbolSyntax -> Unit
|
||||||
|
is OperandSyntax -> perform0(node.operand, infix)
|
||||||
|
|
||||||
|
is UnaryOperatorSyntax -> {
|
||||||
|
perform0(node.prefix, infix)
|
||||||
|
perform0(node.operand, infix)
|
||||||
|
}
|
||||||
|
|
||||||
|
is UnaryPlusSyntax -> perform0(node.operand, infix)
|
||||||
|
is UnaryMinusSyntax -> perform0(node.operand, infix)
|
||||||
|
is RadicalSyntax -> perform0(node.operand, infix)
|
||||||
|
is ExponentSyntax -> perform0(node.operand, infix)
|
||||||
|
|
||||||
|
is SuperscriptSyntax -> {
|
||||||
|
perform0(node.left, true)
|
||||||
|
perform0(node.right, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
is SubscriptSyntax -> {
|
||||||
|
perform0(node.left, true)
|
||||||
|
perform0(node.right, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
is BinaryOperatorSyntax -> {
|
||||||
|
perform0(node.prefix, infix)
|
||||||
|
perform0(node.left, infix)
|
||||||
|
perform0(node.right, infix)
|
||||||
|
}
|
||||||
|
|
||||||
|
is BinaryPlusSyntax -> {
|
||||||
|
perform0(node.left, infix)
|
||||||
|
perform0(node.right, infix)
|
||||||
|
}
|
||||||
|
|
||||||
|
is BinaryMinusSyntax -> {
|
||||||
|
perform0(node.left, infix)
|
||||||
|
perform0(node.right, infix)
|
||||||
|
}
|
||||||
|
|
||||||
|
is FractionSyntax -> {
|
||||||
|
node.infix = infix
|
||||||
|
perform0(node.left, infix)
|
||||||
|
perform0(node.right, infix)
|
||||||
|
}
|
||||||
|
|
||||||
|
is RadicalWithIndexSyntax -> {
|
||||||
|
perform0(node.left, true)
|
||||||
|
perform0(node.right, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
is MultiplicationSyntax -> {
|
||||||
|
perform0(node.left, infix)
|
||||||
|
perform0(node.right, infix)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override fun perform(node: MathSyntax): Unit = perform0(node)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Applies [ExponentSyntax.useOperatorForm] to [ExponentSyntax] when the operand contains a fraction, a
|
* Applies [ExponentSyntax.useOperatorForm] to [ExponentSyntax] when the operand contains a fraction, a
|
||||||
@ -102,7 +171,7 @@ public object BetterExponent : FeaturedMathRendererWithPostProcess.PostProcessSt
|
|||||||
is UnaryOperatorSyntax -> perform0(node.prefix) || perform0(node.operand)
|
is UnaryOperatorSyntax -> perform0(node.prefix) || perform0(node.operand)
|
||||||
is UnaryPlusSyntax -> perform0(node.operand)
|
is UnaryPlusSyntax -> perform0(node.operand)
|
||||||
is UnaryMinusSyntax -> perform0(node.operand)
|
is UnaryMinusSyntax -> perform0(node.operand)
|
||||||
is RadicalSyntax -> perform0(node.operand)
|
is RadicalSyntax -> true
|
||||||
|
|
||||||
is ExponentSyntax -> {
|
is ExponentSyntax -> {
|
||||||
val r = perform0(node.operand)
|
val r = perform0(node.operand)
|
||||||
@ -116,7 +185,7 @@ public object BetterExponent : FeaturedMathRendererWithPostProcess.PostProcessSt
|
|||||||
is BinaryPlusSyntax -> perform0(node.left) || perform0(node.right)
|
is BinaryPlusSyntax -> perform0(node.left) || perform0(node.right)
|
||||||
is BinaryMinusSyntax -> perform0(node.left) || perform0(node.right)
|
is BinaryMinusSyntax -> perform0(node.left) || perform0(node.right)
|
||||||
is FractionSyntax -> true
|
is FractionSyntax -> true
|
||||||
is RadicalWithIndexSyntax -> perform0(node.left) || perform0(node.right)
|
is RadicalWithIndexSyntax -> true
|
||||||
is MultiplicationSyntax -> perform0(node.left) || perform0(node.right)
|
is MultiplicationSyntax -> perform0(node.left) || perform0(node.right)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -163,8 +232,11 @@ public class SimplifyParentheses(public val precedenceFunction: (MathSyntax) ->
|
|||||||
val isInsideExpOperator =
|
val isInsideExpOperator =
|
||||||
node.parent is ExponentSyntax && (node.parent as ExponentSyntax).useOperatorForm
|
node.parent is ExponentSyntax && (node.parent as ExponentSyntax).useOperatorForm
|
||||||
|
|
||||||
|
val isOnOrUnderNormalFraction = node.parent is FractionSyntax && !((node.parent as FractionSyntax).infix)
|
||||||
|
|
||||||
node.parentheses = !isRightOfSuperscript
|
node.parentheses = !isRightOfSuperscript
|
||||||
&& (needParenthesesByPrecedence || node.parent is UnaryOperatorSyntax || isInsideExpOperator)
|
&& (needParenthesesByPrecedence || node.parent is UnaryOperatorSyntax || isInsideExpOperator)
|
||||||
|
&& !isOnOrUnderNormalFraction
|
||||||
|
|
||||||
perform(node.operand)
|
perform(node.operand)
|
||||||
}
|
}
|
||||||
|
@ -99,13 +99,17 @@ internal class TestFeatures {
|
|||||||
fun multiplication() = testLatex("x*1", "x\\times1")
|
fun multiplication() = testLatex("x*1", "x\\times1")
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun inverseTrigonometry() {
|
fun inverseTrigonometric() {
|
||||||
testLatex("asin(x)", "\\operatorname{sin}^{-1}\\,\\left(x\\right)")
|
testLatex("asin(x)", "\\operatorname{arcsin}\\,\\left(x\\right)")
|
||||||
testLatex("asinh(x)", "\\operatorname{sinh}^{-1}\\,\\left(x\\right)")
|
testLatex("acos(x)", "\\operatorname{arccos}\\,\\left(x\\right)")
|
||||||
testLatex("acos(x)", "\\operatorname{cos}^{-1}\\,\\left(x\\right)")
|
testLatex("atan(x)", "\\operatorname{arctan}\\,\\left(x\\right)")
|
||||||
testLatex("acosh(x)", "\\operatorname{cosh}^{-1}\\,\\left(x\\right)")
|
}
|
||||||
testLatex("atan(x)", "\\operatorname{tan}^{-1}\\,\\left(x\\right)")
|
|
||||||
testLatex("atanh(x)", "\\operatorname{tanh}^{-1}\\,\\left(x\\right)")
|
@Test
|
||||||
|
fun inverseHyperbolic() {
|
||||||
|
testLatex("asinh(x)", "\\operatorname{arsinh}\\,\\left(x\\right)")
|
||||||
|
testLatex("acosh(x)", "\\operatorname{arcosh}\\,\\left(x\\right)")
|
||||||
|
testLatex("atanh(x)", "\\operatorname{artanh}\\,\\left(x\\right)")
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Test
|
// @Test
|
||||||
|
@ -37,4 +37,10 @@ internal class TestStages {
|
|||||||
testLatex("exp(x/2)", "\\operatorname{exp}\\,\\left(\\frac{x}{2}\\right)")
|
testLatex("exp(x/2)", "\\operatorname{exp}\\,\\left(\\frac{x}{2}\\right)")
|
||||||
testLatex("exp(x^2)", "\\operatorname{exp}\\,\\left(x^{2}\\right)")
|
testLatex("exp(x^2)", "\\operatorname{exp}\\,\\left(x^{2}\\right)")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun fraction() {
|
||||||
|
testLatex("x/y", "\\frac{x}{y}")
|
||||||
|
testLatex("x^(x/y)", "x^{x/y}")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ The Maven coordinates of this project are `space.kscience:kmath-for-real:0.3.0-d
|
|||||||
```gradle
|
```gradle
|
||||||
repositories {
|
repositories {
|
||||||
maven { url 'https://repo.kotlin.link' }
|
maven { url 'https://repo.kotlin.link' }
|
||||||
maven { url "https://dl.bintray.com/kotlin/kotlin-eap" } // include for builds based on kotlin-eap
|
mavenCentral()
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
@ -26,7 +26,7 @@ dependencies {
|
|||||||
```kotlin
|
```kotlin
|
||||||
repositories {
|
repositories {
|
||||||
maven("https://repo.kotlin.link")
|
maven("https://repo.kotlin.link")
|
||||||
maven("https://dl.bintray.com/kotlin/kotlin-eap") // include for builds based on kotlin-eap
|
mavenCentral()
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
@ -17,7 +17,7 @@ The Maven coordinates of this project are `space.kscience:kmath-functions:0.3.0-
|
|||||||
```gradle
|
```gradle
|
||||||
repositories {
|
repositories {
|
||||||
maven { url 'https://repo.kotlin.link' }
|
maven { url 'https://repo.kotlin.link' }
|
||||||
maven { url "https://dl.bintray.com/kotlin/kotlin-eap" } // include for builds based on kotlin-eap
|
mavenCentral()
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
@ -28,7 +28,7 @@ dependencies {
|
|||||||
```kotlin
|
```kotlin
|
||||||
repositories {
|
repositories {
|
||||||
maven("https://repo.kotlin.link")
|
maven("https://repo.kotlin.link")
|
||||||
maven("https://dl.bintray.com/kotlin/kotlin-eap") // include for builds based on kotlin-eap
|
mavenCentral()
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
Loading…
Reference in New Issue
Block a user