Implementing the Problem-Specific PartNow it's time to implement the problem-specific part of the least squares fit analysis. The problem-specific elements of the analysis are the type of polynomial equation to be used and the data that will be modeled. The data to be modeled can be stored in 1-D arrays. Information about the curve fit polynomial equation will be stored in an instance of the Polynomial class, which encapsulates a general polynomial equation. Equation 23.2
The order of the polynomial equation in Eq. (23.2) is equal to the largest exponent in the equation. For example, the quadratic equation, y = c 2 x 2 + c 1 x + c , would be a second-order polynomial expression. The Polynomial class defines four data members . The first is an integer variable that stores the order of the equation. The A[][] array stores the values of A T A . The b[] array stores the values of A T b . The coeffs[] array stores the coefficients of the polynomial curve fit equation. The Polynomial class then defines a series of methods to get or set the values of its data members. The getA() and getB() methods return a reference to the A[][] and b[] arrays. In the leastSquaresFit() method, the getA() and getB() methods are used to send the A[][] and b[] arrays to the gaussian() method. The setA() and setB() methods are used by Polynomial subclasses. The loadArrays() method loads the values for A T A and A T b into the A[][] and b[] arrays. The implementation is to load the arrays for a general polynomial equation. The mathematical formulation of the A T A and A T b arrays for a general polynomial is provided in Chapter 24. Finally, the getValue() method returns a value along the curve fit equation. This method would be called after the least squares fit had been performed. The Polynomial class source code is shown here. package TechJava.MathLib; public class Polynomial { private int order; private double A[][]; private double b[]; private double coeff[]; public Polynomial(int order){ this.order = order; A = new double[order+1][order+1]; b = new double[order+1]; coeff = new double[order+1]; } // These methods return the current value // of the data members. public int getOrder() { return order; } public double[][] getA(){ return A; } public double[] getB() { return b; } public double getCoefficient(int index) { return coeff[index]; } public double[] getCoefficients() { return coeff; } // These methods are to change one or more elements // of the A[][], b[], or coeff[] arrays public void setA(int i, int j, double value){ A[i][j] = value; } public void setB(int j, double value) { b[j] = value; } public void setCoefficients(double coeff[]) { this.coeff = coeff; } // Load the A[][] and b[] arrays. The A[][] array // stores the values of AT*A. The b[] array stores // the values of AT*b. This implementation // is for a general polynomial expression public void loadArrays(double x[], double y[]) { int numPoints = x.length; for(int j=0; j<order+1; ++j) { b[j] = 0.0; for(int k=0; k<numPoints; ++k) { b[j] += Math.pow(x[k],order - j)*y[k]; } } for(int i=0; i<order+1; ++i) { for(int j=0; j<order+1; ++j) { A[i][j] = 0.0; for(int k=0; k<numPoints; ++k) { A[i][j] += Math.pow(x[k],2.0*order i - j); } } } } // Return a value along the least squares fit line. // This implementation is for a general polynomial // expression. public double getValue(double x) { double y = 0.0; for(int i=0; i<getOrder()+1; ++i) { y += coeff[i]*Math.pow(x,order - i); } return y; } } |