1dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond/* 2dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Licensed to the Apache Software Foundation (ASF) under one or more 3dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * contributor license agreements. See the NOTICE file distributed with 4dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * this work for additional information regarding copyright ownership. 5dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * The ASF licenses this file to You under the Apache License, Version 2.0 6dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * (the "License"); you may not use this file except in compliance with 7dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * the License. You may obtain a copy of the License at 8dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 9dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * http://www.apache.org/licenses/LICENSE-2.0 10dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 11dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Unless required by applicable law or agreed to in writing, software 12dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * distributed under the License is distributed on an "AS IS" BASIS, 13dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * See the License for the specific language governing permissions and 15dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * limitations under the License. 16dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 17dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondpackage org.apache.commons.math.analysis.polynomials; 18dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 19dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondimport java.io.Serializable; 20dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondimport java.util.Arrays; 21dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 22dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondimport org.apache.commons.math.exception.util.LocalizedFormats; 23dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondimport org.apache.commons.math.exception.NoDataException; 24dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondimport org.apache.commons.math.analysis.DifferentiableUnivariateRealFunction; 25dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondimport org.apache.commons.math.analysis.UnivariateRealFunction; 26dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondimport org.apache.commons.math.util.FastMath; 27dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 28dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond/** 29dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Immutable representation of a real polynomial function with real coefficients. 30dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <p> 31dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <a href="http://mathworld.wolfram.com/HornersMethod.html">Horner's Method</a> 32dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * is used to evaluate the function.</p> 33dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 34dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @version $Revision: 1042376 $ $Date: 2010-12-05 16:54:55 +0100 (dim. 05 déc. 2010) $ 35dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 36dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondpublic class PolynomialFunction implements DifferentiableUnivariateRealFunction, Serializable { 37dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 38dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 39dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Serialization identifier 40dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 41dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond private static final long serialVersionUID = -7726511984200295583L; 42dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 43dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 44dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * The coefficients of the polynomial, ordered by degree -- i.e., 45dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * coefficients[0] is the constant term and coefficients[n] is the 46dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * coefficient of x^n where n is the degree of the polynomial. 47dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 48dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond private final double coefficients[]; 49dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 50dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 51dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Construct a polynomial with the given coefficients. The first element 52dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * of the coefficients array is the constant term. Higher degree 53dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * coefficients follow in sequence. The degree of the resulting polynomial 54dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * is the index of the last non-null element of the array, or 0 if all elements 55dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * are null. 56dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <p> 57dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * The constructor makes a copy of the input array and assigns the copy to 58dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * the coefficients property.</p> 59dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 60dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param c polynomial coefficients 61dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @throws NullPointerException if c is null 62dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @throws NoDataException if c is empty 63dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 64dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public PolynomialFunction(double c[]) { 65dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond super(); 66dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond int n = c.length; 67dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (n == 0) { 68dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond throw new NoDataException(LocalizedFormats.EMPTY_POLYNOMIALS_COEFFICIENTS_ARRAY); 69dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 70dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond while ((n > 1) && (c[n - 1] == 0)) { 71dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond --n; 72dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 73dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond this.coefficients = new double[n]; 74dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond System.arraycopy(c, 0, this.coefficients, 0, n); 75dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 76dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 77dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 78dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Compute the value of the function for the given argument. 79dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <p> 80dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * The value returned is <br> 81dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <code>coefficients[n] * x^n + ... + coefficients[1] * x + coefficients[0]</code> 82dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * </p> 83dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 84dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param x the argument for which the function value should be computed 85dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return the value of the polynomial at the given point 86dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @see UnivariateRealFunction#value(double) 87dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 88dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public double value(double x) { 89dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return evaluate(coefficients, x); 90dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 91dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 92dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 93dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 94dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Returns the degree of the polynomial 95dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 96dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return the degree of the polynomial 97dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 98dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public int degree() { 99dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return coefficients.length - 1; 100dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 101dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 102dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 103dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Returns a copy of the coefficients array. 104dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <p> 105dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Changes made to the returned copy will not affect the coefficients of 106dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * the polynomial.</p> 107dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 108dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return a fresh copy of the coefficients array 109dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 110dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public double[] getCoefficients() { 111dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return coefficients.clone(); 112dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 113dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 114dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 115dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Uses Horner's Method to evaluate the polynomial with the given coefficients at 116dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * the argument. 117dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 118dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param coefficients the coefficients of the polynomial to evaluate 119dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param argument the input value 120dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return the value of the polynomial 121dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @throws NoDataException if coefficients is empty 122dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @throws NullPointerException if coefficients is null 123dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 124dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond protected static double evaluate(double[] coefficients, double argument) { 125dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond int n = coefficients.length; 126dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (n == 0) { 127dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond throw new NoDataException(LocalizedFormats.EMPTY_POLYNOMIALS_COEFFICIENTS_ARRAY); 128dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 129dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double result = coefficients[n - 1]; 130dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond for (int j = n -2; j >=0; j--) { 131dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond result = argument * result + coefficients[j]; 132dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 133dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return result; 134dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 135dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 136dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 137dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Add a polynomial to the instance. 138dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param p polynomial to add 139dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return a new polynomial which is the sum of the instance and p 140dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 141dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public PolynomialFunction add(final PolynomialFunction p) { 142dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 143dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // identify the lowest degree polynomial 144dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final int lowLength = FastMath.min(coefficients.length, p.coefficients.length); 145dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final int highLength = FastMath.max(coefficients.length, p.coefficients.length); 146dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 147dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // build the coefficients array 148dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double[] newCoefficients = new double[highLength]; 149dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond for (int i = 0; i < lowLength; ++i) { 150dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond newCoefficients[i] = coefficients[i] + p.coefficients[i]; 151dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 152dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond System.arraycopy((coefficients.length < p.coefficients.length) ? 153dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond p.coefficients : coefficients, 154dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond lowLength, 155dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond newCoefficients, lowLength, 156dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond highLength - lowLength); 157dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 158dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return new PolynomialFunction(newCoefficients); 159dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 160dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 161dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 162dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 163dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Subtract a polynomial from the instance. 164dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param p polynomial to subtract 165dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return a new polynomial which is the difference the instance minus p 166dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 167dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public PolynomialFunction subtract(final PolynomialFunction p) { 168dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 169dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // identify the lowest degree polynomial 170dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond int lowLength = FastMath.min(coefficients.length, p.coefficients.length); 171dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond int highLength = FastMath.max(coefficients.length, p.coefficients.length); 172dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 173dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // build the coefficients array 174dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double[] newCoefficients = new double[highLength]; 175dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond for (int i = 0; i < lowLength; ++i) { 176dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond newCoefficients[i] = coefficients[i] - p.coefficients[i]; 177dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 178dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (coefficients.length < p.coefficients.length) { 179dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond for (int i = lowLength; i < highLength; ++i) { 180dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond newCoefficients[i] = -p.coefficients[i]; 181dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 182dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } else { 183dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond System.arraycopy(coefficients, lowLength, newCoefficients, lowLength, 184dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond highLength - lowLength); 185dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 186dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 187dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return new PolynomialFunction(newCoefficients); 188dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 189dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 190dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 191dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 192dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Negate the instance. 193dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return a new polynomial 194dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 195dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public PolynomialFunction negate() { 196dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double[] newCoefficients = new double[coefficients.length]; 197dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond for (int i = 0; i < coefficients.length; ++i) { 198dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond newCoefficients[i] = -coefficients[i]; 199dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 200dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return new PolynomialFunction(newCoefficients); 201dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 202dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 203dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 204dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Multiply the instance by a polynomial. 205dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param p polynomial to multiply by 206dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return a new polynomial 207dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 208dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public PolynomialFunction multiply(final PolynomialFunction p) { 209dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 210dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double[] newCoefficients = new double[coefficients.length + p.coefficients.length - 1]; 211dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 212dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond for (int i = 0; i < newCoefficients.length; ++i) { 213dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond newCoefficients[i] = 0.0; 214dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond for (int j = FastMath.max(0, i + 1 - p.coefficients.length); 215dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond j < FastMath.min(coefficients.length, i + 1); 216dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ++j) { 217dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond newCoefficients[i] += coefficients[j] * p.coefficients[i-j]; 218dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 219dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 220dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 221dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return new PolynomialFunction(newCoefficients); 222dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 223dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 224dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 225dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 226dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Returns the coefficients of the derivative of the polynomial with the given coefficients. 227dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 228dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param coefficients the coefficients of the polynomial to differentiate 229dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return the coefficients of the derivative or null if coefficients has length 1. 230dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @throws NoDataException if coefficients is empty 231dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @throws NullPointerException if coefficients is null 232dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 233dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond protected static double[] differentiate(double[] coefficients) { 234dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond int n = coefficients.length; 235dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (n == 0) { 236dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond throw new NoDataException(LocalizedFormats.EMPTY_POLYNOMIALS_COEFFICIENTS_ARRAY); 237dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 238dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (n == 1) { 239dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return new double[]{0}; 240dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 241dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double[] result = new double[n - 1]; 242dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond for (int i = n - 1; i > 0; i--) { 243dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond result[i - 1] = i * coefficients[i]; 244dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 245dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return result; 246dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 247dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 248dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 249dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Returns the derivative as a PolynomialRealFunction 250dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 251dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return the derivative polynomial 252dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 253dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public PolynomialFunction polynomialDerivative() { 254dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return new PolynomialFunction(differentiate(coefficients)); 255dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 256dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 257dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 258dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Returns the derivative as a UnivariateRealFunction 259dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 260dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return the derivative function 261dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 262dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public UnivariateRealFunction derivative() { 263dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return polynomialDerivative(); 264dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 265dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 266dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** Returns a string representation of the polynomial. 267dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 268dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <p>The representation is user oriented. Terms are displayed lowest 269dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * degrees first. The multiplications signs, coefficients equals to 270dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * one and null terms are not displayed (except if the polynomial is 0, 271dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * in which case the 0 constant term is displayed). Addition of terms 272dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * with negative coefficients are replaced by subtraction of terms 273dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * with positive coefficients except for the first displayed term 274dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * (i.e. we display <code>-3</code> for a constant negative polynomial, 275dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * but <code>1 - 3 x + x^2</code> if the negative coefficient is not 276dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * the first one displayed).</p> 277dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 278dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return a string representation of the polynomial 279dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 280dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 281dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond @Override 282dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public String toString() { 283dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 284dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond StringBuilder s = new StringBuilder(); 285dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (coefficients[0] == 0.0) { 286dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (coefficients.length == 1) { 287dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return "0"; 288dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 289dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } else { 290dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond s.append(Double.toString(coefficients[0])); 291dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 292dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 293dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond for (int i = 1; i < coefficients.length; ++i) { 294dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 295dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (coefficients[i] != 0) { 296dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 297dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (s.length() > 0) { 298dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (coefficients[i] < 0) { 299dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond s.append(" - "); 300dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } else { 301dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond s.append(" + "); 302dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 303dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } else { 304dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (coefficients[i] < 0) { 305dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond s.append("-"); 306dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 307dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 308dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 309dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double absAi = FastMath.abs(coefficients[i]); 310dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if ((absAi - 1) != 0) { 311dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond s.append(Double.toString(absAi)); 312dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond s.append(' '); 313dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 314dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 315dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond s.append("x"); 316dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (i > 1) { 317dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond s.append('^'); 318dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond s.append(Integer.toString(i)); 319dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 320dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 321dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 322dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 323dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 324dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return s.toString(); 325dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 326dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 327dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 328dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** {@inheritDoc} */ 329dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond @Override 330dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public int hashCode() { 331dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final int prime = 31; 332dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond int result = 1; 333dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond result = prime * result + Arrays.hashCode(coefficients); 334dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return result; 335dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 336dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 337dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** {@inheritDoc} */ 338dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond @Override 339dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public boolean equals(Object obj) { 340dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (this == obj) 341dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return true; 342dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (!(obj instanceof PolynomialFunction)) 343dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return false; 344dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond PolynomialFunction other = (PolynomialFunction) obj; 345dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (!Arrays.equals(coefficients, other.coefficients)) 346dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return false; 347dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return true; 348dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 349dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 350dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond} 351