package edu.stanford.rsl.conrad.fitting;
import edu.stanford.rsl.conrad.numerics.SimpleMatrix;
import edu.stanford.rsl.conrad.numerics.SimpleOperators;
import edu.stanford.rsl.conrad.numerics.SimpleVector;
public class PolynomialFunction extends Function {
/**
*
*/
private static final long serialVersionUID = -1557807323919814217L;
private int degree =2;
private double [] params;
public PolynomialFunction (){
params = new double [degree +1];
}
/**
* @return the degree
*/
public int getDegree() {
return degree;
}
/**
* Sets the degree of the polynomial function. Note that this will reset the parameter array.
* @param degree the degree to set
*/
public void setDegree(int degree) {
this.degree = degree;
params = new double [degree +1];
}
@Override
public double[] getParametersAsDoubleArray() {
return params;
}
@Override
public void fitToPoints(double[] x, double[] y) {
// setup observation vector
SimpleVector observations = new SimpleVector(y);
// setup measurement matrix:
SimpleMatrix measurements = new SimpleMatrix(x.length, degree+1);
for (int i = 0; i < x.length; i++){
for (int j = 0; j <= degree; j++){
measurements.setElementValue(i, j, Math.pow(x[i], j));
}
}
SimpleMatrix inverseMeasurements = measurements.inverse(SimpleMatrix.InversionType.INVERT_SVD);
SimpleVector parameters = SimpleOperators.multiply(inverseMeasurements, observations);
parameters.copyTo(params);
}
@Override
public double evaluate(double x) {
double revan = 0;
double xx = 1;
for (int i=0; i <= degree; i++){
revan += params[i] * xx;
xx *= x;
}
return revan;
}
@Override
public String toString() {
String revan = "" + params[0] + " ";
for (int i=1; i <= degree; i++){
revan += params[i] + " x^" +i;
}
return revan;
}
@Override
public int getMinimumNumberOfCorrespondences() {
return degree + 1;
}
}