Add attribute builder accessors for fits
This commit is contained in:
parent
a756490d20
commit
ef31e35603
CHANGELOG.md
examples/src/main/kotlin/space/kscience/kmath/fit
kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization
@ -3,6 +3,7 @@
|
||||
## Unreleased
|
||||
|
||||
### Added
|
||||
- Fit accessors with Attribute
|
||||
|
||||
### Changed
|
||||
- Upgrade tensorflow version to 1.0.0
|
||||
|
@ -14,7 +14,10 @@ import space.kscience.kmath.expressions.autodiff
|
||||
import space.kscience.kmath.expressions.symbol
|
||||
import space.kscience.kmath.operations.asIterable
|
||||
import space.kscience.kmath.operations.toList
|
||||
import space.kscience.kmath.optimization.*
|
||||
import space.kscience.kmath.optimization.minimize
|
||||
import space.kscience.kmath.optimization.optimizeWith
|
||||
import space.kscience.kmath.optimization.result
|
||||
import space.kscience.kmath.optimization.resultValue
|
||||
import space.kscience.kmath.random.RandomGenerator
|
||||
import space.kscience.kmath.real.DoubleVector
|
||||
import space.kscience.kmath.real.map
|
||||
@ -79,9 +82,10 @@ suspend fun main() {
|
||||
val result = chi2.optimizeWith(
|
||||
CMOptimizer,
|
||||
mapOf(a to 1.5, b to 0.9, c to 1.0),
|
||||
) {
|
||||
FunctionOptimizationTarget(OptimizationDirection.MINIMIZE)
|
||||
}
|
||||
attributesBuilder = {
|
||||
minimize()
|
||||
}
|
||||
)
|
||||
|
||||
//display a page with plot and numerical results
|
||||
val page = Plotly.page {
|
||||
|
@ -7,7 +7,6 @@ package space.kscience.kmath.fit
|
||||
|
||||
import kotlinx.html.br
|
||||
import kotlinx.html.h3
|
||||
import space.kscience.attributes.Attributes
|
||||
import space.kscience.kmath.data.XYErrorColumnarData
|
||||
import space.kscience.kmath.distributions.NormalDistribution
|
||||
import space.kscience.kmath.expressions.Symbol
|
||||
@ -65,7 +64,9 @@ suspend fun main() {
|
||||
QowOptimizer,
|
||||
Double.autodiff,
|
||||
mapOf(a to 0.9, b to 1.2, c to 2.0, e to 1.0, d to 1.0, e to 0.0),
|
||||
attributes = Attributes(OptimizationParameters, listOf(a, b, c, d))
|
||||
attributesBuilder = {
|
||||
freeParameters(a, b, c, d)
|
||||
},
|
||||
) { arg ->
|
||||
//bind variables to autodiff context
|
||||
val a by binding
|
||||
|
17
kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/FunctionOptimization.kt
17
kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/FunctionOptimization.kt
@ -22,6 +22,15 @@ public enum class OptimizationDirection {
|
||||
|
||||
public object FunctionOptimizationTarget : OptimizationAttribute<OptimizationDirection>
|
||||
|
||||
public fun AttributesBuilder<FunctionOptimization<*>>.maximize() {
|
||||
FunctionOptimizationTarget(OptimizationDirection.MAXIMIZE)
|
||||
}
|
||||
|
||||
public fun AttributesBuilder<FunctionOptimization<*>>.minimize() {
|
||||
FunctionOptimizationTarget(OptimizationDirection.MINIMIZE)
|
||||
}
|
||||
|
||||
|
||||
public class FunctionOptimization<T>(
|
||||
public val expression: DifferentiableExpression<T>,
|
||||
override val attributes: Attributes,
|
||||
@ -74,11 +83,11 @@ public fun <T> FunctionOptimization<T>.withAttributes(
|
||||
public suspend fun <T> DifferentiableExpression<T>.optimizeWith(
|
||||
optimizer: Optimizer<T, FunctionOptimization<T>>,
|
||||
startingPoint: Map<Symbol, T>,
|
||||
modifier: AttributesBuilder<FunctionOptimization<T>>.() -> Unit = {},
|
||||
attributesBuilder: AttributesBuilder<FunctionOptimization<T>>.() -> Unit = {},
|
||||
): FunctionOptimization<T> {
|
||||
val problem = FunctionOptimization(this) {
|
||||
startAt(startingPoint)
|
||||
modifier()
|
||||
attributesBuilder()
|
||||
}
|
||||
return optimizer.optimize(problem)
|
||||
}
|
||||
@ -93,11 +102,11 @@ public val <T> FunctionOptimization<T>.resultValue: T
|
||||
public suspend fun <T> DifferentiableExpression<T>.optimizeWith(
|
||||
optimizer: Optimizer<T, FunctionOptimization<T>>,
|
||||
vararg startingPoint: Pair<Symbol, T>,
|
||||
builder: AttributesBuilder<FunctionOptimization<T>>.() -> Unit = {},
|
||||
attributesBuilder: AttributesBuilder<FunctionOptimization<T>>.() -> Unit = {},
|
||||
): FunctionOptimization<T> {
|
||||
val problem = FunctionOptimization<T>(this) {
|
||||
startAt(mapOf(*startingPoint))
|
||||
builder()
|
||||
attributesBuilder()
|
||||
}
|
||||
return optimizer.optimize(problem)
|
||||
}
|
||||
|
@ -58,9 +58,15 @@ public object OptimizationLog : OptimizationAttribute<Loggable>
|
||||
*/
|
||||
public object OptimizationParameters : OptimizationAttribute<List<Symbol>>
|
||||
|
||||
public fun AttributesBuilder<OptimizationProblem<*>>.freeParameters(vararg symbols: Symbol) {
|
||||
OptimizationParameters(symbols.asList())
|
||||
}
|
||||
|
||||
/**
|
||||
* Maximum allowed number of iterations
|
||||
*/
|
||||
public object OptimizationIterations : OptimizationAttribute<Int>
|
||||
|
||||
|
||||
public fun AttributesBuilder<OptimizationProblem<*>>.iterations(iterations: Int) {
|
||||
OptimizationIterations(iterations)
|
||||
}
|
||||
|
@ -137,6 +137,24 @@ public suspend fun XYColumnarData<Double, Double, Double>.fitWith(
|
||||
return optimizer.optimize(problem)
|
||||
}
|
||||
|
||||
public suspend fun XYColumnarData<Double, Double, Double>.fitWith(
|
||||
optimizer: Optimizer<Double, XYFit>,
|
||||
modelExpression: DifferentiableExpression<Float64>,
|
||||
startingPoint: Map<Symbol, Double>,
|
||||
attributesBuilder: AttributesBuilder<XYFit>.() -> Unit,
|
||||
xSymbol: Symbol = Symbol.x,
|
||||
pointToCurveDistance: PointToCurveDistance = PointToCurveDistance.byY,
|
||||
pointWeight: PointWeight = PointWeight.byYSigma,
|
||||
): XYFit = fitWith(
|
||||
optimizer = optimizer,
|
||||
modelExpression = modelExpression,
|
||||
startingPoint = startingPoint,
|
||||
attributes = Attributes<XYFit>(attributesBuilder),
|
||||
xSymbol = xSymbol,
|
||||
pointToCurveDistance = pointToCurveDistance,
|
||||
pointWeight = pointWeight
|
||||
)
|
||||
|
||||
/**
|
||||
* Fit given data with a model provided as an expression
|
||||
*/
|
||||
@ -166,6 +184,26 @@ public suspend fun <I : Any, A> XYColumnarData<Double, Double, Double>.fitWith(
|
||||
)
|
||||
}
|
||||
|
||||
public suspend fun <I : Any, A> XYColumnarData<Double, Double, Double>.fitWith(
|
||||
optimizer: Optimizer<Double, XYFit>,
|
||||
processor: AutoDiffProcessor<Double, I, A>,
|
||||
startingPoint: Map<Symbol, Double>,
|
||||
attributesBuilder: AttributesBuilder<XYFit>.() -> Unit,
|
||||
xSymbol: Symbol = Symbol.x,
|
||||
pointToCurveDistance: PointToCurveDistance = PointToCurveDistance.byY,
|
||||
pointWeight: PointWeight = PointWeight.byYSigma,
|
||||
model: A.(I) -> I,
|
||||
): XYFit where A : ExtendedField<I>, A : ExpressionAlgebra<Double, I> = fitWith(
|
||||
optimizer = optimizer,
|
||||
processor = processor,
|
||||
startingPoint = startingPoint,
|
||||
attributes = Attributes<XYFit>(attributesBuilder),
|
||||
xSymbol = xSymbol,
|
||||
pointToCurveDistance = pointToCurveDistance,
|
||||
pointWeight = pointWeight,
|
||||
model = model
|
||||
)
|
||||
|
||||
/**
|
||||
* Compute chi squared value for completed fit. Return null for incomplete fit
|
||||
*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user