diff --git a/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/LatexSyntaxRenderer.kt b/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/LatexSyntaxRenderer.kt
index 34230f3c8..1c82bd6e7 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
@@ -71,6 +71,15 @@ public object LatexSyntaxRenderer : SyntaxRenderer {
append('}')
}
+ is ExponentSyntax -> if (node.useOperatorForm) {
+ append("\\operatorname{exp}\\,")
+ render(node.operand)
+ } else {
+ append("e^{")
+ render(node.operand)
+ append('}')
+ }
+
is SuperscriptSyntax -> {
render(node.left)
append("^{")
diff --git a/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/MathMLSyntaxRenderer.kt b/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/MathMLSyntaxRenderer.kt
index f7487a356..decd4ba46 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
@@ -82,6 +82,19 @@ public object MathMLSyntaxRenderer : SyntaxRenderer {
is RadicalSyntax -> tag("msqrt") { render(node.operand) }
+ is ExponentSyntax -> if (node.useOperatorForm) {
+ tag("mo") { append("exp") }
+ tag("mspace", "width" to "0.167em")
+ render(node.operand)
+ } else {
+ tag("msup") {
+ tag("mrow") {
+ tag("mi") { append("e") }
+ }
+ tag("mrow") { render(node.operand) }
+ }
+ }
+
is SuperscriptSyntax -> tag("msup") {
tag("mrow") { render(node.left) }
tag("mrow") { render(node.right) }
diff --git a/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/MathRenderer.kt b/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/MathRenderer.kt
index 891e8f05b..9df2c54dd 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
@@ -83,7 +83,7 @@ public open class FeaturedMathRendererWithPostProcess(
Fraction.Default,
Power.Default,
SquareRoot.Default,
- Exponential.Default,
+ Exponent.Default,
InverseTrigonometricOperations.Default,
// Fallback option for unknown operations - printing them as operator
@@ -100,6 +100,7 @@ public open class FeaturedMathRendererWithPostProcess(
PrintSymbolic,
),
listOf(
+ BetterExponent,
SimplifyParentheses.Default,
BetterMultiplication,
),
diff --git a/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/MathSyntax.kt b/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/MathSyntax.kt
index 069e56c71..6a46bf535 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
@@ -189,6 +189,24 @@ public data class RadicalSyntax(
}
}
+/**
+ * Represents exponential function.
+ *
+ * @property operand The argument of function.
+ * @property useOperatorForm `true` if operator form is used (*exp (x)*), `false` if exponentiation form is used
+ * (*ex*).
+ * @author Iaroslav Postovalov
+ */
+public data class ExponentSyntax(
+ public override val operation: String,
+ public override val operand: OperandSyntax,
+ public var useOperatorForm: Boolean,
+) : UnarySyntax() {
+ init {
+ operand.parent = this
+ }
+}
+
/**
* Represents a syntax node with superscript (usually, for exponentiation).
*
diff --git a/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/features.kt b/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/features.kt
index 5d6c7bb0a..c09282bb6 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
@@ -56,10 +56,14 @@ private fun printSignedNumberString(s: String): MathSyntax {
public class PrettyPrintFloats(public val types: Set>) : RenderFeature {
public override fun render(renderer: FeaturedMathRenderer, node: MST): MathSyntax? {
if (node !is MST.Numeric || node.value::class !in types) return null
- val toString = node.value.toString().removeSuffix(".0")
+ val toString = when (val v = node.value) {
+ is Float -> v.multiplatformToString()
+ is Double -> v.multiplatformToString()
+ else -> v.toString()
+ }.removeSuffix(".0")
- if ('E' in toString) {
- val (beforeE, afterE) = toString.split('E')
+ if (toString.contains('E', ignoreCase = true)) {
+ val (beforeE, afterE) = toString.split('E', ignoreCase = true)
val significand = beforeE.toDouble().toString().removeSuffix(".0")
val exponent = afterE.toDouble().toString().removeSuffix(".0")
@@ -108,9 +112,7 @@ public class PrettyPrintFloats(public val types: Set>) : Rend
*/
public class PrettyPrintIntegers(public val types: Set>) : RenderFeature {
public override fun render(renderer: FeaturedMathRenderer, node: MST): MathSyntax? {
- if (node !is MST.Numeric || node.value::class !in types)
- return null
-
+ if (node !is MST.Numeric || node.value::class !in types) return null
return printSignedNumberString(node.value.toString())
}
@@ -282,15 +284,15 @@ public class SquareRoot(operations: Collection?) : Unary(operations) {
}
}
-public class Exponential(operations: Collection?) : Unary(operations) {
- public override fun render0(parent: FeaturedMathRenderer, node: MST.Unary): MathSyntax = SuperscriptSyntax(
+public class Exponent(operations: Collection?) : Unary(operations) {
+ public override fun render0(parent: FeaturedMathRenderer, node: MST.Unary): MathSyntax = ExponentSyntax(
operation = node.operation,
- left = SymbolSyntax(string = "e"),
- right = parent.render(node.value),
+ operand = OperandSyntax(operand = parent.render(node.value), parentheses = true),
+ useOperatorForm = true,
)
public companion object {
- public val Default: Exponential = Exponential(setOf(ExponentialOperations.EXP_OPERATION))
+ public val Default: Exponent = Exponent(setOf(ExponentialOperations.EXP_OPERATION))
}
}
diff --git a/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/multiplatformToString.kt b/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/multiplatformToString.kt
new file mode 100644
index 000000000..291399cee
--- /dev/null
+++ b/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/multiplatformToString.kt
@@ -0,0 +1,9 @@
+/*
+ * Copyright 2018-2021 KMath contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package space.kscience.kmath.ast.rendering
+
+internal expect fun Double.multiplatformToString(): String
+internal expect fun Float.multiplatformToString(): String
diff --git a/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/stages.kt b/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/stages.kt
index 0ebb41b28..a08f089f1 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
@@ -16,69 +16,110 @@ import space.kscience.kmath.operations.RingOperations
* @author Iaroslav Postovalov
*/
public object BetterMultiplication : FeaturedMathRendererWithPostProcess.PostProcessStage {
- public override fun perform(node: MathSyntax) {
- when (node) {
- is NumberSyntax -> Unit
- is SymbolSyntax -> Unit
- is OperatorNameSyntax -> Unit
- is SpecialSymbolSyntax -> Unit
- is OperandSyntax -> perform(node.operand)
+ public override fun perform(node: MathSyntax): Unit = when (node) {
+ is NumberSyntax -> Unit
+ is SymbolSyntax -> Unit
+ is OperatorNameSyntax -> Unit
+ is SpecialSymbolSyntax -> Unit
+ is OperandSyntax -> perform(node.operand)
- is UnaryOperatorSyntax -> {
- perform(node.prefix)
- perform(node.operand)
- }
-
- is UnaryPlusSyntax -> perform(node.operand)
- is UnaryMinusSyntax -> perform(node.operand)
- is RadicalSyntax -> perform(node.operand)
-
- is SuperscriptSyntax -> {
- perform(node.left)
- perform(node.right)
- }
-
- is SubscriptSyntax -> {
- perform(node.left)
- perform(node.right)
- }
-
- is BinaryOperatorSyntax -> {
- perform(node.prefix)
- perform(node.left)
- perform(node.right)
- }
-
- is BinaryPlusSyntax -> {
- perform(node.left)
- perform(node.right)
- }
-
- is BinaryMinusSyntax -> {
- perform(node.left)
- perform(node.right)
- }
-
- is FractionSyntax -> {
- perform(node.left)
- perform(node.right)
- }
-
- is RadicalWithIndexSyntax -> {
- perform(node.left)
- perform(node.right)
- }
-
- is MultiplicationSyntax -> {
- node.times = node.right.operand is NumberSyntax && !node.right.parentheses
- || node.left.operand is NumberSyntax && node.right.operand is FractionSyntax
- || node.left.operand is NumberSyntax && node.right.operand is NumberSyntax
- || node.left.operand is NumberSyntax && node.right.operand is SuperscriptSyntax && node.right.operand.left is NumberSyntax
-
- perform(node.left)
- perform(node.right)
- }
+ is UnaryOperatorSyntax -> {
+ perform(node.prefix)
+ perform(node.operand)
}
+
+ is UnaryPlusSyntax -> perform(node.operand)
+ is UnaryMinusSyntax -> perform(node.operand)
+ is RadicalSyntax -> perform(node.operand)
+ is ExponentSyntax -> perform(node.operand)
+
+ is SuperscriptSyntax -> {
+ perform(node.left)
+ perform(node.right)
+ }
+
+ is SubscriptSyntax -> {
+ perform(node.left)
+ perform(node.right)
+ }
+
+ is BinaryOperatorSyntax -> {
+ perform(node.prefix)
+ perform(node.left)
+ perform(node.right)
+ }
+
+ is BinaryPlusSyntax -> {
+ perform(node.left)
+ perform(node.right)
+ }
+
+ is BinaryMinusSyntax -> {
+ perform(node.left)
+ perform(node.right)
+ }
+
+ is FractionSyntax -> {
+ perform(node.left)
+ perform(node.right)
+ }
+
+ is RadicalWithIndexSyntax -> {
+ perform(node.left)
+ perform(node.right)
+ }
+
+ is MultiplicationSyntax -> {
+ node.times = node.right.operand is NumberSyntax && !node.right.parentheses
+ || node.left.operand is NumberSyntax && node.right.operand is FractionSyntax
+ || node.left.operand is NumberSyntax && node.right.operand is NumberSyntax
+ || node.left.operand is NumberSyntax && node.right.operand is SuperscriptSyntax && node.right.operand.left is NumberSyntax
+
+ perform(node.left)
+ perform(node.right)
+ }
+ }
+}
+
+
+/**
+ * Applies [ExponentSyntax.useOperatorForm] to [ExponentSyntax] when the operand contains a fraction, a
+ * superscript or a subscript to improve readability.
+ *
+ * @author Iaroslav Postovalov
+ */
+public object BetterExponent : FeaturedMathRendererWithPostProcess.PostProcessStage {
+ private fun perform0(node: MathSyntax): Boolean {
+ return when (node) {
+ is NumberSyntax -> false
+ is SymbolSyntax -> false
+ is OperatorNameSyntax -> false
+ is SpecialSymbolSyntax -> false
+ is OperandSyntax -> perform0(node.operand)
+ is UnaryOperatorSyntax -> perform0(node.prefix) || perform0(node.operand)
+ is UnaryPlusSyntax -> perform0(node.operand)
+ is UnaryMinusSyntax -> perform0(node.operand)
+ is RadicalSyntax -> perform0(node.operand)
+
+ is ExponentSyntax -> {
+ val r = perform0(node.operand)
+ node.useOperatorForm = r
+ r
+ }
+
+ is SuperscriptSyntax -> true
+ is SubscriptSyntax -> true
+ is BinaryOperatorSyntax -> perform0(node.prefix) || perform0(node.left) || perform0(node.right)
+ is BinaryPlusSyntax -> perform0(node.left) || perform0(node.right)
+ is BinaryMinusSyntax -> perform0(node.left) || perform0(node.right)
+ is FractionSyntax -> true
+ is RadicalWithIndexSyntax -> perform0(node.left) || perform0(node.right)
+ is MultiplicationSyntax -> perform0(node.left) || perform0(node.right)
+ }
+ }
+
+ public override fun perform(node: MathSyntax) {
+ perform0(node)
}
}
@@ -90,89 +131,89 @@ public object BetterMultiplication : FeaturedMathRendererWithPostProcess.PostPro
*/
public class SimplifyParentheses(public val precedenceFunction: (MathSyntax) -> Int) :
FeaturedMathRendererWithPostProcess.PostProcessStage {
- public override fun perform(node: MathSyntax) {
- when (node) {
- is NumberSyntax -> Unit
- is SymbolSyntax -> Unit
- is OperatorNameSyntax -> Unit
- is SpecialSymbolSyntax -> Unit
+ public override fun perform(node: MathSyntax): Unit = when (node) {
+ is NumberSyntax -> Unit
+ is SymbolSyntax -> Unit
+ is OperatorNameSyntax -> Unit
+ is SpecialSymbolSyntax -> Unit
- is OperandSyntax -> {
- val isRightOfSuperscript =
- (node.parent is SuperscriptSyntax) && (node.parent as SuperscriptSyntax).right === node
+ is OperandSyntax -> {
+ val isRightOfSuperscript =
+ (node.parent is SuperscriptSyntax) && (node.parent as SuperscriptSyntax).right === node
- val precedence = precedenceFunction(node.operand)
+ val precedence = precedenceFunction(node.operand)
- val needParenthesesByPrecedence = when (val parent = node.parent) {
- null -> false
+ val needParenthesesByPrecedence = when (val parent = node.parent) {
+ null -> false
- is BinarySyntax -> {
- val parentPrecedence = precedenceFunction(parent)
+ is BinarySyntax -> {
+ val parentPrecedence = precedenceFunction(parent)
- parentPrecedence < precedence ||
- parentPrecedence == precedence && parentPrecedence != 0 && node === parent.right
- }
-
- else -> precedence > precedenceFunction(parent)
+ parentPrecedence < precedence ||
+ parentPrecedence == precedence && parentPrecedence != 0 && node === parent.right
}
- node.parentheses = !isRightOfSuperscript
- && (needParenthesesByPrecedence || node.parent is UnaryOperatorSyntax)
-
- perform(node.operand)
+ else -> precedence > precedenceFunction(parent)
}
- is UnaryOperatorSyntax -> {
- perform(node.prefix)
- perform(node.operand)
- }
+ val isInsideExpOperator =
+ node.parent is ExponentSyntax && (node.parent as ExponentSyntax).useOperatorForm
- is UnaryPlusSyntax -> perform(node.operand)
- is UnaryMinusSyntax -> {
- perform(node.operand)
- }
- is RadicalSyntax -> perform(node.operand)
+ node.parentheses = !isRightOfSuperscript
+ && (needParenthesesByPrecedence || node.parent is UnaryOperatorSyntax || isInsideExpOperator)
- is SuperscriptSyntax -> {
- perform(node.left)
- perform(node.right)
- }
+ perform(node.operand)
+ }
- is SubscriptSyntax -> {
- perform(node.left)
- perform(node.right)
- }
+ is UnaryOperatorSyntax -> {
+ perform(node.prefix)
+ perform(node.operand)
+ }
- is BinaryOperatorSyntax -> {
- perform(node.prefix)
- perform(node.left)
- perform(node.right)
- }
+ is UnaryPlusSyntax -> perform(node.operand)
+ is UnaryMinusSyntax -> perform(node.operand)
+ is RadicalSyntax -> perform(node.operand)
+ is ExponentSyntax -> perform(node.operand)
- is BinaryPlusSyntax -> {
- perform(node.left)
- perform(node.right)
- }
+ is SuperscriptSyntax -> {
+ perform(node.left)
+ perform(node.right)
+ }
- is BinaryMinusSyntax -> {
- perform(node.left)
- perform(node.right)
- }
+ is SubscriptSyntax -> {
+ perform(node.left)
+ perform(node.right)
+ }
- is FractionSyntax -> {
- perform(node.left)
- perform(node.right)
- }
+ is BinaryOperatorSyntax -> {
+ perform(node.prefix)
+ perform(node.left)
+ perform(node.right)
+ }
- is MultiplicationSyntax -> {
- perform(node.left)
- perform(node.right)
- }
+ is BinaryPlusSyntax -> {
+ perform(node.left)
+ perform(node.right)
+ }
- is RadicalWithIndexSyntax -> {
- perform(node.left)
- perform(node.right)
- }
+ is BinaryMinusSyntax -> {
+ perform(node.left)
+ perform(node.right)
+ }
+
+ is FractionSyntax -> {
+ perform(node.left)
+ perform(node.right)
+ }
+
+ is MultiplicationSyntax -> {
+ perform(node.left)
+ perform(node.right)
+ }
+
+ is RadicalWithIndexSyntax -> {
+ perform(node.left)
+ perform(node.right)
}
}
diff --git a/kmath-ast/src/commonTest/kotlin/space/kscisnce/kmath/ast/ParserPrecedenceTest.kt b/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/ParserPrecedenceTest.kt
similarity index 97%
rename from kmath-ast/src/commonTest/kotlin/space/kscisnce/kmath/ast/ParserPrecedenceTest.kt
rename to kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/ParserPrecedenceTest.kt
index 14ceefc30..ca3a95bc8 100644
--- a/kmath-ast/src/commonTest/kotlin/space/kscisnce/kmath/ast/ParserPrecedenceTest.kt
+++ b/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/ParserPrecedenceTest.kt
@@ -3,7 +3,7 @@
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
-package space.kscisnce.kmath.ast
+package space.kscience.kmath.ast
import space.kscience.kmath.ast.parseMath
import space.kscience.kmath.expressions.evaluate
diff --git a/kmath-ast/src/commonTest/kotlin/space/kscisnce/kmath/ast/ParserTest.kt b/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/ParserTest.kt
similarity index 95%
rename from kmath-ast/src/commonTest/kotlin/space/kscisnce/kmath/ast/ParserTest.kt
rename to kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/ParserTest.kt
index a0dcba9c0..185659a1f 100644
--- a/kmath-ast/src/commonTest/kotlin/space/kscisnce/kmath/ast/ParserTest.kt
+++ b/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/ParserTest.kt
@@ -3,9 +3,8 @@
* 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.kscisnce.kmath.ast
+package space.kscience.kmath.ast
-import space.kscience.kmath.ast.parseMath
import space.kscience.kmath.complex.Complex
import space.kscience.kmath.complex.ComplexField
import space.kscience.kmath.expressions.evaluate
diff --git a/kmath-ast/src/commonTest/kotlin/space/kscisnce/kmath/ast/rendering/TestFeatures.kt b/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/rendering/TestFeatures.kt
similarity index 81%
rename from kmath-ast/src/commonTest/kotlin/space/kscisnce/kmath/ast/rendering/TestFeatures.kt
rename to kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/rendering/TestFeatures.kt
index 1584293ce..1ab20ed85 100644
--- a/kmath-ast/src/commonTest/kotlin/space/kscisnce/kmath/ast/rendering/TestFeatures.kt
+++ b/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/rendering/TestFeatures.kt
@@ -42,6 +42,22 @@ internal class TestFeatures {
testLatex(Numeric(1.1e-10), "1.1\\times10^{-10}")
testLatex(Numeric(-1.1e-10), "-1.1\\times10^{-10}")
testLatex(Numeric(-1.1e10), "-1.1\\times10^{10}")
+ testLatex(Numeric(0.001), "0.001")
+ testLatex(Numeric(0.0000001), "1\\times10^{-7}")
+
+ testLatex(Numeric(Float.NaN), "NaN")
+ testLatex(Numeric(Float.POSITIVE_INFINITY), "\\infty")
+ testLatex(Numeric(Float.NEGATIVE_INFINITY), "-\\infty")
+ testLatex(Numeric(1.0f), "1")
+ testLatex(Numeric(-1.0f), "-1")
+ testLatex(Numeric(1.42f), "1.42")
+ testLatex(Numeric(-1.42f), "-1.42")
+ testLatex(Numeric(1e10f), "1\\times10^{10}")
+ testLatex(Numeric(1e-10f), "1\\times10^{-10}")
+ testLatex(Numeric(-1e-10f), "-1\\times10^{-10}")
+ testLatex(Numeric(-1e10f), "-1\\times10^{10}")
+ testLatex(Numeric(0.001f), "0.001")
+ testLatex(Numeric(0.0000001f), "1\\times10^{-7}")
}
@Test
diff --git a/kmath-ast/src/commonTest/kotlin/space/kscisnce/kmath/ast/rendering/TestLatex.kt b/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/rendering/TestLatex.kt
similarity index 100%
rename from kmath-ast/src/commonTest/kotlin/space/kscisnce/kmath/ast/rendering/TestLatex.kt
rename to kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/rendering/TestLatex.kt
diff --git a/kmath-ast/src/commonTest/kotlin/space/kscisnce/kmath/ast/rendering/TestMathML.kt b/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/rendering/TestMathML.kt
similarity index 100%
rename from kmath-ast/src/commonTest/kotlin/space/kscisnce/kmath/ast/rendering/TestMathML.kt
rename to kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/rendering/TestMathML.kt
diff --git a/kmath-ast/src/commonTest/kotlin/space/kscisnce/kmath/ast/rendering/TestStages.kt b/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/rendering/TestStages.kt
similarity index 81%
rename from kmath-ast/src/commonTest/kotlin/space/kscisnce/kmath/ast/rendering/TestStages.kt
rename to kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/rendering/TestStages.kt
index a4017fdb4..599e43eb2 100644
--- a/kmath-ast/src/commonTest/kotlin/space/kscisnce/kmath/ast/rendering/TestStages.kt
+++ b/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/rendering/TestStages.kt
@@ -30,4 +30,11 @@ internal class TestStages {
testLatex("(x+x)^x+x*x", "\\left(x+x\\right)^{x}+x\\,x")
testLatex("x^(x+x)", "x^{x+x}")
}
+
+ @Test
+ fun exponent() {
+ testLatex("exp(x)", "e^{x}")
+ testLatex("exp(x/2)", "\\operatorname{exp}\\,\\left(\\frac{x}{2}\\right)")
+ testLatex("exp(x^2)", "\\operatorname{exp}\\,\\left(x^{2}\\right)")
+ }
}
diff --git a/kmath-ast/src/commonTest/kotlin/space/kscisnce/kmath/ast/rendering/TestUtils.kt b/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/rendering/TestUtils.kt
similarity index 100%
rename from kmath-ast/src/commonTest/kotlin/space/kscisnce/kmath/ast/rendering/TestUtils.kt
rename to kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/rendering/TestUtils.kt
diff --git a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/ast/rendering/multiplatformToString.kt b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/ast/rendering/multiplatformToString.kt
new file mode 100644
index 000000000..521907d2c
--- /dev/null
+++ b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/ast/rendering/multiplatformToString.kt
@@ -0,0 +1,18 @@
+/*
+ * Copyright 2018-2021 KMath contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package space.kscience.kmath.ast.rendering
+
+internal actual fun Double.multiplatformToString(): String {
+ val d = this
+ if (d >= 1e7 || d <= -1e7) return js("d.toExponential()") as String
+ return toString()
+}
+
+internal actual fun Float.multiplatformToString(): String {
+ val d = this
+ if (d >= 1e7f || d <= -1e7f) return js("d.toExponential()") as String
+ return toString()
+}
diff --git a/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/ast/rendering/multiplatformToString.kt b/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/ast/rendering/multiplatformToString.kt
new file mode 100644
index 000000000..556adbe7d
--- /dev/null
+++ b/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/ast/rendering/multiplatformToString.kt
@@ -0,0 +1,9 @@
+/*
+ * Copyright 2018-2021 KMath contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package space.kscience.kmath.ast.rendering
+
+internal actual fun Double.multiplatformToString(): String = toString()
+internal actual fun Float.multiplatformToString(): String = toString()