EigenvaluePolynomialRootFinder implements Polynomial1DRootFinder<Double> { @Override public Double[] getRoots(final RealPolynomialFunction1D function) { Validate.notNull(function, "function"); final double[] coeffs = function.getCoefficients(); final int l = coeffs.length - 1; final DoubleMatrix2D hessian = DoubleFactory2D.dense.make(l, l); for (int i = 0; i < l; i++) { hessian.setQuick(0, i, -coeffs[l - i - 1] / coeffs[l]); for (int j = 1; j < l; j++) { hessian.setQuick(j, i, 0); if (i != l - 1) { hessian.setQuick(i + 1, i, 1); } } } final double[] d = new EigenvalueDecomposition(hessian).getRealEigenvalues().toArray(); final Double[] result = new Double[d.length]; for (int i = 0; i < d.length; i++) { result[i] = d[i]; } return result; }  @Override Double[] getRoots(final RealPolynomialFunction1D function);  }
@Test(expectedExceptions = IllegalArgumentException.class) public void testNull() { FINDER.getRoots(null); }
@Test public void test() { final double[] r = new double[] {-RANDOM.nextDouble(), -RANDOM.nextDouble(), RANDOM.nextDouble(), RANDOM.nextDouble()}; final double a0 = r[0] * r[1] * r[2] * r[3]; final double a1 = r[0] * r[1] * r[2] + r[0] * r[1] * r[3] + r[0] * r[2] * r[3] + r[1] * r[2] * r[3]; final double a2 = r[0] * r[1] + r[0] * r[2] + r[0] * r[3] + r[1] * r[2] + r[1] * r[3] + r[2] * r[3]; final double a3 = r[0] + r[1] + r[2] + r[3]; final double a4 = 1; final RealPolynomialFunction1D f = new RealPolynomialFunction1D(new double[] {a0, a1, a2, a3, a4}); final Double[] roots = FINDER.getRoots(f); Arrays.sort(roots); final double[] expected = new double[r.length]; for (int i = 0; i < r.length; i++) { expected[i] = -r[i]; } Arrays.sort(expected); for (int i = 0; i < roots.length; i++) { assertEquals(roots[i], expected[i], 1e-12); } }