fit method
LevenbergMarquardtResult
fit({
- required Vector<
double> xs, - required Vector<
double> ys, - double weight = 1.0,
- Vector<
double> ? weights,
override
Fits a list of data points to the configured model.
Implementation
@override
LevenbergMarquardtResult fit({
required Vector<double> xs,
required Vector<double> ys,
double weight = 1.0,
Vector<double>? weights,
}) {
checkPoints(DataType.float, xs: xs, ys: ys, min: 2);
weights ??=
Vector<double>.constant(DataType.float, ys.count, value: weight);
if (weights.count != xs.count) {
throw ArgumentError.value(
weights, 'weights', 'Expected ${xs.count} values.');
}
final squaredWeights =
weights.map((i, v) => v * v, DataType.float).toVector();
var parameters = initialValues.toVector();
var error = _errorCalculation(parametrizedFunction.bind(parameters),
x: xs, y: ys, squaredWeights: squaredWeights);
var optimalError = error;
var optimalParameters = parameters.toVector();
var converged = error <= errorTolerance;
var currentDamping = damping;
var iteration = 0;
for (; iteration < maxIterations && !converged; iteration++) {
var previousError = error;
final stepResult = _step(
x: xs,
y: ys,
params: parameters,
currentDamping: currentDamping,
squaredWeights: squaredWeights,
);
final perturbations = stepResult.first;
final jacobianWeightResidualError = stepResult.second;
for (var k = 0; k < parameters.count; k++) {
parameters[k] = (parameters[k] - perturbations.get(k, 0))
.clamp(minValues[k], maxValues[k]);
}
error = _errorCalculation(
parametrizedFunction.bind(parameters),
x: xs,
y: ys,
squaredWeights: squaredWeights,
);
if (error.isNaN) break;
if (error < optimalError - errorTolerance) {
optimalError = error;
optimalParameters = parameters.toVector();
}
var improvementMetric = (previousError - error) /
(perturbations.transposed *
(perturbations * currentDamping +
jacobianWeightResidualError))
.get(0, 0);
if (improvementMetric > improvementThreshold) {
currentDamping = max(currentDamping / dampingStepDown, 1e-7);
} else {
currentDamping = min(currentDamping * dampingStepUp, 1e7);
}
converged = error <= errorTolerance;
}
return LevenbergMarquardtResult(
parametrizedFunction.bind(optimalParameters),
parameters: parametrizedFunction.toBindings(optimalParameters),
error: optimalError,
iterations: iteration,
);
}