private static RealPolynomialFunction1D quadratic(double[] x, double[] y, int index) { double a = y[index]; double dx1 = x[index] - x[index - 1]; double dx2 = x[index + 1] - x[index]; double dy1 = y[index] - y[index - 1]; double dy2 = y[index + 1] - y[index]; double b = (dx1 * dy2 / dx2 + dx2 * dy1 / dx1) / (dx1 + dx2); double c = (dy2 / dx2 - dy1 / dx1) / (dx1 + dx2); return new RealPolynomialFunction1D(new double[] {a, b, c}); }
private static RealPolynomialFunction1D quadraticFirstDerivative(double[] x, double[] y, int index) { double dx1 = x[index] - x[index - 1]; double dx2 = x[index + 1] - x[index]; double dy1 = y[index] - y[index - 1]; double dy2 = y[index + 1] - y[index]; double b = (dx1 * dy2 / dx2 + dx2 * dy1 / dx1) / (dx1 + dx2); double c = (dy2 / dx2 - dy1 / dx1) / (dx1 + dx2); return new RealPolynomialFunction1D(new double[] {b, 2. * c}); }
/** * Returns the derivative of this polynomial (also a polynomial), where * $$ * \begin{align*} * P'(x) = a_1 + 2 a_2 x + 3 a_3 x^2 + 4 a_4 x^3 + \dots + n a_n x^{n-1} * \end{align*} * $$. * * @return the derivative polynomial */ @Override public RealPolynomialFunction1D derivative() { int n = _coefficients.length - 1; double[] coefficients = new double[n]; for (int i = 1; i <= n; i++) { coefficients[i - 1] = i * _coefficients[i]; } return new RealPolynomialFunction1D(coefficients); }
private static RealPolynomialFunction1D[] quadraticsFirstDerivative(double[] x, double[] y, int intervalCount) { if (intervalCount == 1) { double b = (y[1] - y[0]) / (x[1] - x[0]); return new RealPolynomialFunction1D[] {new RealPolynomialFunction1D(b)}; } else { RealPolynomialFunction1D[] quadraticFirstDerivative = new RealPolynomialFunction1D[intervalCount - 1]; for (int i = 1; i < intervalCount; i++) { quadraticFirstDerivative[i - 1] = quadraticFirstDerivative(x, y, i); } return quadraticFirstDerivative; } }
private static RealPolynomialFunction1D[] quadratics(double[] x, double[] y, int intervalCount) { if (intervalCount == 1) { double a = y[1]; double b = (y[1] - y[0]) / (x[1] - x[0]); return new RealPolynomialFunction1D[] {new RealPolynomialFunction1D(a, b)}; } RealPolynomialFunction1D[] quadratic = new RealPolynomialFunction1D[intervalCount - 1]; for (int i = 1; i < intervalCount; i++) { quadratic[i - 1] = quadratic(x, y, i); } return quadratic; }
/** * Subtracts a constant from the polynomial (equivalent to subtracting the value from the * constant term of the polynomial). The result is also a polynomial. * * @param a the value to add * @return $P-a$ */ @Override public RealPolynomialFunction1D subtract(double a) { double[] c = Arrays.copyOf(getCoefficients(), _n); c[0] -= a; return new RealPolynomialFunction1D(c); }
/** * Adds a constant to the polynomial (equivalent to adding the value to the constant * term of the polynomial). The result is also a polynomial. * * @param a the value to add * @return $P+a$ */ @Override public RealPolynomialFunction1D add(double a) { double[] c = Arrays.copyOf(getCoefficients(), _n); c[0] += a; return new RealPolynomialFunction1D(c); }
/** * Divides the polynomial by a constant value (equivalent to dividing each coefficient by this value). * The result is also a polynomial. * * @param a the divisor * @return the polynomial */ @Override public RealPolynomialFunction1D divide(double a) { double[] c = Arrays.copyOf(getCoefficients(), _n); for (int i = 0; i < _n; i++) { c[i] /= a; } return new RealPolynomialFunction1D(c); }
/** * Multiplies the polynomial by a constant value (equivalent to multiplying each * coefficient by this value). The result is also a polynomial. * * @param a the multiplicator * @return the polynomial */ @Override public RealPolynomialFunction1D multiply(double a) { double[] c = Arrays.copyOf(getCoefficients(), _n); for (int i = 0; i < _n; i++) { c[i] *= a; } return new RealPolynomialFunction1D(c); }
double an = _coefficients[_n - 1]; if (DoubleMath.fuzzyEquals(an, (double) 1, 1e-15)) { return new RealPolynomialFunction1D(Arrays.copyOf(_coefficients, _n)); rescaled[i] = _coefficients[i] / an; return new RealPolynomialFunction1D(rescaled);
@Test(expectedExceptions = IllegalArgumentException.class) public void testNullCoefficients() { new RealPolynomialFunction1D(null); }
@Test(expectedExceptions = IllegalArgumentException.class) public void testEmptyCoefficients() { new RealPolynomialFunction1D(new double[0]); }
/** * Adds a function to the polynomial. * If the function is not a {@link RealPolynomialFunction1D} then the addition takes * place as in {@link DoubleFunction1D}, otherwise the result will also be a polynomial. * * @param f the function to add * @return $P+f$ */ @Override public DoubleFunction1D add(DoubleFunction1D f) { ArgChecker.notNull(f, "function"); if (f instanceof RealPolynomialFunction1D) { RealPolynomialFunction1D p1 = (RealPolynomialFunction1D) f; double[] c1 = p1.getCoefficients(); double[] c = _coefficients; int n = c1.length; boolean longestIsNew = n > _n; double[] c3 = longestIsNew ? Arrays.copyOf(c1, n) : Arrays.copyOf(c, _n); for (int i = 0; i < (longestIsNew ? _n : n); i++) { c3[i] += longestIsNew ? c[i] : c1[i]; } return new RealPolynomialFunction1D(c3); } return DoubleFunction1D.super.add(f); }
@Test(expectedExceptions = IllegalArgumentException.class) public void testNonCubic2() { REAL_ONLY_CUBIC.getRoots(new RealPolynomialFunction1D(1, 1, 1, 1, 1)); }
@Test(expectedExceptions = IllegalArgumentException.class) public void testNonCubic1() { CUBIC.getRoots(new RealPolynomialFunction1D(1, 1, 1, 1, 1)); }
/** * Multiplies the polynomial by a function. * If the function is not a {@link RealPolynomialFunction1D} then the multiplication takes * place as in {@link DoubleFunction1D}, otherwise the result will also be a polynomial. * * @param f the function by which to multiply * @return $P \dot f$ */ @Override public DoubleFunction1D multiply(DoubleFunction1D f) { ArgChecker.notNull(f, "function"); if (f instanceof RealPolynomialFunction1D) { RealPolynomialFunction1D p1 = (RealPolynomialFunction1D) f; double[] c = _coefficients; double[] c1 = p1.getCoefficients(); int m = c1.length; double[] newC = new double[_n + m - 1]; for (int i = 0; i < newC.length; i++) { newC[i] = 0; for (int j = Math.max(0, i + 1 - m); j < Math.min(_n, i + 1); j++) { newC[i] += c[j] * c1[i - j]; } } return new RealPolynomialFunction1D(newC); } return DoubleFunction1D.super.multiply(f); }
@Test public void test() { try { FINDER.getRoots(null); Assert.fail(); } catch (final IllegalArgumentException e) { // Expected } try { FINDER.getRoots(new RealPolynomialFunction1D(1., 2., 3., 4.)); Assert.fail(); } catch (final IllegalArgumentException e) { // Expected } try { FINDER.getRoots(new RealPolynomialFunction1D(12., 1., 12.)); Assert.fail(); } catch (final MathException e) { // Expected } final Double[] roots = FINDER.getRoots(F); assertEquals(roots[0], -4.0, EPS); assertEquals(roots[1], -3.0, EPS); } }
@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); } } }
/** * Gets the polynomials. * * @param n the n value * @param alpha the alpha value * @return the result */ public DoubleFunction1D[] getPolynomials(int n, double alpha) { ArgChecker.isTrue(n >= 0); DoubleFunction1D[] polynomials = new DoubleFunction1D[n + 1]; for (int i = 0; i <= n; i++) { if (i == 0) { polynomials[i] = getOne(); } else if (i == 1) { polynomials[i] = new RealPolynomialFunction1D(new double[] {1 + alpha, -1}); } else { polynomials[i] = (polynomials[i - 1].multiply(2. * i + alpha - 1).subtract(polynomials[i - 1].multiply(getX())) .subtract(polynomials[i - 2].multiply((i - 1. + alpha))).divide(i)); } } return polynomials; }
/** * Calculates polynomials. * @param n the n value * @param alpha the alpha value * @param beta the beta value * @return the result */ public DoubleFunction1D[] getPolynomials(int n, double alpha, double beta) { ArgChecker.isTrue(n >= 0); DoubleFunction1D[] polynomials = new DoubleFunction1D[n + 1]; for (int i = 0; i <= n; i++) { if (i == 0) { polynomials[i] = getOne(); } else if (i == 1) { polynomials[i] = new RealPolynomialFunction1D(new double[] {(alpha - beta) / 2, (alpha + beta + 2) / 2}); } else { int j = i - 1; polynomials[i] = (polynomials[j].multiply(getB(alpha, beta, j)).add(polynomials[j].multiply(getX()).multiply(getC(alpha, beta, j)) .add(polynomials[j - 1].multiply(getD(alpha, beta, j))))) .divide(getA(alpha, beta, j)); } } return polynomials; }