Author: luc
Date: Sun Feb  1 20:56:12 2009
New Revision: 739834

URL: http://svn.apache.org/viewvc?rev=739834&view=rev
Log:
Added add, subtract, negate, multiply and toString methods to PolynomialFunction

Modified:
    
commons/proper/math/trunk/src/java/org/apache/commons/math/analysis/polynomials/PolynomialFunction.java
    commons/proper/math/trunk/src/site/xdoc/changes.xml
    
commons/proper/math/trunk/src/test/org/apache/commons/math/analysis/polynomials/PolynomialFunctionTest.java

Modified: 
commons/proper/math/trunk/src/java/org/apache/commons/math/analysis/polynomials/PolynomialFunction.java
URL: 
http://svn.apache.org/viewvc/commons/proper/math/trunk/src/java/org/apache/commons/math/analysis/polynomials/PolynomialFunction.java?rev=739834&r1=739833&r2=739834&view=diff
==============================================================================
--- 
commons/proper/math/trunk/src/java/org/apache/commons/math/analysis/polynomials/PolynomialFunction.java
 (original)
+++ 
commons/proper/math/trunk/src/java/org/apache/commons/math/analysis/polynomials/PolynomialFunction.java
 Sun Feb  1 20:56:12 2009
@@ -32,25 +32,26 @@
 public class PolynomialFunction implements 
