solve method
Generates the succession generated by the root-finding algorithm. Returns a Record object whose members are:
-
a
guesses
named field, which contains the list of values generated by the algorithm on each step; -
a
convergence
named field, whose value represents the convergence rate for the generated succession (computed using convergence). -
a
efficiency
named field, whose value represents the efficiency of the algorithm (computed using efficiency).
Implementation
@override
({List<double> guesses, double convergence, double efficiency}) solve() {
final guesses = <double>[];
var n = 1;
final evalA = evaluateOn(a);
final evalB = evaluateOn(b);
// Making sure that the root is in the given interval
if (evalA * evalB >= 0) {
throw const NonlinearException('The root is not bracketed.');
}
// Variables setup
var valueA = a;
var valueB = b;
var valueC = a;
var valueD = 0.0;
var diff = (valueB - valueA).abs();
var s = 0.0;
var flag = true;
if (evalA.abs() < evalB.abs()) {
final temp = valueA;
valueA = valueB;
valueB = temp;
}
while ((diff >= tolerance) && (n <= maxSteps)) {
final fa = evaluateOn(valueA);
final fb = evaluateOn(valueB);
final fc = evaluateOn(valueC);
if ((fa != fc) && (fb != fc)) {
// Inverse quadratic interpolation method
final term1 = valueA * fb * fc / ((fa - fb) * (fa - fc));
final term2 = valueB * fa * fc / ((fb - fa) * (fb - fc));
final term3 = valueC * fa * fb / ((fc - fa) * (fc - fb));
s = term1 + term2 + term3;
} else {
// Secant method
s = valueB - (fb * ((valueB - valueA) / (fb - fa)));
}
if (_condition1(s, valueA, valueB) ||
_condition2(s, flag, valueB, valueC) ||
_condition3(s, flag, valueB, valueC, valueD) ||
_condition4(flag, valueB, valueC) ||
_condition5(flag, valueC, valueD)) {
// Bisection method
s = (valueA + valueB) / 2;
} else {
flag = false;
}
// 's' is the value of the root to be discovered
guesses.add(s);
// Generating new brackets for the next iteration
final fs = evaluateOn(s);
valueD = valueC;
valueC = valueB;
if (fa * fs < 0) {
valueB = s;
} else {
valueA = s;
}
if (fa.abs() < fb.abs()) {
final temp = valueA;
valueA = valueB;
valueB = temp;
}
// Updating the exit conditions
++n;
diff = (valueB - valueA).abs();
}
return (
guesses: guesses,
convergence: convergence(guesses, maxSteps),
efficiency: efficiency(guesses, maxSteps),
);
}