// Arup Guha
// 2/16/2012
// Written to help solve COT 4500 Homework #3 question 3.3 #19.

public class poly {
	
	private double[] coeff;
	
	// Returns a poly with constant value, value.
	public poly(double value) {
		coeff = new double[1];
		coeff[0] = value;
	}
	
	// Just copy in all the coefficients.
	public poly(double[] mypoly) {
		coeff = new double[mypoly.length];
		for (int i=0; i<coeff.length; i++)
			coeff[i] = mypoly[i];
	}

	// Returns a new poly that is the sum of this object and other.	
	public poly add(poly other) {
		
		// Degree for answer.
		int degree = Math.max(coeff.length,other.coeff.length)-1;
		
		
		double[] newpoly = new double[degree+1];
		
		// Add each coefficient, as long as it exists.
		for (int i=0; i<newpoly.length; i++) {
			
			newpoly[i] = 0;
			if (i < this.coeff.length)
				newpoly[i] += coeff[i];
			if (i < other.coeff.length)
				newpoly[i] += other.coeff[i];
		}
		
		return new poly(newpoly);
	}
	
	// Returns a new poly that is the product of this object and other.
	public poly multiply(poly other) {
		
		// Degree of the answer.
		int degree = coeff.length+other.coeff.length-2;
		
		double[] newpoly = new double[degree+1];
		
		for (int i=0; i<newpoly.length; i++)
			newpoly[i] = 0;
			
		// This is how we multiply polynomials...
		for (int i=0; i<coeff.length; i++) {
			for (int j=0; j<other.coeff.length; j++) {
				newpoly[i+j] += coeff[i]*other.coeff[j];
			}
		}
		
		return new poly(newpoly);
	}
	
	// Returns a new poly that is the product of this object and a constant.
	public poly multConst(double c) {
		
		double[] ans = new double[coeff.length];
		
		for (int i=0; i<ans.length; i++)
			ans[i] = coeff[i]*c;
			
		return new poly(ans);
	}
	
	public String toString() {
		
		String ans = "";
		for (int i=coeff.length-1; i>=2; i--) {
			ans = ans + coeff[i] + "x^" + i;
			ans = ans + " + ";
		}
		
		if (coeff.length > 1)
			ans = ans + coeff[1] + "x + ";
		ans = ans + coeff[0];
		
		return ans;
	}
	
	// Returns the value of the polynomial evaluated at x.
	public double eval(double x) {
		
		// Use Horner's method here.
		double ans = 0;
		for (int i=coeff.length-1; i>=0; i--)
			ans = x*ans + coeff[i];
		return ans;
	}
	
	// Finds the maximum value of f(low), f(low+step), f(low+2*step), ..., f(high)
	// where step = (high - low)/numintervals
	public double maxInInterval(double low, double high, double numintervals) {
		
		double step = (high - low)/numintervals;
		
		// Initial value for our max.
		double max = eval(low);
		
		// Next x to try.
		double myx = low + step;
		
		// Keep on trying x's equally spaced out.
		while (myx <= high + 1e-10) {
			
			// If we get an f(x) bigger than before, save it.
			double nextEval = eval(myx);
			if (nextEval > max)
				max = nextEval;
				
			// Go to the next x value.
			myx += step;
		}
		
		return max;
		
	}

}