Skip to content

Commit a6efa00

Browse files
committed
Adding sanity test of upper bound Cauchy method result.
In practice have occasionally found roots slightly above upper bound. Perhaps related to how sturm chain is tweaked during pruning. Sort it later.
1 parent fdc5358 commit a6efa00

File tree

1 file changed

+24
-27
lines changed

1 file changed

+24
-27
lines changed

source/core/math/polynomialsolver.cpp

Lines changed: 24 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1542,43 +1542,40 @@ static int polysolve(int order, const DBL *Coeffs, DBL *roots)
15421542
min_value = 0.0;
15431543
max_value = MAX_DISTANCE;
15441544

1545-
// Optionally use Augustin-Louis Cauchy's methods to determine an upper bound for max_value.
1546-
1547-
// This is the lower bound or bound including, for certain, only the first root but
1548-
// perhaps others.
1549-
if (0)
1550-
{
1551-
max_value = fabs(Coeffs[order]);
1552-
Abs_Coeff_n = fabs(Coeffs[0]);
1553-
for (i = 1; i < order; i++)
1554-
{
1555-
max_value = max(fabs(Coeffs[i]),max_value);
1556-
}
1557-
max_value /= Abs_Coeff_n + 1;
1558-
max_value = min(max_value,MAX_DISTANCE);
1559-
}
1545+
// Use variation of Augustin-Louis Cauchy's methods to determine an upper bound for max_value.
15601546

15611547
// Tighter upper bound found at:
15621548
// https://en.wikipedia.org/wiki/Properties_of_polynomial_roots#Other_bounds
15631549
// which took it from:
15641550
// Cohen, Alan M. (2009). "Bounds for the roots of polynomial equations".
15651551
// Mathematical Gazette. 93: 87-88.
15661552
// NOTE: Had to use > 1.0 in max_value2 calculation in practice...
1567-
if (1)
1553+
1554+
Abs_Coeff_n = fabs(Coeffs[0]); // Solve_Polynomial() dumps leading zeroes.
1555+
max_value2 = 1.1 + fabs(Coeffs[1]/Abs_Coeff_n);
1556+
max_value = fabs(Coeffs[2]);
1557+
for (i = 3; i <= order; i++)
15681558
{
1569-
Abs_Coeff_n = fabs(Coeffs[0]); // Solve_Polynomial() dumps leading zeroes.
1570-
max_value2 = 1.1 + fabs(Coeffs[1]/Abs_Coeff_n);
1571-
max_value = fabs(Coeffs[2]);
1572-
for (i = 3; i <= order; i++)
1573-
{
1574-
max_value = max(fabs(Coeffs[i]),max_value);
1575-
}
1576-
max_value /= Abs_Coeff_n + EPSILON;
1577-
max_value = min(max(max_value,max_value2),MAX_DISTANCE);
1559+
max_value = max(fabs(Coeffs[i]),max_value);
1560+
}
1561+
max_value /= Abs_Coeff_n + EPSILON;
1562+
max_value = min(max(max_value,max_value2),MAX_DISTANCE);
1563+
1564+
// NOTE: Found in practice roots occasionally, slightly outside upper bound...
1565+
// Perhaps related to how the sturm chain is pruned in modp(). Until sorted adding
1566+
// the following sanity check which restores a MAX_DISTANCE upper bound where
1567+
// root(s) exists above estimated upper bound.
1568+
atmin = numchanges(np, sseq, max_value);
1569+
atmax = numchanges(np, sseq, MAX_DISTANCE);
1570+
if ((atmin - atmax) != 0)
1571+
{
1572+
max_value = MAX_DISTANCE;
1573+
}
1574+
else
1575+
{
1576+
atmax = atmin;
15781577
}
1579-
15801578
atmin = numchanges(np, sseq, min_value);
1581-
atmax = numchanges(np, sseq, max_value);
15821579

15831580
nroots = atmin - atmax;
15841581

0 commit comments

Comments
 (0)