// Arup Guha
// 2/16/2012
// Written to help solve COT 4500 Homework #3 question 3.3 #19.

public class lagrange {
	
	private point[] ptArray;
	private poly lagPoly;

	// Creates a lagrange polynomial object.	
	public lagrange(point[] mypoints) {
		ptArray = new point[mypoints.length];
		for (int i=0; i<ptArray.length; i++) {
			ptArray[i] = new point(mypoints[i].x, mypoints[i].y);
		}
	}
	
	// Sets the Lagrange Polynomial using the formula in the text.
	public void setPoly() {
		
		lagPoly = new poly(0);
		
		// Adding in poly L-i(x).
		for (int i=0; i<ptArray.length; i++) {
			
			poly thisterm = new poly(1);
			for (int j=0; j<ptArray.length; j++) {
				
				if (j == i) continue;
				
				// Create this single term of degree 1.
				double[] temp = new double[2];
				temp[0] = -ptArray[j].x;
				temp[1] = 1;
				
				// Multiplying our current term by (x - xj) and dividing by (xi - xj)
				thisterm = thisterm.multiply(new poly(temp));
				thisterm = thisterm.multConst(1.0/(ptArray[i].x-ptArray[j].x));
			}
			
			// We must multiply L-i(x) by f(x-i).
			thisterm = thisterm.multConst(ptArray[i].y);	
			lagPoly = lagPoly.add(thisterm);
		}
	}
	
	// Essentially a wrapper function...
	public double maxInInterval(double low, double high, double numIntervals) {
		return lagPoly.maxInInterval(low,high,numIntervals);
	}
	
	// Returns poly(x).
	public double eval(double x) {
		return lagPoly.eval(x);
	}
	
	public String toString() {
		return lagPoly.toString();
	}
	
	public static void main(String[] args) {
		
		// Input data for both samples.
		double[] x = {0,6,10,13,17,20,28};
		double[] y1 = {6.67,17.33,42.67,37.33,30.10,29.31,28.74};
		double[] y2 = {6.67,16.11,18.89,15.00,10.56,9.44,8.89};
		
		// Solve leaf1.
		point[] sample1 = new point[7];
		for (int i=0; i<7; i++)
			sample1[i] = new point(x[i],y1[i]);
			
		lagrange leaf1 = new lagrange(sample1);
		leaf1.setPoly();
		System.out.println(leaf1);
		
		// Get the maximum value.
		System.out.println(leaf1.maxInInterval(0,28,28));
		System.out.println();
			
		// Solve leaf2.
		point[] sample2 = new point[7];
		for (int i=0; i<7; i++)
			sample2[i] = new point(x[i],y2[i]);
		lagrange leaf2 = new lagrange(sample2);
		leaf2.setPoly();
		System.out.println(leaf2);
		System.out.println(leaf2.maxInInterval(0,28,1000000));
			
	}
}