DifferentiableUnivariateRealFunction, Serializable {
 
     /** Serializable version identifier */
-    private static final long serialVersionUID = 3322454535052136809L;
-    
+    private static final long serialVersionUID = -7726511984200295583L;
+
     /**
      * The coefficients of the polynomial, ordered by degree -- i.e.,  
      * coefficients[0] is the constant term and coefficients[n] is the 
      * coefficient of x^n where n is the degree of the polynomial.
      */
-    private double coefficients[];
+    private final double coefficients[];
 
     /**
      * Construct a polynomial with the given coefficients.  The first element
      * of the coefficients array is the constant term.  Higher degree
      * coefficients follow in sequence.  The degree of the resulting polynomial
-     * is the length of the array minus 1. 
+     * is the index of the last non-null element of the array, or 0 if all 
elements
+     * are null. 
      * <p>
      * The constructor makes a copy of the input array and assigns the copy to
      * the coefficients property.</p>
      * 
-     * @param c polynominal coefficients
+     * @param c polynomial coefficients
      * @throws NullPointerException if c is null
      * @throws IllegalArgumentException if c is empty
      */
@@ -59,8 +60,12 @@
         if (c.length < 1) {
             throw new IllegalArgumentException("Polynomial coefficient array 
must have postive length.");
         }
-        this.coefficients = new double[c.length];
-        System.arraycopy(c, 0, this.coefficients, 0, c.length);
+        int l = c.length;
+        while ((l > 1) && (c[l - 1] == 0)) {
+            --l;
+        }
+        this.coefficients = new double[l];
+        System.arraycopy(c, 0, this.coefficients, 0, l);
     }
 
     /**
@@ -97,9 +102,7 @@
      * @return  a fresh copy of the coefficients array
      */
     public double[] getCoefficients() {
-        double[] out = new double[coefficients.length];
-        System.arraycopy(coefficients,0, out, 0, coefficients.length);
-        return out;
+        return coefficients.clone();
     }
     
     /**
@@ -123,7 +126,96 @@
         }
         return result;
     }
-    
+
+    /**
+     * Add a polynomial to the instance.
+     * @param p polynomial to add
+     * @return a new polynomial which is the sum of the instance and p
+     */
+    public PolynomialFunction add(final PolynomialFunction p) {
+
+        // identify the lowest degree polynomial
+        final int lowLength  = Math.min(coefficients.length, 
p.coefficients.length);
+        final int highLength = Math.max(coefficients.length, 
p.coefficients.length);
+
+        // build the coefficients array
+        double[] newCoefficients = new double[highLength];
+        for (int i = 0; i < lowLength; ++i) {
+            newCoefficients[i] = coefficients[i] + p.coefficients[i];
+        }
+        System.arraycopy((coefficients.length < p.coefficients.length) ?
+                         p.coefficients : coefficients,
+                         lowLength,
+                         newCoefficients, lowLength,
+                         highLength - lowLength);
+
+        return new PolynomialFunction(newCoefficients);
+
+    }
+
+    /**
+     * Subtract a polynomial from the instance.
+     * @param p polynomial to subtract
+     * @return a new polynomial which is the difference the instance minus p
+     */
+    public PolynomialFunction subtract(final PolynomialFunction p) {
+
+        // identify the lowest degree polynomial
+        int lowLength  = Math.min(coefficients.length, p.coefficients.length);
+        int highLength = Math.max(coefficients.length, p.coefficients.length);
+
+        // build the coefficients array
+        double[] newCoefficients = new double[highLength];
+        for (int i = 0; i < lowLength; ++i) {
+            newCoefficients[i] = coefficients[i] - p.coefficients[i];
+        }
+        if (coefficients.length < p.coefficients.length) {
+            for (int i = lowLength; i < highLength; ++i) {
+                newCoefficients[i] = -p.coefficients[i];
+            }
+        } else {
+            System.arraycopy(coefficients, lowLength, newCoefficients, 
lowLength,
+                             highLength - lowLength);
+        }
+
+        return new PolynomialFunction(newCoefficients);
+
+    }
+
+    /**
+     * Negate the instance.
+     * @return a new polynomial
+     */
+    public PolynomialFunction negate() {
+        double[] newCoefficients = new double[coefficients.length];
+        for (int i = 0; i < coefficients.length; ++i) {
+            newCoefficients[i] = -coefficients[i];
+        }
+        return new PolynomialFunction(newCoefficients);
+    }
+
+    /**
+     * Multiply the instance by a polynomial.
+     * @param p polynomial to multiply by
+     * @return a new polynomial
+     */
+    public PolynomialFunction multiply(final PolynomialFunction p) {
+
+        double[] newCoefficients = new double[coefficients.length + 
p.coefficients.length - 1];
+
+        for (int i = 0; i < newCoefficients.length; ++i) {
+            newCoefficients[i] = 0.0;
+            for (int j = Math.max(0, i + 1 - p.coefficients.length);
+                 j < Math.min(coefficients.length, i + 1);
+                 ++j) {
+                newCoefficients[i] += coefficients[j] * p.coefficients[i-j];
+            }
+        }
+
+        return new PolynomialFunction(newCoefficients);
+
+    }
+
     /**
      * Returns the coefficients of the derivative of the polynomial with the 
given coefficients.
      * 
@@ -164,5 +256,66 @@
     public UnivariateRealFunction derivative() {
         return polynomialDerivative();
     }
-   
+
+    /** Returns a string representation of the polynomial.
+
+     * <p>The representation is user oriented. Terms are displayed lowest
+     * degrees first. The multiplications signs, coefficients equals to
+     * one and null terms are not displayed (except if the polynomial is 0,
+     * in which case the 0 constant term is displayed). Addition of terms
+     * with negative coefficients are replaced by subtraction of terms
+     * with positive coefficients except for the first displayed term
+     * (i.e. we display <code>-3</code> for a constant negative polynomial,
+     * but <code>1 - 3 x + x^2</code> if the negative coefficient is not
+     * the first one displayed).</p>
+
+     * @return a string representation of the polynomial
+
+     */
+     public String toString() {
+
+       StringBuffer s = new StringBuffer();
+       if (coefficients[0] == 0.0) {
+         if (coefficients.length == 1) {
+           return "0";
+         }
+       } else {
+         s.append(Double.toString(coefficients[0]));
+       }
+
+       for (int i = 1; i < coefficients.length; ++i) {
+
+         if (coefficients[i] != 0) {
+
+           if (s.length() > 0) {
+             if (coefficients[i] < 0) {
+               s.append(" - ");
+             } else {
+               s.append(" + ");
+             }
+           } else {
+             if (coefficients[i] < 0) {
+               s.append("-");
+             }
+           }
+
+           double absAi = Math.abs(coefficients[i]);
+           if ((absAi - 1) != 0) {
+             s.append(Double.toString(absAi));
+             s.append(' ');
+           }
+
+           s.append("x");
+           if (i > 1) {
+             s.append('^');
+             s.append(Integer.toString(i));
+           }
+         }
+
+       }
+
+       return s.toString();
+
+     }
+
 }

Modified: commons/proper/math/trunk/src/site/xdoc/changes.xml
URL: 
http://svn.apache.org/viewvc/commons/proper/math/trunk/src/site/xdoc/changes.xml?rev=739834&r1=739833&r2=739834&view=diff
==============================================================================
--- commons/proper/math/trunk/src/site/xdoc/changes.xml (original)
+++ commons/proper/math/trunk/src/site/xdoc/changes.xml Sun Feb  1 20:56:12 2009
@@ -39,6 +39,9 @@
   </properties>
   <body>
     <release version="2.0" date="TBD" description="TBD">
