Feature/diff api #154

Merged
altavir merged 20 commits from feature/diff-api into dev 2020-10-28 13:25:24 +03:00
9 changed files with 188 additions and 114 deletions
Showing only changes of commit 1fbe12149d - Show all commits

View File

@ -1 +1,3 @@
job("Build") { gradlew("openjdk:11", "build") } job("Build") {
gradlew("openjdk:11", "build")
}

View File

@ -106,7 +106,7 @@ public class DerivativeStructureExpression(
/** /**
* Get the derivative expression with given orders * Get the derivative expression with given orders
*/ */
public override fun derivative(orders: Map<Symbol, Int>): Expression<Double> = Expression { arguments -> public override fun derivativeOrNull(orders: Map<Symbol, Int>): Expression<Double> = Expression { arguments ->
with(DerivativeStructureField(orders.values.maxOrNull() ?: 0, arguments)) { function().derivative(orders) } with(DerivativeStructureField(orders.values.maxOrNull() ?: 0, arguments)) { function().derivative(orders) }
} }
} }

View File

@ -0,0 +1,100 @@
package kscience.kmath.commons.optimization
import kscience.kmath.expressions.*
import org.apache.commons.math3.optim.*
import org.apache.commons.math3.optim.nonlinear.scalar.GoalType
import org.apache.commons.math3.optim.nonlinear.scalar.MultivariateOptimizer
import org.apache.commons.math3.optim.nonlinear.scalar.ObjectiveFunction
import org.apache.commons.math3.optim.nonlinear.scalar.ObjectiveFunctionGradient
import org.apache.commons.math3.optim.nonlinear.scalar.gradient.NonLinearConjugateGradientOptimizer
import org.apache.commons.math3.optim.nonlinear.scalar.noderiv.AbstractSimplex
import org.apache.commons.math3.optim.nonlinear.scalar.noderiv.NelderMeadSimplex
import org.apache.commons.math3.optim.nonlinear.scalar.noderiv.SimplexOptimizer
import kotlin.reflect.KClass
public operator fun PointValuePair.component1(): DoubleArray = point
public operator fun PointValuePair.component2(): Double = value
public class CMOptimizationProblem(
override val symbols: List<Symbol>,
) : OptimizationProblem<Double>, SymbolIndexer {
protected val optimizationData: HashMap<KClass<out OptimizationData>, OptimizationData> = HashMap()
private var optimizatorBuilder: (() -> MultivariateOptimizer)? = null
public var convergenceChecker: ConvergenceChecker<PointValuePair> = SimpleValueChecker(DEFAULT_RELATIVE_TOLERANCE,
DEFAULT_ABSOLUTE_TOLERANCE, DEFAULT_MAX_ITER)
private fun addOptimizationData(data: OptimizationData) {
optimizationData[data::class] = data
}
init {
addOptimizationData(MaxEval.unlimited())
}
public fun initialGuess(map: Map<Symbol, Double>): Unit {
addOptimizationData(InitialGuess(map.toDoubleArray()))
}
public fun expression(expression: Expression<Double>): Unit {
val objectiveFunction = ObjectiveFunction {
val args = it.toMap()
expression(args)
}
addOptimizationData(objectiveFunction)
}
public fun derivatives(expression: DifferentiableExpression<Double>): Unit {
expression(expression)
val gradientFunction = ObjectiveFunctionGradient {
val args = it.toMap()
DoubleArray(symbols.size) { index ->
expression.derivative(symbols[index])(args)
}
}
addOptimizationData(gradientFunction)
if (optimizatorBuilder == null) {
optimizatorBuilder = {
NonLinearConjugateGradientOptimizer(
NonLinearConjugateGradientOptimizer.Formula.FLETCHER_REEVES,
convergenceChecker
)
}
}
}
public fun simplex(simplex: AbstractSimplex) {
addOptimizationData(simplex)
//Set optimization builder to simplex if it is not present
if (optimizatorBuilder == null) {
optimizatorBuilder = { SimplexOptimizer(convergenceChecker) }
}
}
public fun simplexSteps(steps: Map<Symbol, Double>) {
simplex(NelderMeadSimplex(steps.toDoubleArray()))
}
public fun goal(goalType: GoalType) {
addOptimizationData(goalType)
}
public fun optimizer(block: () -> MultivariateOptimizer) {
optimizatorBuilder = block
}
override fun optimize(): OptimizationResult<Double> {
val optimizer = optimizatorBuilder?.invoke() ?: error("Optimizer not defined")
val (point, value) = optimizer.optimize(*optimizationData.values.toTypedArray())
return OptimizationResult(point.toMap(), value)
}
public companion object {
public const val DEFAULT_RELATIVE_TOLERANCE: Double = 1e-4
public const val DEFAULT_ABSOLUTE_TOLERANCE: Double = 1e-4
public const val DEFAULT_MAX_ITER: Int = 1000
}
}
public fun CMOptimizationProblem.initialGuess(vararg pairs: Pair<Symbol, Double>): Unit = initialGuess(pairs.toMap())
public fun CMOptimizationProblem.simplexSteps(vararg pairs: Pair<Symbol, Double>): Unit = simplexSteps(pairs.toMap())

