Skip to content

Commit 74f1382

Browse files
committed
Adding Cauchy based bound estimate to polysolve.
Added code for an original Cauchy bound estimate good for the lower root and a Cauchy based upper bound method good for all roots. The latter is currently hard coded on and this value is used over MAX_DISTANCE. Longer term want to allow passed value and option to pick either of the two methods added with this commit or use MAX_DISTANCE.
1 parent d0c7f30 commit 74f1382

File tree

1 file changed

+38
-4
lines changed

1 file changed

+38
-4
lines changed

source/core/math/polynomialsolver.cpp

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1513,11 +1513,10 @@ static int solve_quartic(const DBL *x, DBL *results)
15131513
static int polysolve(int order, const DBL *Coeffs, DBL *roots)
15141514
{
15151515
polynomial sseq[MAX_ORDER+1];
1516-
DBL min_value, max_value;
1516+
DBL min_value, max_value, max_value2, Abs_Coeff_n;
15171517
int i, nroots, np, atmin, atmax;
15181518

1519-
/* Put the coefficients into the top of the stack. */
1520-
1519+
// Reverse coefficients into order used herein.
15211520
for (i = 0; i <= order; i++)
15221521
{
15231522
sseq[0].coef[order-i] = Coeffs[i];
@@ -1534,11 +1533,46 @@ static int polysolve(int order, const DBL *Coeffs, DBL *roots)
15341533
return(0);
15351534
}
15361535

1537-
/* Bracket the roots */
1536+
// Bracket the roots
15381537

15391538
min_value = 0.0;
15401539
max_value = MAX_DISTANCE;
15411540

1541+
// Optionally use Augustin-Louis Cauchy's methods to determine an upper bound for max_value.
1542+
1543+
// This is the lower bound or bound including, for certain, only the first root but
1544+
// perhaps others.
1545+
if (0)
1546+
{
1547+
max_value = fabs(Coeffs[order]);
1548+
Abs_Coeff_n = fabs(Coeffs[0]);
1549+
for (i = 1; i < order; i++)
1550+
{
1551+
max_value = max(fabs(Coeffs[i]),max_value);
1552+
}
1553+
max_value /= Abs_Coeff_n + 1;
1554+
max_value = min(max_value,MAX_DISTANCE);
1555+
}
1556+
1557+
// Tighter upper bound found at:
1558+
// https://en.wikipedia.org/wiki/Properties_of_polynomial_roots#Other_bounds
1559+
// which took it from:
1560+
// Cohen, Alan M. (2009). "Bounds for the roots of polynomial equations".
1561+
// Mathematical Gazette. 93: 87-88.
1562+
// NOTE: Had to use > 1.0 in max_value2 calculation in practice...
1563+
if (1)
1564+
{
1565+
Abs_Coeff_n = fabs(Coeffs[0]); // Solve_Polynomial() dumps leading zeroes.
1566+
max_value2 = 1.1 + fabs(Coeffs[1]/Abs_Coeff_n);
1567+
max_value = fabs(Coeffs[2]);
1568+
for (i = 3; i <= order; i++)
1569+
{
1570+
max_value = max(fabs(Coeffs[i]),max_value);
1571+
}
1572+
max_value /= Abs_Coeff_n + EPSILON;
1573+
max_value = min(max(max_value,max_value2),MAX_DISTANCE);
1574+
}
1575+
15421576
atmin = numchanges(np, sseq, min_value);
15431577
atmax = numchanges(np, sseq, max_value);
15441578

0 commit comments

Comments
 (0)