+      <action dev="luc" type="add" >
+        Added add, subtract, negate, multiply and toString methods to 
PolynomialFunction.
+      </action> 
       <action dev="psteitz" type="update" issue="MATH-189">
         Changed FractionFormat to extend NumberFormat.
       </action> 

Modified: 
commons/proper/math/trunk/src/test/org/apache/commons/math/analysis/polynomials/PolynomialFunctionTest.java
URL: 
http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/org/apache/commons/math/analysis/polynomials/PolynomialFunctionTest.java?rev=739834&r1=739833&r2=739834&view=diff
==============================================================================
--- 
commons/proper/math/trunk/src/test/org/apache/commons/math/analysis/polynomials/PolynomialFunctionTest.java
 (original)
+++ 
commons/proper/math/trunk/src/test/org/apache/commons/math/analysis/polynomials/PolynomialFunctionTest.java
 Sun Feb  1 20:56:12 2009
@@ -160,4 +160,80 @@
 
     }
 
+    public void testString() {
+        PolynomialFunction p = new PolynomialFunction(new double[] { -5.0, 
3.0, 1.0 });
+        checkPolynomial(p, "-5.0 + 3.0 x + x^2");
+        checkPolynomial(new PolynomialFunction(new double[] { 0.0, -2.0, 3.0 
}),
+                        "-2.0 x + 3.0 x^2");
+        checkPolynomial(new PolynomialFunction(new double[] { 1.0, -2.0, 3.0 
}),
+                      "1.0 - 2.0 x + 3.0 x^2");
+        checkPolynomial(new PolynomialFunction(new double[] { 0.0,  2.0, 3.0 
}),
+                       "2.0 x + 3.0 x^2");
+        checkPolynomial(new PolynomialFunction(new double[] { 1.0,  2.0, 3.0 
}),
+                     "1.0 + 2.0 x + 3.0 x^2");
+        checkPolynomial(new PolynomialFunction(new double[] { 1.0,  0.0, 3.0 
}),
+                     "1.0 + 3.0 x^2");
+        checkPolynomial(new PolynomialFunction(new double[] { 0.0 }),
+                     "0");
+    }
+
+    public void testAddition() {
+
+        PolynomialFunction p1 = new PolynomialFunction(new double[] { -2.0, 
1.0 });
+        PolynomialFunction p2 = new PolynomialFunction(new double[] { 2.0, 
-1.0, 0.0 });
+        checkNullPolynomial(p1.add(p2));
+
+        p2 = p1.add(p1);
+        checkPolynomial(p2, "-4.0 + 2.0 x");
+
+        p1 = new PolynomialFunction(new double[] { 1.0, -4.0, 2.0 });
+        p2 = new PolynomialFunction(new double[] { -1.0, 3.0, -2.0 });
+        p1 = p1.add(p2);
+        assertEquals(1, p1.degree());
+        checkPolynomial(p1, "-x");
+
+    }
+
+    public void testSubtraction() {
+
+        PolynomialFunction p1 = new PolynomialFunction(new double[] { -2.0, 
1.0 });
+        checkNullPolynomial(p1.subtract(p1));
+
+        PolynomialFunction p2 = new PolynomialFunction(new double[] { -2.0, 
6.0 });
+        p2 = p2.subtract(p1);
+        checkPolynomial(p2, "5.0 x");
+
+        p1 = new PolynomialFunction(new double[] { 1.0, -4.0, 2.0 });
+        p2 = new PolynomialFunction(new double[] { -1.0, 3.0, 2.0 });
+        p1 = p1.subtract(p2);
+        assertEquals(1, p1.degree());
+        checkPolynomial(p1, "2.0 - 7.0 x");
+
+    }
+
+    public void testMultiplication() {
+
+        PolynomialFunction p1 = new PolynomialFunction(new double[] { -3.0, 
2.0 });
+        PolynomialFunction p2 = new PolynomialFunction(new double[] { 3.0, 
2.0, 1.0 });
+        checkPolynomial(p1.multiply(p2), "-9.0 + x^2 + 2.0 x^3");
+
+        p1 = new PolynomialFunction(new double[] { 0.0, 1.0 });
+        p2 = p1;
+        for (int i = 2; i < 10; ++i) {
+            p2 = p2.multiply(p1);
+            checkPolynomial(p2, "x^" + i);
+        }
+
+    }
+
+    public void checkPolynomial(PolynomialFunction p, String reference) {
+        assertEquals(reference, p.toString());
+    }
+
+    private void checkNullPolynomial(PolynomialFunction p) {
+        for (double coefficient : p.getCoefficients()) {
+            assertEquals(0.0, coefficient, 1.0e-15);
+        }
+    }
+
 }


Reply via email to