View File

@ -0,0 +1,17 @@
package kscience.kmath.commons.optimization
import kscience.kmath.expressions.Symbol
import kotlin.reflect.KClass
public typealias ParameterSpacePoint<T> = Map<Symbol, T>
public class OptimizationResult<T>(
public val point: ParameterSpacePoint<T>,
public val value: T,
public val extra: Map<KClass<*>, Any> = emptyMap()
)
public interface OptimizationProblem<T : Any> {
public fun optimize(): OptimizationResult<T>
}

View File

@ -1,103 +1,32 @@
package kscience.kmath.commons.optimization package kscience.kmath.commons.optimization
import kscience.kmath.expressions.* import kscience.kmath.expressions.DifferentiableExpression
import org.apache.commons.math3.optim.* import kscience.kmath.expressions.Expression
import org.apache.commons.math3.optim.nonlinear.scalar.GoalType import kscience.kmath.expressions.Symbol
import org.apache.commons.math3.optim.nonlinear.scalar.MultivariateOptimizer
import org.apache.commons.math3.optim.nonlinear.scalar.ObjectiveFunction
import org.apache.commons.math3.optim.nonlinear.scalar.ObjectiveFunctionGradient
import org.apache.commons.math3.optim.nonlinear.scalar.gradient.NonLinearConjugateGradientOptimizer
import org.apache.commons.math3.optim.nonlinear.scalar.noderiv.NelderMeadSimplex
import org.apache.commons.math3.optim.nonlinear.scalar.noderiv.SimplexOptimizer
public typealias ParameterSpacePoint = Map<Symbol, Double>
public class OptimizationResult(public val point: ParameterSpacePoint, public val value: Double)
public operator fun PointValuePair.component1(): DoubleArray = point
public operator fun PointValuePair.component2(): Double = value
public object Optimization {
public const val DEFAULT_RELATIVE_TOLERANCE: Double = 1e-4
public const val DEFAULT_ABSOLUTE_TOLERANCE: Double = 1e-4
public const val DEFAULT_MAX_ITER: Int = 1000
}
private fun SymbolIndexer.objectiveFunction(expression: Expression<Double>) = ObjectiveFunction {
val args = it.toMap()
expression(args)
}
private fun SymbolIndexer.objectiveFunctionGradient(
expression: DifferentiableExpression<Double>,
) = ObjectiveFunctionGradient {
val args = it.toMap()
DoubleArray(symbols.size) { index ->
expression.derivative(symbols[index])(args)
}
}
private fun SymbolIndexer.initialGuess(point: ParameterSpacePoint) = InitialGuess(point.toArray())
/** /**
* Optimize expression without derivatives * Optimize expression without derivatives
*/ */
public fun Expression<Double>.optimize( public fun Expression<Double>.optimize(
startingPoint: ParameterSpacePoint, vararg symbols: Symbol,
goalType: GoalType = GoalType.MAXIMIZE, configuration: CMOptimizationProblem.() -> Unit,
vararg additionalArguments: OptimizationData, ): OptimizationResult<Double> {
optimizerBuilder: () -> MultivariateOptimizer = { require(symbols.isNotEmpty()) { "Must provide a list of symbols for optimization" }
SimplexOptimizer( val problem = CMOptimizationProblem(symbols.toList()).apply(configuration).apply(configuration)
SimpleValueChecker( problem.expression(this)
Optimization.DEFAULT_RELATIVE_TOLERANCE, return problem.optimize()
Optimization.DEFAULT_ABSOLUTE_TOLERANCE,
Optimization.DEFAULT_MAX_ITER
)
)
},
): OptimizationResult = withSymbols(startingPoint.keys) {
val optimizer = optimizerBuilder()
val objectiveFunction = objectiveFunction(this@optimize)
val (point, value) = optimizer.optimize(
objectiveFunction,
initialGuess(startingPoint),
goalType,
MaxEval.unlimited(),
NelderMeadSimplex(symbols.size, 1.0),
*additionalArguments
)
OptimizationResult(point.toMap(), value)
} }
/** /**
* Optimize differentiable expression * Optimize differentiable expression
*/ */
public fun DifferentiableExpression<Double>.optimize( public fun DifferentiableExpression<Double>.optimize(
startingPoint: ParameterSpacePoint, vararg symbols: Symbol,
goalType: GoalType = GoalType.MAXIMIZE, configuration: CMOptimizationProblem.() -> Unit,
vararg additionalArguments: OptimizationData, ): OptimizationResult<Double> {
optimizerBuilder: () -> NonLinearConjugateGradientOptimizer = { require(symbols.isNotEmpty()) { "Must provide a list of symbols for optimization" }
NonLinearConjugateGradientOptimizer( val problem = CMOptimizationProblem(symbols.toList()).apply(configuration).apply(configuration)
NonLinearConjugateGradientOptimizer.Formula.FLETCHER_REEVES, problem.derivatives(this)
SimpleValueChecker( return problem.optimize()
Optimization.DEFAULT_RELATIVE_TOLERANCE,
Optimization.DEFAULT_ABSOLUTE_TOLERANCE,
Optimization.DEFAULT_MAX_ITER
)
)
},
): OptimizationResult = withSymbols(startingPoint.keys) {
val optimizer = optimizerBuilder()
val objectiveFunction = objectiveFunction(this@optimize)
val objectiveGradient = objectiveFunctionGradient(this@optimize)
val (point, value) = optimizer.optimize(
objectiveFunction,
objectiveGradient,
initialGuess(startingPoint),
goalType,
MaxEval.unlimited(),
*additionalArguments
)
OptimizationResult(point.toMap(), value)
} }

