@@ -1544,8 +1544,8 @@ static int polysolve(int order, const DBL *Coeffs, DBL *roots)
15441544 // ---
15451545 // Reverse coefficients into order used herein.
15461546 // Drop any leading original order coefficients meaningfully 0.0.
1547- // Set any remaining coefficients meaningfully 0.0 to exactly 0.0.
1548- //
1547+ // (Commented below) Set any remaining coefficients meaningfully 0.0 to exactly 0.0.
1548+
15491549 np = 0 ;
15501550 for (i = 0 ; i <= order; i++)
15511551 {
@@ -1556,14 +1556,14 @@ static int polysolve(int order, const DBL *Coeffs, DBL *roots)
15561556 else
15571557 {
15581558 potentialLeadingZero = false ;
1559- if (fabs (Coeffs[i]) < POV_DBL_EPSILON)
1560- {
1561- sseq[0 ].coef [order-i] = (PRECISE_FLOAT)0.0 ;
1562- }
1563- else
1564- {
1559+ // if (fabs(Coeffs[i]) < POV_DBL_EPSILON)
1560+ // {
1561+ // sseq[0].coef[order-i] = (PRECISE_FLOAT)0.0;
1562+ // }
1563+ // else
1564+ // {
15651565 sseq[0 ].coef [order-i] = (PRECISE_FLOAT)Coeffs[i];
1566- }
1566+ // }
15671567 }
15681568 }
15691569 order -= np;
@@ -1580,23 +1580,23 @@ static int polysolve(int order, const DBL *Coeffs, DBL *roots)
15801580
15811581 // ---
15821582 // Build the Sturm sequence
1583- //
1583+
15841584 np = buildsturm (order, &sseq[0 ]);
15851585
15861586 // ---
15871587 // Calculate the total number of visible roots.
15881588 // NOTE: Changed to <=0 test over ==0 due sphere_sweep b_spline
15891589 // going negative when the modp leading coef filter set lower.
15901590 // Similar change to the numchanges based test below.
1591- //
1591+
15921592 if ((nroots = visible_roots (np, sseq)) <= 0 )
15931593 {
15941594 return (0 );
15951595 }
15961596
15971597 // ---
15981598 // Bracket the roots
1599- //
1599+
16001600 min_value = 0.0 ;
16011601 max_value = MAX_DISTANCE;
16021602
@@ -1608,7 +1608,7 @@ static int polysolve(int order, const DBL *Coeffs, DBL *roots)
16081608 // Cohen, Alan M. (2009). "Bounds for the roots of polynomial equations".
16091609 // Mathematical Gazette. 93: 87-88.
16101610 // NOTE: Had to use > 1.0 in max_value2 calculation in practice...
1611- //
1611+
16121612 Abs_Coeff_n = fabs (Coeffs[0 ]); // Leading zeros dropped above.
16131613 max_value2 = 1.1 + fabs (Coeffs[1 ]/Abs_Coeff_n);
16141614 max_value = fabs (Coeffs[2 ]);
@@ -1623,7 +1623,7 @@ static int polysolve(int order, const DBL *Coeffs, DBL *roots)
16231623 // Perhaps related to how the sturm chain is pruned in modp(). Until sorted adding
16241624 // the following sanity check which restores a MAX_DISTANCE upper bound where
16251625 // root(s) exists above estimated upper bound.
1626- //
1626+
16271627 atmin = numchanges (np, sseq, (PRECISE_FLOAT)max_value);
16281628 atmax = numchanges (np, sseq, (PRECISE_FLOAT)MAX_DISTANCE);
16291629 if ((atmin - atmax) != 0 )
@@ -1643,10 +1643,39 @@ static int polysolve(int order, const DBL *Coeffs, DBL *roots)
16431643 return (0 );
16441644 }
16451645
1646- // perform the bisection.
1647- //
1648- return (sbisect (np, sseq, (PRECISE_FLOAT)min_value, (PRECISE_FLOAT)max_value,
1649- atmin, atmax, roots));
1646+ // Perform the bisection.
1647+
1648+ nroots = sbisect (np, sseq, (PRECISE_FLOAT)min_value, (PRECISE_FLOAT)max_value,
1649+ atmin, atmax, roots);
1650+
1651+ // Newton Raphson root polishing step. Using SMALL_ENOUGH value currently
1652+ // to limit to one pass, but could try for more accuracy if need be.
1653+ // See similar code in solve_quartic for additional comment.
1654+
1655+ DBL pv, dpv, t, dt;
1656+ for (int c = 0 ; c < nroots; c++)
1657+ {
1658+ t = roots[c];
1659+ for (int j = 0 ; j < 7 ; j++)
1660+ {
1661+ pv = sseq[0 ].coef [order] * t + sseq[0 ].coef [order-1 ];
1662+ dpv = sseq[0 ].coef [order];
1663+ for (int k=order-2 ; k>=0 ; k--)
1664+ {
1665+ dpv = dpv * t + pv;
1666+ pv = pv * t + sseq[0 ].coef [k];
1667+ }
1668+
1669+ dt = pv / dpv;
1670+ t -= dt;
1671+ if (fabs (dt) < SMALL_ENOUGH)
1672+ {
1673+ roots[c] = t;
1674+ break ;
1675+ }
1676+ }
1677+ }
1678+ return (nroots);
16501679}
16511680
16521681
0 commit comments