Merge remote-tracking branch 'mipt-npm/adv-expr' into adv-expr-refactor-agc

# Conflicts:
#	kmath-ast/src/jvmMain/kotlin/scientifik/kmath/asm/AsmBuilders.kt
#	kmath-ast/src/jvmMain/kotlin/scientifik/kmath/asm/AsmExpressions.kt
#	kmath-ast/src/jvmMain/kotlin/scientifik/kmath/asm/internal/AsmBuilder.kt
#	kmath-ast/src/jvmMain/kotlin/scientifik/kmath/asm/internal/optimization.kt
This commit is contained in:
Iaroslav 2020-06-15 17:23:35 +07:00
commit b57b55ec1a
No known key found for this signature in database
GPG Key ID: 46E15E4A31B3BCD7
9 changed files with 57 additions and 6 deletions

4
kmath-ast/README.md Normal file
View File

@ -0,0 +1,4 @@
# AST based expression representation and operations
## Dynamic expression code generation
Contributed by [Iaroslav Postovalov](https://github.com/CommanderTvis).

View File

@ -11,7 +11,7 @@ sealed class MST {
/** /**
* A node containing unparsed string * A node containing unparsed string
*/ */
data class Singular(val value: String) : MST() data class Symbolic(val value: String) : MST()
/** /**
* A node containing a number * A node containing a number
@ -43,7 +43,7 @@ sealed class MST {
fun <T> NumericAlgebra<T>.evaluate(node: MST): T { fun <T> NumericAlgebra<T>.evaluate(node: MST): T {
return when (node) { return when (node) {
is MST.Numeric -> number(node.value) is MST.Numeric -> number(node.value)
is MST.Singular -> symbol(node.value) is MST.Symbolic -> symbol(node.value)
is MST.Unary -> unaryOperation(node.operation, evaluate(node.value)) is MST.Unary -> unaryOperation(node.operation, evaluate(node.value))
is MST.Binary -> when { is MST.Binary -> when {
node.left is MST.Numeric && node.right is MST.Numeric -> { node.left is MST.Numeric && node.right is MST.Numeric -> {

View File

@ -0,0 +1,47 @@
package scientifik.kmath.asm
import scientifik.kmath.ast.MST
import scientifik.kmath.ast.evaluate
import scientifik.kmath.expressions.Expression
import scientifik.kmath.operations.Field
import scientifik.kmath.operations.NumericAlgebra
import scientifik.kmath.operations.Ring
import scientifik.kmath.operations.Space
internal fun buildName(expression: AsmExpression<*>, collision: Int = 0): String {
val name = "scientifik.kmath.expressions.generated.AsmCompiledExpression_${expression.hashCode()}_$collision"
try {
Class.forName(name)
} catch (ignored: ClassNotFoundException) {
return name
}
return buildName(expression, collision + 1)
}
inline fun <reified T : Any, A : NumericAlgebra<T>, E : AsmExpressionAlgebra<T, A>> A.asm(
expressionAlgebra: E,
block: E.() -> AsmExpression<T>
): Expression<T> = expressionAlgebra.block()
inline fun <reified T : Any> NumericAlgebra<T>.asm(ast: MST): Expression<T> =
AsmExpressionAlgebra(T::class, this).evaluate(ast)
inline fun <reified T : Any, A> A.asmSpace(block: AsmExpressionSpace<T, A>.() -> AsmExpression<T>): Expression<T> where A : NumericAlgebra<T>, A : Space<T> =
AsmExpressionSpace<T, A>(T::class, this).block()
inline fun <reified T : Any, A> A.asmSpace(ast: MST): Expression<T> where A : NumericAlgebra<T>, A : Space<T> =
asmSpace { evaluate(ast) }
inline fun <reified T : Any, A> A.asmRing(block: AsmExpressionRing<T, A>.() -> AsmExpression<T>): Expression<T> where A : NumericAlgebra<T>, A : Ring<T> =
AsmExpressionRing(T::class, this).block()
inline fun <reified T : Any, A> A.asmRing(ast: MST): Expression<T> where A : NumericAlgebra<T>, A : Ring<T> =
asmRing { evaluate(ast) }
inline fun <reified T : Any, A> A.asmField(block: AsmExpressionField<T, A>.() -> AsmExpression<T>): Expression<T> where A : NumericAlgebra<T>, A : Field<T> =
AsmExpressionField(T::class, this).block()
inline fun <reified T : Any, A> A.asmField(ast: MST): Expression<T> where A : NumericAlgebra<T>, A : Field<T> =
asmRing { evaluate(ast) }

View File

@ -1,4 +1,4 @@
package scietifik.kmath.ast.asm package scietifik.kmath.asm
import scientifik.kmath.asm.asmField import scientifik.kmath.asm.asmField
import scientifik.kmath.asm.asmRing import scientifik.kmath.asm.asmRing

View File

@ -1,4 +1,4 @@
package scietifik.kmath.ast.asm package scietifik.kmath.asm
import scientifik.kmath.asm.asmField import scientifik.kmath.asm.asmField
import scientifik.kmath.expressions.invoke import scientifik.kmath.expressions.invoke

View File

@ -31,7 +31,7 @@ class ExpressionFieldTest {
@Test @Test
fun separateContext() { fun separateContext() {
fun <T> FunctionalExpressionField<T>.expression(): Expression<T> { fun <T> FunctionalExpressionField<T,*>.expression(): Expression<T> {
val x = variable("x") val x = variable("x")
return x * x + 2 * x + one return x * x + 2 * x + one
} }
@ -42,7 +42,7 @@ class ExpressionFieldTest {
@Test @Test
fun valueExpression() { fun valueExpression() {
val expressionBuilder: FunctionalExpressionField<Double>.() -> Expression<Double> = { val expressionBuilder: FunctionalExpressionField<Double,*>.() -> Expression<Double> = {
val x = variable("x") val x = variable("x")
x * x + 2 * x + one x * x + 2 * x + one
} }