mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-10-15 16:51:07 +00:00
IncrementalLeastSquares now has noIntercept Option
This commit is contained in:
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
+63
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
+39
-9
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user