View File

@ -1,10 +1,7 @@
package kscience.kmath.commons.optimization package kscience.kmath.commons.optimization
import kscience.kmath.commons.expressions.DerivativeStructureExpression import kscience.kmath.commons.expressions.DerivativeStructureExpression
import kscience.kmath.expressions.Expression
import kscience.kmath.expressions.Symbol
import kscience.kmath.expressions.symbol import kscience.kmath.expressions.symbol
import org.apache.commons.math3.optim.nonlinear.scalar.noderiv.SimplexOptimizer
import org.junit.jupiter.api.Test import org.junit.jupiter.api.Test
internal class OptimizeTest { internal class OptimizeTest {
@ -14,22 +11,25 @@ internal class OptimizeTest {
val normal = DerivativeStructureExpression { val normal = DerivativeStructureExpression {
val x = bind(x) val x = bind(x)
val y = bind(y) val y = bind(y)
exp(-x.pow(2)/2) + exp(-y.pow(2)/2) exp(-x.pow(2) / 2) + exp(-y.pow(2) / 2)
} }
val startingPoint: Map<Symbol, Double> = mapOf(x to 1.0, y to 1.0)
@Test @Test
fun testOptimization() { fun testOptimization() {
val result = normal.optimize(startingPoint) val result = normal.optimize(x, y) {
initialGuess(x to 1.0, y to 1.0)
//no need to select optimizer. Gradient optimizer is used by default
}
println(result.point) println(result.point)
println(result.value) println(result.value)
} }
@Test @Test
fun testSimplexOptimization() { fun testSimplexOptimization() {
val result = (normal as Expression<Double>).optimize(startingPoint){ val result = normal.optimize(x, y) {
SimplexOptimizer(1e-4,1e-4) initialGuess(x to 1.0, y to 1.0)
simplexSteps(x to 2.0, y to 0.5)
//this sets simplex optimizer
} }
println(result.point) println(result.point)
println(result.value) println(result.value)

View File

@ -4,9 +4,15 @@ package kscience.kmath.expressions
CommanderTvis commented 2020-10-26 22:57:33 +03:00 (Migrated from github.com)
Review
  1. SAM interface.
  2. Does it have any uses, except the one in DifferentiableExpression? This trait can be extracted to separate into separate interface at any moment.
1. SAM interface. 2. Does it have any uses, except the one in DifferentiableExpression? This trait can be extracted to separate into separate interface at any moment.
CommanderTvis commented 2020-10-26 22:57:33 +03:00 (Migrated from github.com)
Review
  1. SAM interface.
  2. Does it have any uses, except the one in DifferentiableExpression? This trait can be extracted to separate into separate interface at any moment.
1. SAM interface. 2. Does it have any uses, except the one in DifferentiableExpression? This trait can be extracted to separate into separate interface at any moment.
altavir commented 2020-10-28 09:26:02 +03:00 (Migrated from github.com)
Review

Removed

Removed
altavir commented 2020-10-28 09:26:02 +03:00 (Migrated from github.com)
Review

Removed

Removed
* And object that could be differentiated * And object that could be differentiated
*/ */
public interface Differentiable<T> { public interface Differentiable<T> {
public fun derivative(orders: Map<Symbol, Int>): T public fun derivativeOrNull(orders: Map<Symbol, Int>): T?
CommanderTvis commented 2020-10-26 22:57:33 +03:00 (Migrated from github.com)
Review
  1. SAM interface.
  2. Does it have any uses, except the one in DifferentiableExpression? This trait can be extracted to separate into separate interface at any moment.
1. SAM interface. 2. Does it have any uses, except the one in DifferentiableExpression? This trait can be extracted to separate into separate interface at any moment.
altavir commented 2020-10-28 09:26:02 +03:00 (Migrated from github.com)
Review

Removed

Removed
CommanderTvis commented 2020-10-26 22:57:33 +03:00 (Migrated from github.com)
Review
  1. SAM interface.
  2. Does it have any uses, except the one in DifferentiableExpression? This trait can be extracted to separate into separate interface at any moment.
1. SAM interface. 2. Does it have any uses, except the one in DifferentiableExpression? This trait can be extracted to separate into separate interface at any moment.
altavir commented 2020-10-28 09:26:02 +03:00 (Migrated from github.com)
Review

Removed

Removed
} }
public fun <T> Differentiable<T>.derivative(orders: Map<Symbol, Int>): T =
CommanderTvis commented 2020-10-26 22:57:33 +03:00 (Migrated from github.com)
Review
  1. SAM interface.
  2. Does it have any uses, except the one in DifferentiableExpression? This trait can be extracted to separate into separate interface at any moment.
1. SAM interface. 2. Does it have any uses, except the one in DifferentiableExpression? This trait can be extracted to separate into separate interface at any moment.
altavir commented 2020-10-28 09:26:02 +03:00 (Migrated from github.com)
Review

Removed

Removed
derivativeOrNull(orders) ?: error("Derivative with orders $orders not provided")
CommanderTvis commented 2020-10-26 22:57:33 +03:00 (Migrated from github.com)
Review
  1. SAM interface.
  2. Does it have any uses, except the one in DifferentiableExpression? This trait can be extracted to separate into separate interface at any moment.
1. SAM interface. 2. Does it have any uses, except the one in DifferentiableExpression? This trait can be extracted to separate into separate interface at any moment.
altavir commented 2020-10-28 09:26:02 +03:00 (Migrated from github.com)
Review

Removed

Removed
CommanderTvis commented 2020-10-26 22:57:33 +03:00 (Migrated from github.com)
Review
  1. SAM interface.
  2. Does it have any uses, except the one in DifferentiableExpression? This trait can be extracted to separate into separate interface at any moment.
1. SAM interface. 2. Does it have any uses, except the one in DifferentiableExpression? This trait can be extracted to separate into separate interface at any moment.
altavir commented 2020-10-28 09:26:02 +03:00 (Migrated from github.com)
Review

Removed

Removed
/**
CommanderTvis commented 2020-10-26 22:55:36 +03:00 (Migrated from github.com)
Review

Overload with vararg symbols: Symbol for order 1 can be added, too.

Overload with `vararg symbols: Symbol` for order 1 can be added, too.
CommanderTvis commented 2020-10-26 22:57:33 +03:00 (Migrated from github.com)
Review
  1. SAM interface.
  2. Does it have any uses, except the one in DifferentiableExpression? This trait can be extracted to separate into separate interface at any moment.
1. SAM interface. 2. Does it have any uses, except the one in DifferentiableExpression? This trait can be extracted to separate into separate interface at any moment.
altavir commented 2020-10-28 09:26:02 +03:00 (Migrated from github.com)
Review

Removed

Removed
altavir commented 2020-10-28 09:27:49 +03:00 (Migrated from github.com)
Review

No sense in that. People will use first, maximum second derivatives. There is an extension for the first. The second one could be added any moment.

No sense in that. People will use first, maximum second derivatives. There is an extension for the first. The second one could be added any moment.
* An expression that provid
CommanderTvis commented 2020-10-26 22:57:33 +03:00 (Migrated from github.com)
Review
  1. SAM interface.
  2. Does it have any uses, except the one in DifferentiableExpression? This trait can be extracted to separate into separate interface at any moment.
1. SAM interface. 2. Does it have any uses, except the one in DifferentiableExpression? This trait can be extracted to separate into separate interface at any moment.
altavir commented 2020-10-28 09:26:02 +03:00 (Migrated from github.com)
Review

Removed

Removed
*/
CommanderTvis commented 2020-10-26 22:57:33 +03:00 (Migrated from github.com)
Review
  1. SAM interface.
  2. Does it have any uses, except the one in DifferentiableExpression? This trait can be extracted to separate into separate interface at any moment.
1. SAM interface. 2. Does it have any uses, except the one in DifferentiableExpression? This trait can be extracted to separate into separate interface at any moment.
altavir commented 2020-10-28 09:26:02 +03:00 (Migrated from github.com)
Review

Removed

Removed
public interface DifferentiableExpression<T> : Differentiable<Expression<T>>, Expression<T> public interface DifferentiableExpression<T> : Differentiable<Expression<T>>, Expression<T>
public fun <T> DifferentiableExpression<T>.derivative(vararg orders: Pair<Symbol, Int>): Expression<T> = public fun <T> DifferentiableExpression<T>.derivative(vararg orders: Pair<Symbol, Int>): Expression<T> =
@ -14,8 +20,19 @@ public fun <T> DifferentiableExpression<T>.derivative(vararg orders: Pair<Symbol
CommanderTvis commented 2020-10-26 22:57:33 +03:00 (Migrated from github.com)
Review
  1. SAM interface.
  2. Does it have any uses, except the one in DifferentiableExpression? This trait can be extracted to separate into separate interface at any moment.
1. SAM interface. 2. Does it have any uses, except the one in DifferentiableExpression? This trait can be extracted to separate into separate interface at any moment.
CommanderTvis commented 2020-10-26 22:57:33 +03:00 (Migrated from github.com)
Review
  1. SAM interface.
  2. Does it have any uses, except the one in DifferentiableExpression? This trait can be extracted to separate into separate interface at any moment.
1. SAM interface. 2. Does it have any uses, except the one in DifferentiableExpression? This trait can be extracted to separate into separate interface at any moment.
altavir commented 2020-10-28 09:26:02 +03:00 (Migrated from github.com)
Review

Removed

Removed
altavir commented 2020-10-28 09:26:02 +03:00 (Migrated from github.com)
Review

Removed

Removed
public fun <T> DifferentiableExpression<T>.derivative(symbol: Symbol): Expression<T> = derivative(symbol to 1) public fun <T> DifferentiableExpression<T>.derivative(symbol: Symbol): Expression<T> = derivative(symbol to 1)
public fun <T> DifferentiableExpression<T>.derivative(name: String): Expression<T> = derivative(StringSymbol(name) to 1) public fun <T> DifferentiableExpression<T>.derivative(name: String): Expression<T> =
CommanderTvis commented 2020-10-26 22:57:33 +03:00 (Migrated from github.com)
Review
  1. SAM interface.
  2. Does it have any uses, except the one in DifferentiableExpression? This trait can be extracted to separate into separate interface at any moment.
1. SAM interface. 2. Does it have any uses, except the one in DifferentiableExpression? This trait can be extracted to separate into separate interface at any moment.
altavir commented 2020-10-28 09:26:02 +03:00 (Migrated from github.com)
Review

Removed

Removed
CommanderTvis commented 2020-10-26 22:57:33 +03:00 (Migrated from github.com)
Review
  1. SAM interface.
  2. Does it have any uses, except the one in DifferentiableExpression? This trait can be extracted to separate into separate interface at any moment.
1. SAM interface. 2. Does it have any uses, except the one in DifferentiableExpression? This trait can be extracted to separate into separate interface at any moment.
altavir commented 2020-10-28 09:26:02 +03:00 (Migrated from github.com)
Review

Removed

Removed
derivative(StringSymbol(name) to 1)
CommanderTvis commented 2020-10-26 22:57:33 +03:00 (Migrated from github.com)
Review
  1. SAM interface.
  2. Does it have any uses, except the one in DifferentiableExpression? This trait can be extracted to separate into separate interface at any moment.
1. SAM interface. 2. Does it have any uses, except the one in DifferentiableExpression? This trait can be extracted to separate into separate interface at any moment.
altavir commented 2020-10-28 09:26:02 +03:00 (Migrated from github.com)
Review

Removed

Removed
//public interface DifferentiableExpressionBuilder<T, E, A : ExpressionAlgebra<T, E>>: ExpressionBuilder<T,E,A> { //public interface DifferentiableExpressionBuilder<T, E, A : ExpressionAlgebra<T, E>>: ExpressionBuilder<T,E,A> {
// public override fun expression(block: A.() -> E): DifferentiableExpression<T> // public override fun expression(block: A.() -> E): DifferentiableExpression<T>
//} //}
CommanderTvis commented 2020-10-26 22:57:33 +03:00 (Migrated from github.com)
Review
  1. SAM interface.
  2. Does it have any uses, except the one in DifferentiableExpression? This trait can be extracted to separate into separate interface at any moment.
1. SAM interface. 2. Does it have any uses, except the one in DifferentiableExpression? This trait can be extracted to separate into separate interface at any moment.
altavir commented 2020-10-28 09:26:02 +03:00 (Migrated from github.com)
Review

Removed

Removed
public abstract class FirstDerivativeExpression<T> : DifferentiableExpression<T> {
CommanderTvis commented 2020-10-26 22:57:33 +03:00 (Migrated from github.com)
Review
  1. SAM interface.
  2. Does it have any uses, except the one in DifferentiableExpression? This trait can be extracted to separate into separate interface at any moment.
1. SAM interface. 2. Does it have any uses, except the one in DifferentiableExpression? This trait can be extracted to separate into separate interface at any moment.
altavir commented 2020-10-28 09:26:02 +03:00 (Migrated from github.com)
Review

Removed

Removed
CommanderTvis commented 2020-10-26 22:57:33 +03:00 (Migrated from github.com)
Review
  1. SAM interface.
  2. Does it have any uses, except the one in DifferentiableExpression? This trait can be extracted to separate into separate interface at any moment.
1. SAM interface. 2. Does it have any uses, except the one in DifferentiableExpression? This trait can be extracted to separate into separate interface at any moment.
altavir commented 2020-10-28 09:26:02 +03:00 (Migrated from github.com)
Review

Removed

Removed
public abstract fun derivativeOrNull(symbol: Symbol): Expression<T>?
CommanderTvis commented 2020-10-26 22:57:33 +03:00 (Migrated from github.com)
Review
  1. SAM interface.
  2. Does it have any uses, except the one in DifferentiableExpression? This trait can be extracted to separate into separate interface at any moment.
1. SAM interface. 2. Does it have any uses, except the one in DifferentiableExpression? This trait can be extracted to separate into separate interface at any moment.
altavir commented 2020-10-28 09:26:02 +03:00 (Migrated from github.com)
Review

Removed

Removed
CommanderTvis commented 2020-10-26 22:57:33 +03:00 (Migrated from github.com)
Review
  1. SAM interface.
  2. Does it have any uses, except the one in DifferentiableExpression? This trait can be extracted to separate into separate interface at any moment.
1. SAM interface. 2. Does it have any uses, except the one in DifferentiableExpression? This trait can be extracted to separate into separate interface at any moment.
altavir commented 2020-10-28 09:26:02 +03:00 (Migrated from github.com)
Review

Removed

Removed
public override fun derivativeOrNull(orders: Map<Symbol, Int>): Expression<T>? {
CommanderTvis commented 2020-10-26 22:57:33 +03:00 (Migrated from github.com)
Review
  1. SAM interface.
  2. Does it have any uses, except the one in DifferentiableExpression? This trait can be extracted to separate into separate interface at any moment.
1. SAM interface. 2. Does it have any uses, except the one in DifferentiableExpression? This trait can be extracted to separate into separate interface at any moment.
altavir commented 2020-10-28 09:26:02 +03:00 (Migrated from github.com)
Review

Removed

Removed
val dSymbol = orders.entries.singleOrNull { it.value == 1 }?.key ?: return null
CommanderTvis commented 2020-10-26 22:57:33 +03:00 (Migrated from github.com)
Review
  1. SAM interface.
  2. Does it have any uses, except the one in DifferentiableExpression? This trait can be extracted to separate into separate interface at any moment.
1. SAM interface. 2. Does it have any uses, except the one in DifferentiableExpression? This trait can be extracted to separate into separate interface at any moment.
altavir commented 2020-10-28 09:26:02 +03:00 (Migrated from github.com)
Review

Removed

Removed
return derivativeOrNull(dSymbol)
CommanderTvis commented 2020-10-26 22:57:33 +03:00 (Migrated from github.com)
Review
  1. SAM interface.
  2. Does it have any uses, except the one in DifferentiableExpression? This trait can be extracted to separate into separate interface at any moment.
1. SAM interface. 2. Does it have any uses, except the one in DifferentiableExpression? This trait can be extracted to separate into separate interface at any moment.
altavir commented 2020-10-28 09:26:02 +03:00 (Migrated from github.com)
Review

Removed

Removed
}
CommanderTvis commented 2020-10-26 22:57:33 +03:00 (Migrated from github.com)
Review
  1. SAM interface.
  2. Does it have any uses, except the one in DifferentiableExpression? This trait can be extracted to separate into separate interface at any moment.
1. SAM interface. 2. Does it have any uses, except the one in DifferentiableExpression? This trait can be extracted to separate into separate interface at any moment.
altavir commented 2020-10-28 09:26:02 +03:00 (Migrated from github.com)
Review

Removed

Removed
}
CommanderTvis commented 2020-10-26 22:57:33 +03:00 (Migrated from github.com)
Review
  1. SAM interface.
  2. Does it have any uses, except the one in DifferentiableExpression? This trait can be extracted to separate into separate interface at any moment.
1. SAM interface. 2. Does it have any uses, except the one in DifferentiableExpression? This trait can be extracted to separate into separate interface at any moment.
altavir commented 2020-10-28 09:26:02 +03:00 (Migrated from github.com)
Review

Removed

Removed
CommanderTvis commented 2020-10-28 12:56:06 +03:00 (Migrated from github.com)
Review

SAM

SAM
altavir commented 2020-10-28 13:04:11 +03:00 (Migrated from github.com)
Review

I see no reason for that. This interface is mostly implemented by companion objects. Also I plan to add additional methods later.

I see no reason for that. This interface is mostly implemented by companion objects. Also I plan to add additional methods later.

View File

@ -221,23 +221,16 @@ private class AutoDiffContext<T : Any, F : Field<T>>(
public class SimpleAutoDiffExpression<T : Any, F : Field<T>>( public class SimpleAutoDiffExpression<T : Any, F : Field<T>>(
public val field: F, public val field: F,
public val function: AutoDiffField<T, F>.() -> AutoDiffValue<T>, public val function: AutoDiffField<T, F>.() -> AutoDiffValue<T>,
) : DifferentiableExpression<T> { ) : FirstDerivativeExpression<T>() {
public override operator fun invoke(arguments: Map<Symbol, T>): T { public override operator fun invoke(arguments: Map<Symbol, T>): T {
//val bindings = arguments.entries.map { it.key.bind(it.value) } //val bindings = arguments.entries.map { it.key.bind(it.value) }
return AutoDiffContext(field, arguments).function().value return AutoDiffContext(field, arguments).function().value
} }
/** override fun derivativeOrNull(symbol: Symbol): Expression<T> = Expression { arguments ->
* Get the derivative expression with given orders //val bindings = arguments.entries.map { it.key.bind(it.value) }
*/ val derivationResult = AutoDiffContext(field, arguments).derivate(function)
public override fun derivative(orders: Map<Symbol, Int>): Expression<T> { derivationResult.derivative(symbol)
val dSymbol = orders.entries.singleOrNull { it.value == 1 }
?: error("SimpleAutoDiff supports only first order derivatives")
return Expression { arguments ->
//val bindings = arguments.entries.map { it.key.bind(it.value) }
val derivationResult = AutoDiffContext(field, arguments).derivate(function)
derivationResult.derivative(dSymbol.key)
}
} }
} }

View File

@ -1,7 +1,12 @@
package kscience.kmath.expressions package kscience.kmath.expressions
import kscience.kmath.linear.Point
import kscience.kmath.structures.BufferFactory
import kscience.kmath.structures.Structure2D
/** /**
* An environment to easy transform indexed variables to symbols and back. * An environment to easy transform indexed variables to symbols and back.
* TODO requires multi-receivers to be beutiful
*/ */
public interface SymbolIndexer { public interface SymbolIndexer {
public val symbols: List<Symbol> public val symbols: List<Symbol>
@ -22,15 +27,26 @@ public interface SymbolIndexer {
return get(this@SymbolIndexer.indexOf(symbol)) return get(this@SymbolIndexer.indexOf(symbol))
} }
public operator fun <T> Point<T>.get(symbol: Symbol): T {
require(size == symbols.size) { "The input buffer size for indexer should be ${symbols.size} but $size found" }
return get(this@SymbolIndexer.indexOf(symbol))
}
public fun DoubleArray.toMap(): Map<Symbol, Double> { public fun DoubleArray.toMap(): Map<Symbol, Double> {
require(size == symbols.size) { "The input array size for indexer should be ${symbols.size} but $size found" } require(size == symbols.size) { "The input array size for indexer should be ${symbols.size} but $size found" }
return symbols.indices.associate { symbols[it] to get(it) } return symbols.indices.associate { symbols[it] to get(it) }
} }
public operator fun <T> Structure2D<T>.get(rowSymbol: Symbol, columnSymbol: Symbol): T =
get(indexOf(rowSymbol), indexOf(columnSymbol))
public fun <T> Map<Symbol, T>.toList(): List<T> = symbols.map { getValue(it) } public fun <T> Map<Symbol, T>.toList(): List<T> = symbols.map { getValue(it) }
public fun Map<Symbol, Double>.toArray(): DoubleArray = DoubleArray(symbols.size) { getValue(symbols[it]) } public fun <T> Map<Symbol, T>.toPoint(bufferFactory: BufferFactory<T>): Point<T> =
bufferFactory(symbols.size) { getValue(symbols[it]) }
public fun Map<Symbol, Double>.toDoubleArray(): DoubleArray = DoubleArray(symbols.size) { getValue(symbols[it]) }
} }
public inline class SimpleSymbolIndexer(override val symbols: List<Symbol>) : SymbolIndexer public inline class SimpleSymbolIndexer(override val symbols: List<Symbol>) : SymbolIndexer