/*
* Copyright 1997 Phil Burk, Mobileer Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.softsynth.math;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Vector;
/**
* Polynomial
* Implement polynomial using Vector as coefficient holder. Element index is power of X, value at a
* given index is coefficient.
*
*
* @author Nick Didkovsky, (C) 1997 Phil Burk and Nick Didkovsky
*/
public class Polynomial {
private static final Logger LOGGER = LoggerFactory.getLogger(Polynomial.class);
private final Vector terms;
// TODO: Does this need to exist?
static class DoubleHolder {
double value;
public DoubleHolder(double val) {
value = val;
}
public double get() {
return value;
}
public void set(double val) {
value = val;
}
}
/** create a polynomial with no terms */
public Polynomial() {
terms = new Vector();
}
/** create a polynomial with one term of specified constant */
public Polynomial(double c0) {
this();
appendTerm(c0);
}
/** create a polynomial with two terms with specified coefficients */
public Polynomial(double c1, double c0) {
this(c0);
appendTerm(c1);
}
/** create a polynomial with specified coefficients */
public Polynomial(double c2, double c1, double c0) {
this(c1, c0);
appendTerm(c2);
}
/** create a polynomial with specified coefficients */
public Polynomial(double c3, double c2, double c1, double c0) {
this(c2, c1, c0);
appendTerm(c3);
}
/** create a polynomial with specified coefficients */
public Polynomial(double c4, double c3, double c2, double c1, double c0) {
this(c3, c2, c1, c0);
appendTerm(c4);
}
/**
* Append a term with specified coefficient. Power will be next available order (ie if the
* polynomial is of order 2, appendTerm will supply the coefficient for x^3
*/
public void appendTerm(double coefficient) {
terms.addElement(new DoubleHolder(coefficient));
}
/** Set the coefficient of given term */
public void setTerm(double coefficient, int power) {
// If setting a term greater than the current order of the polynomial, pad with zero terms
int size = terms.size();
if (power >= size) {
for (int i = 0; i < (power - size + 1); i++) {
appendTerm(0);
}
}
((DoubleHolder) terms.elementAt(power)).set(coefficient);
}
/**
* Add the coefficient of given term to the specified coefficient. ex. addTerm(3, 1) add 3x to a
* polynomial, addTerm(4, 3) adds 4x^3
*/
public void addTerm(double coefficient, int power) {
setTerm(coefficient + get(power), power);
}
/** @return coefficient of nth term (first term=0) */
public double get(int power) {
if (power >= terms.size())
return 0.0;
else
return ((DoubleHolder) terms.elementAt(power)).get();
}
/** @return number of terms in this polynomial */
public int size() {
return terms.size();
}
/**
* Add two polynomials together
*
* @return new Polynomial that is the sum of p1 and p2
*/
public static Polynomial plus(Polynomial p1, Polynomial p2) {
Polynomial sum = new Polynomial();
for (int i = 0; i < Math.max(p1.size(), p2.size()); i++) {
sum.appendTerm(p1.get(i) + p2.get(i));
}
return sum;
}
/**
* Subtract polynomial from another. (First arg - Second arg)
*
* @return new Polynomial p1 - p2
*/
public static Polynomial minus(Polynomial p1, Polynomial p2) {
Polynomial sum = new Polynomial();
for (int i = 0; i < Math.max(p1.size(), p2.size()); i++) {
sum.appendTerm(p1.get(i) - p2.get(i));
}
return sum;
}
/**
* Multiply two Polynomials
*
* @return new Polynomial that is the product p1 * p2
*/
public static Polynomial mult(Polynomial p1, Polynomial p2) {
Polynomial product = new Polynomial();
for (int i = 0; i < p1.size(); i++) {
for (int j = 0; j < p2.size(); j++) {
product.addTerm(p1.get(i) * p2.get(j), i + j);
}
}
return product;
}
/**
* Multiply a Polynomial by a scaler
*
* @return new Polynomial that is the product p1 * p2
*/
public static Polynomial mult(double scaler, Polynomial p1) {
Polynomial product = new Polynomial();
for (int i = 0; i < p1.size(); i++) {
product.appendTerm(p1.get(i) * scaler);
}
return product;
}
/** Evaluate this polynomial for x */
public double evaluate(double x) {
double result = 0.0;
for (int i = 0; i < terms.size(); i++) {
result += get(i) * Math.pow(x, i);
}
return result;
}
@Override
public String toString() {
String s = "";
if (size() == 0)
s = "empty polynomial";
boolean somethingPrinted = false;
for (int i = size() - 1; i >= 0; i--) {
if (get(i) != 0.0) {
if (somethingPrinted)
s += " + ";
String coeff = "";
// if (get(i) == (int)(get(i)))
// coeff = (int)(get(i)) + "";
if ((get(i) != 1.0) || (i == 0))
coeff += get(i);
if (i == 0)
s += coeff;
else {
String power = "";
if (i != 1)
power = "^" + i;
s += coeff + "x" + power;
}
somethingPrinted = true;
}
}
return s;
}
public static void main(String[] args) {
Polynomial p1 = new Polynomial();
LOGGER.debug("p1=" + p1);
Polynomial p2 = new Polynomial(3);
LOGGER.debug("p2=" + p2);
Polynomial p3 = new Polynomial(2, 3);
LOGGER.debug("p3=" + p3);
Polynomial p4 = new Polynomial(1, 2, 3);
LOGGER.debug("p4=" + p4);
LOGGER.debug("p4*5=" + Polynomial.mult(5.0, p4));
LOGGER.debug("{}", p4.evaluate(10));
LOGGER.debug("{}", Polynomial.plus(p4, p1));
LOGGER.debug("{}", Polynomial.minus(p4, p3));
p4.setTerm(12.2, 5);
LOGGER.debug("{}", p4);
p4.addTerm(0.8, 5);
LOGGER.debug("{}", p4);
p4.addTerm(0.8, 7);
LOGGER.debug("{}", p4);
LOGGER.debug("{}", Polynomial.mult(p3, p2));
LOGGER.debug("{}", Polynomial.mult(p3, p3));
LOGGER.debug("{}", Polynomial.mult(p2, p2));
Polynomial t2 = new Polynomial(2, 0, -1); // 2x^2-1, Chebyshev Polynomial of order 2
Polynomial t3 = new Polynomial(4, 0, -3, 0); // 4x^3-3x, Chebyshev Polynomial of order 3
// Calculate Chebyshev Polynomial of order 4 from relation Tk+1(x) = 2xTk(x) - Tk-1(x)
Polynomial t4 = Polynomial.minus(Polynomial.mult(t3, (new Polynomial(2, 0))), t2);
LOGGER.debug(t2 + "\n" + t3 + "\n" + t4);
// com.softsynth.jmsl.util
}
}