diff --git a/README.md b/README.md
index 773eb6398..97ce164e1 100644
--- a/README.md
+++ b/README.md
@@ -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.
@@ -200,6 +200,12 @@ One can still use generic algebras though.
> **Maturity**: PROTOTYPE
+* ### [kmath-jupyter](kmath-jupyter)
+>
+>
+> **Maturity**: PROTOTYPE
+
+
* ### [kmath-kotlingrad](kmath-kotlingrad)
>
>
diff --git a/kmath-ast/README.md b/kmath-ast/README.md
index 4de165e72..26ee98ba5 100644
--- a/kmath-ast/README.md
+++ b/kmath-ast/README.md
@@ -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
@@ -39,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` with implemented `invoke` function.
+`kmath-ast` JVM module supports runtime code generation to eliminate overhead of tree traversal. Code generator builds a
+special implementation of `Expression` with implemented `invoke` function.
For example, the following builder:
```kotlin
+import space.kscience.kmath.expressions.*
+import space.kscience.kmath.operations.*
+import space.kscience.kmath.asm.*
+
MstField { bindSymbol("x") + 2 }.compileToExpression(DoubleField)
```
@@ -54,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;
@@ -63,7 +68,7 @@ public final class AsmCompiledExpression_45045_0 implements Expression {
private final Object[] constants;
public final Double invoke(Map arguments) {
- return (Double)((Function2)this.constants[0]).invoke((Double)MapIntrinsics.getOrFail(arguments, "x"), 2);
+ return (Double) ((Function2) this.constants[0]).invoke((Double) MapIntrinsics.getOrFail(arguments, "x"), 2);
}
public AsmCompiledExpression_45045_0(Object[] constants) {
@@ -75,8 +80,8 @@ public final class AsmCompiledExpression_45045_0 implements Expression {
#### 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
@@ -84,6 +89,10 @@ public final class AsmCompiledExpression_45045_0 implements Expression {
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)
```
@@ -91,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)
@@ -128,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)
@@ -144,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):
+
+
```html
-ex-sin-12x2×1010+x3-12
+
```
+
+
It is also possible to create custom algorithms of render, and even add support of other markup languages
(see API reference).
diff --git a/kmath-ast/docs/README-TEMPLATE.md b/kmath-ast/docs/README-TEMPLATE.md
index 1ecf477ef..80ea31642 100644
--- a/kmath-ast/docs/README-TEMPLATE.md
+++ b/kmath-ast/docs/README-TEMPLATE.md
@@ -1,6 +1,6 @@
# Module kmath-ast
-Abstract syntax tree expression representation and related optimizations.
+Performance and visualization extensions to MST API.
${features}
@@ -10,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` with implemented `invoke` function.
+`kmath-ast` JVM module supports runtime code generation to eliminate overhead of tree traversal. Code generator builds a
+special implementation of `Expression` with implemented `invoke` function.
For example, the following builder:
```kotlin
+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 {
private final Object[] constants;
public final Double invoke(Map arguments) {
- return (Double)((Function2)this.constants[0]).invoke((Double)MapIntrinsics.getOrFail(arguments, "x"), 2);
+ return (Double) ((Function2) this.constants[0]).invoke((Double) MapIntrinsics.getOrFail(arguments, "x"), 2);
}
public AsmCompiledExpression_45045_0(Object[] constants) {
@@ -46,8 +51,8 @@ public final class AsmCompiledExpression_45045_0 implements Expression {
#### 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 {
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):
+
+
```html
-ex-sin-12x2×1010+x3-12
+
```
+
+
It is also possible to create custom algorithms of render, and even add support of other markup languages
(see API reference).
diff --git a/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/LatexSyntaxRenderer.kt b/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/LatexSyntaxRenderer.kt
index 5909f1f9d..01717b0f9 100644
--- a/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/LatexSyntaxRenderer.kt
+++ b/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/LatexSyntaxRenderer.kt
@@ -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("}{")
diff --git a/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/MathMLSyntaxRenderer.kt b/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/MathMLSyntaxRenderer.kt
index 5b44e660d..cda8e2322 100644
--- a/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/MathMLSyntaxRenderer.kt
+++ b/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/MathMLSyntaxRenderer.kt
@@ -133,14 +133,13 @@ public object MathMLSyntaxRenderer : SyntaxRenderer {
render(node.right)
}
- is FractionSyntax -> tag("mfrac") {
- tag("mrow") {
- render(node.left)
- }
-
- tag("mrow") {
- render(node.right)
- }
+ is FractionSyntax -> if (node.infix) {
+ render(node.left)
+ tag("mo") { append('/') }
+ render(node.right)
+ } else tag("mfrac") {
+ tag("mrow") { render(node.left) }
+ tag("mrow") { render(node.right) }
}
is RadicalWithIndexSyntax -> tag("mroot") {
diff --git a/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/MathRenderer.kt b/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/MathRenderer.kt
index 6b22ac519..c33f95483 100644
--- a/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/MathRenderer.kt
+++ b/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/MathRenderer.kt
@@ -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,
),
diff --git a/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/MathSyntax.kt b/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/MathSyntax.kt
index 3c023e342..a71985fbc 100644
--- a/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/MathSyntax.kt
+++ b/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/MathSyntax.kt
@@ -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., *∞*).
*
* @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 (*√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 (*x2*).
*
* @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 (*xi*).
*
* @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 (*½*) 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 (*3√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×2).
+ * Represents binary, infix multiplication in the form of coefficient (*2 x*) or with operator (*x × 2*).
*
* @property left The multiplicand.
* @property right The multiplier.
- * @property times whether the times (×) symbol should be used.
+ * @property times Whether the times (×) symbol should be used.
* @author Iaroslav Postovalov
*/
@UnstableKMathAPI
diff --git a/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/features.kt b/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/features.kt
index c1b513345..ac716f9ff 100644
--- a/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/features.kt
+++ b/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/features.kt
@@ -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>) : RenderFeature {
@@ -113,6 +114,7 @@ public class PrettyPrintFloats(public val types: Set>) : Rend
* Special printing for numeric types which are printed in form of *'-'? DIGIT+*.
*
* @property types The suitable types.
+ * @author Iaroslav Postovalov
*/
@UnstableKMathAPI
public class PrettyPrintIntegers(public val types: Set>) : RenderFeature {
@@ -135,6 +137,7 @@ public class PrettyPrintIntegers(public val types: Set>) : Re
* Special printing for symbols meaning Pi.
*
* @property symbols The allowed symbols.
+ * @author Iaroslav Postovalov
*/
@UnstableKMathAPI
public class PrettyPrintPi(public val symbols: Set) : RenderFeature {
@@ -157,6 +160,7 @@ public class PrettyPrintPi(public val symbols: Set) : RenderFeature {
* not [MST.Unary].
*
* @param operations the allowed operations. If `null`, any operation is accepted.
+ * @author Iaroslav Postovalov
*/
@UnstableKMathAPI
public abstract class Unary(public val operations: Collection?) : RenderFeature {
@@ -177,6 +181,7 @@ public abstract class Unary(public val operations: Collection?) : Render
* not [MST.Binary].
*
* @property operations the allowed operations. If `null`, any operation is accepted.
+ * @author Iaroslav Postovalov
*/
@UnstableKMathAPI
public abstract class Binary(public val operations: Collection?) : RenderFeature {
@@ -193,6 +198,8 @@ public abstract class Binary(public val operations: Collection?) : Rende
/**
* Handles binary nodes by producing [BinaryPlusSyntax].
+ *
+ * @author Iaroslav Postovalov
*/
@UnstableKMathAPI
public class BinaryPlus(operations: Collection?) : Binary(operations) {
@@ -213,6 +220,8 @@ public class BinaryPlus(operations: Collection?) : Binary(operations) {
/**
* Handles binary nodes by producing [BinaryMinusSyntax].
+ *
+ * @author Iaroslav Postovalov
*/
@UnstableKMathAPI
public class BinaryMinus(operations: Collection?) : Binary(operations) {
@@ -233,6 +242,8 @@ public class BinaryMinus(operations: Collection?) : Binary(operations) {
/**
* Handles unary nodes by producing [UnaryPlusSyntax].
+ *
+ * @author Iaroslav Postovalov
*/
@UnstableKMathAPI
public class UnaryPlus(operations: Collection?) : Unary(operations) {
@@ -251,6 +262,8 @@ public class UnaryPlus(operations: Collection?) : Unary(operations) {
/**
* Handles binary nodes by producing [UnaryMinusSyntax].
+ *
+ * @author Iaroslav Postovalov
*/
@UnstableKMathAPI
public class UnaryMinus(operations: Collection?) : Unary(operations) {
@@ -269,13 +282,16 @@ public class UnaryMinus(operations: Collection?) : Unary(operations) {
/**
* Handles binary nodes by producing [FractionSyntax].
+ *
+ * @author Iaroslav Postovalov
*/
@UnstableKMathAPI
public class Fraction(operations: Collection?) : 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?) : Binary(operations) {
/**
* Handles binary nodes by producing [BinaryOperatorSyntax].
+ *
+ * @author Iaroslav Postovalov
*/
@UnstableKMathAPI
public class BinaryOperator(operations: Collection?) : Binary(operations) {
@@ -309,6 +327,8 @@ public class BinaryOperator(operations: Collection?) : Binary(operations
/**
* Handles unary nodes by producing [UnaryOperatorSyntax].
+ *
+ * @author Iaroslav Postovalov
*/
@UnstableKMathAPI
public class UnaryOperator(operations: Collection?) : Unary(operations) {
@@ -329,6 +349,8 @@ public class UnaryOperator(operations: Collection?) : Unary(operations)
/**
* Handles binary nodes by producing [SuperscriptSyntax].
+ *
+ * @author Iaroslav Postovalov
*/
@UnstableKMathAPI
public class Power(operations: Collection?) : Binary(operations) {
@@ -365,6 +387,8 @@ public class SquareRoot(operations: Collection?) : Unary(operations) {
/**
* Handles unary nodes by producing [ExponentSyntax].
+ *
+ * @author Iaroslav Postovalov
*/
@UnstableKMathAPI
public class Exponent(operations: Collection?) : Unary(operations) {
@@ -384,6 +408,8 @@ public class Exponent(operations: Collection?) : Unary(operations) {
/**
* Handles binary nodes by producing [MultiplicationSyntax].
+ *
+ * @author Iaroslav Postovalov
*/
@UnstableKMathAPI
public class Multiplication(operations: Collection?) : Binary(operations) {
@@ -404,36 +430,52 @@ public class Multiplication(operations: Collection?) : Binary(operations
}
/**
- * Handles binary nodes by producing inverse [UnaryOperatorSyntax] (like *sin-1*) 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?) : 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?) : Unary(operations) {
+ public override fun renderUnary(parent: FeaturedMathRenderer, node: MST.Unary): UnaryOperatorSyntax =
+ UnaryOperatorSyntax(
+ operation = node.operation,
+ prefix = OperatorNameSyntax(name = node.operation.replaceFirst("a", "ar")),
+ operand = OperandSyntax(operand = parent.render(node.value), parentheses = true),
+ )
+
+ public companion object {
+ /**
+ * The default instance configured with [ExponentialOperations.ACOSH_OPERATION],
+ * [ExponentialOperations.ASINH_OPERATION], and [ExponentialOperations.ATANH_OPERATION].
+ */
+ public val Default: InverseHyperbolicOperations = InverseHyperbolicOperations(setOf(
ExponentialOperations.ACOSH_OPERATION,
ExponentialOperations.ASINH_OPERATION,
ExponentialOperations.ATANH_OPERATION,
diff --git a/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/stages.kt b/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/stages.kt
index 7eb75b9ff..1f31af853 100644
--- a/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/stages.kt
+++ b/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/stages.kt
@@ -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)
}
diff --git a/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/rendering/TestFeatures.kt b/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/rendering/TestFeatures.kt
index 1ab20ed85..a40c785b9 100644
--- a/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/rendering/TestFeatures.kt
+++ b/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/rendering/TestFeatures.kt
@@ -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
diff --git a/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/rendering/TestStages.kt b/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/rendering/TestStages.kt
index 599e43eb2..09ec127c7 100644
--- a/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/rendering/TestStages.kt
+++ b/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/rendering/TestStages.kt
@@ -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}")
+ }
}
diff --git a/kmath-for-real/README.md b/kmath-for-real/README.md
index 46bf657c3..a77f9d98b 100644
--- a/kmath-for-real/README.md
+++ b/kmath-for-real/README.md
@@ -15,7 +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/kotlin/kotlin-eap" } // include for builds based on kotlin-eap
+ mavenCentral()
}
dependencies {
@@ -26,7 +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
+ mavenCentral()
}
dependencies {
diff --git a/kmath-functions/README.md b/kmath-functions/README.md
index c7c30f1a1..2090ede3e 100644
--- a/kmath-functions/README.md
+++ b/kmath-functions/README.md
@@ -17,7 +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/kotlin/kotlin-eap" } // include for builds based on kotlin-eap
+ mavenCentral()
}
dependencies {
@@ -28,7 +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
+ mavenCentral()
}
dependencies {