diff --git a/CHANGELOG.md b/CHANGELOG.md index 9c6b14b95..524d2a1de 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -45,6 +45,7 @@ - MSTExpression - Expression algebra builders - Complex and Quaternion no longer are elements. +- Second generic from DifferentiableExpression ### Fixed - Ring inherits RingOperations, not GroupOperations diff --git a/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/expressions/DerivativeStructureExpression.kt b/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/expressions/DerivativeStructureExpression.kt index 89e216601..361027968 100644 --- a/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/expressions/DerivativeStructureExpression.kt +++ b/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/expressions/DerivativeStructureExpression.kt @@ -106,7 +106,7 @@ public class DerivativeStructureField( public companion object : AutoDiffProcessor> { - public override fun process(function: DerivativeStructureField.() -> DerivativeStructure): DifferentiableExpression> = + public override fun process(function: DerivativeStructureField.() -> DerivativeStructure): DifferentiableExpression = DerivativeStructureExpression(function) } } @@ -116,7 +116,7 @@ public class DerivativeStructureField( */ public class DerivativeStructureExpression( public val function: DerivativeStructureField.() -> DerivativeStructure, -) : DifferentiableExpression> { +) : DifferentiableExpression { public override operator fun invoke(arguments: Map): Double = DerivativeStructureField(0, arguments).function().value diff --git a/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/optimization/CMOptimization.kt b/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/optimization/CMOptimization.kt index 282f1670d..549683d60 100644 --- a/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/optimization/CMOptimization.kt +++ b/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/optimization/CMOptimization.kt @@ -15,6 +15,7 @@ import space.kscience.kmath.expressions.derivative import space.kscience.kmath.expressions.withSymbols import space.kscience.kmath.misc.UnstableKMathAPI import space.kscience.kmath.optimization.* +import kotlin.collections.set import kotlin.reflect.KClass public operator fun PointValuePair.component1(): DoubleArray = point diff --git a/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/optimization/cmFit.kt b/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/optimization/cmFit.kt index f1095ef73..b1d7f5ca3 100644 --- a/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/optimization/cmFit.kt +++ b/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/optimization/cmFit.kt @@ -22,7 +22,7 @@ public fun FunctionOptimization.Companion.chiSquaredExpression( y: Buffer, yErr: Buffer, model: DerivativeStructureField.(x: DerivativeStructure) -> DerivativeStructure, -): DifferentiableExpression> = chiSquaredExpression(DerivativeStructureField, x, y, yErr, model) +): DifferentiableExpression = chiSquaredExpression(DerivativeStructureField, x, y, yErr, model) /** * Generate a chi squared expression from given x-y-sigma data and inline model. Provides automatic differentiation @@ -32,7 +32,7 @@ public fun FunctionOptimization.Companion.chiSquaredExpression( y: Iterable, yErr: Iterable, model: DerivativeStructureField.(x: DerivativeStructure) -> DerivativeStructure, -): DifferentiableExpression> = chiSquaredExpression( +): DifferentiableExpression = chiSquaredExpression( DerivativeStructureField, x.toList().asBuffer(), y.toList().asBuffer(), @@ -56,12 +56,12 @@ public suspend fun Expression.optimize( /** * Optimize differentiable expression */ -public suspend fun DifferentiableExpression>.optimize( +public suspend fun DifferentiableExpression.optimize( vararg symbols: Symbol, configuration: CMOptimization.() -> Unit, ): OptimizationResult = optimizeWith(CMOptimization, symbols = symbols, configuration) -public suspend fun DifferentiableExpression>.minimize( +public suspend fun DifferentiableExpression.minimize( vararg startPoint: Pair, configuration: CMOptimization.() -> Unit = {}, ): OptimizationResult { diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/DifferentiableExpression.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/DifferentiableExpression.kt index 280238447..011dc26e2 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/DifferentiableExpression.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/DifferentiableExpression.kt @@ -11,35 +11,51 @@ package space.kscience.kmath.expressions * @param T the type this expression takes as argument and returns. * @param R the type of expression this expression can be differentiated to. */ -public interface DifferentiableExpression> : Expression { +public interface DifferentiableExpression : Expression { /** * Differentiates this expression by ordered collection of [symbols]. * * @param symbols the symbols. * @return the derivative or `null`. */ - public fun derivativeOrNull(symbols: List): R? + public fun derivativeOrNull(symbols: List): Expression? } -public fun > DifferentiableExpression.derivative(symbols: List): R = +public fun DifferentiableExpression.derivative(symbols: List): Expression = derivativeOrNull(symbols) ?: error("Derivative by symbols $symbols not provided") -public fun > DifferentiableExpression.derivative(vararg symbols: Symbol): R = +public fun DifferentiableExpression.derivative(vararg symbols: Symbol): Expression = derivative(symbols.toList()) -public fun > DifferentiableExpression.derivative(name: String): R = +public fun DifferentiableExpression.derivative(name: String): Expression = + derivative(StringSymbol(name)) + +/** + * A special type of [DifferentiableExpression] which returns typed expressions as derivatives + */ +public interface SpecialDifferentiableExpression>: DifferentiableExpression { + override fun derivativeOrNull(symbols: List): R? +} + +public fun > SpecialDifferentiableExpression.derivative(symbols: List): R = + derivativeOrNull(symbols) ?: error("Derivative by symbols $symbols not provided") + +public fun > SpecialDifferentiableExpression.derivative(vararg symbols: Symbol): R = + derivative(symbols.toList()) + +public fun > SpecialDifferentiableExpression.derivative(name: String): R = derivative(StringSymbol(name)) /** * A [DifferentiableExpression] that defines only first derivatives */ -public abstract class FirstDerivativeExpression> : DifferentiableExpression { +public abstract class FirstDerivativeExpression : DifferentiableExpression { /** * Returns first derivative of this expression by given [symbol]. */ - public abstract fun derivativeOrNull(symbol: Symbol): R? + public abstract fun derivativeOrNull(symbol: Symbol): Expression? - public final override fun derivativeOrNull(symbols: List): R? { + public final override fun derivativeOrNull(symbols: List): Expression? { val dSymbol = symbols.firstOrNull() ?: return null return derivativeOrNull(dSymbol) } @@ -49,5 +65,5 @@ public abstract class FirstDerivativeExpression> : Differen * A factory that converts an expression in autodiff variables to a [DifferentiableExpression] */ public fun interface AutoDiffProcessor, out R : Expression> { - public fun process(function: A.() -> I): DifferentiableExpression + public fun process(function: A.() -> I): DifferentiableExpression } diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/SimpleAutoDiff.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/SimpleAutoDiff.kt index 254d60b3d..478b85620 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/SimpleAutoDiff.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/SimpleAutoDiff.kt @@ -232,7 +232,7 @@ public fun > F.simpleAutoDiff( public class SimpleAutoDiffExpression>( public val field: F, public val function: SimpleAutoDiffField.() -> AutoDiffValue, -) : FirstDerivativeExpression>() { +) : FirstDerivativeExpression() { public override operator fun invoke(arguments: Map): T { //val bindings = arguments.entries.map { it.key.bind(it.value) } return SimpleAutoDiffField(field, arguments).function().value diff --git a/kmath-kotlingrad/src/main/kotlin/space/kscience/kmath/kotlingrad/KotlingradExpression.kt b/kmath-kotlingrad/src/main/kotlin/space/kscience/kmath/kotlingrad/KotlingradExpression.kt index 72ecee4f1..4294462c0 100644 --- a/kmath-kotlingrad/src/main/kotlin/space/kscience/kmath/kotlingrad/KotlingradExpression.kt +++ b/kmath-kotlingrad/src/main/kotlin/space/kscience/kmath/kotlingrad/KotlingradExpression.kt @@ -24,7 +24,7 @@ import space.kscience.kmath.operations.NumericAlgebra public class KotlingradExpression>( public val algebra: A, public val mst: MST, -) : DifferentiableExpression> { +) : SpecialDifferentiableExpression> { public override fun invoke(arguments: Map): T = mst.interpret(algebra, arguments) public override fun derivativeOrNull(symbols: List): KotlingradExpression = diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/optimization/FunctionOptimization.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/optimization/FunctionOptimization.kt index 2c70da308..ee75bfbd6 100644 --- a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/optimization/FunctionOptimization.kt +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/optimization/FunctionOptimization.kt @@ -22,7 +22,7 @@ public enum class FunctionOptimizationTarget : OptimizationFeature { public class FunctionOptimization( override val features: FeatureSet, - public val expression: DifferentiableExpression>, + public val expression: DifferentiableExpression, ) : OptimizationProblem{ public companion object{ @@ -35,7 +35,7 @@ public class FunctionOptimization( y: Buffer, yErr: Buffer, model: A.(I) -> I, - ): DifferentiableExpression> where A : ExtendedField, A : ExpressionAlgebra { + ): DifferentiableExpression where A : ExtendedField, A : ExpressionAlgebra { require(x.size == y.size) { "X and y buffers should be of the same size" } require(y.size == yErr.size) { "Y and yErr buffer should of the same size" }