IncrementalLeastSquares now has noIntercept Option

This commit is contained in:
Frederik Petersen committed 2015-02-17 13:55:18 +01:00
1 parent 1576b00aef
commit 4a030a33d3
3 files changed
+8722 -9

No files matched your search

File diff suppressed because it is too large. Load diff
@@ -3,6 +3,11 @@ package com.sap.sailing.polars.regression.test;
import static org.hamcrest.Matchers.closeTo;
import static org.junit.Assert.assertThat;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.Random;
import org.junit.Test;
@@ -67,6 +72,64 @@ public class IncrementalLeastSquaresTest {
assertThat(coeffs[3], closeTo(0.2169 , ERROR));
assertThat(coeffs[4], closeTo(-0.01182 , ERROR));
}
@Test
public void testIncrementalRegressionWithRealData() throws NotEnoughDataHasBeenAddedException {
IncrementalLeastSquares leastSquares = new IncrementalAnyOrderLeastSquaresImpl(3);
fillRegression(leastSquares);
double[] coeffs = leastSquares.getOrCreatePolynomialFunction().getCoefficients();
assertThat(coeffs[0], closeTo(6.319899225, ERROR));
assertThat(coeffs[1], closeTo(-0.427890096, ERROR));
assertThat(coeffs[2], closeTo(0.057763706, ERROR));
assertThat(coeffs[3], closeTo(-0.001574209 , ERROR));
}
@Test
public void testIncrementalRegressionWithRealDataNoIntercept() throws NotEnoughDataHasBeenAddedException {
IncrementalLeastSquares leastSquares = new IncrementalAnyOrderLeastSquaresImpl(3, false);
fillRegression(leastSquares);
double[] coeffs = leastSquares.getOrCreatePolynomialFunction().getCoefficients();
assertThat(coeffs[0], closeTo(0, ERROR));
assertThat(coeffs[1], closeTo(0.9317759507, ERROR));
assertThat(coeffs[2], closeTo(-0.0364029315, ERROR));
assertThat(coeffs[3], closeTo(0.0005326266, ERROR));
}
private void fillRegression(IncrementalLeastSquares leastSquares) {
File file = new File("resources/5O5Worlds14_Winners_Upwind4550.csv");
BufferedReader br = null;
String line = "";
String cvsSplitBy = ",";
try {
br = new BufferedReader(new FileReader(file));
while ((line = br.readLine()) != null) {
// use comma as separator
String[] row = line.split(cvsSplitBy);
leastSquares.addData(Double.parseDouble(row[0]), Double.parseDouble(row[1]));
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
@@ -44,10 +44,22 @@ public class IncrementalAnyOrderLeastSquaresImpl implements IncrementalLeastSqua
private PolynomialFunction cachedFunction;
public IncrementalAnyOrderLeastSquaresImpl(int polynomialOrder) {
private final boolean hasIntercept;
public IncrementalAnyOrderLeastSquaresImpl(int polynomialOrder, boolean hasIntercept) {
this.hasIntercept = hasIntercept;
this.polynomialOrder = polynomialOrder;
matrixOfXSums = new double[polynomialOrder + 1][polynomialOrder + 1];
vectorOfXYMultSums = new double[polynomialOrder + 1];
if (hasIntercept) {
matrixOfXSums = new double[polynomialOrder + 1][polynomialOrder + 1];
vectorOfXYMultSums = new double[polynomialOrder + 1];
} else {
matrixOfXSums = new double[polynomialOrder][polynomialOrder];
vectorOfXYMultSums = new double[polynomialOrder];
}
}
public IncrementalAnyOrderLeastSquaresImpl(int polynomialOrder) {
this(polynomialOrder, true);
}
@Override
@@ -56,13 +68,15 @@ public class IncrementalAnyOrderLeastSquaresImpl implements IncrementalLeastSqua
try {
numberOfPointsAdded.incrementAndGet();
functionNeedsUpdate.set(true);
for (int i = 0; i <= polynomialOrder; i++) {
vectorOfXYMultSums[i] += y * Math.pow(x, i);
for (int j = 0; j <= polynomialOrder; j++) {
if (i == 0 && j == 0) {
for (int i = 0; hasIntercept ? i <= polynomialOrder : i < polynomialOrder; i++) {
int powerI = hasIntercept ? i : i+1;
vectorOfXYMultSums[i] += y * Math.pow(x, powerI);
for (int j = 0; hasIntercept ? j <= polynomialOrder : j < polynomialOrder; j++) {
int powerJ = hasIntercept ? j : j+1;
if (powerI == 0 && powerJ == 0) {
matrixOfXSums[i][j] += 1;
} else {
matrixOfXSums[i][j] += Math.pow(x, i+j);
matrixOfXSums[i][j] += Math.pow(x, powerI+powerJ);
}
}
}
@@ -115,7 +129,23 @@ public class IncrementalAnyOrderLeastSquaresImpl implements IncrementalLeastSqua
}
RealMatrix inversedMatrix = new LUDecompositionImpl(matrixOfXSumsCopy).getSolver().getInverse();
RealVector coeffs = inversedMatrix.operate(vectorOfXYMultSumsCopy);
resultFunction = new PolynomialFunction(coeffs.toArray());
if (!hasIntercept) {
resultFunction = createFunctionWithZeroIntercept(coeffs);
} else {
resultFunction = new PolynomialFunction(coeffs.toArray());
}
return resultFunction;
}
private PolynomialFunction createFunctionWithZeroIntercept(RealVector coeffs) {
PolynomialFunction resultFunction;
double[] coeffsNoIntercept = coeffs.toArray();
double[] coeffsWithZeroIntercept = new double[coeffsNoIntercept.length + 1];
coeffsWithZeroIntercept[0] = 0;
for (int i = 1; i < coeffsWithZeroIntercept.length; i++) {
coeffsWithZeroIntercept[i] = coeffsNoIntercept[i-1];
}
resultFunction = new PolynomialFunction(coeffsWithZeroIntercept);
return resultFunction;
}