All Downloads are FREE. Search and download functionalities are using the official Maven repository.

commonMain.space.kscience.kmath.expressions.FunctionalExpressionAlgebra.kt Maven / Gradle / Ivy

package space.kscience.kmath.expressions

import space.kscience.kmath.operations.*

/**
 * A context class for [Expression] construction.
 *
 * @param algebra The algebra to provide for Expressions built.
 */
public abstract class FunctionalExpressionAlgebra>(
    public val algebra: A,
) : ExpressionAlgebra> {
    /**
     * Builds an Expression of constant expression which does not depend on arguments.
     */
    public override fun const(value: T): Expression = Expression { value }

    /**
     * Builds an Expression to access a variable.
     */
    public override fun bindSymbolOrNull(symbol: Symbol): Expression? = Expression { arguments ->
        arguments[symbol] ?: error("Argument not found: $symbol")
    }

    /**
     * Builds an Expression of dynamic call of binary operation [operation] on [left] and [right].
     */
    public override fun binaryOperationFunction(operation: String): (left: Expression, right: Expression) -> Expression =
        { left, right ->
            Expression { arguments ->
                algebra.binaryOperationFunction(operation)(left.invoke(arguments), right.invoke(arguments))
            }
        }

    /**
     * Builds an Expression of dynamic call of unary operation with name [operation] on [arg].
     */
    public override fun unaryOperationFunction(operation: String): (arg: Expression) -> Expression = { arg ->
        Expression { arguments -> algebra.unaryOperationFunction(operation)(arg.invoke(arguments)) }
    }
}

/**
 * A context class for [Expression] construction for [Space] algebras.
 */
public open class FunctionalExpressionSpace>(
    algebra: A,
) : FunctionalExpressionAlgebra(algebra), Space> {
    public override val zero: Expression get() = const(algebra.zero)

    /**
     * Builds an Expression of addition of two another expressions.
     */
    public override fun add(a: Expression, b: Expression): Expression =
        binaryOperationFunction(SpaceOperations.PLUS_OPERATION)(a, b)

    /**
     * Builds an Expression of multiplication of expression by number.
     */
    public override fun multiply(a: Expression, k: Number): Expression = Expression { arguments ->
        algebra.multiply(a.invoke(arguments), k)
    }

    public operator fun Expression.plus(arg: T): Expression = this + const(arg)
    public operator fun Expression.minus(arg: T): Expression = this - const(arg)
    public operator fun T.plus(arg: Expression): Expression = arg + this
    public operator fun T.minus(arg: Expression): Expression = arg - this

    public override fun unaryOperationFunction(operation: String): (arg: Expression) -> Expression =
        super.unaryOperationFunction(operation)

    public override fun binaryOperationFunction(operation: String): (left: Expression, right: Expression) -> Expression =
        super.binaryOperationFunction(operation)
}

public open class FunctionalExpressionRing>(
    algebra: A,
) : FunctionalExpressionSpace(algebra), Ring> {
    public override val one: Expression
        get() = const(algebra.one)

    /**
     * Builds an Expression of multiplication of two expressions.
     */
    public override fun multiply(a: Expression, b: Expression): Expression =
        binaryOperationFunction(RingOperations.TIMES_OPERATION)(a, b)

    public operator fun Expression.times(arg: T): Expression = this * const(arg)
    public operator fun T.times(arg: Expression): Expression = arg * this

    public override fun unaryOperationFunction(operation: String): (arg: Expression) -> Expression =
        super.unaryOperationFunction(operation)

    public override fun binaryOperationFunction(operation: String): (left: Expression, right: Expression) -> Expression =
        super.binaryOperationFunction(operation)
}

public open class FunctionalExpressionField>(
    algebra: A,
) : FunctionalExpressionRing(algebra), Field> {
    /**
     * Builds an Expression of division an expression by another one.
     */
    public override fun divide(a: Expression, b: Expression): Expression =
        binaryOperationFunction(FieldOperations.DIV_OPERATION)(a, b)

    public operator fun Expression.div(arg: T): Expression = this / const(arg)
    public operator fun T.div(arg: Expression): Expression = arg / this

    public override fun unaryOperationFunction(operation: String): (arg: Expression) -> Expression =
        super.unaryOperationFunction(operation)

    public override fun binaryOperationFunction(operation: String): (left: Expression, right: Expression) -> Expression =
        super.binaryOperationFunction(operation)
}

public open class FunctionalExpressionExtendedField>(
    algebra: A,
) : FunctionalExpressionField(algebra), ExtendedField> {

    override fun number(value: Number): Expression = const(algebra.number(value))

    public override fun sin(arg: Expression): Expression =
        unaryOperationFunction(TrigonometricOperations.SIN_OPERATION)(arg)

    public override fun cos(arg: Expression): Expression =
        unaryOperationFunction(TrigonometricOperations.COS_OPERATION)(arg)

    public override fun asin(arg: Expression): Expression =
        unaryOperationFunction(TrigonometricOperations.ASIN_OPERATION)(arg)

    public override fun acos(arg: Expression): Expression =
        unaryOperationFunction(TrigonometricOperations.ACOS_OPERATION)(arg)

    public override fun atan(arg: Expression): Expression =
        unaryOperationFunction(TrigonometricOperations.ATAN_OPERATION)(arg)

    public override fun power(arg: Expression, pow: Number): Expression =
        binaryOperationFunction(PowerOperations.POW_OPERATION)(arg, number(pow))

    public override fun exp(arg: Expression): Expression =
        unaryOperationFunction(ExponentialOperations.EXP_OPERATION)(arg)

    public override fun ln(arg: Expression): Expression =
        unaryOperationFunction(ExponentialOperations.LN_OPERATION)(arg)

    public override fun unaryOperationFunction(operation: String): (arg: Expression) -> Expression =
        super.unaryOperationFunction(operation)

    public override fun binaryOperationFunction(operation: String): (left: Expression, right: Expression) -> Expression =
        super.binaryOperationFunction(operation)
}

public inline fun > A.expressionInSpace(block: FunctionalExpressionSpace.() -> Expression): Expression =
    FunctionalExpressionSpace(this).block()

public inline fun > A.expressionInRing(block: FunctionalExpressionRing.() -> Expression): Expression =
    FunctionalExpressionRing(this).block()

public inline fun > A.expressionInField(block: FunctionalExpressionField.() -> Expression): Expression =
    FunctionalExpressionField(this).block()

public inline fun > A.expressionInExtendedField(block: FunctionalExpressionExtendedField.() -> Expression): Expression =
    FunctionalExpressionExtendedField(this).block()




© 2015 - 2025 Weber Informatics LLC | Privacy Policy