forked from kscience/kmath
A minor change to XYfit arguments
This commit is contained in:
parent
3f4fe9e43b
commit
2e4be2aa3a
@ -30,7 +30,7 @@ public interface PointToCurveDistance : OptimizationFeature {
|
|||||||
|
|
||||||
return object : DifferentiableExpression<Double> {
|
return object : DifferentiableExpression<Double> {
|
||||||
override fun derivativeOrNull(
|
override fun derivativeOrNull(
|
||||||
symbols: List<Symbol>
|
symbols: List<Symbol>,
|
||||||
): Expression<Double>? = problem.model.derivativeOrNull(symbols)?.let { derivExpression ->
|
): Expression<Double>? = problem.model.derivativeOrNull(symbols)?.let { derivExpression ->
|
||||||
Expression { arguments ->
|
Expression { arguments ->
|
||||||
derivExpression.invoke(arguments + (Symbol.x to x))
|
derivExpression.invoke(arguments + (Symbol.x to x))
|
||||||
@ -93,24 +93,15 @@ public fun XYFit.withFeature(vararg features: OptimizationFeature): XYFit {
|
|||||||
return XYFit(data, model, this.features.with(*features), pointToCurveDistance, pointWeight)
|
return XYFit(data, model, this.features.with(*features), pointToCurveDistance, pointWeight)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public suspend fun XYColumnarData<Double, Double, Double>.fitWith(
|
||||||
* Fit given dta with
|
|
||||||
*/
|
|
||||||
public suspend fun <I : Any, A> XYColumnarData<Double, Double, Double>.fitWith(
|
|
||||||
optimizer: Optimizer<Double, XYFit>,
|
optimizer: Optimizer<Double, XYFit>,
|
||||||
processor: AutoDiffProcessor<Double, I, A>,
|
modelExpression: DifferentiableExpression<Double>,
|
||||||
startingPoint: Map<Symbol, Double>,
|
startingPoint: Map<Symbol, Double>,
|
||||||
vararg features: OptimizationFeature = emptyArray(),
|
vararg features: OptimizationFeature = emptyArray(),
|
||||||
xSymbol: Symbol = Symbol.x,
|
xSymbol: Symbol = Symbol.x,
|
||||||
pointToCurveDistance: PointToCurveDistance = PointToCurveDistance.byY,
|
pointToCurveDistance: PointToCurveDistance = PointToCurveDistance.byY,
|
||||||
pointWeight: PointWeight = PointWeight.byYSigma,
|
pointWeight: PointWeight = PointWeight.byYSigma,
|
||||||
model: A.(I) -> I
|
): XYFit {
|
||||||
): XYFit where A : ExtendedField<I>, A : ExpressionAlgebra<Double, I> {
|
|
||||||
val modelExpression = processor.differentiate {
|
|
||||||
val x = bindSymbol(xSymbol)
|
|
||||||
model(x)
|
|
||||||
}
|
|
||||||
|
|
||||||
var actualFeatures = FeatureSet.of(*features, OptimizationStartPoint(startingPoint))
|
var actualFeatures = FeatureSet.of(*features, OptimizationStartPoint(startingPoint))
|
||||||
|
|
||||||
if (actualFeatures.getFeature<OptimizationLog>() == null) {
|
if (actualFeatures.getFeature<OptimizationLog>() == null) {
|
||||||
@ -127,20 +118,50 @@ public suspend fun <I : Any, A> XYColumnarData<Double, Double, Double>.fitWith(
|
|||||||
return optimizer.optimize(problem)
|
return optimizer.optimize(problem)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fit given data with a model provided as an expression
|
||||||
|
*/
|
||||||
|
public suspend fun <I : Any, A> XYColumnarData<Double, Double, Double>.fitWith(
|
||||||
|
optimizer: Optimizer<Double, XYFit>,
|
||||||
|
processor: AutoDiffProcessor<Double, I, A>,
|
||||||
|
startingPoint: Map<Symbol, Double>,
|
||||||
|
vararg features: OptimizationFeature = emptyArray(),
|
||||||
|
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> {
|
||||||
|
val modelExpression: DifferentiableExpression<Double> = processor.differentiate {
|
||||||
|
val x = bindSymbol(xSymbol)
|
||||||
|
model(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
return fitWith(
|
||||||
|
optimizer = optimizer,
|
||||||
|
modelExpression = modelExpression,
|
||||||
|
startingPoint = startingPoint,
|
||||||
|
features = features,
|
||||||
|
xSymbol = xSymbol,
|
||||||
|
pointToCurveDistance = pointToCurveDistance,
|
||||||
|
pointWeight = pointWeight
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compute chi squared value for completed fit. Return null for incomplete fit
|
* Compute chi squared value for completed fit. Return null for incomplete fit
|
||||||
*/
|
*/
|
||||||
public val XYFit.chiSquaredOrNull: Double? get() {
|
public val XYFit.chiSquaredOrNull: Double?
|
||||||
val result = resultPointOrNull ?: return null
|
get() {
|
||||||
|
val result = resultPointOrNull ?: return null
|
||||||
|
|
||||||
return data.indices.sumOf { index->
|
return data.indices.sumOf { index ->
|
||||||
|
|
||||||
val x = data.x[index]
|
val x = data.x[index]
|
||||||
val y = data.y[index]
|
val y = data.y[index]
|
||||||
val yErr = data[Symbol.yError]?.get(index) ?: 1.0
|
val yErr = data[Symbol.yError]?.get(index) ?: 1.0
|
||||||
|
|
||||||
val mu = model.invoke(result + (xSymbol to x) )
|
val mu = model.invoke(result + (xSymbol to x))
|
||||||
|
|
||||||
((y - mu)/yErr).pow(2)
|
((y - mu) / yErr).pow(2)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user