Improved trigonometry operations #99
@ -25,12 +25,3 @@ interface ExpressionContext<T, E> : Algebra<E> {
|
|||||||
*/
|
*/
|
||||||
fun const(value: T): E
|
fun const(value: T): E
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <T, E> ExpressionContext<T, E>.produce(node: SyntaxTreeNode): E {
|
|
||||||
return when (node) {
|
|
||||||
is NumberNode -> error("Single number nodes are not supported")
|
|
||||||
is SingularNode -> variable(node.value)
|
|
||||||
is UnaryNode -> unaryOperation(node.operation, produce(node.value))
|
|
||||||
is BinaryNode -> binaryOperation(node.operation, produce(node.left), produce(node.right))
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,11 +1,25 @@
|
|||||||
package scientifik.kmath.expressions
|
package scientifik.kmath.expressions
|
||||||
|
|
||||||
|
import scientifik.kmath.operations.NumericAlgebra
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A syntax tree node for mathematical expressions
|
||||||
|
*/
|
||||||
sealed class SyntaxTreeNode
|
sealed class SyntaxTreeNode
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A node containing unparsed string
|
||||||
|
*/
|
||||||
data class SingularNode(val value: String) : SyntaxTreeNode()
|
data class SingularNode(val value: String) : SyntaxTreeNode()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A node containing a number
|
||||||
|
*/
|
||||||
data class NumberNode(val value: Number) : SyntaxTreeNode()
|
data class NumberNode(val value: Number) : SyntaxTreeNode()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A node containing an unary operation
|
||||||
|
*/
|
||||||
data class UnaryNode(val operation: String, val value: SyntaxTreeNode) : SyntaxTreeNode() {
|
data class UnaryNode(val operation: String, val value: SyntaxTreeNode) : SyntaxTreeNode() {
|
||||||
companion object {
|
companion object {
|
||||||
const val ABS_OPERATION = "abs"
|
const val ABS_OPERATION = "abs"
|
||||||
@ -17,12 +31,22 @@ data class UnaryNode(val operation: String, val value: SyntaxTreeNode) : SyntaxT
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A node containing binary operation
|
||||||
|
*/
|
||||||
data class BinaryNode(val operation: String, val left: SyntaxTreeNode, val right: SyntaxTreeNode) : SyntaxTreeNode() {
|
data class BinaryNode(val operation: String, val left: SyntaxTreeNode, val right: SyntaxTreeNode) : SyntaxTreeNode() {
|
||||||
companion object {
|
companion object
|
||||||
//TODO add operations
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO add a function with positional arguments
|
//TODO add a function with positional arguments
|
||||||
|
|
||||||
//TODO add a function with named arguments
|
//TODO add a function with named arguments
|
||||||
|
|
||||||
|
fun <T> NumericAlgebra<T>.compile(node: SyntaxTreeNode): T{
|
||||||
|
return when (node) {
|
||||||
|
is NumberNode -> number(node.value)
|
||||||
|
is SingularNode -> raw(node.value)
|
||||||
|
is UnaryNode -> unaryOperation(node.operation, compile(node.value))
|
||||||
|
is BinaryNode -> binaryOperation(node.operation, compile(node.left), compile(node.right))
|
||||||
|
}
|
||||||
|
}
|
@ -7,10 +7,35 @@ annotation class KMathContext
|
|||||||
* Marker interface for any algebra
|
* Marker interface for any algebra
|
||||||
*/
|
*/
|
||||||
interface Algebra<T> {
|
interface Algebra<T> {
|
||||||
|
/**
|
||||||
|
* Wrap raw string or variable
|
||||||
|
*/
|
||||||
|
fun raw(value: String): T = error("Wrapping of '$value' is not supported in $this")
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dynamic call of unary operation with name [operation] on [arg]
|
||||||
|
*/
|
||||||
fun unaryOperation(operation: String, arg: T): T
|
fun unaryOperation(operation: String, arg: T): T
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dynamic call of binary operation [operation] on [left] and [right]
|
||||||
|
*/
|
||||||
fun binaryOperation(operation: String, left: T, right: T): T
|
fun binaryOperation(operation: String, left: T, right: T): T
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An algebra with numeric representation of members
|
||||||
|
*/
|
||||||
|
interface NumericAlgebra<T> : Algebra<T> {
|
||||||
|
/**
|
||||||
|
* Wrap a number
|
||||||
|
*/
|
||||||
|
fun number(value: Number): T
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call a block with an [Algebra] as receiver
|
||||||
|
*/
|
||||||
inline operator fun <A : Algebra<*>, R> A.invoke(block: A.() -> R): R = run(block)
|
inline operator fun <A : Algebra<*>, R> A.invoke(block: A.() -> R): R = run(block)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -95,12 +120,15 @@ interface RingOperations<T> : SpaceOperations<T> {
|
|||||||
/**
|
/**
|
||||||
* The same as {@link Space} but with additional multiplication operation
|
* The same as {@link Space} but with additional multiplication operation
|
||||||
*/
|
*/
|
||||||
interface Ring<T> : Space<T>, RingOperations<T> {
|
interface Ring<T> : Space<T>, RingOperations<T>, NumericAlgebra<T> {
|
||||||
/**
|
/**
|
||||||
* neutral operation for multiplication
|
* neutral operation for multiplication
|
||||||
*/
|
*/
|
||||||
val one: T
|
val one: T
|
||||||
|
|
||||||
|
override fun number(value: Number): T = one * value.toDouble()
|
||||||
|
|
||||||
|
// those operators are blocked by type conflict in RealField
|
||||||
// operator fun T.plus(b: Number) = this.plus(b * one)
|
// operator fun T.plus(b: Number) = this.plus(b * one)
|
||||||
// operator fun Number.plus(b: T) = b + this
|
// operator fun Number.plus(b: T) = b + this
|
||||||
//
|
//
|
||||||
|
Loading…
Reference in New Issue
Block a user