From 23da497319a687fae5622e71d10a82388c81c8ce Mon Sep 17 00:00:00 2001 From: Gilles Sadowski Date: Thu, 6 Oct 2011 15:44:41 +0000 Subject: [PATCH] MATH-683 New method "shift" to compute coefficients of a polynomial (due to R. di Costanzo). git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/trunk@1179671 13f79535-47bb-0310-9956-ffa450edef68 --- .../polynomials/PolynomialsUtils.java | 56 +++++++++++++++++++ src/site/xdoc/changes.xml | 5 ++ .../polynomials/PolynomialsUtilsTest.java | 30 ++++++++++ 3 files changed, 91 insertions(+) diff --git a/src/main/java/org/apache/commons/math/analysis/polynomials/PolynomialsUtils.java b/src/main/java/org/apache/commons/math/analysis/polynomials/PolynomialsUtils.java index ce2f6ae52..6d8071bc2 100644 --- a/src/main/java/org/apache/commons/math/analysis/polynomials/PolynomialsUtils.java +++ b/src/main/java/org/apache/commons/math/analysis/polynomials/PolynomialsUtils.java @@ -20,6 +20,7 @@ import java.util.ArrayList; import org.apache.commons.math.fraction.BigFraction; import org.apache.commons.math.util.FastMath; +import org.apache.commons.math.util.MathUtils; /** * A collection of static methods that operate on or return polynomials. @@ -184,6 +185,61 @@ public class PolynomialsUtils { }); } + /** + * Compute the coefficients of the polynomial Ps(x) + * whose values at point {@code x} will be the same as the those from the + * original polynomial P(x) when computed at {@code x + shift}. + * Thus, if P(x) = Σi ai xi, + * then + *
+     *  
+     *   
+     *    
+     *    
+     *   
+     *   
+     *    
+     *    
+     *   
+     *  
Ps(x)= Σi bi xi
= Σi ai (x + shift)i
+ *
+ * + * @param coefficients Coefficients of the original polynomial. + * @param shift Shift value. + * @return the coefficients bi of the shifted + * polynomial. + */ + public static double[] shift(final double[] coefficients, + final double shift) { + final int dp1 = coefficients.length; + final double[] newCoefficients = new double[dp1]; + + // Pascal triangle. + final int[][] coeff = new int[dp1][dp1]; + for (int i = 0; i < dp1; i++){ + for(int j = 0; j <= i; j++){ + coeff[i][j] = (int) MathUtils.binomialCoefficient(i, j); + } + } + + // First polynomial coefficient. + for (int i = 0; i < dp1; i++){ + newCoefficients[0] += coefficients[i] * FastMath.pow(shift, i); + } + + // Superior order. + final int d = dp1 - 1; + for (int i = 0; i < d; i++) { + for (int j = i; j < d; j++){ + newCoefficients[i + 1] += coeff[j + 1][j - i] * + coefficients[j + 1] * FastMath.pow(shift, j - i); + } + } + + return newCoefficients; + } + + /** Get the coefficients array for a given degree. * @param degree degree of the polynomial * @param coefficients list where the computed coefficients are stored diff --git a/src/site/xdoc/changes.xml b/src/site/xdoc/changes.xml index a1e8e04f6..22fb79695 100644 --- a/src/site/xdoc/changes.xml +++ b/src/site/xdoc/changes.xml @@ -52,6 +52,11 @@ The type attribute can be add,update,fix,remove. If the output is not quite correct, check for invisible trailing spaces! --> + + Added "shift" method to compute the coefficients of a new polynomial + whose values are the same as those of another polynomial but computed + at a shifted point. + Faster "multiply" method in "Array2DRowRealMatrix". Code inspired from the Jama project. diff --git a/src/test/java/org/apache/commons/math/analysis/polynomials/PolynomialsUtilsTest.java b/src/test/java/org/apache/commons/math/analysis/polynomials/PolynomialsUtilsTest.java index 88220412c..58ab4b868 100644 --- a/src/test/java/org/apache/commons/math/analysis/polynomials/PolynomialsUtilsTest.java +++ b/src/test/java/org/apache/commons/math/analysis/polynomials/PolynomialsUtilsTest.java @@ -207,6 +207,36 @@ public class PolynomialsUtilsTest { } } + @Test + public void testShift(){ + // f1(x) = 1 + x + 2 x^2 + PolynomialFunction f1x = new PolynomialFunction(new double[] { 1, 1, 2 }); + + PolynomialFunction f1x1 + = new PolynomialFunction(PolynomialsUtils.shift(f1x.getCoefficients(), 1)); + checkPolynomial(f1x1, "4 + 5 x + 2 x^2"); + + PolynomialFunction f1xM1 + = new PolynomialFunction(PolynomialsUtils.shift(f1x.getCoefficients(), -1)); + checkPolynomial(f1xM1, "2 - 3 x + 2 x^2"); + + PolynomialFunction f1x3 + = new PolynomialFunction(PolynomialsUtils.shift(f1x.getCoefficients(), 3)); + checkPolynomial(f1x3, "22 + 13 x + 2 x^2"); + + // f2(x) = 2 + 3 x^2 + 8 x^3 + 121 x^5 + PolynomialFunction f2x = new PolynomialFunction(new double[]{2, 0, 3, 8, 0, 121}); + + PolynomialFunction f2x1 + = new PolynomialFunction(PolynomialsUtils.shift(f2x.getCoefficients(), 1)); + checkPolynomial(f2x1, "134 + 635 x + 1237 x^2 + 1218 x^3 + 605 x^4 + 121 x^5"); + + PolynomialFunction f2x3 + = new PolynomialFunction(PolynomialsUtils.shift(f2x.getCoefficients(), 3)); + checkPolynomial(f2x3, "29648 + 49239 x + 32745 x^2 + 10898 x^3 + 1815 x^4 + 121 x^5"); + } + + private void checkPolynomial(PolynomialFunction p, long denominator, String reference) { PolynomialFunction q = new PolynomialFunction(new double[] { denominator}); Assert.assertEquals(reference, p.multiply(q).toString());