solutions method
Calculates the roots (the solutions) of the equation.
Implementation
@override
List<Complex> solutions() {
// In case the polynomial was a constant, just return an empty array because
// there are no solutions
if (coefficients.length <= 1) {
return [];
}
// Proceeding with the setup since the polynomial degree is >= 1.
final coefficientsLength = coefficients.length;
final reversedCoeffs = coefficients.reversed.toList();
// Buffers for numerators and denominators or real and complex parts.
final realBuffer = reversedCoeffs.map((e) => e.real).toList();
final imaginaryBuffer = reversedCoeffs.map((e) => e.imaginary).toList();
// Scaling the various coefficients.
var upperReal = realBuffer[coefficientsLength - 1];
var upperComplex = imaginaryBuffer[coefficientsLength - 1];
final squareSum = upperReal * upperReal + upperComplex * upperComplex;
upperReal /= squareSum;
upperComplex /= -squareSum;
var k1 = 0.0;
var k2 = 0.0;
var k3 = 0.0;
final s = upperComplex - upperReal;
final t = upperReal + upperComplex;
for (var i = 0; i < coefficientsLength - 1; ++i) {
k1 = upperReal * (realBuffer[i] + imaginaryBuffer[i]);
k2 = realBuffer[i] * s;
k3 = imaginaryBuffer[i] * t;
realBuffer[i] = k1 - k3;
imaginaryBuffer[i] = k1 + k2;
}
realBuffer[coefficientsLength - 1] = 1.0;
imaginaryBuffer[coefficientsLength - 1] = 0.0;
// Using default values to compute the solutions. If they aren't provided,
// we will generate default ones.
if (initialGuess.isNotEmpty) {
final real = initialGuess.map((e) => e.real).toList();
final complex = initialGuess.map((e) => e.imaginary).toList();
return _solve(
realValues: real,
imaginaryValues: complex,
realBuffer: realBuffer,
imaginaryBuffer: imaginaryBuffer,
);
} else {
// If we're here, it means that no initial guesses were provided and so we
// need to generate some good ones.
final real = List<double>.generate(
coefficientsLength - 1,
(_) => 0.0,
);
final complex = List<double>.generate(
coefficientsLength - 1,
(_) => 0.0,
);
final factor = 0.65 *
_bound(
value: coefficientsLength,
realBuffer: realBuffer,
imaginaryBuffer: imaginaryBuffer,
);
final multiplier = math.cos(0.25 * 2 * math.pi);
for (var i = 0; i < coefficientsLength - 1; ++i) {
real[i] = factor * multiplier;
complex[i] = factor * math.sqrt(1.0 - multiplier * multiplier);
}
return _solve(
realValues: real,
imaginaryValues: complex,
realBuffer: realBuffer,
imaginaryBuffer: imaginaryBuffer,
);
}
}