2
0
mirror of https://github.com/boostorg/math.git synced 2026-02-26 16:52:27 +00:00

Merge branch 'develop'

This commit is contained in:
Matt Borland
2024-03-28 15:44:24 +01:00
3 changed files with 48 additions and 42 deletions

View File

@@ -790,35 +790,35 @@ inline T schroeder_iterate(F f, T guess, T min, T max, int digits) noexcept(poli
* so this default should recover full precision even in this somewhat pathological case.
* For isolated roots, the problem is so rapidly convergent that this doesn't matter at all.
*/
template<class Complex, class F>
Complex complex_newton(F g, Complex guess, int max_iterations = std::numeric_limits<typename Complex::value_type>::digits)
template<class ComplexType, class F>
ComplexType complex_newton(F g, ComplexType guess, int max_iterations = std::numeric_limits<typename ComplexType::value_type>::digits)
{
typedef typename Complex::value_type Real;
typedef typename ComplexType::value_type Real;
using std::norm;
using std::abs;
using std::max;
// z0, z1, and z2 cannot be the same, in case we immediately need to resort to Muller's Method:
Complex z0 = guess + Complex(1, 0);
Complex z1 = guess + Complex(0, 1);
Complex z2 = guess;
ComplexType z0 = guess + ComplexType(1, 0);
ComplexType z1 = guess + ComplexType(0, 1);
ComplexType z2 = guess;
do {
auto pair = g(z2);
if (norm(pair.second) == 0)
{
// Muller's method. Notation follows Numerical Recipes, 9.5.2:
Complex q = (z2 - z1) / (z1 - z0);
ComplexType q = (z2 - z1) / (z1 - z0);
auto P0 = g(z0);
auto P1 = g(z1);
Complex qp1 = static_cast<Complex>(1) + q;
Complex A = q * (pair.first - qp1 * P1.first + q * P0.first);
ComplexType qp1 = static_cast<ComplexType>(1) + q;
ComplexType A = q * (pair.first - qp1 * P1.first + q * P0.first);
Complex B = (static_cast<Complex>(2) * q + static_cast<Complex>(1)) * pair.first - qp1 * qp1 * P1.first + q * q * P0.first;
Complex C = qp1 * pair.first;
Complex rad = sqrt(B * B - static_cast<Complex>(4) * A * C);
Complex denom1 = B + rad;
Complex denom2 = B - rad;
Complex correction = (z1 - z2) * static_cast<Complex>(2) * C;
ComplexType B = (static_cast<ComplexType>(2) * q + static_cast<ComplexType>(1)) * pair.first - qp1 * qp1 * P1.first + q * q * P0.first;
ComplexType C = qp1 * pair.first;
ComplexType rad = sqrt(B * B - static_cast<ComplexType>(4) * A * C);
ComplexType denom1 = B + rad;
ComplexType denom2 = B - rad;
ComplexType correction = (z1 - z2) * static_cast<ComplexType>(2) * C;
if (norm(denom1) > norm(denom2))
{
correction /= denom1;