Added add, subtract, negate, multiply and toString methods to PolynomialFunction
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/trunk@739834 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
e8bb7ce937
commit
adc64fb8cf
|
@ -32,25 +32,26 @@ import org.apache.commons.math.analysis.UnivariateRealFunction;
|
|||
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 @@ public class PolynomialFunction implements DifferentiableUnivariateRealFunction,
|
|||
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 @@ public class PolynomialFunction implements DifferentiableUnivariateRealFunction,
|
|||
* @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 @@ public class PolynomialFunction implements DifferentiableUnivariateRealFunction,
|
|||
}
|
||||
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 class PolynomialFunction implements DifferentiableUnivariateRealFunction,
|
|||
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();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -39,6 +39,9 @@ The <action> type attribute can be add,update,fix,remove.
|
|||
</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>
|
||||
|
|
|
@ -160,4 +160,80 @@ public final class PolynomialFunctionTest extends TestCase {
|
|||
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue