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
|
## Unreleased
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
- Fit accessors with Attribute
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
- Upgrade tensorflow version to 1.0.0
|
- 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.expressions.symbol
|
||||||
import space.kscience.kmath.operations.asIterable
|
import space.kscience.kmath.operations.asIterable
|
||||||
import space.kscience.kmath.operations.toList
|
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.random.RandomGenerator
|
||||||
import space.kscience.kmath.real.DoubleVector
|
import space.kscience.kmath.real.DoubleVector
|
||||||
import space.kscience.kmath.real.map
|
import space.kscience.kmath.real.map
|
||||||
@ -79,9 +82,10 @@ suspend fun main() {
|
|||||||
val result = chi2.optimizeWith(
|
val result = chi2.optimizeWith(
|
||||||
CMOptimizer,
|
CMOptimizer,
|
||||||
mapOf(a to 1.5, b to 0.9, c to 1.0),
|
mapOf(a to 1.5, b to 0.9, c to 1.0),
|
||||||
) {
|
attributesBuilder = {
|
||||||
FunctionOptimizationTarget(OptimizationDirection.MINIMIZE)
|
minimize()
|
||||||
}
|
}
|
||||||
|
)
|
||||||
|
|
||||||
//display a page with plot and numerical results
|
//display a page with plot and numerical results
|
||||||
val page = Plotly.page {
|
val page = Plotly.page {
|
||||||
|
@ -7,7 +7,6 @@ package space.kscience.kmath.fit
|
|||||||
|
|
||||||
import kotlinx.html.br
|
import kotlinx.html.br
|
||||||
import kotlinx.html.h3
|
import kotlinx.html.h3
|
||||||
import space.kscience.attributes.Attributes
|
|
||||||
import space.kscience.kmath.data.XYErrorColumnarData
|
import space.kscience.kmath.data.XYErrorColumnarData
|
||||||
import space.kscience.kmath.distributions.NormalDistribution
|
import space.kscience.kmath.distributions.NormalDistribution
|
||||||
import space.kscience.kmath.expressions.Symbol
|
import space.kscience.kmath.expressions.Symbol
|
||||||
@ -65,7 +64,9 @@ suspend fun main() {
|
|||||||
QowOptimizer,
|
QowOptimizer,
|
||||||
Double.autodiff,
|
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),
|
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 ->
|
) { arg ->
|
||||||
//bind variables to autodiff context
|
//bind variables to autodiff context
|
||||||
val a by binding
|
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 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 class FunctionOptimization<T>(
|
||||||
public val expression: DifferentiableExpression<T>,
|
public val expression: DifferentiableExpression<T>,
|
||||||
override val attributes: Attributes,
|
override val attributes: Attributes,
|
||||||
@ -74,11 +83,11 @@ public fun <T> FunctionOptimization<T>.withAttributes(
|
|||||||
public suspend fun <T> DifferentiableExpression<T>.optimizeWith(
|
public suspend fun <T> DifferentiableExpression<T>.optimizeWith(
|
||||||
optimizer: Optimizer<T, FunctionOptimization<T>>,
|
optimizer: Optimizer<T, FunctionOptimization<T>>,
|
||||||
startingPoint: Map<Symbol, T>,
|
startingPoint: Map<Symbol, T>,
|
||||||
modifier: AttributesBuilder<FunctionOptimization<T>>.() -> Unit = {},
|
attributesBuilder: AttributesBuilder<FunctionOptimization<T>>.() -> Unit = {},
|
||||||
): FunctionOptimization<T> {
|
): FunctionOptimization<T> {
|
||||||
val problem = FunctionOptimization(this) {
|
val problem = FunctionOptimization(this) {
|
||||||
startAt(startingPoint)
|
startAt(startingPoint)
|
||||||
modifier()
|
attributesBuilder()
|
||||||
}
|
}
|
||||||
return optimizer.optimize(problem)
|
return optimizer.optimize(problem)
|
||||||
}
|
}
|
||||||
@ -93,11 +102,11 @@ public val <T> FunctionOptimization<T>.resultValue: T
|
|||||||
public suspend fun <T> DifferentiableExpression<T>.optimizeWith(
|
public suspend fun <T> DifferentiableExpression<T>.optimizeWith(
|
||||||
optimizer: Optimizer<T, FunctionOptimization<T>>,
|
optimizer: Optimizer<T, FunctionOptimization<T>>,
|
||||||
vararg startingPoint: Pair<Symbol, T>,
|
vararg startingPoint: Pair<Symbol, T>,
|
||||||
builder: AttributesBuilder<FunctionOptimization<T>>.() -> Unit = {},
|
attributesBuilder: AttributesBuilder<FunctionOptimization<T>>.() -> Unit = {},
|
||||||
): FunctionOptimization<T> {
|
): FunctionOptimization<T> {
|
||||||
val problem = FunctionOptimization<T>(this) {
|
val problem = FunctionOptimization<T>(this) {
|
||||||
startAt(mapOf(*startingPoint))
|
startAt(mapOf(*startingPoint))
|
||||||
builder()
|
attributesBuilder()
|
||||||
}
|
}
|
||||||
return optimizer.optimize(problem)
|
return optimizer.optimize(problem)
|
||||||
}
|
}
|
||||||
|
@ -58,9 +58,15 @@ public object OptimizationLog : OptimizationAttribute<Loggable>
|
|||||||
*/
|
*/
|
||||||
public object OptimizationParameters : OptimizationAttribute<List<Symbol>>
|
public object OptimizationParameters : OptimizationAttribute<List<Symbol>>
|
||||||
|
|
||||||
|
public fun AttributesBuilder<OptimizationProblem<*>>.freeParameters(vararg symbols: Symbol) {
|
||||||
|
OptimizationParameters(symbols.asList())
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maximum allowed number of iterations
|
* Maximum allowed number of iterations
|
||||||
*/
|
*/
|
||||||
public object OptimizationIterations : OptimizationAttribute<Int>
|
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)
|
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
|
* 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
|
* Compute chi squared value for completed fit. Return null for incomplete fit
|
||||||
*/
|
*/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user