//----------------------------------------------------------------------------// // // // P o l y n o m i a l // // // //----------------------------------------------------------------------------// // <editor-fold defaultstate="collapsed" desc="hdr"> // // Copyright © Hervé Bitteur and others 2000-2013. All rights reserved. // // This software is released under the GNU General Public License. // // Goto http://kenai.com/projects/audiveris to report bugs or suggestions. // //----------------------------------------------------------------------------// // </editor-fold> package omr.math; /** * Class {@code Polynomial} is a simple polynomial implementation. * * See http://introcs.cs.princeton.edu/java/92symbolic/Polynomial.java.html * * @author Hervé Bitteur */ public class Polynomial { //~ Instance fields -------------------------------------------------------- /** The degree of polynomial */ protected int degree; /** Polynomial coefficient vector, from low to high order */ protected double[] coefficients; //~ Constructors ----------------------------------------------------------- //------------// // Polynomial // //------------// /** * Creates a new Polynomial object (actually just a monomial). * Example new Polynomial(3,2) = 3x^2 * * @param c coefficient * @param degree degree of the monomial term */ public Polynomial (double c, int degree) { if (degree < 0) { throw new IllegalArgumentException("Negative polynomial degree"); } coefficients = new double[degree + 1]; coefficients[degree] = c; this.degree = degree(); } //~ Methods ---------------------------------------------------------------- //---------// // compose // //---------// /** * Compose with that other polynomial. * * @param that the other polynomial * @return a(b(x)) */ public Polynomial compose (Polynomial that) { Polynomial result = new Polynomial(0, 0); for (int i = this.degree; i >= 0; i--) { Polynomial term = new Polynomial(this.coefficients[i], 0); result = term.plus(that.times(result)); } return result; } //--------// // degree // //--------// /** * Report the actual degree. * * @return the degree of this polynomial (0 for the zero polynomial) */ public final int degree () { for (int i = coefficients.length - 1; i >= 0; i--) { if (coefficients[i] != 0) { return i; } } return 0; } //------------// // derivative // //------------// /** * Report the derivative of this polynomial. * * @return the derivative */ public Polynomial derivative () { if (degree == 0) { return new Polynomial(0, 0); } Polynomial derivative = new Polynomial(0, degree - 1); derivative.degree = degree - 1; for (int i = 0; i < degree; i++) { derivative.coefficients[i] = (i + 1) * coefficients[i + 1]; } return derivative; } //----// // eq // //----// /** * Check whether this represent the same polynomial as that. * * @param that the other polynomial * @return true if equal */ public boolean eq (Polynomial that) { if (degree != that.degree) { return false; } for (int i = degree; i >= 0; i--) { if (coefficients[i] != that.coefficients[i]) { return false; } } return true; } //----------// // evaluate // //----------// /** * Return the evaluation of this polynomial for the provided x. * * @param x the provided x * @return value at x */ public double evaluate (double x) { // use Horner's method double result = 0; for (int i = degree; i >= 0; i--) { result = coefficients[i] + (x * result); } return result; } //------// // main // //------// // test client public static void main (String[] args) { Polynomial zero = new Polynomial(0, 0); Polynomial p1 = new Polynomial(4, 3); // 4x^3 Polynomial p2 = new Polynomial(3, 2); // 3x^2 Polynomial p3 = new Polynomial(1, 0); // 1 Polynomial p4 = new Polynomial(2, 1); // 2x Polynomial p = p1.plus(p2) .plus(p3) .plus(p4); // 4x^3 + 3x^2 + 2x + 1 Polynomial q1 = new Polynomial(3, 2); // 3x^2 Polynomial q2 = new Polynomial(5, 0); // 5 Polynomial q = q1.plus(q2); // 3x^2 + 5 Polynomial r = p.plus(q); Polynomial s = p.times(q); Polynomial t = p.compose(q); System.out.println("zero(x) = " + zero); System.out.println("p(x) = " + p); System.out.println("q(x) = " + q); System.out.println("p(x) + q(x) = " + r); System.out.println("p(x) * q(x) = " + s); System.out.println("p(q(x)) = " + t); System.out.println("0 - p(x) = " + zero.minus(p)); System.out.println("p(3) = " + p.evaluate(3)); System.out.println("p'(x) = " + p.derivative()); System.out.println("p''(x) = " + p.derivative().derivative()); System.out.println( "p'''(x) = " + p.derivative().derivative().derivative()); System.out.println( "p''''(x) = " + p.derivative().derivative().derivative().derivative()); } //-------// // minus // //-------// /** * Report this - that. * * @param that other polynomial * @return this - that */ public Polynomial minus (Polynomial that) { Polynomial result = new Polynomial( 0, Math.max(this.degree, that.degree)); for (int i = 0; i <= this.degree; i++) { result.coefficients[i] += this.coefficients[i]; } for (int i = 0; i <= that.degree; i++) { result.coefficients[i] -= that.coefficients[i]; } result.degree = result.degree(); return result; } //------// // plus // //------// /** * Report this + that. * * @param that other polynomial * @return this + that */ public Polynomial plus (Polynomial that) { Polynomial result = new Polynomial( 0, Math.max(this.degree, that.degree)); for (int i = 0; i <= this.degree; i++) { result.coefficients[i] += this.coefficients[i]; } for (int i = 0; i <= that.degree; i++) { result.coefficients[i] += that.coefficients[i]; } result.degree = result.degree(); return result; } //-------// // times // //-------// /** * Report this * that. * * @param that other polynomial * @return this * that */ public Polynomial times (Polynomial that) { Polynomial result = new Polynomial(0, this.degree + that.degree); for (int i = 0; i <= this.degree; i++) { for (int j = 0; j <= that.degree; j++) { result.coefficients[i + j] += (this.coefficients[i] * that.coefficients[j]); } } result.degree = result.degree(); return result; } //-------// // times // //-------// /** * Simple multiplication by a scalar * * @param scalar the scalar multiplicator value * @return the new polynomial (this * scalar) */ public Polynomial times (double scalar) { Polynomial result = new Polynomial(0, degree); for (int i = 0; i <= degree; i++) { result.coefficients[i] = coefficients[i] * scalar; } result.degree = result.degree(); return result; } //----------// // toString // //----------// /** * Print by decreasing term degree. * * @return the polynomial terms, presented by decreasing degree */ @Override public String toString () { if (degree == 0) { return "" + coefficients[0]; } if (degree == 1) { return coefficients[1] + "x + " + coefficients[0]; } String s = coefficients[degree] + "x^" + degree; for (int i = degree - 1; i >= 0; i--) { if (coefficients[i] == 0) { continue; } else if (coefficients[i] > 0) { s = s + " + " + (coefficients[i]); } else if (coefficients[i] < 0) { s = s + " - " + (-coefficients[i]); } if (i == 1) { s += "x"; } else if (i > 1) { s = s + "x^" + i; } } return s; } }